Skip to content

Commit

Permalink
Merge branch 'mh/ref-transaction'
Browse files Browse the repository at this point in the history
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
  ...
  • Loading branch information
Junio C Hamano committed Jun 3, 2014
2 parents 8eaf517 + 6a40233 commit 2cc70ce
Show file tree
Hide file tree
Showing 13 changed files with 585 additions and 285 deletions.
18 changes: 12 additions & 6 deletions Documentation/git-update-ref.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,25 @@ performs all modifications together. Specify commands of the form:
option SP <opt> LF

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

Alternatively, use `-z` to specify in NUL-terminated format, without
quoting:

update SP <ref> NUL <newvalue> NUL [<oldvalue>] NUL
create SP <ref> NUL <newvalue> NUL
delete SP <ref> NUL [<oldvalue>] NUL
verify SP <ref> NUL [<oldvalue>] NUL
option SP <opt> NUL

Lines of any other format or a repeated <ref> produce an error.
Command meanings are:
In this format, use 40 "0" to specify a zero value, and use the empty
string to specify a missing value.

In either format, values can be specified in any form that Git
recognizes as an object name. Commands in any other format or a
repeated <ref> produce an error. Command meanings are:

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

Use 40 "0" or the empty string to specify a zero value, except that
with `-z` an empty <oldvalue> is considered missing.

If all <ref>s can be locked with matching <oldvalue>s
simultaneously, all modifications are performed. Otherwise, no
modifications are performed. Note that while each individual
Expand Down
2 changes: 1 addition & 1 deletion builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ static void update_refs_for_switch(const struct checkout_opts *opts,
/* Nothing to do. */
} else if (opts->force_detach || !new->path) { /* No longer on any branch. */
update_ref(msg.buf, "HEAD", new->commit->object.sha1, NULL,
REF_NODEREF, DIE_ON_ERR);
REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
if (!opts->quiet) {
if (old->path && advice_detached_head)
detach_advice(new->name);
Expand Down
9 changes: 5 additions & 4 deletions builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ static void write_followtags(const struct ref *refs, const char *msg)
if (!has_sha1_file(ref->old_sha1))
continue;
update_ref(msg, ref->name, ref->old_sha1,
NULL, 0, DIE_ON_ERR);
NULL, 0, UPDATE_REFS_DIE_ON_ERR);
}
}

Expand Down Expand Up @@ -589,22 +589,23 @@ static void update_head(const struct ref *our, const struct ref *remote,
create_symref("HEAD", our->name, NULL);
if (!option_bare) {
const char *head = skip_prefix(our->name, "refs/heads/");
update_ref(msg, "HEAD", our->old_sha1, NULL, 0, DIE_ON_ERR);
update_ref(msg, "HEAD", our->old_sha1, NULL, 0,
UPDATE_REFS_DIE_ON_ERR);
install_branch_config(0, head, option_origin, our->name);
}
} else if (our) {
struct commit *c = lookup_commit_reference(our->old_sha1);
/* --branch specifies a non-branch (i.e. tags), detach HEAD */
update_ref(msg, "HEAD", c->object.sha1,
NULL, REF_NODEREF, DIE_ON_ERR);
NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
} else if (remote) {
/*
* We know remote HEAD points to a non-branch, or
* HEAD points to a branch but we don't know which one.
* Detach HEAD in all these cases.
*/
update_ref(msg, "HEAD", remote->old_sha1,
NULL, REF_NODEREF, DIE_ON_ERR);
NULL, REF_NODEREF, UPDATE_REFS_DIE_ON_ERR);
}
}

Expand Down
6 changes: 3 additions & 3 deletions builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static void finish(struct commit *head_commit,
const char *argv_gc_auto[] = { "gc", "--auto", NULL };
update_ref(reflog_message.buf, "HEAD",
new_head, head, 0,
DIE_ON_ERR);
UPDATE_REFS_DIE_ON_ERR);
/*
* We ignore errors in 'gc --auto', since the
* user should see them.
Expand Down Expand Up @@ -1222,7 +1222,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
die(_("%s - not something we can merge"), argv[0]);
read_empty(remote_head->object.sha1, 0);
update_ref("initial pull", "HEAD", remote_head->object.sha1,
NULL, 0, DIE_ON_ERR);
NULL, 0, UPDATE_REFS_DIE_ON_ERR);
goto done;
} else {
struct strbuf merge_names = STRBUF_INIT;
Expand Down Expand Up @@ -1339,7 +1339,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
}

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

if (remoteheads && !common)
; /* No common ancestors found. We need a real merge. */
Expand Down
6 changes: 3 additions & 3 deletions builtin/notes.c
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ static int merge_commit(struct notes_merge_options *o)
strbuf_insert(&msg, 0, "notes: ", 7);
update_ref(msg.buf, o->local_ref, sha1,
is_null_sha1(parent_sha1) ? NULL : parent_sha1,
0, DIE_ON_ERR);
0, UPDATE_REFS_DIE_ON_ERR);

free_notes(t);
strbuf_release(&msg);
Expand Down Expand Up @@ -812,11 +812,11 @@ static int merge(int argc, const char **argv, const char *prefix)
if (result >= 0) /* Merge resulted (trivially) in result_sha1 */
/* Update default notes ref with new commit */
update_ref(msg.buf, default_notes_ref(), result_sha1, NULL,
0, DIE_ON_ERR);
0, UPDATE_REFS_DIE_ON_ERR);
else { /* Merge has unresolved conflicts */
/* Update .git/NOTES_MERGE_PARTIAL with partial merge result */
update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL,
0, DIE_ON_ERR);
0, UPDATE_REFS_DIE_ON_ERR);
/* Store ref-to-be-updated into .git/NOTES_MERGE_REF */
if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL))
die("Failed to store link to current notes ref (%s)",
Expand Down
6 changes: 4 additions & 2 deletions builtin/reset.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,13 @@ static int reset_refs(const char *rev, const unsigned char *sha1)
if (!get_sha1("HEAD", sha1_orig)) {
orig = sha1_orig;
set_reflog_message(&msg, "updating ORIG_HEAD", NULL);
update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0, MSG_ON_ERR);
update_ref(msg.buf, "ORIG_HEAD", orig, old_orig, 0,
UPDATE_REFS_MSG_ON_ERR);
} else if (old_orig)
delete_ref("ORIG_HEAD", old_orig, 0);
set_reflog_message(&msg, "updating HEAD", rev);
update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0, MSG_ON_ERR);
update_ref_status = update_ref(msg.buf, "HEAD", sha1, orig, 0,
UPDATE_REFS_MSG_ON_ERR);
strbuf_release(&msg);
return update_ref_status;
}
Expand Down
Loading

0 comments on commit 2cc70ce

Please sign in to comment.