This week's Git Tip of the Week is about keeping work in progress safe, known as stashing. You can subscribe to the feed if you want to receive new instalments automatically.
Drop everything bugs
Sometimes, when you are working on a problem you need to drop it suddenly in order to work on a different problem, like a critical bug that has been reported against a production version of your code.
Whilst you could easily create a new checkout of your project with the specific branch, it's faster to switch branches in Git natively, and saves setting up other tools like an IDE or a test server.
The problem is, your work may not be in a fit state to commit at the time the bug comes in. Rather than committing a half working state, you ideally want to save the work in progress (including dirty, uncommitted files), to permit you to switch to the higher priority issue, and resume when necessary.
Git Stash
This is where git stash
comes in handy. This takes a working tree and files it away in a location which can be retrieved at a later stage. The stash can then be popped to get the changes back as they were prior to the stash taking place.
To create a stash, just run the git stash
command. You can see what stashes are present with git list
:
$ git stash list $ touch example $ git add example $ git stash Saved working directory and index state WIP on master: dc3ea83 HEAD is now at dc3ea83 $ git stash list stash@{0}: WIP on master: dc3ea83 $ ls example $ # do emergency bugfix here, and afterwards $ git stash pop # or git stash apply $ ls example example
Here, we created a new stash which contained the example
file. Once we'd done the stash, we were reset to the current commit (i.e. a clean workspace), so the example
file is no longer present.
We can list the available stashes with git stash list
, which gives them their identifier (in this case, stash@{0}
) which can be used to identify the changes. (It defaults to the last stash if not specified.)
The stash identifier also includes what branch the stash was created from. Importantly, once the stash has been created, applying (or popping) the stash results in just the differences being added, rather than resetting back to a specific previous state. This allows subsequent changes to be made on the branch, followed by replaying the stash changes on the current version of the branch afterwards.
Git stash can be used to avoid merge conflicts with work-in-progress code. Simply stash before doing a pull, and unstash afterwards, as the example in the manpage shows:
$ git pull ... file foobar not up to date, cannot merge. $ git stash $ git pull $ git stash pop
Notes
-
The stash only applies to added files; it doesn't apply to untracked files. If you want to add untracked files as well, you need to run
git add --all
prior to runninggit stash
operation. The WIP stands for Work In Progress, since it's not obvious to non-English native speakers.
git stash pop
will remove the stash from the list;git stash apply
will keep the stash in the listThe {0} represents the last stash you did, the {1} represents the second to last, and so on. This syntax also turns up elsewhere (e.g. reflogs).
Individual stashes can be removed with
git stash drop
, orgit stash clear
to get rid of all of them.Git stashes are stored as commit objects, but the branch HEAD isn't updated to point to them. Instead, they are referenced from a reflog entry in
.git/logs/refs
. You can usegit show stash@{0}
to see a stash.
Come back next week for another instalment in the Git Tip of the Week series.