Git stash is really cool

Git stash is really cool

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 --hardI 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! πŸ™‚

 

 

Advertisements

2 thoughts on “Git stash is really cool

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s