[Tech] Git Stash!
The process of cleaning up the mess which was created using command “git stash” turned out to be interesting learning about when the command needs to be used, when not to be used, what’s under the hood.
Earlier Understanding
Git stash can be used when one needs to save the local changes, but not commit and push the changes to the remote.
Let there be a developer named B.
B’s Assumption
Git pop returns the changes which are saved using git stash. So, on running ideally changes stashed on the current branch would return.
Problem
B has a task at hand. B was asked to implement a feature hence, code change involves modifying multiple files in the codebase. B decided to embark on the assigned task.
Updated the master branch. Created a new branch for implementing this completely new feature. Checked out the new branch. Started with the code.
In a nutshell
On branch master
git pull origin masterCreated a new branch
git branch feature-xCheck out the new branch.
git checkout feature-x
Midway through the implementation. One bug comes up. The bug was directly impacting the business. Hence, had to be fixed as soon as possible.
B’s task priority got changed. Bug fix had to be completed and pushed.
To start working on the bug fix. B had to leave the changes done on feature-x branch midway. Changes were not tested. So, B was not interested in committing the changes either.
B decides to switch branch to master. Thinks of taking a fresh pull. Followed by creating a branch on which bug fix is to be resolved.
Switches branch from feature-x to master
git checkout master
Git raises an error, and B is not able to switch branch.
Git Error Message
You have uncommitted changes on this branch. Before switching the branch either commit or stash your changes. Otherwise, changes will be overwritten.
At this point in time. B has practically 2 choices in hand. Changes were not tested so B has decided not to commit. Here is when stash came into play.
1. Commit changes
2. Stash changes
Stashing the changes on branch feature-x
git stash
Changes got saved. B was able to switch to master branch. And proceed with working on the bug fix. Likewise, B got some ad-hoc tasks as well. Priority kept changing. To have every task separated. B continued creating separate branches, kept saving changes on every branch using git stash.
B finally got time to work on the initial feature, branch feature-x. B wanted to see the changes last made.
To see the changes last made on the feature-x branch. B runs
git stash popTo check the list of modified files
git status
Unlikely to the expected behavior. Something got messed up.
The Mess
Instead of fetching modified files on branch feature-x. B got a list of files modified on the last branch B worked on and ran a git stash. Screwed.
Learnings
- Git stash does not work as was assumed by B. It does save the changes. But, not per branch. Stash works on the complete repository.
- Git stash pop returns the last stashed changes irrespective of the branch.
If not used and noticed carefully might result in changes getting mixed. - In case stuck up in a similar situation as B. One can commit the changes.
Switch branch. When back on the same old branch. Check the git log. Followed by resetting the HEAD. - Another alternate approach could be. To keep committing the changes to your branch. Even if there is a bug because of the addition of a few lines in the code. With the next commit containing the corrections. The previously made changes to the file would be overwritten.
- If stash still appears to be handy. Here, is one thing which would help to stay away from the mess. Avoid directly running git stash pop.
- Always make sure to check the list of stashes done till now.
Git stash list shows the list of all the stashes made in the repository and on which branch.
git stash liststash@{0}: WIP on feature-a: 049d078 added X,Y,Z things
stash@{1}: WIP on bug-fix: c264051 added exception handling
stash@{2}: WIP on feature-x: 21d80a5 added A,B,C things
Running git stash pop. Would pop stash@{0} from the list. And return all the modified files. Hence, to get only the changes made on branch feature-x we can run
git stash pop stash@{2}
7. If we are interested in popping the stashes but maintaining the history log.
Instead of git stash pop.
git stash apply
Cleaning up our own mess. Comes up with learnings. Things go wrong for good. This marks no more living with the false assumption and two commands.