Brain Phrye

code cooking diy fiction personal photos politics reviews tools


Dashing git

People don’t think of the unix command line as a UI, but it is and it has its own idioms. Nearly all of them are conventions, not hard and fast rules. Because of this sometimes things take on a few meanings.

The first meaning of the dash, "-" is to mark a command line flag like ls -l or mkdir -p. It comes up less often, but another pretty well known meaning is stdout/stdin. The most common use here is with tar: ssh host 'tar cf - dir' | tar xf - is a pretty common way to copy a directory.

In neither case is the "-" actually special. Convention and libraries implementing that convention are what make those things worse. The low-level open(2) call will try and open a file named "-" if you give it that as a file name argument.

The third, far less known meaning of "-" is “the last one.” It exists, afaik, in only one standard unix command: cd -. It’s a way to pop back and forth between two directories. If you’re in /foo and you type cd /bar you can now just type cd - to bounce back and forth between them.

It turns out the git developers noticed this and have made it so git checkout and git merge both understand this. So this is not an uncommon workflow:

1
2
3
4
git checkout -b fix-thing
[... edit and test and commit fixes ...]
git checkout -
git merge -

This way you can really quickly make a test branch to try things out and see if they work and once you’re happy with it just do those last two commands to get those back into the main branch you’re working on.

Note that the apparent originator of this idiom, cd -, works in a per-process way. Each shell session has a different view of dirs to pop back and forth between. This idiom in git is per repo. Multiple shell sessions in the same repo can toggle back and forth between branches.