Skip to content

Commit 6176ee2

Browse files
committed
Merge branch 'kn/ref-batch-output-error-reporting-fix'
A handful of code paths that started using batched ref update API (after Git 2.51 or so) lost detailed error output, which have been corrected. * kn/ref-batch-output-error-reporting-fix: fetch: delay user information post committing of transaction receive-pack: utilize rejected ref error details fetch: utilize rejected ref error details update-ref: utilize rejected error details if available refs: add rejection detail to the callback function refs: skip to next ref when current ref is rejected
2 parents 8087aae + eff9299 commit 6176ee2

12 files changed

Lines changed: 312 additions & 125 deletions

builtin/fetch.c

Lines changed: 198 additions & 57 deletions
Large diffs are not rendered by default.

builtin/receive-pack.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1853,10 +1853,14 @@ static void ref_transaction_rejection_handler(const char *refname,
18531853
const char *old_target UNUSED,
18541854
const char *new_target UNUSED,
18551855
enum ref_transaction_error err,
1856+
const char *details,
18561857
void *cb_data)
18571858
{
18581859
struct strmap *failed_refs = cb_data;
18591860

1861+
if (details)
1862+
rp_error("%s", details);
1863+
18601864
strmap_put(failed_refs, refname, (char *)ref_transaction_error_msg(err));
18611865
}
18621866

@@ -1923,6 +1927,7 @@ static void execute_commands_non_atomic(struct command *commands,
19231927
}
19241928

19251929
ref_transaction_for_each_rejected_update(transaction,
1930+
19261931
ref_transaction_rejection_handler,
19271932
&failed_refs);
19281933

@@ -1934,7 +1939,7 @@ static void execute_commands_non_atomic(struct command *commands,
19341939
if (reported_error)
19351940
cmd->error_string = reported_error;
19361941
else if (strmap_contains(&failed_refs, cmd->ref_name))
1937-
cmd->error_string = strmap_get(&failed_refs, cmd->ref_name);
1942+
cmd->error_string = cmd->error_string_owned = xstrdup(strmap_get(&failed_refs, cmd->ref_name));
19381943
}
19391944

19401945
cleanup:

builtin/update-ref.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,15 +573,18 @@ static void print_rejected_refs(const char *refname,
573573
const char *old_target,
574574
const char *new_target,
575575
enum ref_transaction_error err,
576+
const char *details,
576577
void *cb_data UNUSED)
577578
{
578579
struct strbuf sb = STRBUF_INIT;
579-
const char *reason = ref_transaction_error_msg(err);
580+
581+
if (details && *details)
582+
error("%s", details);
580583

581584
strbuf_addf(&sb, "rejected %s %s %s %s\n", refname,
582585
new_oid ? oid_to_hex(new_oid) : new_target,
583586
old_oid ? oid_to_hex(old_oid) : old_target,
584-
reason);
587+
ref_transaction_error_msg(err));
585588

586589
fwrite(sb.buf, sb.len, 1, stdout);
587590
strbuf_release(&sb);

refs.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,7 @@ void ref_transaction_free(struct ref_transaction *transaction)
12671267
free(transaction->updates[i]->committer_info);
12681268
free((char *)transaction->updates[i]->new_target);
12691269
free((char *)transaction->updates[i]->old_target);
1270+
free((char *)transaction->updates[i]->rejection_details);
12701271
free(transaction->updates[i]);
12711272
}
12721273

@@ -1281,7 +1282,8 @@ void ref_transaction_free(struct ref_transaction *transaction)
12811282

12821283
int ref_transaction_maybe_set_rejected(struct ref_transaction *transaction,
12831284
size_t update_idx,
1284-
enum ref_transaction_error err)
1285+
enum ref_transaction_error err,
1286+
struct strbuf *details)
12851287
{
12861288
if (update_idx >= transaction->nr)
12871289
BUG("trying to set rejection on invalid update index");
@@ -1307,6 +1309,7 @@ int ref_transaction_maybe_set_rejected(struct ref_transaction *transaction,
13071309
transaction->updates[update_idx]->refname, 0);
13081310

13091311
transaction->updates[update_idx]->rejection_err = err;
1312+
transaction->updates[update_idx]->rejection_details = strbuf_detach(details, NULL);
13101313
ALLOC_GROW(transaction->rejections->update_indices,
13111314
transaction->rejections->nr + 1,
13121315
transaction->rejections->alloc);
@@ -2698,30 +2701,33 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs
26982701
if (!initial_transaction &&
26992702
(strset_contains(&conflicting_dirnames, dirname.buf) ||
27002703
!refs_read_raw_ref(refs, dirname.buf, &oid, &referent,
2701-
&type, &ignore_errno))) {
2704+
&type, &ignore_errno))) {
2705+
2706+
strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
2707+
dirname.buf, refname);
2708+
27022709
if (transaction && ref_transaction_maybe_set_rejected(
27032710
transaction, *update_idx,
2704-
REF_TRANSACTION_ERROR_NAME_CONFLICT)) {
2711+
REF_TRANSACTION_ERROR_NAME_CONFLICT, err)) {
27052712
strset_remove(&dirnames, dirname.buf);
27062713
strset_add(&conflicting_dirnames, dirname.buf);
2707-
continue;
2714+
goto next_ref;
27082715
}
27092716

2710-
strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
2711-
dirname.buf, refname);
27122717
goto cleanup;
27132718
}
27142719

27152720
if (extras && string_list_has_string(extras, dirname.buf)) {
2721+
strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
2722+
refname, dirname.buf);
2723+
27162724
if (transaction && ref_transaction_maybe_set_rejected(
27172725
transaction, *update_idx,
2718-
REF_TRANSACTION_ERROR_NAME_CONFLICT)) {
2726+
REF_TRANSACTION_ERROR_NAME_CONFLICT, err)) {
27192727
strset_remove(&dirnames, dirname.buf);
2720-
continue;
2728+
goto next_ref;
27212729
}
27222730

2723-
strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
2724-
refname, dirname.buf);
27252731
goto cleanup;
27262732
}
27272733
}
@@ -2751,14 +2757,14 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs
27512757
if (skip &&
27522758
string_list_has_string(skip, iter->ref.name))
27532759
continue;
2760+
strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
2761+
iter->ref.name, refname);
27542762

27552763
if (transaction && ref_transaction_maybe_set_rejected(
27562764
transaction, *update_idx,
2757-
REF_TRANSACTION_ERROR_NAME_CONFLICT))
2758-
continue;
2765+
REF_TRANSACTION_ERROR_NAME_CONFLICT, err))
2766+
goto next_ref;
27592767

2760-
strbuf_addf(err, _("'%s' exists; cannot create '%s'"),
2761-
iter->ref.name, refname);
27622768
goto cleanup;
27632769
}
27642770

@@ -2768,15 +2774,17 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs
27682774

27692775
extra_refname = find_descendant_ref(dirname.buf, extras, skip);
27702776
if (extra_refname) {
2777+
strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
2778+
refname, extra_refname);
2779+
27712780
if (transaction && ref_transaction_maybe_set_rejected(
27722781
transaction, *update_idx,
2773-
REF_TRANSACTION_ERROR_NAME_CONFLICT))
2774-
continue;
2782+
REF_TRANSACTION_ERROR_NAME_CONFLICT, err))
2783+
goto next_ref;
27752784

2776-
strbuf_addf(err, _("cannot process '%s' and '%s' at the same time"),
2777-
refname, extra_refname);
27782785
goto cleanup;
27792786
}
2787+
next_ref:;
27802788
}
27812789

27822790
ret = 0;
@@ -2905,7 +2913,7 @@ void ref_transaction_for_each_rejected_update(struct ref_transaction *transactio
29052913
(update->flags & REF_HAVE_OLD) ? &update->old_oid : NULL,
29062914
(update->flags & REF_HAVE_NEW) ? &update->new_oid : NULL,
29072915
update->old_target, update->new_target,
2908-
update->rejection_err, cb_data);
2916+
update->rejection_err, update->rejection_details, cb_data);
29092917
}
29102918
}
29112919

refs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,7 @@ typedef void ref_transaction_for_each_rejected_update_fn(const char *refname,
993993
const char *old_target,
994994
const char *new_target,
995995
enum ref_transaction_error err,
996+
const char *details,
996997
void *cb_data);
997998
void ref_transaction_for_each_rejected_update(struct ref_transaction *transaction,
998999
ref_transaction_for_each_rejected_update_fn cb,

refs/files-backend.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2978,10 +2978,9 @@ static int files_transaction_prepare(struct ref_store *ref_store,
29782978
head_ref, &refnames_to_check,
29792979
err);
29802980
if (ret) {
2981-
if (ref_transaction_maybe_set_rejected(transaction, i, ret)) {
2982-
strbuf_reset(err);
2981+
if (ref_transaction_maybe_set_rejected(transaction, i,
2982+
ret, err)) {
29832983
ret = 0;
2984-
29852984
continue;
29862985
}
29872986
goto cleanup;

refs/packed-backend.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,8 +1437,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
14371437
update->refname);
14381438
ret = REF_TRANSACTION_ERROR_CREATE_EXISTS;
14391439

1440-
if (ref_transaction_maybe_set_rejected(transaction, i, ret)) {
1441-
strbuf_reset(err);
1440+
if (ref_transaction_maybe_set_rejected(transaction, i,
1441+
ret, err)) {
14421442
ret = 0;
14431443
continue;
14441444
}
@@ -1452,8 +1452,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
14521452
oid_to_hex(&update->old_oid));
14531453
ret = REF_TRANSACTION_ERROR_INCORRECT_OLD_VALUE;
14541454

1455-
if (ref_transaction_maybe_set_rejected(transaction, i, ret)) {
1456-
strbuf_reset(err);
1455+
if (ref_transaction_maybe_set_rejected(transaction, i,
1456+
ret, err)) {
14571457
ret = 0;
14581458
continue;
14591459
}
@@ -1496,8 +1496,8 @@ static enum ref_transaction_error write_with_updates(struct packed_ref_store *re
14961496
oid_to_hex(&update->old_oid));
14971497
ret = REF_TRANSACTION_ERROR_NONEXISTENT_REF;
14981498

1499-
if (ref_transaction_maybe_set_rejected(transaction, i, ret)) {
1500-
strbuf_reset(err);
1499+
if (ref_transaction_maybe_set_rejected(transaction, i,
1500+
ret, err)) {
15011501
ret = 0;
15021502
continue;
15031503
}

refs/refs-internal.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ struct ref_update {
128128
* was rejected.
129129
*/
130130
enum ref_transaction_error rejection_err;
131+
const char *rejection_details;
131132

132133
/*
133134
* If this ref_update was split off of a symref update via
@@ -153,7 +154,8 @@ int refs_read_raw_ref(struct ref_store *ref_store, const char *refname,
153154
*/
154155
int ref_transaction_maybe_set_rejected(struct ref_transaction *transaction,
155156
size_t update_idx,
156-
enum ref_transaction_error err);
157+
enum ref_transaction_error err,
158+
struct strbuf *details);
157159

158160
/*
159161
* Add a ref_update with the specified properties to transaction, and

refs/reftable-backend.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,10 +1418,9 @@ static int reftable_be_transaction_prepare(struct ref_store *ref_store,
14181418
&refnames_to_check, head_type,
14191419
&head_referent, &referent, err);
14201420
if (ret) {
1421-
if (ref_transaction_maybe_set_rejected(transaction, i, ret)) {
1422-
strbuf_reset(err);
1421+
if (ref_transaction_maybe_set_rejected(transaction, i,
1422+
ret, err)) {
14231423
ret = 0;
1424-
14251424
continue;
14261425
}
14271426
goto done;

0 commit comments

Comments
 (0)