Over the weekend I started using topgit (README), a git wrapper that takes most of the work out of managing dependent “topic branches.” The gist is that you mark branches as depending on one another. Then, when you modify a branch, you can use the
tg update
command to propagate those changes to any branches that depend on it.I’ve been doing a lot of large changes and refactorings recently, so what topgit really means for me is never having to wait for code reviews to keep working.
The basic workflow goes like this:
“refactor” is the name of my new branch, “blogger” is the trunk
$ tg create refactor blogger
hack hack hack
mv mv mv
add add add
commit commit commit
now mail out the CL for review
$ gitwrapper mail -m reviewer
In a pure Perforce environment, I couldn’t continue working on this code at all until the review came back and I could submit. With vanilla git, I can of course
git checkout -b new-branch
and keep going, and this is fine most of the time.Where it starts to get sticky is when my reviewer has comments. No big deal, though. I can just
git checkout
back to the refactor
branch, make those changes, and commit them.Of course, I now need to update my
new-branch
so that I’m working from the latest intermediate state. git merge refactor
handles that fairly well (sometimes I get pedantic and use git rebase
) and I’m back to coding the new feature.topgit supports exactly this pattern of development by automating the “update the
new-branch
” step. If I created the new-branch
branch with tg create
, then I could run tg update
to merge in the latest versions of all of new-branch
’s dependencies.To continue, we have:
git checkout refactor
tweak tweak tweak
git commit -am "fixes from review"
git checkout new-branch
tg update
code code code
“All” is a very operative word in that last sentence. With topgit, a branch can have several dependencies, forming a DAG, and it will recursively update each one of them. This means that I can have several independent changes, with each out for review in parallel, but continue development on a new change that relies on all of them.
topgit works by keeping a separate reference branch for each topgit-managed branch. When you run
tg update
, it merges the dependencies into this branch, then merges that into the normal branch. This gives the added benefit that you can easily git rebase
against the reference branch to clean up your commit graph.