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