From: Karthik Nayak Date: Wed, 14 Jan 2026 15:40:45 GMT Subject: [PATCH 4/6] update-ref: utilize rejected error details if available Message-ID: <20260114-633-regression-lost-diagnostic-message-when-pushing-non-commit-objects-to-refs-heads-v1-4-f5f8b173c501@gmail.com> In-Reply-To: <20260114-633-regression-lost-diagnostic-message-when-pushing-non-commit-objects-to-refs-heads-v1-0-f5f8b173c501@gmail.com> When git-update-ref(1) received the '--update-ref' flag, the error details generated in the refs namespace wasn't propagated with failed updates. Instead only an error code pertaining to the type of rejection was noted. This missed detailed error message which the user can act upon. The previous commits added the required code to propagate these detailed error messages from the refs namespace. Now that additional details are available, use them instead of the generic error message based of the error code. Fix the tests to also accommodate these error messages. Reported-by: Elijah Newren Co-authored-by: Jeff King Signed-off-by: Karthik Nayak --- builtin/update-ref.c | 14 ++++++++------ t/t1400-update-ref.sh | 26 +++++++++++++------------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 0046a87c57..800e380d32 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -573,16 +573,18 @@ static void print_rejected_refs(const char *refname, const char *old_target, const char *new_target, enum ref_transaction_error err, - const char *details UNUSED, + const char *details, void *cb_data UNUSED) { struct strbuf sb = STRBUF_INIT; - const char *reason = ref_transaction_error_msg(err); - strbuf_addf(&sb, "rejected %s %s %s %s\n", refname, - new_oid ? oid_to_hex(new_oid) : new_target, - old_oid ? oid_to_hex(old_oid) : old_target, - reason); + if (details) + strbuf_addf(&sb, "%s\n", details); + else + strbuf_addf(&sb, "rejected %s %s %s %s\n", refname, + new_oid ? oid_to_hex(new_oid) : new_target, + old_oid ? oid_to_hex(old_oid) : old_target, + ref_transaction_error_msg(err)); fwrite(sb.buf, sb.len, 1, stdout); strbuf_release(&sb); diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index db7f5444da..6cd6b45411 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -2100,7 +2100,7 @@ do echo $head >expect && git rev-parse refs/heads/ref2 >actual && test_cmp expect actual && - test_grep -q "invalid new value provided" stdout + test_grep -q "trying to write ref ${SQ}refs/heads/ref2${SQ} with nonexistent object" stdout ) ' @@ -2126,7 +2126,7 @@ do echo $head >expect && git rev-parse refs/heads/ref2 >actual && test_cmp expect actual && - test_grep -q "invalid new value provided" stdout + test_grep -q "trying to write non-commit object $head_tree to branch ${SQ}refs/heads/ref2${SQ}" stdout ) ' @@ -2148,7 +2148,7 @@ do git rev-parse refs/heads/ref1 >actual && test_cmp expect actual && test_must_fail git rev-parse refs/heads/ref2 && - test_grep -q "reference does not exist" stdout + test_grep -q "cannot lock ref ${SQ}refs/heads/ref2${SQ}: unable to resolve reference ${SQ}refs/heads/ref2${SQ}" stdout ) ' @@ -2172,7 +2172,7 @@ do test_cmp expect actual && echo $head >expect && test_must_fail git rev-parse refs/heads/ref2 && - test_grep -q "reference does not exist" stdout + test_grep -q "cannot lock ref ${SQ}refs/heads/ref2${SQ}: reference is missing but expected $head" stdout ) ' @@ -2198,7 +2198,7 @@ do echo $head >expect && git rev-parse refs/heads/ref2 >actual && test_cmp expect actual && - test_grep -q "expected symref but found regular ref" stdout + test_grep -q "cannot lock ref ${SQ}refs/heads/ref2${SQ}: expected symref with target ${SQ}refs/heads/nonexistent${SQ}: but is a regular ref" stdout ) ' @@ -2223,7 +2223,7 @@ do echo $head >expect && git rev-parse refs/heads/ref2 >actual && test_cmp expect actual && - test_grep -q "reference already exists" stdout + test_grep -q "cannot lock ref ${SQ}refs/heads/ref2${SQ}: reference already exists" stdout ) ' @@ -2248,7 +2248,7 @@ do echo $head >expect && git rev-parse refs/heads/ref2 >actual && test_cmp expect actual && - test_grep -q "incorrect old value provided" stdout + test_grep -q "cannot lock ref ${SQ}refs/heads/ref2${SQ}: is at $head but expected $old_head" stdout ) ' @@ -2269,7 +2269,7 @@ do echo $old_head >expect && git rev-parse refs/heads/ref/foo >actual && test_cmp expect actual && - test_grep -q "refname conflict" stdout + test_grep -q "${SQ}refs/heads/ref/foo${SQ} exists; cannot create ${SQ}refs/heads/ref${SQ}" stdout ) ' @@ -2290,7 +2290,7 @@ do echo $old_head >expect && git rev-parse refs/heads/foo >actual && test_cmp expect actual && - test_grep -q "refname conflict" stdout + test_grep -q "${SQ}refs/heads/ref/foo${SQ} exists; cannot create ${SQ}refs/heads/ref${SQ}" stdout ) ' @@ -2316,7 +2316,7 @@ do echo $old_head >expect && git rev-parse refs/heads/ref >actual && test_cmp expect actual && - test_grep -q "reference conflict due to case-insensitive filesystem" stdout + test_grep -e "cannot lock ref ${SQ}refs/heads/Foo${SQ}: Unable to create" -e "Foo.lock" stdout ) ' @@ -2358,7 +2358,7 @@ do format_command $type "delete refs/heads/symbolic" "$head" >stdin && git update-ref $type --stdin --batch-updates stdout && - test_grep "reference does not exist" stdout + test_grep "cannot lock ref ${SQ}refs/heads/symbolic${SQ}: unable to resolve reference ${SQ}refs/heads/non-existent${SQ}" stdout ) ' @@ -2374,7 +2374,7 @@ do format_command $type "delete refs/heads/new-branch" "$head" >stdin && git update-ref $type --stdin --batch-updates stdout && - test_grep "incorrect old value provided" stdout + test_grep "cannot lock ref ${SQ}refs/heads/new-branch${SQ}: is at $(git rev-parse new-branch) but expected $head" stdout ) ' @@ -2388,7 +2388,7 @@ do format_command $type "delete refs/heads/non-existent" "$head" >stdin && git update-ref $type --stdin --batch-updates stdout && - test_grep "reference does not exist" stdout + test_grep "cannot lock ref ${SQ}refs/heads/non-existent${SQ}: unable to resolve reference ${SQ}refs/heads/non-existent${SQ}" stdout ) ' done -- 2.51.2