11

First of all, I do know about --keep-index. This is not what I want because it still stashes all changes, but leaves the staged one in the worktree. I would like to only stash the unstaged files, if possible without adding all changes again with git stash --patch.

13
  • 1
    Could this question provide an answer? Commented Mar 15, 2018 at 14:29
  • I typically avoid using only stash in tricky cases like this and simply go with commit -- commit the things you want to keep, and after that stash the rest temporarily, if needed.
    – jsageryd
    Commented Mar 17, 2018 at 18:10
  • @jsageryd that doesn't work if you have a pre-commit hook and the unstaged changes don't satisfy that hook. Commented Jul 18, 2018 at 21:53
  • 1
    I never use pre-commit hooks for this reason -- in my opinion it is the wrong place to put validation since it hinders workflows like the one above. If you have a pre-commit hook you can pass the -n (--no-verify) option to git commit to bypass it.
    – jsageryd
    Commented Jul 20, 2018 at 8:30
  • @jsageryd so basically, you avoid using pre-commit hooks because git-stash sucks and can't stash only the unstaged changes? I think the solution to this is fix git so that it can stash only the unstaged changes...
    – scaly
    Commented Jan 20, 2021 at 4:49

3 Answers 3

2
+25

If you want to store the diff between the index (what's staged) and the worktree (what's not staged yet), this simply is git diff :

# store it :
git diff > stash.patch

# if you additionally want to put the unstaged changes away :
git stash -k

To apply at later these changes on the worktree (not on the index) : use git apply

git apply stash.patch

You could also use what gets stored in the stash to re-create that diff :

# stash the changes :
git stash -k

# to reapply them on the worktree at a later time :
#   the 'unstaged changes' are the diff between 
#    - what the index was (stash^2)
#    - and what the worktree was (stash)
git diff stash^2 stash | git apply -

# again : 'git apply' will apply the changes on the *worktree*, not the index
1

Best I can come up with is:

git commit -n -m temp
git stash push -u
git reset HEAD~1

This will commit without triggering any pre-commit hooks. Then it will stash the changes that remain (i.e. the unstaged changes from before). Finally, it will reset head back to the pre-commit state (before the "temp" commit).

0

You cannot do it direclty, but you can eventually isolate only unstaged or only staged changes, or both, without even using any git-stash command at all :


git switch -c separated-stashes

Equivalent to the old checkout -b : creates a new branch and switch on it. It won't change neither your worktree nor your index so you'll basically have the same git status' output as before, but this time on the new branch. Contrary to a simple git switch / git checkout, it won't warn you to stash or commit your changes before switching branches, because you are explicitly creating a brand new branch through -c/-b.


git commit -m "staged"

Create a first commit on the new branch containing only staged changes from the beginning.


git add -u && git commit -m "unstaged"

Create a second commit with unstaged changes from the beginning.


git switch - # == git checkout -

Go back to the previous branch you were on.

Now you have stashed everything and can cherry-pick what you need (staged / unstaged) wherever and whenever you want.


This might look a little cumbersome but you're free to define a git alias to automate it :

git config --global alias.bratisla '!git switch -c separated-stashes; git commit -m "staged changes"; git add -u; git commit -m "unstaged changes"; git switch -' # why this name ? : youtu.be/LpE1bJp8-4w
2
  • So it makes it impossible to use this logic in a pre-commit hook because you have to make new commits just to stash only the unstaged changes. This is super lame.
    – scaly
    Commented Jan 20, 2021 at 4:47
  • Well, OP didn't ask about a pre-commit hook compliant solution, it seems it was more a manual command line solution, and as stated in this comment you don't necessarily want to make one, especially for stashing stuff. But if you have a way to assess the problem without having to commit so that you can make it a hook, I would love to ear it @scaly
    – dilavasso
    Commented Feb 1, 2021 at 21:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.