{"thread":{"id":"66050","subject":"[PATCH] revision: honor --exclude-first-parent-only with SEEN first parent","startedAt":"2026-07-22T17:03:17Z","lastAt":"2026-07-22T17:03:17Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"548788","messageId":"xmqqbjbzq7n2.fsf@gitster.g","threadId":"66050","inReplyTo":null,"subject":"[PATCH] revision: honor --exclude-first-parent-only with SEEN first parent","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-07-22T17:03:13Z","receivedAt":"2026-07-22T17:03:17Z","isPatch":true,"body":"The '--exclude-first-parent-only' option instructs the revision\nwalker to follow only the first parent of a merge commit to\npropagate down the UNINTERESTING bit.\n\nHowever, if the first parent has already been marked SEEN (for\nexample, because it was explicitly specified on the command line),\nprocess_parents() skips it with a 'continue' statement.  But the\nloop then continues on to process the second parent, because the\ncheck for the '--exclude-first-parent-only' option is near the end\nof the loop, which the 'continue' statement skips.  Consequently, we\nend up marking the second parent as UNINTERESTING.\n\nBreak out of the loop instead of continuing when the first parent is\nalready SEEN or fails to parse.  This ensures that we do not process\nsubsequent parents and mark them as UNINTERESTING.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\nReviewed-by: Jerry Zhang <jerry@skydio.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n\n * This time with a commit log message.\n\n revision.c                   | 10 ++++++++--\n t/t6012-rev-list-simplify.sh | 18 ++++++++++++++++++\n 2 files changed, 26 insertions(+), 2 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 599b3a66c3..9b30663669 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -1152,12 +1152,18 @@ static int process_parents(struct rev_info *revs, struct commit *commit,\n \t\t\tif (p)\n \t\t\t\tp->object.flags |= UNINTERESTING |\n \t\t\t\t\t\t   CHILD_VISITED;\n-\t\t\tif (repo_parse_commit_gently(revs->repo, p, 1) < 0)\n+\t\t\tif (repo_parse_commit_gently(revs->repo, p, 1) < 0) {\n+\t\t\t\tif (revs->exclude_first_parent_only)\n+\t\t\t\t\tbreak;\n \t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tif (p->parents)\n \t\t\t\tmark_parents_uninteresting(revs, p);\n-\t\t\tif (p->object.flags & SEEN)\n+\t\t\tif (p->object.flags & SEEN) {\n+\t\t\t\tif (revs->exclude_first_parent_only)\n+\t\t\t\t\tbreak;\n \t\t\t\tcontinue;\n+\t\t\t}\n \t\t\tp->object.flags |= (SEEN | NOT_USER_GIVEN);\n \t\t\tif (list)\n \t\t\t\tcommit_list_insert_by_date(p, list);\ndiff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh\nindex 4cecb6224c..2284bbba12 100755\n--- a/t/t6012-rev-list-simplify.sh\n+++ b/t/t6012-rev-list-simplify.sh\n@@ -285,4 +285,22 @@ test_expect_success 'log --graph --simplify-merges --show-pulls' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'exclude-first-parent-only with parent already seen' '\n+\tgit checkout --orphan test-seen &&\n+\tgit rm -rf . &&\n+\ttest_commit r1 &&\n+\tgit checkout -b branch-f &&\n+\ttest_commit f &&\n+\tgit checkout test-seen &&\n+\tgit merge --no-ff --no-edit -m r2 branch-f &&\n+\tgit tag r2 &&\n+\n+\tgit rev-list --exclude-first-parent-only f ^r2 >actual &&\n+\tgit rev-parse f >expect &&\n+\ttest_cmp expect actual &&\n+\n+\tgit rev-list --exclude-first-parent-only f r1 ^r2 >actual2 &&\n+\ttest_cmp expect actual2\n+'\n+\n test_done\n-- \n2.55.0-496-g61638ae030\n\n"}]}