The official Git documentation presents the following example as a valid
use-case for the
You are in the middle of a refactoring session and your boss comes in and demands that you fix something immediately. You might typically use git-stash1 to store your changes away temporarily. However, your working tree is in such a state of disarray (with new, moved, and removed files and other bits and pieces strewn around) that you don’t want to risk disturbing any of it. (source)
If you don’t know about
worktree, you should check it out. It is a handy,
powerful yet little known command. I don’t use it, however. It will check out
a new branch to a new directory, and I don’t like that. I prefer to keep the
simple, default 1:1 relationship between the repository and the file system.
Managing multiple working trees seems like an unnecessary complication when
similar results can be achieved with a few aliases.
Indeed, for the use-case above, my workflow revolves around three git-aliases. Over the years, I collected many. Most of them (like the ones mentioned here) are not my doing. I stumbled upon them somewhere, tinkered as needed, and then incorporated them into my daily workflow.
This adds all changes, including untracked files, to the staging area and then
commits with a
SAVEPOINT message. When an emergency hits and I need to
quickly switch context, I’ll just
git save and check out to a new branch to
do whatever I am tasked to do. When I’m done, I’ll switch back to my original
git undo(see below), and resume work. It’s easily configured with:
$ git config --global alias.save '!git add -A && git commit -m "SAVEPOINT"'
wip is similar to
save. It stages all tracked changes and then commits with
WIP message. So yes, it offers the same features as above but leaves
untracked files unstaged, a significant difference. Like above, when done with
the extra work, I’ll switch back,
git undo, and resume. Set it up with:
$ git config --global alias.wip '!git add -u && git commit -m "WIP"'
This alias allows me to quickly resume work after a
wip. It undoes
the last commit but keeps its changes, with files unstaged. It can also be used
in other circumstances (for those, however, I have a functionally identical
r1 alias at hand). Configure with:
$ git config —-global alias.undo 'reset HEAD^ —-mixed'
This is a special, use-with-caution one. It adds changes in the working tree to
WIPE SAVEPOINT commit, then it wipes the commit. At that point, the working
tree is clean, but I can still go back to that work if the need arises (via
reflog). Seldom used, this
wipe comes in handy when I have some experimental
code that is not going into production and yet, I want to keep it around. Set
it up with:
$ git config --global alias.wipe \ '!git add -A && git commit -qm "WIPE SAVEPOINT" && git reset HEAD~1 --hard'
If you are not familiar with the git reflog, you might want to stay clear from
One advantage of this workflow is that saved changes will stay with their
relevant branch. When you get back to it,
git log will hint at what happened
when you left. Assuming it is a private branch, you might even decide to push
it for backup before starting the hotfix work.