Making sense of many merged branches
Lukas Krejci
lkrejci at redhat.com
Fri Feb 28 18:28:04 UTC 2014
Hi all,
with the move to github, I'm hoping we are going to see an increase in using
code reviews and hopefully even external code contributions using github's
pull requests.
Because PRs are merged, not rebased, we are going to see an increase in
parallel development with relative large number of parallel branches.
(It is of course possible to rebase a pull request, but one loses information
about exactly what commits were committed to mainline (of course you do know
that when you rebase, but not 3 months after that). There is no information in
the git history about that and one has to resort to matching commit messages
and the actual contents of the commits).
When for example a PR is rebased into the master and the contributor then
updates their PR branch, it would be very hard to rebase such PR branch again.
There would be no record in the history that git could use to correctly rebase
the PR branch again. One would have to resort to manual cherry-picking of
commits that weren't in the mainline yet (which would be potentially hard to
figure out, too, because their hashes would be different than in the PR
branch, so one would have to search by commit message, etc).
Our policy in the past was to merge any long(er) term feature branches but try
to avoid merges when doing more short-term work. We feared the
incomprehensible log listings and cluttering the history with merge commits.
I do think that none of the two reasons we tried to avoid merges are severe
enough to forego the advantages of retaining the full history of the parallel
distributed development. More so when the "complex" history and the merge
commits can be mitigated by configuring git log and/or gitk correctly.
So without further ado, let's how to make sense of complex commit history.
1) Merge commits
git log --no-merges
gitk --no-merges
(in gitk you can also create persistent views that you can set up to your
liking)
I also recommend using these with git log:
--oneline (commit on single line)
--decorate (prints out the branch along with the commit message (this is what
gitk does by default)
2) Complex history with many multiple parallel streams
One important takeaway is that when you look at multiple branches, you usually
aren't interested in individual commits in those branches but rather you want
to know the relationship between them - i.e when the branches diverged. So you
don't have to actually see the unteen individual commits in-between the
"branching points" - this is what --simplify-by-decoration does - it only
considers HEADs (tips) of branches and the branching points.
a) seeing what unmerged branches there are in the repo:
git log --all --graph --oneline --decorate --simplify-by-decoration
gitk --all --simplify-by-decoration
(in here, all the leaf commits are branches not merged into any other)
b) list only commits *present* on a feature-branch:
git log origin/master..feature-branch
gitk origin/master..feature-branch
c) list only commits *made* on a feature-branch to which master is regularly
merged:
git log --first-parent master..feature-branch
gitk --first-parent master..feature-branch
For more advanced "archaeology" in git, check out git log -L, git blame, etc.
http://jfire.io/blog/2012/03/07/code-archaeology-with-git/
I am still learning and wanted to share what I found so far about this brand
new world, so please share whatever you find worth sharing, too.
Hope this helps,
Lukas
More information about the rhq-devel
mailing list