Skip to content

Commit d4c8db8

Browse files
pks-tgitster
authored andcommitted
fetch: allow passing a transaction to s_update_ref()
The handling of ref updates is completely handled by `s_update_ref()`, which will manage the complete lifecycle of the reference transaction. This is fine right now given that git-fetch(1) does not support atomic fetches, so each reference gets its own transaction. It is quite inflexible though, as `s_update_ref()` only knows about a single reference update at a time, so it doesn't allow us to alter the strategy. This commit prepares `s_update_ref()` and its only caller `update_local_ref()` to allow passing an external transaction. If none is given, then the existing behaviour is triggered which creates a new transaction and directly commits it. Otherwise, if the caller provides a transaction, then we only queue the update but don't commit it. This optionally allows the caller to manage when a transaction will be committed. Given that `update_local_ref()` is always called with a `NULL` transaction for now, no change in behaviour is expected from this change. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent c45889f commit d4c8db8

File tree

1 file changed

+31
-20
lines changed

1 file changed

+31
-20
lines changed

builtin/fetch.c

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,12 @@ static struct ref *get_ref_map(struct remote *remote,
583583

584584
static int s_update_ref(const char *action,
585585
struct ref *ref,
586+
struct ref_transaction *transaction,
586587
int check_old)
587588
{
588589
char *msg;
589590
char *rla = getenv("GIT_REFLOG_ACTION");
590-
struct ref_transaction *transaction;
591+
struct ref_transaction *our_transaction = NULL;
591592
struct strbuf err = STRBUF_INIT;
592593
int ret;
593594

@@ -597,10 +598,17 @@ static int s_update_ref(const char *action,
597598
rla = default_rla.buf;
598599
msg = xstrfmt("%s: %s", rla, action);
599600

600-
transaction = ref_transaction_begin(&err);
601+
/*
602+
* If no transaction was passed to us, we manage the transaction
603+
* ourselves. Otherwise, we trust the caller to handle the transaction
604+
* lifecycle.
605+
*/
601606
if (!transaction) {
602-
ret = STORE_REF_ERROR_OTHER;
603-
goto out;
607+
transaction = our_transaction = ref_transaction_begin(&err);
608+
if (!transaction) {
609+
ret = STORE_REF_ERROR_OTHER;
610+
goto out;
611+
}
604612
}
605613

606614
ret = ref_transaction_update(transaction, ref->name, &ref->new_oid,
@@ -611,19 +619,21 @@ static int s_update_ref(const char *action,
611619
goto out;
612620
}
613621

614-
switch (ref_transaction_commit(transaction, &err)) {
615-
case 0:
616-
break;
617-
case TRANSACTION_NAME_CONFLICT:
618-
ret = STORE_REF_ERROR_DF_CONFLICT;
619-
goto out;
620-
default:
621-
ret = STORE_REF_ERROR_OTHER;
622-
goto out;
622+
if (our_transaction) {
623+
switch (ref_transaction_commit(our_transaction, &err)) {
624+
case 0:
625+
break;
626+
case TRANSACTION_NAME_CONFLICT:
627+
ret = STORE_REF_ERROR_DF_CONFLICT;
628+
goto out;
629+
default:
630+
ret = STORE_REF_ERROR_OTHER;
631+
goto out;
632+
}
623633
}
624634

625635
out:
626-
ref_transaction_free(transaction);
636+
ref_transaction_free(our_transaction);
627637
if (ret)
628638
error("%s", err.buf);
629639
strbuf_release(&err);
@@ -766,6 +776,7 @@ static void format_display(struct strbuf *display, char code,
766776
}
767777

768778
static int update_local_ref(struct ref *ref,
779+
struct ref_transaction *transaction,
769780
const char *remote,
770781
const struct ref *remote_ref,
771782
struct strbuf *display,
@@ -806,7 +817,7 @@ static int update_local_ref(struct ref *ref,
806817
starts_with(ref->name, "refs/tags/")) {
807818
if (force || ref->force) {
808819
int r;
809-
r = s_update_ref("updating tag", ref, 0);
820+
r = s_update_ref("updating tag", ref, transaction, 0);
810821
format_display(display, r ? '!' : 't', _("[tag update]"),
811822
r ? _("unable to update local ref") : NULL,
812823
remote, pretty_ref, summary_width);
@@ -843,7 +854,7 @@ static int update_local_ref(struct ref *ref,
843854
what = _("[new ref]");
844855
}
845856

846-
r = s_update_ref(msg, ref, 0);
857+
r = s_update_ref(msg, ref, transaction, 0);
847858
format_display(display, r ? '!' : '*', what,
848859
r ? _("unable to update local ref") : NULL,
849860
remote, pretty_ref, summary_width);
@@ -865,7 +876,7 @@ static int update_local_ref(struct ref *ref,
865876
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
866877
strbuf_addstr(&quickref, "..");
867878
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
868-
r = s_update_ref("fast-forward", ref, 1);
879+
r = s_update_ref("fast-forward", ref, transaction, 1);
869880
format_display(display, r ? '!' : ' ', quickref.buf,
870881
r ? _("unable to update local ref") : NULL,
871882
remote, pretty_ref, summary_width);
@@ -877,7 +888,7 @@ static int update_local_ref(struct ref *ref,
877888
strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
878889
strbuf_addstr(&quickref, "...");
879890
strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
880-
r = s_update_ref("forced-update", ref, 1);
891+
r = s_update_ref("forced-update", ref, transaction, 1);
881892
format_display(display, r ? '!' : '+', quickref.buf,
882893
r ? _("unable to update local ref") : _("forced update"),
883894
remote, pretty_ref, summary_width);
@@ -1094,8 +1105,8 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
10941105

10951106
strbuf_reset(&note);
10961107
if (ref) {
1097-
rc |= update_local_ref(ref, what, rm, &note,
1098-
summary_width);
1108+
rc |= update_local_ref(ref, NULL, what,
1109+
rm, &note, summary_width);
10991110
free(ref);
11001111
} else if (write_fetch_head || dry_run) {
11011112
/*

0 commit comments

Comments
 (0)