jonas / tig

Text-mode interface for git
https://jonas.github.io/tig/
GNU General Public License v2.0
12.47k stars 611 forks source link

tig --all shows incorrect tree if HEAD is on a branch (see screenshot) #761

Open proski opened 7 years ago

proski commented 7 years ago

tig --all shows (incorrectly): tig-screenshot gitk --all shows (correctly): gitk-screenshot "First PR revision, bad" is a parent of "Second PR revision, good". Packed repository: repo.tar.gz Confirmed with the latest tig commit 0f340c0327220228764dd1c38676205187839f1d Fedora 27, git 2.14.3, x86_64.

CDanU commented 6 years ago

tig has several ways of ordering the commits, the one that you are having active is the default one. I can't definitively tell you if that output is intended.

Your example works if you set the order to auto or topo (] key, or tigrc)

nyanpasu64 commented 2 years ago

I get this bug in set commit-order = default (which is otherwise good for showing commits in order). I do not get the issue with auto or topo (which I dislike because it doesn't show commits in order), or date and author-date (not sure what to pick, I think date acts closer to default minus the bug, putting rebases after branches, whereas author-date interleaves branches and rebases).

nyanpasu64 commented 2 years ago

I managed to hit this bug in default order without --all, using a merge commit:

default

date doesn't encounter the bug. The only difference is at the two arms of the merge commit:

date

Cause of bug

I think the trigger for the bug is that Actually kill Boost descends from Unindent, and has a later author date (as expected), but the same commit date due to a rebase.

In default order, the child commit is erroneously(?) sorted older than (below) the parent commit, so it never finds a parent commit to merge up with. I conjecture that tig first sorts commits independently(?) of the graph structure, then connects each commit with a line to its parent (which never gets found in case of incorrect sorting).

In this case, it appears default and date first sort commits by descending commit date (which is hopefully monotonic or equal). However many commits have the same commit date due to rebasing.

I'm actually not sure how default breaks commit time ties. Possibly default is nondeterministic or something, whereas date breaks ties with parent-child relationships(?).

Testing my theory

Is my theory correct? When I append a new commit at year 2000, my theory predicts that it would get sorted at the bottom of the list, after its parent. Instead both default and date sort it on top based on graph topology, instead of labeling it the oldest commit.

When I rebase my commit tree, and reword the first commit to alter the history's commit dates, my theory predicts my commit tree will (sometimes) render incorrectly if the merge arms don't have a later commit date than its parent. In fact, the commit tree always renders incorrectly if I don't pause before the merge, which more-or-less matches my theory's predictions.

Another speculation is that this bug only affects side branches and non-first parents of merge commits, since the first parent chain of the (top? first requested?) history is always ordered correctly. At some point I'd be better off reading the source code instead of guessing.