Subject: Re: [PATCH RFC] graph: implement git-log(1) --untangle

From: Toon Claes <[email-masked]>
Date: Mon, 09 Feb 2026 07:38:21 +0100

Johannes Sixt <[email-masked]> writes:

> IMNSHO, we need a better way to show where links to parents were
> truncated. Otherwise, I must consider this chart an incorrect
> representation of the history above.

The only alternative I can come up is showing as if the branch was made
from the parent commit of the merge commit. Like so:

Real:

    *
    |\
    | *
    | *
    *  \
    |\  |
    * * |
    |/ /
    * /
    *

My current implementation:

    *
    |\
    | *
    | *
    *
    |\
    * *
    |/
    *
    *

The suggestion:

    *
    |\
    | *
    | *
    |/
    *
    |\
    * *
    |/
    *
    *

But either way, what it shown it wrong. And that's in my opinion a
tradeoff of this feature.

I've been thinking about something else. Display in some way part of the
history is missing, maybe by showing a '.' in the graph:

    *
    |\
    | *
    | *
    | .
    *
    |\
    * *
    |/
    *
    *

This indicates a piece of the history is truncated. I'm still on the
fence about this

>
>> As you can see, this untangles the arms of the octopus.
>
> This example is too small to show any real improvement. But I think I
> understood what the goal is.

I would like to invite anyone here to try the feature on some of your
repositories you have. I feel it's impossible to really demonstrate it's
power through some examples over email.

> So, the option's effect is to untangle visual representation of the
> history. It is achieved by truncating links between merge-bases and
> commits that appear in non-first parent links.

Yes, that's the idea.

> How does this work with criss-cross merges?
>
>   Z
>  / \
> o   o
> |\ /|
> | x |
> |/ \|
> o   o
>  \ /
>   A

I haven't tried it yet.

>
> (not sure how --graph would represent this...)
>
> How does this work with backward merges?
>
> * main
> |\
> * | C
> | * sync with main
> |/|
> * | B
> | * A
> |/
> * initial

I've been trying in this first version to address that, but I haven't
been fully able to make it work.

I assume you and other readers know, but your example is a
simplification of:

    * main
    |\
    * | C
    | * sync with main
    | |\
    | |/
    |/|
    * | B
    | * A
    |/
    * initial

So here there merge-base isn't the first parent, so things get a little
more complicated. Also when 'B' is ignored as merge-base, the merge-base
needs to be recalculated to be 'initial'.

Anyhow, the idea is to show it like this:

    * main
    |\
    * | C
    | * sync with main
    * | B
    | * A
    * initial

If you don't like my proposal of being fully disconnected from the
merge-base, we could consider using a different symbol for "truncated"
history:

    * main
    |\
    * | C
    | + sync with main
    * | B
    | + A
    * initial

The commits with a '+' have more parents but they are not shown.

> How does this interact with --boundary?

Haven't tried it yet.

> Speaking of which, boundary commits are listed last. Since they need to
> be linked to the commits for which they are the boundary, a whole lot of
> these "unnecessary" lines accumulate the longer the list of commits is.

That's good to know, when I continue work on this feature.

> If only there were a way to show boundary commits as soon as possible,
> then this accumulation would not happen.

I'll need to dive deeper into this to understand what you're saying
here.

-- 
Cheers,
Toon