Monday, July 15, 2013

Force git to show diverged branches log

Look like it's not an easy task to make git show the history of two branches simultaneously starting from divergence point.

Consider the following diverging branches:

$ git log  --all --graph --format="%h %d %s"
* c4c7035  (HEAD, master) commit #10 master
* f41150e  commit #9 master
* 41af5d9  Commit #5 master
* 97a530f  commit #4 master
| * 271d605  (new_branch) commit #8 branch
| * 52409b4  commit #7 branch
| * ad3d575  commit #6 branch
|/
* 4a24c6d  commit #3 master
* e21ca0c  commit #2 master
* f02ecbd  commit #1 to master





Repository  history is quite tiny, but what if you have hundreds of commits in each branch? Viewing a log using "--all" would be the hell. Basically I want git to show the same info, but for  arbitrary branches.

Here what git provides for basic history viewing:

$ git log  master..new_branch
271d605  (new_branch) commit #8 branch
52409b4  commit #7 branch
ad3d575  commit #6 branch


$ git log  new_branch..master
c4c7035  (HEAD, master) commit #10 master
f41150e  commit #9 master
41af5d9  Commit #5 master
97a530f  commit #4 master
 Although git shows truth and only the truth - both ways shows difference between branches, - it's still not very helpful, especially when you're in a huge repository.

Let's find out the best common ancestor for both branches:

$ git merge-base master new_branch
4a24c6d5af4c80680af27d82c65a137927525307
 True, that is the commit where branches diverged - "commit #3 master".  But if we try to view log using this commit, we'll see the following:
$ git log  master  new_branch --graph 4a24c6d5a..master
* c4c7035  (HEAD, master) commit #10 master
* f41150e  commit #9 master
* 41af5d9  Commit #5 master
* 97a530f  commit #4 master
* 271d605  (new_branch) commit #8 branch
* 52409b4  commit #7 branch
* ad3d575  commit #6 branch
Sad, but divergence point is excluded again. Let's view history from the commit which is located before the merge-base commit:

 $ git log  master  new_branch --graph 4a24c6d5a^1..master
* c4c7035  (HEAD, master) commit #10 master
* f41150e  commit #9 master
* 41af5d9  Commit #5 master
* 97a530f  commit #4 master
| * 271d605  (new_branch) commit #8 branch
| * 52409b4  commit #7 branch
| * ad3d575  commit #6 branch
|/
* 4a24c6d  commit #3 master
 And - just to simplify the approach for scripting, I'd make it one-line expression and make it work from a branch relatively to the master:

$ git checkout new_branch
Switched to branch 'new_branch'

$ git log master --graph $(git merge-base master HEAD)^1..HEAD
* c4c7035  (master) commit #10 master
* f41150e  commit #9 master
* 41af5d9  Commit #5 master
* 97a530f  commit #4 master
| * 271d605  (HEAD, new_branch) commit #8 branch
| * 52409b4  commit #7 branch
| * ad3d575  commit #6 branch
|/
* 4a24c6d  commit #3 master

 That's what I wanted to achieve.



No comments:

Post a Comment