'git log: show second parent on the left

Consider this example git repository.

#!/bin/bash -e
rm -rf example
git init example
cd example
echo 0 > file.txt
git add file.txt
git commit -am "initial commit"
git branch branch1
echo 1 > file.txt
git commit -am "1 (on master)"
git branch branch2
git checkout branch1
echo 2 > file2.txt
git add file2.txt
git commit -m "2 (on branch1)"
git merge --no-edit master
echo 3 > file2.txt
git commit -am "3 (on branch1)"
git checkout master
echo 4 > file.txt
git commit -am "4 (on master)"
git checkout branch1
git merge --no-edit master
echo 5 > file2.txt
git commit -am "5 (on branch1)"
git checkout master
git merge --no-edit --no-ff branch1
git log --graph --oneline

We create a branch branch1, merge up to it from the master branch a couple of times, and finally merge back to master.

git log --oneline --graph looks weirdly twisted.

*   2c3b97a Merge branch 'branch1'
|\
| * 1d722df 5 (on branch1)
| *   54039b6 Merge branch 'master' into branch1
| |\
| |/
|/|
* | d80d82c 4 (on master)
| * 2399286 3 (on branch1)
| *   9a0cb38 Merge branch 'master' into branch1
| |\
| |/
|/|
* | 31df841 1 (on master)
| * 5809072 2 (on branch1)
|/
* 08fc7a6 initial commit

The graph would be simpler if it looked like this:

*   2c3b97a Merge branch 'branch1'
|\
| * 1d722df 5 (on branch1)
| *   54039b6 Merge branch 'master' into branch1
|/|
* | d80d82c 4 (on master)
| * 2399286 3 (on branch1)
| *   9a0cb38 Merge branch 'master' into branch1
|/|
* | 31df841 1 (on master)
| * 5809072 2 (on branch1)
|/
* 08fc7a6 initial commit

The reason it doesn't look like that, as I understand it, is that git log always prefers to show the "second parent" of each merge commit on the right-hand side, so for each merge commit it has to snake around to the right. (The "second parent" is the branch merging in; the "first parent" is the branch we're merging into.)

  1. Is there a way to convince git log to generate the simpler graph I'd prefer? There's an old gist from 2013 proposing fixing this ("Let me specify which branches sink to the left"; there are other interesting ideas there, too), but I see no progress on that.
  2. Assuming git log can't do it naturally, is there another git commit graphing tool/library I can use to make a graph like this?
git


Solution 1:[1]

  1. Is there a way to convince git log to generate the simpler graph I'd prefer? There's an old gist from 2013 proposing fixing this ("Let me specify which branches sink to the left"; there are other interesting ideas there, too), but I see no progress on that.

No. (And as I said in the other question, in general this is kind of a hard problem—in fact, it's "NP hard" in general. Git's log-drawing code is fairly cheat-y but swapping the parents around would probably do the trick for this case, but there are many other cases.)

  1. Assuming git log can't do it naturally, is there another git commit graphing tool/library I can use to make a graph like this?

I don't know of any. The gitk code that draws graphs is quite different from the git log code that draws graphs, but the problem—which generalizes to "draw a DAG with minimal crossings"—is just plain hard. There are a lot of graph-drawing programs out there, though. Reportedly, dot is pretty good.

See also Wikipedia and this CS stackexchange question and answer.

Solution 2:[2]

As of 2022, git log seems to work the same as before. But GitKraken handles this beautifully:

enter image description here

Solution 3:[3]

Assuming git log can't do it naturally, is there another git commit graphing tool/library I can use to make a graph like this?

The answer is that as far as i know you cant,
The only thing closed (but not what you are asking) is to use rebase (can be combined with --onto) whenever you want it so the log will be more flat.

But again - what you are asking is not possible due to the nature of git

The closest way to achieve what you are trying to do (but again not exactly what you want)

git log --all --graph --decorate --oneline --boundary master...branch1

When trying to add --topo-order && --no-walk it does not help as well and has no effect.

To summerize:

As you figured out its not possible due to the nature of git.

Assuming git log can't do it naturally, is there another git commit graphing tool/library I can use to make a graph like this?

I dont thing any other tool can do it since git will not "display" the different branch commit ( in your sample 9a0cb38) on the same "line" with another branch

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Community
Solution 2 Magnus
Solution 3 Community