Development Git

Git Stash with Name

How to Git Stash Your Changes with Associated Name and Find it Afterwards

Developers often have to multitask. You might be working on a new feature and there might be a request to fix a bug. Or you might be the lead developer on multiple projects.

When you are switching between tasks, sometimes you don’t want to commit unfinished work. In these cases, the git stash command can be a great help. It allows you to stack your changes and later come back to the unfinished work without adding unnecessary commits to your git repositories.

A Workflow for Git Stash

Let’s initialize a git master branch and commit a file ReadMe.txt.

$ mkdir my_project
$ cd my_project/
$ git init
$ touch ReadMe.txt
$ git add -A
$ git commit -m "Initialize"

Now let’s add another file called a.txt to the master branch.

$ touch a.txt
$ git add -A
$ git commit -m "Added a.txt"

If you check the history, you’ll see:

$ git log --oneline
d79f7aa Added a.txt
9434d7e Initialize

Now let’s create a feature1 branch and add a b.txt file:

$ git branch feature1
$ git checkout feature1
$ touch b.txt
$ git add -A
$ git commit -m "Added b.txt"

Open your b.txt file in an editor and put in the line:

I am about to change this to ...

And save the file. If you check your git status, you see the following:

$ git status
On branch feature1
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:   b.txt
 
no changes added to commit (use "git add" and/or "git commit -a")

Suppose, at this stage, you get a request to update the a.txt file on the master branch. But you are not done with the b.txt file. If you try to check out the master branch, you get the following error:

$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
b.txt
Please, commit your changes or stash them before you can switch branches.
Aborting

But you don’t want to commit the unfinished work in b.txt. You can use the git stash in this situation:

$ git stash
Saved working directory and index state WIP on feature1: 2cfe39b Added b.txt
HEAD is now at 2cfe39b Added b.txt

If you check b.txt, it should be empty:

$ cat b.txt
$

If you check the stash, you’ll see:

$ git stash list
stash@{0}: WIP on feature1: 2cfe39b Added b.txt

If you try to check out the master branch, you should be able to do it now:

$ git checkout master
Switched to branch 'master'

Suppose you make the changes necessary on the master and then go back to feature1 branch:

$ git checkout feature1

Your b.txt is still empty:

$ cat b.txt
$

But if you get the changes from the stash using the following command:

$ git stash apply
 
On branch feature1
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:   b.txt
 
no changes added to commit (use "git add" and/or "git commit -a")

The stash apply command took the stashed changes and applied it to b.txt file
You can complete your work in b.txt my modifying the line

I am about to change this to ...

 
To

I am about to change this to DONE

Now go ahead and commit your changes:

$ git add -A
$ git commit -m "Modified b.txt”

Applying a stash doesn’t automatically clean it from the stash. You have to clean it up manually:

$ git stash drop
Dropped refs/stash@{0} (0a66a16b32633e8d564d08e38254c491c1b1d3be)

Why Git Stash with Name?

The git stash is a stack. So you can keep piling your changes.

Suppose you add “X” to b.txt, stash it, add a “Y” to b.txt, stash it and add a “Z” to b.txt and stash it. If you check the stash history, you’ll see something like this:

$ git stash list
stash@{0}: WIP on feature1: 2d6f515 Modified b.txt
stash@{1}: WIP on feature1: 2d6f515 Modified b.txt
stash@{2}: WIP on feature1: 2d6f515 Modified b.txt

You have no way of knowing which stash has which change. When you are stashing, you can use the save option to put in comments. You can use the comments to attach a name to your stash and make them recognizable:

$ git stash save "X"
Saved working directory and index state On feature1: X
HEAD is now at 2d6f515 Modified b.txt

For adding “X”, “Y” and “Z” modification, you can get the following in your stash using the save option for each stash:

$ git stash list
stash@{0}: On feature1: Z
stash@{1}: On feature1: Y
stash@{2}: On feature1: X

Now you have a name for each change you stashed. Unfortunately, you can’t use the name to retrieve the stash. You’ll have to use the stash number. Suppose you want to get your “Y” change. You see that stash@{1} is Y. So you can apply that change to your current branch:

$ git stash apply stash@{1}

And your b.txt should have the changes from stash@{1}.

You can use the same method to drop a stash. Suppose, you realize you don’t need the X stash any longer. You can just use the following command to delete that stash:

$ git stash drop stash@{2}

And the stash should be gone:

$ git stash list
stash@{0}: On feature1: Z
stash@{1}: On feature1: Y

Remember that if you use the apply and drop options without any parameters, it will use the top of the stack (stash@{0}).

Conclusion

The git stash command is a powerful way to manage your workspace. Mastering this command will help you work more efficiently.

Further Study:
References:

Stack Overflow: how-to-name-and-retrieve-a-stash-by-name-in-git

About the author

Zak H

Zak H

Zak H. lives in Los Angeles. He enjoys the California sunshine and loves working in emerging technologies and writing about Linux and DevOps topics.