Skip to content

Commit 2cc70ce

Browse files
committed
Merge branch 'mh/ref-transaction'
Update "update-ref --stdin [-z]" and then introduce a transactional support for (multi-)reference updates. * mh/ref-transaction: (27 commits) ref_transaction_commit(): work with transaction->updates in place struct ref_update: add a type field struct ref_update: add a lock field ref_transaction_commit(): simplify code using temporary variables struct ref_update: store refname as a FLEX_ARRAY struct ref_update: rename field "ref_name" to "refname" refs: remove API function update_refs() update-ref --stdin: reimplement using reference transactions refs: add a concept of a reference transaction update-ref --stdin: harmonize error messages update-ref --stdin: improve the error message for unexpected EOF t1400: test one mistake at a time update-ref --stdin -z: deprecate interpreting the empty string as zeros update-ref.c: extract a new function, parse_next_sha1() t1400: test that stdin -z update treats empty <newvalue> as zeros update-ref --stdin: simplify error messages for missing oldvalues update-ref --stdin: make error messages more consistent update-ref --stdin: improve error messages for invalid values update-ref.c: extract a new function, parse_refname() parse_cmd_verify(): copy old_sha1 instead of evaluating <oldvalue> twice ...
2 parents 8eaf517 + 6a40233 commit 2cc70ce

13 files changed

Lines changed: 585 additions & 285 deletions

File tree

Documentation/git-update-ref.txt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,25 @@ performs all modifications together. Specify commands of the form:
6868
option SP <opt> LF
6969

7070
Quote fields containing whitespace as if they were strings in C source
71-
code. Alternatively, use `-z` to specify commands without quoting:
71+
code; i.e., surrounded by double-quotes and with backslash escapes.
72+
Use 40 "0" characters or the empty string to specify a zero value. To
73+
specify a missing value, omit the value and its preceding SP entirely.
74+
75+
Alternatively, use `-z` to specify in NUL-terminated format, without
76+
quoting:
7277

7378
update SP <ref> NUL <newvalue> NUL [<oldvalue>] NUL
7479
create SP <ref> NUL <newvalue> NUL
7580
delete SP <ref> NUL [<oldvalue>] NUL
7681
verify SP <ref> NUL [<oldvalue>] NUL
7782
option SP <opt> NUL
7883

79-
Lines of any other format or a repeated <ref> produce an error.
80-
Command meanings are:
84+
In this format, use 40 "0" to specify a zero value, and use the empty
85+
string to specify a missing value.
86+
87+
In either format, values can be specified in any form that Git
88+
recognizes as an object name. Commands in any other format or a
89+
repeated <ref> produce an error. Command meanings are:
8190

8291
update::
8392
Set <ref> to <newvalue> after verifying <oldvalue>, if given.
@@ -102,9 +111,6 @@ option::
102111
The only valid option is `no-deref` to avoid dereferencing
103112
a symbolic ref.
104113

105-
Use 40 "0" or the empty string to specify a zero value, except that
106-
with `-z` an empty <oldvalue> is considered missing.
107-
108114
If all <ref>s can be locked with matching <oldvalue>s
109115
simultaneously, all modifications are performed. Otherwise, no
110116
modifications are performed. Note that while each individual

builtin/checkout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
624624
/* Nothing to do. */
625625
} else if (opts->force_detach || !new->path) { /* No longer on any branch. */
626626
update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
627-
REF_NODEREF, DIE_ON_ERR);
627+
REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
628628
if (!opts->quiet) {
629629
if (old->path && advice_detached_head)
630630
detach_advice(new->name);

builtin/clone.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,7 @@ static void write_followtags(const struct ref *refs, const char *msg)
521521
if (!has_sha1_file(ref->old_sha1))
522522
continue;
523523
update_ref(msg, ref->name, ref->old_sha1,
524-
NULL, 0, DIE_ON_ERR);
524+
NULL, 0, UPDATE_REFS_DIE_ON_ERR);
525525
}
526526
}
527527

@@ -589,22 +589,23 @@ static void update_head(const struct ref *our, const struct ref *remote,
589589
create_symref("HEAD", our->name, NULL);
590590
if (!option_bare) {
591591
const char *head = skip_prefix(our->name, "refs/heads/");
592-
update_ref(msg, "HEAD", our->old_sha1, NULL, 0, DIE_ON_ERR);
592+
update_ref(msg, "HEAD", our->old_sha1, NULL, 0,
593+
UPDATE_REFS_DIE_ON_ERR);
593594
install_branch_config(0, head, option_origin, our->name);
594595
}
595596
} else if (our) {
596597
struct commit *c = lookup_commit_reference(our->old_sha1);
597598
/* --branch specifies a non-branch (i.e. tags), detach HEAD */
598599
update_ref(msg, "HEAD", c->object.sha1,
599-
NULL, REF_NODEREF, DIE_ON_ERR);
600+
NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
600601
} else if (remote) {
601602
/*
602603
* We know remote HEAD points to a non-branch, or
603604
* HEAD points to a branch but we don't know which one.
604605
* Detach HEAD in all these cases.
605606
*/
606607
update_ref(msg, "HEAD", remote->old_sha1,
607-
NULL, REF_NODEREF, DIE_ON_ERR);
608+
NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
608609
}
609610
}
610611

builtin/merge.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ static void finish(struct commit *head_commit,
398398
const char *argv_gc_auto[] = { "gc", "--auto", NULL };
399399
update_ref(reflog_message.buf, "HEAD",
400400
new_head, head, 0,
401-
DIE_ON_ERR);
401+
UPDATE_REFS_DIE_ON_ERR);
402402
/*
403403
* We ignore errors in 'gc --auto', since the
404404
* user should see them.
@@ -1222,7 +1222,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
12221222
die(_("%s - not something we can merge"), argv[0]);
12231223
read_empty(remote_head->object.sha1, 0);
12241224
update_ref("initial pull", "HEAD", remote_head->object.sha1,
1225-
NULL, 0, DIE_ON_ERR);
1225+
NULL, 0, UPDATE_REFS_DIE_ON_ERR);
12261226
goto done;
12271227
} else {
12281228
struct strbuf merge_names = STRBUF_INIT;
@@ -1339,7 +1339,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
13391339
}
13401340

13411341
update_ref("updating ORIG_HEAD", "ORIG_HEAD", head_commit->object.sha1,
1342-
NULL, 0, DIE_ON_ERR);
1342+
NULL, 0, UPDATE_REFS_DIE_ON_ERR);
13431343

13441344
if (remoteheads && !common)
13451345
; /* No common ancestors found. We need a real merge. */

builtin/notes.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ static int merge_commit(struct notes_merge_options *o)
717717
strbuf_insert(&msg, 0, "notes: ", 7);
718718
update_ref(msg.buf, o->local_ref, sha1,
719719
is_null_sha1(parent_sha1) ? NULL : parent_sha1,
720-
0, DIE_ON_ERR);
720+
0, UPDATE_REFS_DIE_ON_ERR);
721721

722722
free_notes(t);
723723
strbuf_release(&msg);
@@ -812,11 +812,11 @@ static int merge(int argc, const char **argv, const char *prefix)
812812
if (result >= 0) /* Merge resulted (trivially) in result_sha1 */
813813
/* Update default notes ref with new commit */
814814
update_ref(msg.buf, default_notes_ref(), result_sha1, NULL,
815-
0, DIE_ON_ERR);
815+
0, UPDATE_REFS_DIE_ON_ERR);
816816
else { /* Merge has unresolved conflicts */
817817
/* Update .git/NOTES_MERGE_PARTIAL with partial merge result */
818818
update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL,
819-
0, DIE_ON_ERR);
819+
0, UPDATE_REFS_DIE_ON_ERR);
820820
/* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
821821
if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL))
822822
die("Failed to store link to current notes ref (%s)",

builtin/reset.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,13 @@ static int reset_refs(const char *rev, const unsigned char *sha1)
252252
if (!get_sha1("HEAD", sha1_orig)) {
253253
orig = sha1_orig;
254254
set_reflog_message(&msg, "updating ORIG_HEAD", NULL);
255-
update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
255+
update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0,
256+
UPDATE_REFS_MSG_ON_ERR);
256257
} else if (old_orig)
257258
delete_ref("ORIG_HEAD", old_orig, 0);
258259
set_reflog_message(&msg, "updating HEAD", rev);
259-
update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, MSG_ON_ERR);
260+
update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0,
261+
UPDATE_REFS_MSG_ON_ERR);
260262
strbuf_release(&msg);
261263
return update_ref_status;
262264
}

0 commit comments

Comments
 (0)