Skip to content

Commit

Permalink
Merge branch 'rs/ref-transaction'
Browse files Browse the repository at this point in the history
The API to update refs have been restructured to allow introducing
a true transactional updates later.  We would even allow storing
refs in backends other than the traditional filesystem-based one.

* rs/ref-transaction: (25 commits)
  ref_transaction_commit: bail out on failure to remove a ref
  lockfile: remove unable_to_lock_error
  refs.c: do not permit err == NULL
  remote rm/prune: print a message when writing packed-refs fails
  for-each-ref: skip and warn about broken ref names
  refs.c: allow listing and deleting badly named refs
  test: put tests for handling of bad ref names in one place
  packed-ref cache: forbid dot-components in refnames
  branch -d: simplify by using RESOLVE_REF_READING
  branch -d: avoid repeated symref resolution
  reflog test: test interaction with detached HEAD
  refs.c: change resolve_ref_unsafe reading argument to be a flags field
  refs.c: make write_ref_sha1 static
  fetch.c: change s_update_ref to use a ref transaction
  refs.c: ref_transaction_commit: distinguish name conflicts from other errors
  refs.c: pass a list of names to skip to is_refname_available
  refs.c: call lock_ref_sha1_basic directly from commit
  refs.c: refuse to lock badly named refs in lock_ref_sha1_basic
  rename_ref: don't ask read_ref_full where the ref came from
  refs.c: pass the ref log message to _create/delete/update instead of _commit
  ...
  • Loading branch information
Junio C Hamano committed Oct 21, 2014
2 parents 13da0fc + 6573284 commit 3c85452
Show file tree
Hide file tree
Showing 45 changed files with 849 additions and 350 deletions.
6 changes: 3 additions & 3 deletions branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
const char *head;
unsigned char sha1[20];

head = resolve_ref_unsafe("HEAD", sha1, 0, NULL);
head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
if (!is_bare_repository() && head && !strcmp(head, ref->buf))
die(_("Cannot force update the current branch."));
}
Expand Down Expand Up @@ -285,8 +285,8 @@ void create_branch(const char *head,
transaction = ref_transaction_begin(&err);
if (!transaction ||
ref_transaction_update(transaction, ref.buf, sha1,
null_sha1, 0, !forcing, &err) ||
ref_transaction_commit(transaction, msg, &err))
null_sha1, 0, !forcing, msg, &err) ||
ref_transaction_commit(transaction, &err))
die("%s", err.buf);
ref_transaction_free(transaction);
strbuf_release(&err);
Expand Down
2 changes: 1 addition & 1 deletion builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -2286,7 +2286,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
commit->date = now;
parent_tail = &commit->parents;

if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
die("no such ref: HEAD");

parent_tail = append_parent(parent_tail, head_sha1);
Expand Down
22 changes: 13 additions & 9 deletions builtin/branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ static int branch_merged(int kind, const char *name,
branch->merge[0] &&
branch->merge[0]->dst &&
(reference_name = reference_name_to_free =
resolve_refdup(branch->merge[0]->dst, sha1, 1, NULL)) != NULL)
resolve_refdup(branch->merge[0]->dst, RESOLVE_REF_READING,
sha1, NULL)) != NULL)
reference_rev = lookup_commit_reference(sha1);
}
if (!reference_rev)
Expand Down Expand Up @@ -234,17 +235,20 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
free(name);

name = mkpathdup(fmt, bname.buf);
target = resolve_ref_unsafe(name, sha1, 0, &flags);
if (!target ||
(!(flags & REF_ISSYMREF) && is_null_sha1(sha1))) {
target = resolve_ref_unsafe(name,
RESOLVE_REF_READING
| RESOLVE_REF_NO_RECURSE
| RESOLVE_REF_ALLOW_BAD_NAME,
sha1, &flags);
if (!target) {
error(remote_branch
? _("remote branch '%s' not found.")
: _("branch '%s' not found."), bname.buf);
ret = 1;
continue;
}

if (!(flags & REF_ISSYMREF) &&
if (!(flags & (REF_ISSYMREF|REF_ISBROKEN)) &&
check_branch_commit(bname.buf, name, sha1, head_rev, kinds,
force)) {
ret = 1;
Expand All @@ -264,8 +268,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
? _("Deleted remote branch %s (was %s).\n")
: _("Deleted branch %s (was %s).\n"),
bname.buf,
(flags & REF_ISSYMREF)
? target
(flags & REF_ISBROKEN) ? "broken"
: (flags & REF_ISSYMREF) ? target
: find_unique_abbrev(sha1, DEFAULT_ABBREV));
}
delete_branch_config(bname.buf);
Expand Down Expand Up @@ -298,7 +302,7 @@ static char *resolve_symref(const char *src, const char *prefix)
int flag;
const char *dst;

dst = resolve_ref_unsafe(src, sha1, 0, &flag);
dst = resolve_ref_unsafe(src, 0, sha1, &flag);
if (!(dst && (flag & REF_ISSYMREF)))
return NULL;
if (prefix)
Expand Down Expand Up @@ -868,7 +872,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)

track = git_branch_track;

head = resolve_refdup("HEAD", head_sha1, 0, NULL);
head = resolve_refdup("HEAD", 0, head_sha1, NULL);
if (!head)
die(_("Failed to resolve HEAD as a valid ref."));
if (!strcmp(head, "HEAD"))
Expand Down
6 changes: 3 additions & 3 deletions builtin/checkout.c
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ static int checkout_paths(const struct checkout_opts *opts,
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
die(_("unable to write new index file"));

read_ref_full("HEAD", rev, 0, &flag);
read_ref_full("HEAD", 0, rev, &flag);
head = lookup_commit_reference_gently(rev, 1);

errs |= post_checkout_hook(head, head, 0);
Expand Down Expand Up @@ -775,7 +775,7 @@ static int switch_branches(const struct checkout_opts *opts,
unsigned char rev[20];
int flag, writeout_error = 0;
memset(&old, 0, sizeof(old));
old.path = path_to_free = resolve_refdup("HEAD", rev, 0, &flag);
old.path = path_to_free = resolve_refdup("HEAD", 0, rev, &flag);
old.commit = lookup_commit_reference_gently(rev, 1);
if (!(flag & REF_ISSYMREF))
old.path = NULL;
Expand Down Expand Up @@ -1072,7 +1072,7 @@ static int checkout_branch(struct checkout_opts *opts,
unsigned char rev[20];
int flag;

if (!read_ref_full("HEAD", rev, 0, &flag) &&
if (!read_ref_full("HEAD", 0, rev, &flag) &&
(flag & REF_ISSYMREF) && is_null_sha1(rev))
return switch_unborn_to_new_branch(opts);
}
Expand Down
2 changes: 1 addition & 1 deletion builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ static int checkout(void)
if (option_no_checkout)
return 0;

head = resolve_refdup("HEAD", sha1, 1, NULL);
head = resolve_refdup("HEAD", RESOLVE_REF_READING, sha1, NULL);
if (!head) {
warning(_("remote HEAD refers to nonexistent ref, "
"unable to checkout.\n"));
Expand Down
6 changes: 3 additions & 3 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1513,7 +1513,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
rev.diffopt.break_opt = 0;
diff_setup_done(&rev.diffopt);

head = resolve_ref_unsafe("HEAD", junk_sha1, 0, NULL);
head = resolve_ref_unsafe("HEAD", 0, junk_sha1, NULL);
if (!strcmp(head, "HEAD"))
head = _("detached HEAD");
else
Expand Down Expand Up @@ -1809,8 +1809,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
ref_transaction_update(transaction, "HEAD", sha1,
current_head
? current_head->object.sha1 : NULL,
0, !!current_head, &err) ||
ref_transaction_commit(transaction, sb.buf, &err)) {
0, !!current_head, sb.buf, &err) ||
ref_transaction_commit(transaction, &err)) {
rollback_index_files();
die("%s", err.buf);
}
Expand Down
34 changes: 24 additions & 10 deletions builtin/fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -404,23 +404,37 @@ static int s_update_ref(const char *action,
{
char msg[1024];
char *rla = getenv("GIT_REFLOG_ACTION");
static struct ref_lock *lock;
struct ref_transaction *transaction;
struct strbuf err = STRBUF_INIT;
int ret, df_conflict = 0;

if (dry_run)
return 0;
if (!rla)
rla = default_rla.buf;
snprintf(msg, sizeof(msg), "%s: %s", rla, action);
lock = lock_any_ref_for_update(ref->name,
check_old ? ref->old_sha1 : NULL,
0, NULL);
if (!lock)
return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
STORE_REF_ERROR_OTHER;
if (write_ref_sha1(lock, ref->new_sha1, msg) < 0)
return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
STORE_REF_ERROR_OTHER;

transaction = ref_transaction_begin(&err);
if (!transaction ||
ref_transaction_update(transaction, ref->name, ref->new_sha1,
ref->old_sha1, 0, check_old, msg, &err))
goto fail;

ret = ref_transaction_commit(transaction, &err);
if (ret) {
df_conflict = (ret == TRANSACTION_NAME_CONFLICT);
goto fail;
}

ref_transaction_free(transaction);
strbuf_release(&err);
return 0;
fail:
ref_transaction_free(transaction);
error("%s", err.buf);
strbuf_release(&err);
return df_conflict ? STORE_REF_ERROR_DF_CONFLICT
: STORE_REF_ERROR_OTHER;
}

#define REFCOL_WIDTH 10
Expand Down
2 changes: 1 addition & 1 deletion builtin/fmt-merge-msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,

/* get current branch */
current_branch = current_branch_to_free =
resolve_refdup("HEAD", head_sha1, 1, NULL);
resolve_refdup("HEAD", RESOLVE_REF_READING, head_sha1, NULL);
if (!current_branch)
die("No current branch");
if (starts_with(current_branch, "refs/heads/"))
Expand Down
11 changes: 9 additions & 2 deletions builtin/for-each-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,8 @@ static void populate_value(struct refinfo *ref)

if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
unsigned char unused1[20];
ref->symref = resolve_refdup(ref->refname, unused1, 1, NULL);
ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
unused1, NULL);
if (!ref->symref)
ref->symref = "";
}
Expand Down Expand Up @@ -694,7 +695,8 @@ static void populate_value(struct refinfo *ref)
const char *head;
unsigned char sha1[20];

head = resolve_ref_unsafe("HEAD", sha1, 1, NULL);
head = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
sha1, NULL);
if (!strcmp(ref->refname, head))
v->s = "*";
else
Expand Down Expand Up @@ -838,6 +840,11 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
struct refinfo *ref;
int cnt;

if (flag & REF_BAD_NAME) {
warning("ignoring ref with broken name %s", refname);
return 0;
}

if (*cb->grab_pattern) {
const char **pattern;
int namelen = strlen(refname);
Expand Down
2 changes: 1 addition & 1 deletion builtin/fsck.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ static int fsck_head_link(void)
if (verbose)
fprintf(stderr, "Checking HEAD link\n");

head_points_at = resolve_ref_unsafe("HEAD", head_sha1, 0, &flag);
head_points_at = resolve_ref_unsafe("HEAD", 0, head_sha1, &flag);
if (!head_points_at)
return error("Invalid HEAD");
if (!strcmp(head_points_at, "HEAD"))
Expand Down
3 changes: 2 additions & 1 deletion builtin/log.c
Original file line number Diff line number Diff line change
Expand Up @@ -1400,7 +1400,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (check_head) {
unsigned char sha1[20];
const char *ref, *v;
ref = resolve_ref_unsafe("HEAD", sha1, 1, NULL);
ref = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
sha1, NULL);
if (ref && skip_prefix(ref, "refs/heads/", &v))
branch_name = xstrdup(v);
else
Expand Down
2 changes: 1 addition & 1 deletion builtin/merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -1101,7 +1101,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
* Check if we are _not_ on a detached HEAD, i.e. if there is a
* current branch.
*/
branch = branch_to_free = resolve_refdup("HEAD", head_sha1, 0, &flag);
branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, &flag);
if (branch && starts_with(branch, "refs/heads/"))
branch += 11;
if (!branch || is_null_sha1(head_sha1))
Expand Down
2 changes: 1 addition & 1 deletion builtin/notes.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,7 +702,7 @@ static int merge_commit(struct notes_merge_options *o)
init_notes(t, "NOTES_MERGE_PARTIAL", combine_notes_overwrite, 0);

o->local_ref = local_ref_to_free =
resolve_refdup("NOTES_MERGE_REF", sha1, 0, NULL);
resolve_refdup("NOTES_MERGE_REF", 0, sha1, NULL);
if (!o->local_ref)
die("Failed to resolve NOTES_MERGE_REF");

Expand Down
9 changes: 5 additions & 4 deletions builtin/receive-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -842,8 +842,9 @@ static const char *update(struct command *cmd, struct shallow_info *si)
transaction = ref_transaction_begin(&err);
if (!transaction ||
ref_transaction_update(transaction, namespaced_name,
new_sha1, old_sha1, 0, 1, &err) ||
ref_transaction_commit(transaction, "push", &err)) {
new_sha1, old_sha1, 0, 1, "push",
&err) ||
ref_transaction_commit(transaction, &err)) {
ref_transaction_free(transaction);

rp_error("%s", err.buf);
Expand Down Expand Up @@ -908,7 +909,7 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
int flag;

strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name);
dst_name = resolve_ref_unsafe(buf.buf, sha1, 0, &flag);
dst_name = resolve_ref_unsafe(buf.buf, 0, sha1, &flag);
strbuf_release(&buf);

if (!(flag & REF_ISSYMREF))
Expand Down Expand Up @@ -1069,7 +1070,7 @@ static void execute_commands(struct command *commands,
check_aliased_updates(commands);

free(head_name_to_free);
head_name = head_name_to_free = resolve_refdup("HEAD", sha1, 0, NULL);
head_name = head_name_to_free = resolve_refdup("HEAD", 0, sha1, NULL);

checked_connectivity = 1;
for (cmd = commands; cmd; cmd = cmd->next) {
Expand Down
20 changes: 14 additions & 6 deletions builtin/remote.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,8 @@ static int read_remote_branches(const char *refname,
strbuf_addf(&buf, "refs/remotes/%s/", rename->old);
if (starts_with(refname, buf.buf)) {
item = string_list_append(rename->remote_branches, xstrdup(refname));
symref = resolve_ref_unsafe(refname, orig_sha1, 1, &flag);
symref = resolve_ref_unsafe(refname, RESOLVE_REF_READING,
orig_sha1, &flag);
if (flag & REF_ISSYMREF)
item->util = xstrdup(symref);
else
Expand Down Expand Up @@ -703,7 +704,7 @@ static int mv(int argc, const char **argv)
int flag = 0;
unsigned char sha1[20];

read_ref_full(item->string, sha1, 1, &flag);
read_ref_full(item->string, RESOLVE_REF_READING, sha1, &flag);
if (!(flag & REF_ISSYMREF))
continue;
if (delete_ref(item->string, NULL, REF_NODEREF))
Expand Down Expand Up @@ -748,13 +749,16 @@ static int mv(int argc, const char **argv)

static int remove_branches(struct string_list *branches)
{
struct strbuf err = STRBUF_INIT;
const char **branch_names;
int i, result = 0;

branch_names = xmalloc(branches->nr * sizeof(*branch_names));
for (i = 0; i < branches->nr; i++)
branch_names[i] = branches->items[i].string;
result |= repack_without_refs(branch_names, branches->nr, NULL);
if (repack_without_refs(branch_names, branches->nr, &err))
result |= error("%s", err.buf);
strbuf_release(&err);
free(branch_names);

for (i = 0; i < branches->nr; i++) {
Expand Down Expand Up @@ -1331,9 +1335,13 @@ static int prune_remote(const char *remote, int dry_run)
delete_refs = xmalloc(states.stale.nr * sizeof(*delete_refs));
for (i = 0; i < states.stale.nr; i++)
delete_refs[i] = states.stale.items[i].util;
if (!dry_run)
result |= repack_without_refs(delete_refs,
states.stale.nr, NULL);
if (!dry_run) {
struct strbuf err = STRBUF_INIT;
if (repack_without_refs(delete_refs, states.stale.nr,
&err))
result |= error("%s", err.buf);
strbuf_release(&err);
}
free(delete_refs);
}

Expand Down
5 changes: 3 additions & 2 deletions builtin/replace.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,9 @@ static int replace_object_sha1(const char *object_ref,

transaction = ref_transaction_begin(&err);
if (!transaction ||
ref_transaction_update(transaction, ref, repl, prev, 0, 1, &err) ||
ref_transaction_commit(transaction, NULL, &err))
ref_transaction_update(transaction, ref, repl, prev,
0, 1, NULL, &err) ||
ref_transaction_commit(transaction, &err))
die("%s", err.buf);

ref_transaction_free(transaction);
Expand Down
7 changes: 5 additions & 2 deletions builtin/show-branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,9 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
if (ac == 0) {
static const char *fake_av[2];

fake_av[0] = resolve_refdup("HEAD", sha1, 1, NULL);
fake_av[0] = resolve_refdup("HEAD",
RESOLVE_REF_READING,
sha1, NULL);
fake_av[1] = NULL;
av = fake_av;
ac = 1;
Expand Down Expand Up @@ -789,7 +791,8 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
}
}

head_p = resolve_ref_unsafe("HEAD", head_sha1, 1, NULL);
head_p = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
head_sha1, NULL);
if (head_p) {
head_len = strlen(head_p);
memcpy(head, head_p, head_len + 1);
Expand Down
Loading

0 comments on commit 3c85452

Please sign in to comment.