Stashing only un-staged changes in Git
I'd like to do the following work flow:
- Add changes to the stage.
- Stash all the other changes that were not staged.
- Do some stuff with the things in stage (i.e. build, run tests, etc)
- Apply the stash.
Is there a way to do step 2?
Example
echo "123" > foo
git add foo # Assumes this is a git directory
echo "456" >> foo
git stash
cat foo # Should yield 123
git stash push
has an option --keep-index
that does exactly what you need.
So, run git stash push --keep-index
.
This may be done in 3 steps: save staged changes, stash everything else, restore index with staged changes. Which is basically:
git commit -m 'Save index'
git stash push -u -m 'Unstaged changes and untracked files'
git reset --soft HEAD^
This will do exactly what you want.
git stash save --keep-index
Also, Re:
Why not commit your changes after staging them? – Shin
A: Because you should always checkin tested code :) That means, you need to run the tests with only the changes you are about to commit
All this apart from the fact that of course, as an experienced programmer, you have the innate urge to test and review just those changes -- only partly kidding
With git version 2.7.4
you may do:
git stash save --patch
The git
will ask you to add or not your changes into stash.
And you then just answer y
or n
You can restore working directory as you always do that:
git stash pop
or, if you want to keep saved changes in stash:
git stash apply
Stashing just the working tree (unstaged changes) in Git is more difficult than it should be. The accepted answer stashes the unstaged changes, but also stashes the staged changes (and leaves them staged as well), which is rarely what you want.
This alias works well:
stash-working = "!f() { \
git commit --quiet --no-verify -m \"temp for stash-working\" && \
git stash push \"$@\" && \
git reset --quiet --soft HEAD~1; }; f"
It commits the staged changes temporarily, creates a stash from the remaining changes (and allows additional arguments such as --include-untracked
and --message
to be passed as alias arguments), and then resets the temporary commit to get back the staged changes.
It is similar to @Simon Knapp's answer, but with a few minor differences -- it uses --quiet
on the temporary actions taken, and it accepts any number of parameters for the stash push
, rather than hard-coding the -m
, and it does add --soft
to the final reset so that the index remains as it started. It also uses --no-verify
on the commit to avoid changes to the working copy from pre-commit hooks (HT: @Granfalloner).
For the opposite problem of stashing just the staged changes (alias stash-index
) see this answer.