public
Last active

How to simplify the graph produced by git log --graph

  • Download Gist
git-branch-simplify.md
Markdown

Ideas for improvements to git log --graph

I will maybe someday get around to dusting off my C and making these changes myself unless someone else does it first.

Make the graph for --topo-order less wiggly

Imagine a long-running development branch periodically merges from master. The git log --graph --all --topo-order is not as simple as it could be, as of git version 1.7.10.4.

It doesn't seem like a big deal in this example, but when you're trying to follow the history trails in ASCII and you've got several different branches displayed at once, it gets difficult quickly.

To simulate:

git init example
cd example
git commit --allow-empty -m "initial empty commit"
git branch dev
for x in `seq 4`; do
    echo 1 >> 1.txt
    git add 1.txt
    git commit -m "commit"
    git checkout dev
    git merge --no-ff --no-edit master
    git checkout master
done

The result:

$ git log --graph --all --topo-order --decorate --oneline --boundary
*   a9f8d93 (dev) Merge branch 'master' into dev
|\
| * 5f32650 (HEAD, master) commit
* |   b511501 Merge branch 'master' into dev
|\ \
| |/
| * 4e6810e commit
* |   2cd55b4 Merge branch 'master' into dev
|\ \
| |/
| * 4f74695 commit
* |   372799e Merge branch 'master' into dev
|\ \
| |/
| * 076669f commit
|/
* 7382440 initial empty commit

What I would like it to display:

$ git log --graph --all --topo-order --decorate --oneline --boundary
*   a9f8d93 (dev) Merge branch 'master' into dev
|\
| * 5f32650 (HEAD, master) commit
* | b511501 Merge branch 'master' into dev
|\|
| * 4e6810e commit
* | 2cd55b4 Merge branch 'master' into dev
|\|
| * 4f74695 commit
* | 372799e Merge branch 'master' into dev
|\|
| * 076669f commit
|/
* 7382440 initial empty commit

Let me specify which branches sink to the left.

Sometimes I'm faced with a very complex mess of merges and branches. I'd like to be able to ask git log to show me the graph, but to always set commits from specific branches into specific columns in the output. This might make for more line-drawing to connect the commits, but that's okay in this situation.

Using the very same repo above, I'd like to say "make left-most columns for master and dev, in that order" and see:

$ git log --graph --all --topo-order --decorate --oneline --boundary --force-branch-columns=master,dev

.-- master
| .-- dev
v v

  * a9f8d93 (dev) Merge branch 'master' into dev
 /|
* | 5f32650 (HEAD, master) commit
| * b511501 Merge branch 'master' into dev
|/|
* | 4e6810e commit
| * 2cd55b4 Merge branch 'master' into dev
|/|
* | 4f74695 commit
| * 372799e Merge branch 'master' into dev
|/|
* | 076669f commit
 \|
  * 7382440 initial empty commit

Maybe that doesn't seem like it's of much value, but let's throw another branch into the mix and see what it might look like.

Branch from somewhere in the middle of dev, create two commits, then merge from master:

git checkout -b newbranch dev~3
echo 2 >> 2.txt; git add 2.txt; git commit -m "commit"
echo 2 >> 2.txt; git add 2.txt; git commit -m "commit"
git merge --no-ff --no-edit master

The unmodified result:

$ git log --graph --all --topo-order --decorate --oneline --boundary
*   f745bf5 (HEAD, newbranch) Merge branch 'master' into newbranch
|\
* | 7031537 commit
* | 416ab2c commit
| | *   a9f8d93 (dev) Merge branch 'master' into dev
| | |\
| | |/
| |/|
| * | 5f32650 (master) commit
| | *   b511501 Merge branch 'master' into dev
| | |\
| | |/
| |/|
| * | 4e6810e commit
| | *   2cd55b4 Merge branch 'master' into dev
| | |\
| |/ /
|/| /
| |/
| * 4f74695 commit
* |   372799e Merge branch 'master' into dev
|\ \
| |/
| * 076669f commit
|/
* 7382440 initial empty commit

What's most striking to me about the as-is unmodified output is the frequency with which we see this cross-legged pattern:

  *   b511501 Merge branch 'master' into dev
  |\
  |/
 /|
* | 4e6810e commit
  *   2cd55b4 Merge branch 'master' into dev

Is the output perhaps intentionally like this to show which parent of a merge commit is the "first" parent? If so, that may be useful sometimes, so I wouldn't want to see that style completely removed in favor of my suggestion.

With different line-drawing logic and forced columns, it might look like this:

$ git log --graph --all --topo-order --decorate --oneline --boundary --force-branch-columns=master,dev

.-- master
| .-- dev
v v

    * f745bf5 (HEAD, newbranch) Merge branch 'master' into newbranch
   /|
  / * 7031537 commit
 /  * 416ab2c commit
| * | a9f8d93 (dev) Merge branch 'master' into dev
|/| |
* | | 5f32650 (master) commit
| * | b511501 Merge branch 'master' into dev
|/| |
* | | 4e6810e commit
| * | 2cd55b4 Merge branch 'master' into dev
|/|/
| /
|/|
* | 4f74695 commit
| * 372799e Merge branch 'master' into dev
|/|
* | 076669f commit
 \|
  * 7382440 initial empty commit

I think that it is much easier with that visualization to track which commits are in master and dev, and see the points at which other branches forked from and merged with them.

It would be cool :+1: !

:+1:

Somewhat two years ago, I had an idea for a pet project that resembled this feature a lot. I never pursued it, though :(

I wanted to use that for git-flow based projects, where you typically have two "fixed" branches (develop and master), and the rest of the branches lives somewhere in between, or "to the left of" develop. Basically, I would love to use this option:

--force-branch-columns="*,develop,release*,hotfix*,master"

This would basically draw git logs laid out as the branching model's main picture.

I think having such a feature would tremendously simplify reading your git logs, as it renders branches the way you would love to think about them.

yes,that would be great feature

Maybe I am resurrecting a dead thread, but I love this idea. Just throwing that out there.

I'd like to be able to ask git log to show me the graph, but to always set commits from specific branches into specific columns in the output.

I'm not really sure on how this would work. The branch is a pointer to a commit, not more. While it's definitely possible to order the "lane position" of the current commit of a branch, git has no way to tell if a commit "belongs to a branch" further past in history.

I would love to see this too, and I've been wondering how to develop it (let's call it "git flog"? Flow + log). pkoch pointed out the main problem, and probably to accomplish "git flog", one would need to modify git further.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.