Git Stashing with an Example

Stashing is nothing but temporary storage, where git stash command temporarily stores the modified files, untracked files and staged changes made to our working directory in its stack and we can move forward and work on something else and can come back to the previous section and work whenever we want.

Let us go ahead and understand stashing with an example as follow:

In this section am going to walk through the steps necessary to execute a stash. Let us go to my project folder and then into my Git repository called Starter-web-1/, If you do git status, Git tells that, we are on a master branch with a clean working directory.
SWE-git-status

  • So, before going to modify a few files let's check for the file list, do an ls
    SWE-git-ls
  • Edit the file simple.html by using the default text editor, here am going to update the title as shown in the below image then save and exit.
    SWE-modified-simple-html-file
  • If you do git status, you can see your modified file however, if the simple.html file program is still in progress and hence I cannot commit this file in its current state.
    SWE-git-status-two

So I can modify a different file for something that just has to get done right now. In order to save the changes that I have for simple.html, I can use Git's stash command to stash away any changes that are work in progress.

So that I can move to another file, and work on something else, let's do that now git stash by default, it is going to execute the save command.
SWE-git-stash


Since it is the default command being executed when we invoke git stash

Now, let us check the state of our working directory git status, Git tells us that, we are still on master branch with a clean working directory and there are no files which are staged for commit or there is nothing in the Git's staging area.
SWE-git-status-three

  • So if I open the simple.html file once again, I can see that the title is back to where it was before editing the file.
    SWE-simple-html-back-to-original-state
  • Let's go ahead and modify the README.md file, just improve the copyright section as shown in the below image and then save and exit.
    SWE-modified-README-file
  • Once again if you do a git status, You can see that we have our modified file.
    SWE-git-status-four
  • And hence commit the changes using the express commit git commit -am "Quick fix in production to improve copyright notice"
    SWE-git-commit-one
  • If you do a git status, you can see that your working directory is clean.
    SWE-git-status-five
  • What about the stash that we created for the simple.html file?, How do we get that back, till now we have completed whatever work we needed to do? that was on a high priority.
  • So we need to get back to our changes that we were working on before, to do that we need to apply our stash command as git stash apply
    SWE-git-stash-apply
  • The above command basically gives us the git status on our working directory.
    SWE-git-status-six

Which confirms whatever actions the git stash apply command has to do. If you open the simple.html file, it put us back to the way it was, right before we issued the git stash command.

So now, we can pick up where we left off and continue editing this file. if you wanted to do any additional changes to this file, let's do it then save and exit.
SWE-additional-modified-simple-html

  • Let us commit the changes you have made to the simple.html file using the express commit git commit -am "Done with simple.html file"
    SWE-git-commit-two
  • And now, if you do a git status, you can see that you are in a clean working directory.
    SWE-git-status-seven

We are not quite done yet. Let us move forward, use the stash sub-command as git stash list , you can see a single item which is referenced as {0} which is nothing but where we start off, WIP means work in progress in the master branch and reference id.
SWE-git-stash-list

Since we've already applied the stash, we don't need it anymore, which means we can drop the stash. So, we can just issue git stash drop command and it will drop the last stash.
SWE-git-stash-drop

Git Commit Operation

Stashing Untracked File in Git

In the previous section, you come to know that how Stash command will work, Now let us know how to stash an untracked file as shown below:

We will start where we left off, Currently, am in the working directory of my Git repository, The first thing we have to understand is that by default git stash command will stash only the tracked files in Git repository.

If you do a git ls -files , you can see a list of all the files that the Git repository is tracking including humans.txt file.
SUF-ls-files
SUF-humans-file

  • Go ahead and edit that file by adding some text as shown in the below image and then save and exit.
    SUF-modified-humans-files
  • If you do a git status , we can see that we have the Changes not staged for commit, This is the status that is given to the working directory changes for files that are being tracked by Git.
    SUF-git-status-one
  • Let us create a new file called ANewFile.txt and add some text in this file, save then exit.
    SUF-creating-new-file
  • If I do a git status, we can see a slightly different status, saying that the Git is not tracking yet.
    SUF-git-status-two
  • If I do git stash , we can see only the modified file humans.txt.
    SUF-git-stash
  • And if I do a git status , we still see an untracked file ANewFile.txt in the working directory.
    SUF-git-status-three
  • This means that our working directory is not clean yet, So am going to re-apply the git stash command, git stash apply So this will have both tracked modified file and the untracked file.
    SUF-git-stash-apply
  • Let's drop the last stashing by using the command git stash drop
    SUF-git-stash-drop
  • If I do a git stash list there won't be any result because we do not have any stashes pending here.
    SUF-git-stash-list

we could just simply add the new file to the Git staging area and once that occurs, Git will start tracking the file.

However, if you are not sure, if you want to add that new file, but you still want to stash it, so you can determine that later, Let us do a git status, it shows as follow.
SUF-git-status-four

  • We can use an extra parameter with git stash command, git stash -u
    SUF-git-stash-u
  • So the above command will now include any untracked files that are not being excluded by the .gitignore
  • Now, let us do git status, you can see that you have a clean working directory.
    SUF-git-status-five
  • Let's have a look at stash list, git stash list , we can see that we have a single item on the master branch.
    SUF-git-stash-list-two
  • Go ahead and edit README.md file, just add some text as shown in the below image.save and then exit.
    SUF-editing-README-file
  • Now commit the changes without mentioning the m parameter by using the text editor, git commit -a "Quick fix after stash on Readme file", save and exit.
    SUF-git-commit-a
  • Once again do a git status, it says that we are on a clean working directory.
    SUF-git-status-eight
  • Instead of doing git stash apply and git stash drop we can use git stash pop, it is nothing but just popping the stack. you can see that we have tracked and modified file and an untracked file back in our working directory and the same command is going to drop the last stash as well.
    SUF-git-stash-pop
  • If you do a git status, we have our modified file and our new file.
  • Well, am not really keen on the new file, so am going to get remove it, rm ANewFile.txt
    SUF-rm-anewfile
  • Now, if you do a git status, we have only modified file in our working directory.
    SUF-git-status-six
  • Let us commit the changes git commit -am "Updates to humans file after stash pop".
    SUF-git-commit
  • At last, if you do a git status, Git confirms that we are on a clean working directory.
    SUF-git-status-seven

Configuring P4merge on Windows

Managing Multiple Stashes in Git

In this Section am going to teach you all how to manage multiple stashes in the Git repository.

Let us start from where we left off, If you do a git status, Git tells that, we are in the clean working directory on master branch with my Git repository.
MMS-git-status-one

  • If you do an ls, you can see multiple files, which are part of this repository, and let us modify a few of these files.
    MMS-ls
  • Let's start with a simple.html file, add some text in the title section as Updating Title for Multiple Stash Example and then save and close.
    MMS-modify-simple-html

In the previous section, we used only git stash command because we were doing just one stash at a time, but now we have to use a parameter called save when we are going to do multiple stashes.

This git stash save "simple changes" this will be like a commit message but for a stash, This will make it easier for us to differentiate between the different stashes, Hence we have created our first stash.
MMS-simple-stash

Let us go ahead and edit the index.html file, add some text to the title tag, Adding a title for Stash example, save then exit.
MMS-modify-index-html

And then do another stash like git stash save "index changes"
MMS-index-stash

Now let us edit README.md file, add some text under the starter web project as shown in the below image and save then exit.
MMS-modify-readme-file

Once you have done with editing, let's create another one stash git stash save "Readme changes"
MMS-readme-stash

Now, list out all our stashes using, git stash list .It will list all our stashes.
MMS-stash-list-one

You will notice something interesting here that, the stash index is probably the reverse of what we are expecting that the last stash is index "{0}".

Now, the index "{0}" may be a thing that is throwing you off as well, but that comes from a programming background, where indexes of lists or arrays start with index "{0}". But, the part that is counter-intuitive here is that the last stash is index "{0}", and not index "{2}".

Let us pick out the specific stash to look at by using the command called git stash show stash@{1} , this is called as the reflog syntax, which will allow us to reference the specific stash to show, so here the stash@{1} shows us index.html is part of this stash.
MMS-reflog-stash

If you do a git status, Git tells that, we are on a clean working directory.
MMS-git-status-two

And now, you can re-apply the stashes, just like in the other command, you can specify the specific stash we want to apply, here am going to apply for the middle stash that is nothing but index changes, so let's do that now git stash apply stash@{1} and press enter.

The git stash will apply that specific change that is captured in that stash, so now, we have our modified file index.html.
MMS-git-stash-apply

If you do a git status, Git tells that, we have modified file just like stash apply.
MMS-git-status-three

Like other commands we covered, the drop command will also take the stash references, Before that, just list out all the stashes once more, git stash list .
MMS-git-stash-list-two

So we have applied the stash to the reference {1}, that is nothing but index changes, so we do not need anymore, let us drop that stash git stash drop stash@{1} , so the index stash has no longer listed in the stash list.
MMS-git-stash-drop

If you do git stash list , here the interesting thing is that the next stash available has gone in to populate the stashes at "{1}", which is the simple changes.
MMS-git-stash-list-three

You can see only two stashes listed here if in case, you do not need these two stashes for some reason, then you can delete these stashes as well by using the command called git stash clear , so it has cleared all the stashes.
MMS-git-stash-clear

If you do git stash list, there is no result.
MMS-git-stash-list-four

Comparing Working Directory with Staging Area

Branch Stashing in Git

Let us understand how to do a branch stashing in Git.

Start from where we left off, If you do a git status, you can see that you have a modified file called index.html in your working directory.
BS-git-status

  • Let us list out the stashes over here, git stash list , you do not have any stashes.
    BS-stash-list
  • Along with the index.html file, let's modify some other file too, Edit simple.html file, add some text in the title as shown in the below image and then save and close.
    BS-modify-simple-html
  • And also edit humans.txt file, Add some more values to the technology section and then save and close.
    BS-modify-humans-txt
  • If you do a git status, you can see three modified files in your working directory.
    BS-git-status-one
  • Go ahead and add one of them to the Git staging area, here am adding the index.html file to the staging area git add index.html
    BS-git-add-index-html
  • Now, let's do a git status, you can see index.html in the changes to be committed state in the staging area and rest of two are in the changes not staged for commit basically a modified file in the working directory.
    BS-git-status-two
  • Just for the demo purpose let's create another file called New.md and then add some text in the default editor as shown in the image. save then close.
    BS-creting-new-md-file
  • If you do a git status one more time, you can see the files in the three different bucket of Git.
  • Changes to be committed, that is the Git staging area that contains the index.html file, two files that are modified in the working directory, so that is changes not staged for commit and the last one is the new file is in the untracked state.
    BS-git-status-three

By doing all these I realize that this really does belong on a feature branch and not against the master branch.

We can correct these by moving all it to the feature branch, the first thing we need to do is that we have to add all these modified files and also new files to stash.

This can be done by using the -u parameter with git stash command, git stash -u, here -u parameter is going to save not only the modified files but also the new file.
BS-git-stash-u

  • If you do a git status, you can see that, we are in a clean working directory.
    BS-git-status-six
  • Let's apply a stash to the new branch, to do that we use git stash branch newchanges , where newchanges is the branch name.
    BS-git-stash-branch-newchanges
  • There are several things happened by passing the above command, first thing is that new branch has created called newchanges and then we are switched to that new branch, and also our stash has been applied at the very end and the same stash has been dropped.
  • So, list out our stashes now git stash list currently, there are no stashes in the stashed list.
    BS-git-stash-list-one
  • If you do git status, it will give the same output as our git stash branch command gave us.
    BS-git-status-four
  • Now, let us go ahead and commit all the changes, Before that just remove the unwanted file, thus am going to remove new.md file rm new.md , we have successfully removed new.md file.
    BS-remove-new-md
  • Let us add rest of the file to the staging area, git add .
    BS-git-add
  • Once again if you do git status, you can see that all the files which we have modified are in the changes to be committed state that is nothing but the staging area.
    BS-git-status-five
  • Now you can commit the changes by using the default text editor, git commit , this will brings up the text editor, enter the commit message changes after git stash-branch-command save and then exit.
    BS-git-commit
  • Now we have successfully committed the changes so we can integrate these changes to the master.
  • Return back to the master branch, let us use git checkout master command so we are back on the master branch.
    BS-git-checkout-master
  • Let us merge the branch newchanges git merge newchanges , thus it resulted in a Fast forward merge.
    BS-git-merge-newchanges
  • Now let us delete the newchanges branch git branch -d newchanges
    BS-delete-newchanges
  • If you do a git branch, it will list only the master branch, that means the new branch called newchanges branch has deleted.
    BS-git-branch

Comparison Section cleanup and Push back to Github

Stashing Section Cleanup

We have reached the last section of stashing, here am just going to synchronize changes to the Github.

  • So, let us start from where we left off, If you do a git status , we are currently in the working directory of my Git repository on the master branch, with a clean working directory with 5 commits ahead of origin/master branch.
    SCL-git-status
  • As a best practice, let's do pull before pushing anything to the GitHub, let us pull now git pull origin master , as expected we are already up-to-date.
    SCL-git-pull
  • Now push all your changes, git push origin master
    SCL-git-push
  • Now, you can go to Github and refresh the page and then go to your git repository, there you can see your latest commit pop up there.
    SCL-github-page

Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions