{"thread":{"id":"66521","subject":"log --graph draws an orphaned branch with parents","startedAt":"2026-10-13T19:00:00Z","lastAt":"2026-11-04T18:00:17Z","messageCount":9,"participants":["herr.kaste","Pablo Sabater","Caspar Duregger","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"554894","messageId":"CAFzd1+4Jx_sWvMrV10gi9400BBNJOUXW0WwsypiM7yCh5x8fow@mail.gmail.com","threadId":"66521","inReplyTo":null,"subject":"log --graph draws an orphaned branch with parents","fromName":"herr.kaste","fromEmail":"herr.kaste@gmail.com","sentAt":"2026-10-13T19:00:00Z","receivedAt":"2026-10-13T19:00:00Z","isPatch":false,"sender":{"key":"herr.kaste@gmail.com","avatar":null},"body":"Hi!  I have the following:\n\nCheckout https://github.com/packagecontrol/thecrawl.git then draw the graph\n\n$ git log --graph --all --oneline\n\na few pages down, (I don't have a more minimal reproduction, --all is required)\nI see\n\nWhat happened? (Actual behavior)\n\n* | | 03b117815 Changed metadata of `Modelines`\n* | | 30f679f1f Bulk edit\n \\ | |\n  * | | 5a2cecdd9 Initial revision\n / /\n| | * 6062ecf4f (origin/feat/compare-registries) Add script to compare\ntwo registries\n| |/\n| * 8f034813a Clarify fatal crawl skip logs\n\n5a2cecdd9 is actually the birth of an orphaned branch, gitk also shows\nit like that.\n\nWhat did you expect to happen? (Expected behavior)\n\nE.g. something like this:\n\n● | | 03b117815 Changed metadata of `Modelines`\n● | | 30f679f1f Bulk edit\n● | | 5a2cecdd9 Initial revision\n / /\n| | ● 6062ecf4f (origin/feat/compare-registries) ...\n| |/\n| ● 8f034813a Clarify fatal crawl skip logs\n\nWhat's different between what you expected and what actually happened?\nAn obvious drawing error, 5a2cecdd9 is drawn as if it had parents, and\nthe rightmost lane goes to nirvana.\n\n[System Info]\ngit version:\ngit version 2.56.0.windows.2\ncpu: x86_64\nbuilt from commit: cc4dbf752a05efdc0e04e71fd3e8110d11bdd35c\nsizeof-long: 4\nsizeof-size_t: 8\nshell-path: D:/git-sdk-64-build-installers/usr/bin/sh\nrust: disabled\nfeature: fsmonitor--daemon\ngettext: enabled\nlibcurl: 8.22.0\nOpenSSL: OpenSSL 3.5.9 29 Sep 2026\nzlib: 1.3.2\nSHA-1: SHA1_DC\nSHA-256: SHA256_BLK\ndefault-ref-format: files\ndefault-hash: sha1\nuname: Windows 10.0 26200\ncompiler info: gnuc: 16.2\nlibc info: no libc information available\n$SHELL (typically, interactive shell): C:\\Dev\\Git\\usr\\bin\\bash.exe\n\nRegards\nCaspar Duregger\n\n"},{"id":"557362","messageId":"CAFzd1+5s6V+YC3onNjYQmxRPVnsMROpsVi=qy1mg2=LOAnU+gg@mail.gmail.com","threadId":"66521","inReplyTo":"CAFzd1+4Jx_sWvMrV10gi9400BBNJOUXW0WwsypiM7yCh5x8fow@mail.gmail.com","subject":"Re: log --graph draws an orphaned branch with parents","fromName":"herr.kaste","fromEmail":"herr.kaste@gmail.com","sentAt":"2026-11-03T19:25:30Z","receivedAt":"2026-11-03T19:25:30Z","isPatch":false,"sender":{"key":"herr.kaste@gmail.com","avatar":null},"body":"Finally had time for a repro (tested with git 2.56.0.windows.3):\n\nsh\ngit init -q -b main repro && cd repro\nexport GIT_COMMITTER_DATE=\"@1700000000 +0000\"\nGIT_AUTHOR_DATE=\"@1700000000 +0000\"\ngit commit -q --allow-empty -m B\ngit switch -q -c topic\ngit commit -q --allow-empty -m T\ngit switch -q --orphan orphan\ngit commit -q --allow-empty -m R\ngit merge -q --allow-unrelated-histories --no-ff -m M main\ngit log --graph --oneline --all\n\nActual output:\n\n*   40a81a9 M\n|\\\n \\ |\n  * | 1d9120a R\n /\n| * 5a29a85 T\n|/\n* f1cd12c B\n\nWith --no-graph-indent:\n\n*   40a81a9 M\n|\\\n* | 1d9120a R\n /\n| * 5a29a85 T\n|/\n* f1cd12c B\n\nRegards\nCaspar\n\n\nAm Di., 13. Okt. 2026 um 21:00 Uhr schrieb herr.kaste <herr.kaste@gmail.com>:\n>\n> Hi!  I have the following:\n>\n> Checkout https://github.com/packagecontrol/thecrawl.git then draw the graph\n>\n> $ git log --graph --all --oneline\n>\n> a few pages down, (I don't have a more minimal reproduction, --all is required)\n> I see\n>\n> What happened? (Actual behavior)\n>\n> * | | 03b117815 Changed metadata of `Modelines`\n> * | | 30f679f1f Bulk edit\n>  \\ | |\n>   * | | 5a2cecdd9 Initial revision\n>  / /\n> | | * 6062ecf4f (origin/feat/compare-registries) Add script to compare\n> two registries\n> | |/\n> | * 8f034813a Clarify fatal crawl skip logs\n>\n> 5a2cecdd9 is actually the birth of an orphaned branch, gitk also shows\n> it like that.\n>\n> What did you expect to happen? (Expected behavior)\n>\n> E.g. something like this:\n>\n> ● | | 03b117815 Changed metadata of `Modelines`\n> ● | | 30f679f1f Bulk edit\n> ● | | 5a2cecdd9 Initial revision\n>  / /\n> | | ● 6062ecf4f (origin/feat/compare-registries) ...\n> | |/\n> | ● 8f034813a Clarify fatal crawl skip logs\n>\n> What's different between what you expected and what actually happened?\n> An obvious drawing error, 5a2cecdd9 is drawn as if it had parents, and\n> the rightmost lane goes to nirvana.\n>\n> [System Info]\n> git version:\n> git version 2.56.0.windows.2\n> cpu: x86_64\n> built from commit: cc4dbf752a05efdc0e04e71fd3e8110d11bdd35c\n> sizeof-long: 4\n> sizeof-size_t: 8\n> shell-path: D:/git-sdk-64-build-installers/usr/bin/sh\n> rust: disabled\n> feature: fsmonitor--daemon\n> gettext: enabled\n> libcurl: 8.22.0\n> OpenSSL: OpenSSL 3.5.9 29 Sep 2026\n> zlib: 1.3.2\n> SHA-1: SHA1_DC\n> SHA-256: SHA256_BLK\n> default-ref-format: files\n> default-hash: sha1\n> uname: Windows 10.0 26200\n> compiler info: gnuc: 16.2\n> libc info: no libc information available\n> $SHELL (typically, interactive shell): C:\\Dev\\Git\\usr\\bin\\bash.exe\n>\n> Regards\n> Caspar Duregger\n\n"},{"id":"557378","messageId":"DMLW72EXMN1K.3IXVPHWNYQ3EH@gmail.com","threadId":"66521","inReplyTo":"CAFzd1+5s6V+YC3onNjYQmxRPVnsMROpsVi=qy1mg2=LOAnU+gg@mail.gmail.com","subject":"Re: log --graph draws an orphaned branch with parents","fromName":"Pablo Sabater","fromEmail":"pabloosabaterr@gmail.com","sentAt":"2026-11-03T21:27:04Z","receivedAt":"2026-11-03T21:27:04Z","isPatch":false,"sender":{"key":"pabloosabaterr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/63864637?v=4"},"body":"On Tue Nov 3, 2026 at 7:25 PM WET, herr.kaste wrote:\n> Finally had time for a repro (tested with git 2.56.0.windows.3):\n>\n> sh\n> git init -q -b main repro && cd repro\n> export GIT_COMMITTER_DATE=\"@1700000000 +0000\"\n> GIT_AUTHOR_DATE=\"@1700000000 +0000\"\n> git commit -q --allow-empty -m B\n> git switch -q -c topic\n> git commit -q --allow-empty -m T\n> git switch -q --orphan orphan\n> git commit -q --allow-empty -m R\n> git merge -q --allow-unrelated-histories --no-ff -m M main\n> git log --graph --oneline --all\n\nHi!\n\nThanks for the repro and the bug report.\n\n>\n> Actual output:\n\nThe bug is because the indentation state GRAPH_PRE_ROOT is being\ntriggered, due to \"R\" being a root. What this state does is add a new\nrow to connect the indentation:\n\n>\n> *   40a81a9 M\n> |\\\n>  \\ |\n^^^\nThis one\n\n>   * | 1d9120a R\n\nThen it pushes everything to the right.\n\n>  /\n> | * 5a29a85 T\n> |/\n> * f1cd12c B\n>\n> With --no-graph-indent:\n>\n> *   40a81a9 M\n> |\\\n> * | 1d9120a R\n>  /\n> | * 5a29a85 T\n> |/\n> * f1cd12c B\n\nThe fix should be that the rendering of the graph is the same with the\nindentation or without it, as there is nothing ambiguous in this case\nthat needs it.\n\nI think I may be able to see how to fix it tomorrow, but I'm quite busy\nuntil next week.\n\nRegards,\nPablo\n\n"},{"id":"557379","messageId":"DMLW93TBSOXK.2OLM5O3HGK1ZY@gmail.com","threadId":"66521","inReplyTo":"DMLW72EXMN1K.3IXVPHWNYQ3EH@gmail.com","subject":"Re: log --graph draws an orphaned branch with parents","fromName":"Pablo Sabater","fromEmail":"pabloosabaterr@gmail.com","sentAt":"2026-11-03T21:29:43Z","receivedAt":"2026-11-03T21:29:43Z","isPatch":false,"sender":{"key":"pabloosabaterr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/63864637?v=4"},"body":"On Tue Nov 3, 2026 at 9:27 PM WET, Pablo Sabater wrote:\n>\n> I think I may be able to see how to fix it tomorrow, but I'm quite busy\n> until next week.\n\nI forgot to ask if you want to try to fix it yourself, I'm happy to\nreview it :).\n\nPablo.\n\n\n"},{"id":"557381","messageId":"CAFzd1+6fiuT1R3B7aK6mN842g5+EiQ4Qt2_GCS1YFMVs+mXFaQ@mail.gmail.com","threadId":"66521","inReplyTo":"DMLW93TBSOXK.2OLM5O3HGK1ZY@gmail.com","subject":"Re: log --graph draws an orphaned branch with parents","fromName":"herr.kaste","fromEmail":"herr.kaste@gmail.com","sentAt":"2026-11-03T21:51:25Z","receivedAt":"2026-11-03T21:51:25Z","isPatch":false,"sender":{"key":"herr.kaste@gmail.com","avatar":null},"body":"From 48bbcf965dc630251cc32f38d7efca5e6fb77c5e Mon Sep 17 00:00:00 2001\nFrom: Caspar Duregger <caspar.duregger@gmail.com>\nDate: Tue, 3 Nov 2026 22:38:22 +0100\nSubject: [PATCH] graph: do not indent visual roots with columns to their right\n\nSince a34c00d96 (graph: indent visual root in graph, 2026-07-14), a\nvisual root that has a child is drawn indented, connected to its child\nby an extra GRAPH_PRE_ROOT line.  When there are columns to the right\nof the root, this breaks the graph:\n\n*   M\n|\\\n\\ |\n * | R\n/\n| * T\n|/\n* B\n\ngraph_output_pre_root_line() writes the extra \" \" for the root column\nwithout shifting the columns to its right, so they are drawn between\ntwo columns.  graph_output_commit_line() then pushes them one column\nto the right, but the following GRAPH_COLLAPSING line is computed from\nthe mapping, which knows nothing about that offset.  The column next\nto R does not continue into the next line, and with more columns to\nthe right of R one of them goes nowhere.\n\nBut in this situation the indentation is not needed in the first\nplace.  The columns to the right of the root collapse into its column\nonce it is rendered, so the collapsing line always leaves a blank\nright below the root, and the next commit cannot end up vertically\nadjacent to it.\n\nDo not consider a commit a visual root when there are columns to its\nright, which gives:\n\n*   M\n|\\\n* | R\n/\n| * T\n|/\n* B\n\nSigned-off-by: Caspar Duregger <caspar.duregger@gmail.com>\n---\n graph.c                          | 12 ++++++++++++\n t/t4218-log-graph-indentation.sh | 18 ++++++++++++++++++\n 2 files changed, 30 insertions(+)\n\ndiff --git a/graph.c b/graph.c\nindex 28bef1b88..95eef3a95 100644\n--- a/graph.c\n+++ b/graph.c\n@@ -969,10 +969,22 @@ static int graph_is_visual_root(struct git_graph *graph,\n  * already a column, so it will not be rendered below, the\n  * current commit has to act as the last commit and omit\n  * indentation.\n+ *\n+ * If there are columns to the right of the commit, they collapse\n+ * into its column once it is rendered, so nothing can be rendered\n+ * right below it and there is no need to indent it.\n+ *\n+ *   * | <- visual root with a column to its right\n+ *    /\n+ *   | *\n+ *\n+ * Indenting it would also push these columns to the right, but\n+ * the collapsing code does not know about that offset.\n  */\n  return graph_is_visual_root_candidate(graph->commit, graph) &&\n        !(graph->commit_in_columns &&\n  graph->columns[graph->commit_index].is_merge_parent) &&\n+       graph->commit_index + 1 >= graph->num_columns &&\n        flags->is_next_visible &&\n        (!flags->next_has_column || graph->visual_root_depth > 0);\n }\ndiff --git a/t/t4218-log-graph-indentation.sh b/t/t4218-log-graph-indentation.sh\nindex 24dc9b497..b3b9f7c14 100755\n--- a/t/t4218-log-graph-indentation.sh\n+++ b/t/t4218-log-graph-indentation.sh\n@@ -449,6 +449,24 @@ test_expect_success 'two unrelated merges' '\n  EOF\n '\n\n+test_expect_success 'visual root with columns to its right is not indented' '\n+ create_orphan _70 && test_commit 70_A &&\n+ git checkout -b _71 && test_commit 71_A &&\n+ create_orphan _72 && test_commit 72_A &&\n+ TREE=$(git write-tree) &&\n+ MERGE=$(git commit-tree $TREE -p _72 -p _70 -m 72_merge) &&\n+ git reset --hard $MERGE &&\n+ lib_test_check_graph _72 _71 <<-\\EOF\n+ *   72_merge\n+ |\\\n+ * | 72_A\n+ /\n+ | * 71_A\n+ |/\n+ * 70_A\n+ EOF\n+'\n+\n test_expect_success '--max-count treats the last visible commit as\nthe last commit' '\n  lib_test_check_graph --max-count=2 _8 _9 _10 <<-\\EOF\n   * 10_A\n-- \n2.56.0.350.g48bbcf965\n\n\nAm Di., 3. Nov. 2026 um 22:29 Uhr schrieb Pablo Sabater\n<pabloosabaterr@gmail.com>:\n>\n> On Tue Nov 3, 2026 at 9:27 PM WET, Pablo Sabater wrote:\n> >\n> > I think I may be able to see how to fix it tomorrow, but I'm quite busy\n> > until next week.\n>\n> I forgot to ask if you want to try to fix it yourself, I'm happy to\n> review it :).\n>\n> Pablo.\n>\n\n"},{"id":"557387","messageId":"DMLXRHPI0V08.3JFJGR1LRDGXU@gmail.com","threadId":"66521","inReplyTo":"CAFzd1+6fiuT1R3B7aK6mN842g5+EiQ4Qt2_GCS1YFMVs+mXFaQ@mail.gmail.com","subject":"Re: log --graph draws an orphaned branch with parents","fromName":"Pablo Sabater","fromEmail":"pabloosabaterr@gmail.com","sentAt":"2026-11-03T22:40:45Z","receivedAt":"2026-11-03T22:40:45Z","isPatch":false,"sender":{"key":"pabloosabaterr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/63864637?v=4"},"body":"On Tue Nov 3, 2026 at 9:51 PM WET, herr.kaste wrote:\n> From 48bbcf965dc630251cc32f38d7efca5e6fb77c5e Mon Sep 17 00:00:00 2001\n> From: Caspar Duregger <caspar.duregger@gmail.com>\n> Date: Tue, 3 Nov 2026 22:38:22 +0100\n> Subject: [PATCH] graph: do not indent visual roots with columns to their right\n\nThanks for the patch, but it's wrongly formatted so b4 shazam can't find\nit to apply it, could you sned it with git send-email?\n\nRegards,\nPablo\n\n\n"},{"id":"557388","messageId":"20261103231153.289762-1-caspar.duregger@gmail.com","threadId":"66521","inReplyTo":"CAFzd1+4Jx_sWvMrV10gi9400BBNJOUXW0WwsypiM7yCh5x8fow@mail.gmail.com","subject":"[PATCH] graph: do not indent visual roots with columns to their right","fromName":"Caspar Duregger","fromEmail":"caspar.duregger@gmail.com","sentAt":"2026-11-03T23:11:53Z","receivedAt":"2026-11-03T23:11:53Z","isPatch":true,"sender":{"key":"caspar.duregger@gmail.com","avatar":null},"body":"Since a34c00d96 (graph: indent visual root in graph, 2026-07-14), a\nvisual root that has a child is drawn indented, connected to its child\nby an extra GRAPH_PRE_ROOT line.  When there are columns to the right\nof the root, this breaks the graph:\n\n\t*   M\n\t|\\\n\t \\ |\n\t  * | R\n\t /\n\t| * T\n\t|/\n\t* B\n\ngraph_output_pre_root_line() writes the extra \" \" for the root column\nwithout shifting the columns to its right, so they are drawn between\ntwo columns.  graph_output_commit_line() then pushes them one column\nto the right, but the following GRAPH_COLLAPSING line is computed from\nthe mapping, which knows nothing about that offset.  The column next\nto R does not continue into the next line, and with more columns to\nthe right of R one of them goes nowhere.\n\nBut in this situation the indentation is not needed in the first\nplace.  The columns to the right of the root collapse into its column\nonce it is rendered, so the collapsing line always leaves a blank\nright below the root, and the next commit cannot end up vertically\nadjacent to it.\n\nDo not consider a commit a visual root when there are columns to its\nright, which gives:\n\n\t*   M\n\t|\\\n\t* | R\n\t /\n\t| * T\n\t|/\n\t* B\n\nSigned-off-by: Caspar Duregger <caspar.duregger@gmail.com>\n---\n graph.c                          | 12 ++++++++++++\n t/t4218-log-graph-indentation.sh | 18 ++++++++++++++++++\n 2 files changed, 30 insertions(+)\n\ndiff --git a/graph.c b/graph.c\nindex 28bef1b88..95eef3a95 100644\n--- a/graph.c\n+++ b/graph.c\n@@ -969,10 +969,22 @@ static int graph_is_visual_root(struct git_graph *graph,\n \t * already a column, so it will not be rendered below, the\n \t * current commit has to act as the last commit and omit\n \t * indentation.\n+\t *\n+\t * If there are columns to the right of the commit, they collapse\n+\t * into its column once it is rendered, so nothing can be rendered\n+\t * right below it and there is no need to indent it.\n+\t *\n+\t *   * | <- visual root with a column to its right\n+\t *    /\n+\t *   | *\n+\t *\n+\t * Indenting it would also push these columns to the right, but\n+\t * the collapsing code does not know about that offset.\n \t */\n \treturn graph_is_visual_root_candidate(graph->commit, graph) &&\n \t       !(graph->commit_in_columns &&\n \t\t graph->columns[graph->commit_index].is_merge_parent) &&\n+\t       graph->commit_index + 1 >= graph->num_columns &&\n \t       flags->is_next_visible &&\n \t       (!flags->next_has_column || graph->visual_root_depth > 0);\n }\ndiff --git a/t/t4218-log-graph-indentation.sh b/t/t4218-log-graph-indentation.sh\nindex 24dc9b497..b3b9f7c14 100755\n--- a/t/t4218-log-graph-indentation.sh\n+++ b/t/t4218-log-graph-indentation.sh\n@@ -449,6 +449,24 @@ test_expect_success 'two unrelated merges' '\n \tEOF\n '\n \n+test_expect_success 'visual root with columns to its right is not indented' '\n+\tcreate_orphan _70 && test_commit 70_A &&\n+\tgit checkout -b _71 && test_commit 71_A &&\n+\tcreate_orphan _72 && test_commit 72_A &&\n+\tTREE=$(git write-tree) &&\n+\tMERGE=$(git commit-tree $TREE -p _72 -p _70 -m 72_merge) &&\n+\tgit reset --hard $MERGE &&\n+\tlib_test_check_graph _72 _71 <<-\\EOF\n+\t*   72_merge\n+\t|\\\n+\t* | 72_A\n+\t /\n+\t| * 71_A\n+\t|/\n+\t* 70_A\n+\tEOF\n+'\n+\n test_expect_success '--max-count treats the last visible commit as the last commit' '\n \tlib_test_check_graph --max-count=2 _8 _9 _10 <<-\\EOF\n \t  * 10_A\n-- \n2.56.0.windows.3\n\n\n"},{"id":"557389","messageId":"DMLZ0DCQXG54.2FD3JQXSJCWPD@gmail.com","threadId":"66521","inReplyTo":"20261103231153.289762-1-caspar.duregger@gmail.com","subject":"Re: [PATCH] graph: do not indent visual roots with columns to their right","fromName":"Pablo Sabater","fromEmail":"pabloosabaterr@gmail.com","sentAt":"2026-11-03T23:39:22Z","receivedAt":"2026-11-03T23:39:22Z","isPatch":true,"sender":{"key":"pabloosabaterr@gmail.com","avatar":"https://avatars.githubusercontent.com/u/63864637?v=4"},"body":"On Tue Nov 3, 2026 at 11:11 PM WET, Caspar Duregger wrote:\n> Since a34c00d96 (graph: indent visual root in graph, 2026-07-14), a\n> visual root that has a child is drawn indented, connected to its child\n> by an extra GRAPH_PRE_ROOT line.  When there are columns to the right\n> of the root, this breaks the graph:\n\nThe patch looks good to me!\n\nRegards,\nPablo\n\n\n"},{"id":"557476","messageId":"xmqqbj8432a6.fsf@gitster.g","threadId":"66521","inReplyTo":"DMLZ0DCQXG54.2FD3JQXSJCWPD@gmail.com","subject":"Re: [PATCH] graph: do not indent visual roots with columns to their right","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-11-04T18:00:17Z","receivedAt":"2026-11-04T18:00:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Pablo Sabater\" <pabloosabaterr@gmail.com> writes:\n\n> On Tue Nov 3, 2026 at 11:11 PM WET, Caspar Duregger wrote:\n>> Since a34c00d96 (graph: indent visual root in graph, 2026-07-14), a\n>> visual root that has a child is drawn indented, connected to its child\n>> by an extra GRAPH_PRE_ROOT line.  When there are columns to the right\n>> of the root, this breaks the graph:\n>\n> The patch looks good to me!\n>\n> Regards,\n> Pablo\n\nThanks, both.  Queued.\n\n\n"}]}