Ever messed up with git repositories (who hasn’t)? Git stash may turn out to be a lifesaver. It has some really cool options. Let’s check them out!
Get acquainted with stash methodology
Stash simply does a clearing job. You want to pull changes to your local repo and current changes are blocking the pull. You may use git stash to send them in the background that later on can be popped out. As simple as that.
Stash options:
- push
- list
- show
- pop
- apply
- branch
- clear
- drop
Their brief definitions are available in git-stash
manual. Feel free to give a quick look at man git-stash
. Following are some example based usage in brief.
git stash push
Or you can say just git stash
if you don’t want to use any other option with it. It simply pushes your current changes (both staged or not staged) to stash area.
mkdir test_stash cd test_stash git init touch cool_file git add cool_file git commit -m "Add cool_file" echo "Hello stash" >> cool_file
Now, these changes are not staged. Try:
git status modified: cool_stash git stash Saved working directory and index state WIP on master: 2855c2a Add cool_file
It’s like you made some changes and before making the commit you want to try a different approach. So, you just stashed your current changes and try out a different approach if you like it, then keep it. If you don’t like it, then git reset --hard
and we can bring back our old changes with pop
option shown below.
git stash list
Let’s do one more stash entry first.
echo "hello again" >> cool_stash git stash Saved working directory and index state WIP on master: 2855c2a Add cool_stash
Now if you have done a couple of stash entries, then you may have a look on the stash list with:
git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash stash@{1}: WIP on master: 2855c2a Add cool_stash
Here are our 2 stash entries.
stash@{0} is new and thus on the top of the stack.
stash@{1} is the old one.
But these are not specific. I want to know what changes are stored in each stash entry. Let’s go ahead 🙂
git stash show
To see changes (diff) stored in any stash entry use
git stash show -p stash@{0} diff --git a/cool_stash b/cool_stash index e69de29..13ab7f7 100644 --- a/cool_stash +++ b/cool_stash @@ -0,0 +1 @@ +hello again
For the recent stash, you may omit stash@{0}
.
git stash pop
Okay, now I want to take out the stashed changes in stash@{1}
. It’s simple.
git stash pop stash@{1}
Note that
- popped changes are
unstaged
- popped stash is no longer present in stash area. Verify it with
git stash list
.
What if we want to pop out a stash entry without removing it from the stash area? Here comes the next option.
git stash apply
First, send the current changes back to stash and then try apply
.
git stash Saved working directory and index state WIP on master: 2855c2a Add cool_stash git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash stash@{1}: WIP on master: 2855c2a Add cool_stash git stash apply modified: cool_stash git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash stash@{1}: WIP on master: 2855c2a Add cool_stash
Note that
- applied changes are
unstaged
- applied stash is present in stash area. Verified it with
git stash list
.
git stash branch
In case you want to pop out a stash entry but on a new branch, then you make the use of this option. Example
git status modified: cool_stash git stash Saved working directory and index state WIP on master: 2855c2a Add cool_stash git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash stash@{1}: WIP on master: 2855c2a Add cool_stash stash@{2}: WIP on master: 2855c2a Add cool_stash git stash branch side_branch stash@{0} Switched to a new branch 'side_branch' On branch side_branch Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: cool_stash no changes added to commit (use "git add" and/or "git commit -a") Dropped stash@{0} (919c486edb34e276383eb1682db0c29ac7eb9623)
Note:
- After branching successfully that applied stash is dropped out.
- Branching will be successful, but if the applied changes are creating conflict, then the applied stash is not dropped out.
Useful as per the manual page:
This is useful if the branch on which you ran git stash push has changed enough that git stash apply may fails due to conflicts. Since the stash entry is applied on top of the commit that was HEAD at the time git stash was run, it restores the originally
stashed state with no conflicts.
I understand that if you fear to apply stash changes to the current HEAD because you believe that it may create conflict, then you may use this option to stash out on a test branch.
git stash clear
How many stash entries do you have now in your master? It may be any number, to remove all of them in one shot, clear the stash area with this option.
git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash stash@{1}: WIP on master: 2855c2a Add cool_stash stash@{2}: WIP on master: 2855c2a Add cool_stash git stash clear git stash list
Moving on!
git stash drop
It simply drops (delete) stash entry. Let’s say.
echo "stash stash stash" >> cool_stash git status modified: cool_stash git stash Saved working directory and index state WIP on master: 2855c2a Add cool_stash git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash echo "git git git" >> cool_stash git stash Saved working directory and index state WIP on master: 2855c2a Add cool_stash git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash stash@{1}: WIP on master: 2855c2a Add cool_stash git stash drop stash@{1} Dropped stash@{0} (bd2b6c6d98742ca504677cf36ddb6bc93d535654) git stash list stash@{0}: WIP on master: 2855c2a Add cool_stash
Some less popular options in usage for git stash are also available:
- git stash save
- git stash create
- git stash store
Conclusion
It is fun to use git stash at times. I remember I used it in bringing a deleted file back. I was working on a git repo and had some current changes some were staged and some were unstaged and accidentally I deleted a useful file. I wanted to get that file back and I knew it that I can do it with git reset --hard
to revert all local changes. But at the same time, I didn’t want to loose my current changes. What I did, I stashed my current changes (except the change of deleting the file) and did git reset --hard
I got my file back and then I poped out stashed changes. Simple? Yeah, when you know it.
I used interactive git stash in that case with
git stash push --patch
Where I could exactly choose what hunk of changes to be stashed (as I didn’t want to stash the change of deleting the file).
Hope you liked it. See you in the next post! o/
Thanks for reading! 🙂
Really good post.
Loved the real life example at the end.
That actually showed me the value of this option.
Keep writing!
LikeLiked by 1 person
Glad to hear that 🙂
LikeLike