1

I know there are tons of posts on this topic, but I can't seem to find this specific answer.

Obviously, a way to do this would be to git commit the staged changes, git reset --hard HEAD, then git reset --soft HEAD~, then git add -u, which is quite verbose.

The default behavior for reset is --mixed which accomplishes the inverse of what I'm asking for. There certainly has to be a one command solution for this, or at least a better way.

ram
  • 680
  • 5
  • 15
  • Does this answer your question? [How to remove local (untracked) files from the current Git working tree](https://stackoverflow.com/questions/61212/how-to-remove-local-untracked-files-from-the-current-git-working-tree) – Mickael B. Jan 28 '20 at 19:56
  • Sounds like you want `git stash --keep-index` – William Pursell Jan 28 '20 at 20:03

2 Answers2

5

Prior to Git 2.23, no.

In Git 2.23 or later, git restore can do the job:

git restore -s HEAD

Note that git stash -k does not do the trick: it leaves the working tree matching the index, not the HEAD commit.1

In all Git versions since 2.5, it may be easier and/or better to use git worktree add to create a second work-tree based on the current commit:

git worktree add --detach <path> HEAD

where <path> is wherever you'd like the new work-tree to show up. This has the advantage of not touching your existing work-tree. (In Git versions prior to 2.15, I advise doing whatever you are doing in this added work-tree within two weeks, then deleting it, as there's a nasty little bug in those versions of Git regarding added work-trees. If you're just doing this for the work-tree files, the bug itself is harmless, though.)

In versions of Git prior to 2.23, you can do:

git stash
# do whatever your job is here, followed by `git reset --hard` if needed
git stash apply --index
git stash drop

(or git stash pop --index; I just like to keep the apply and drop separate myself).


1git stash -k makes the two stash commits in the usual way, so they are the same as always. But then, instead of git reset --hard, which a regular non--k git stash does, it forcibly adjusts the work-tree to match the stash commit.

The point of git stash -k is to allow you to run some sort of test that uses the work-tree content, without having to extract the stashed index to another work-tree. For instance, if you have an automated test system that uses what's in the work-tree, rather than what's in the index, you can git stash -k, run the tests, then git reset --hard to make the stash applicable again and apply and drop the stash.

Annoyingly, since git stash doesn't make a stash if the index and work-tree match HEAD, git stash -k is hard to use to do this kind of automated testing, because there's no guarantee that it actually made a stash.

torek
  • 448,244
  • 59
  • 642
  • 775
  • I'd just ``stash=`git write-tree`; git reset --hard; git read-tree $stash``, no need to do all the diffing and committing when you just want the index. – jthill Jan 28 '20 at 21:00
  • @jthill sure, but that's using commands not aimed at the user. :-) The 2.23+ `git restore` is aimed at users. It might be worth adding as an answer though! – torek Jan 28 '20 at 21:27
  • Yah, I composed it, but looking at it it was so close to a repeat of yours I just added it as a comment instead, I'd already upvoted. Gonna have to spend some time staring at the new commands, my reaction right now feels a bit too get-off-my-lawn-ish. – jthill Jan 28 '20 at 21:42
1

Pretty sure you are asking for git stash --keep-index

William Pursell
  • 204,365
  • 48
  • 270
  • 300
  • Yes, this is exactly what I wanted. I'll accept your answer in 4 mins. Thank You! – ram Jan 28 '20 at 20:06