gitrevisions(7) says: "A suffix '^' followed by an exclamation mark is the same as giving commit '<rev>' and then all its parents prefixed with '^' to exclude them (and their ancestors)." handle_revision_arg_1() however adds the negated parents first. This leads to unexpected results with git diff and merge commits, as that command expects the documented order. Split up the handling of ^! by moving the actual addition of the parents after the addition of the child. Reported-by: Tim Jaacks <tim.jaacks@xxxxxxxxxxxxxxx> Signed-off-by: René Scharfe <l.s.r@xxxxxx> --- revision.c | 13 ++++++------- t/t4038-diff-combined.sh | 10 ++++++++++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/revision.c b/revision.c index 5e756b76aa..8385127f1a 100644 --- a/revision.c +++ b/revision.c @@ -2107,6 +2107,7 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl const char *arg = arg_; int cant_be_filename = revarg_opt & REVARG_CANNOT_BE_FILENAME; unsigned get_sha1_flags = GET_OID_RECORD_PATH; + struct commit *caret_bang_commit = NULL; flags = flags & UNINTERESTING ? flags | BOTTOM : flags & ~BOTTOM; @@ -2135,14 +2136,9 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl } mark = strstr(arg, "^!"); if (mark && !mark[2]) { - struct commit *commit; - *mark = 0; - commit = get_commit(revs, arg); - if (commit) - add_parents(revs, commit->parents, arg, - flags ^ (UNINTERESTING | BOTTOM)); - else + caret_bang_commit = get_commit(revs, arg); + if (!caret_bang_commit) *mark = '^'; } mark = strstr(arg, "^-"); @@ -2179,6 +2175,9 @@ static int handle_revision_arg_1(const char *arg_, struct rev_info *revs, int fl add_rev_cmdline(revs, object, arg_, REV_CMD_REV, flags ^ local_flags); add_pending_object_with_path(revs, object, arg, oc.mode, oc.path); free(oc.path); + if (caret_bang_commit) + add_parents(revs, caret_bang_commit->parents, arg, + flags ^ (UNINTERESTING | BOTTOM)); return 0; } diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index 9a292bac70..2ce26e585c 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -80,11 +80,21 @@ test_expect_success 'check combined output (1)' ' verify_helper sidewithone ' +test_expect_success 'check combined output (1) with git diff <rev>^!' ' + git diff sidewithone^! -- >sidewithone && + verify_helper sidewithone +' + test_expect_success 'check combined output (2)' ' git show sidesansone -- >sidesansone && verify_helper sidesansone ' +test_expect_success 'check combined output (2) with git diff <rev>^!' ' + git diff sidesansone^! -- >sidesansone && + verify_helper sidesansone +' + test_expect_success 'diagnose truncated file' ' >file && git add file && -- 2.37.3