Skip to content

Commit 3c85452

Browse files
committed
Merge branch 'rs/ref-transaction'
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 ...
2 parents 13da0fc + 6573284 commit 3c85452

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+849
-350
lines changed

branch.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ int validate_new_branchname(const char *name, struct strbuf *ref,
170170
const char *head;
171171
unsigned char sha1[20];
172172

173-
head = resolve_ref_unsafe("HEAD", sha1, 0, NULL);
173+
head = resolve_ref_unsafe("HEAD", 0, sha1, NULL);
174174
if (!is_bare_repository() && head && !strcmp(head, ref->buf))
175175
die(_("Cannot force update the current branch."));
176176
}
@@ -285,8 +285,8 @@ void create_branch(const char *head,
285285
transaction = ref_transaction_begin(&err);
286286
if (!transaction ||
287287
ref_transaction_update(transaction, ref.buf, sha1,
288-
null_sha1, 0, !forcing, &err) ||
289-
ref_transaction_commit(transaction, msg, &err))
288+
null_sha1, 0, !forcing, msg, &err) ||
289+
ref_transaction_commit(transaction, &err))
290290
die("%s", err.buf);
291291
ref_transaction_free(transaction);
292292
strbuf_release(&err);

builtin/blame.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2286,7 +2286,7 @@ static struct commit *fake_working_tree_commit(struct diff_options *opt,
22862286
commit->date = now;
22872287
parent_tail = &commit->parents;
22882288

2289-
if (!resolve_ref_unsafe("HEAD", head_sha1, 1, NULL))
2289+
if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, head_sha1, NULL))
22902290
die("no such ref: HEAD");
22912291

22922292
parent_tail = append_parent(parent_tail, head_sha1);

builtin/branch.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ static int branch_merged(int kind, const char *name,
130130
branch->merge[0] &&
131131
branch->merge[0]->dst &&
132132
(reference_name = reference_name_to_free =
133-
resolve_refdup(branch->merge[0]->dst, sha1, 1, NULL)) != NULL)
133+
resolve_refdup(branch->merge[0]->dst, RESOLVE_REF_READING,
134+
sha1, NULL)) != NULL)
134135
reference_rev = lookup_commit_reference(sha1);
135136
}
136137
if (!reference_rev)
@@ -234,17 +235,20 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
234235
free(name);
235236

236237
name = mkpathdup(fmt, bname.buf);
237-
target = resolve_ref_unsafe(name, sha1, 0, &flags);
238-
if (!target ||
239-
(!(flags & REF_ISSYMREF) && is_null_sha1(sha1))) {
238+
target = resolve_ref_unsafe(name,
239+
RESOLVE_REF_READING
240+
| RESOLVE_REF_NO_RECURSE
241+
| RESOLVE_REF_ALLOW_BAD_NAME,
242+
sha1, &flags);
243+
if (!target) {
240244
error(remote_branch
241245
? _("remote branch '%s' not found.")
242246
: _("branch '%s' not found."), bname.buf);
243247
ret = 1;
244248
continue;
245249
}
246250

247-
if (!(flags & REF_ISSYMREF) &&
251+
if (!(flags & (REF_ISSYMREF|REF_ISBROKEN)) &&
248252
check_branch_commit(bname.buf, name, sha1, head_rev, kinds,
249253
force)) {
250254
ret = 1;
@@ -264,8 +268,8 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
264268
? _("Deleted remote branch %s (was %s).\n")
265269
: _("Deleted branch %s (was %s).\n"),
266270
bname.buf,
267-
(flags & REF_ISSYMREF)
268-
? target
271+
(flags & REF_ISBROKEN) ? "broken"
272+
: (flags & REF_ISSYMREF) ? target
269273
: find_unique_abbrev(sha1, DEFAULT_ABBREV));
270274
}
271275
delete_branch_config(bname.buf);
@@ -298,7 +302,7 @@ static char *resolve_symref(const char *src, const char *prefix)
298302
int flag;
299303
const char *dst;
300304

301-
dst = resolve_ref_unsafe(src, sha1, 0, &flag);
305+
dst = resolve_ref_unsafe(src, 0, sha1, &flag);
302306
if (!(dst && (flag & REF_ISSYMREF)))
303307
return NULL;
304308
if (prefix)
@@ -868,7 +872,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
868872

869873
track = git_branch_track;
870874

871-
head = resolve_refdup("HEAD", head_sha1, 0, NULL);
875+
head = resolve_refdup("HEAD", 0, head_sha1, NULL);
872876
if (!head)
873877
die(_("Failed to resolve HEAD as a valid ref."));
874878
if (!strcmp(head, "HEAD"))

builtin/checkout.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ static int checkout_paths(const struct checkout_opts *opts,
355355
if (write_locked_index(&the_index, lock_file, COMMIT_LOCK))
356356
die(_("unable to write new index file"));
357357

358-
read_ref_full("HEAD", rev, 0, &flag);
358+
read_ref_full("HEAD", 0, rev, &flag);
359359
head = lookup_commit_reference_gently(rev, 1);
360360

361361
errs |= post_checkout_hook(head, head, 0);
@@ -775,7 +775,7 @@ static int switch_branches(const struct checkout_opts *opts,
775775
unsigned char rev[20];
776776
int flag, writeout_error = 0;
777777
memset(&old, 0, sizeof(old));
778-
old.path = path_to_free = resolve_refdup("HEAD", rev, 0, &flag);
778+
old.path = path_to_free = resolve_refdup("HEAD", 0, rev, &flag);
779779
old.commit = lookup_commit_reference_gently(rev, 1);
780780
if (!(flag & REF_ISSYMREF))
781781
old.path = NULL;
@@ -1072,7 +1072,7 @@ static int checkout_branch(struct checkout_opts *opts,
10721072
unsigned char rev[20];
10731073
int flag;
10741074

1075-
if (!read_ref_full("HEAD", rev, 0, &flag) &&
1075+
if (!read_ref_full("HEAD", 0, rev, &flag) &&
10761076
(flag & REF_ISSYMREF) && is_null_sha1(rev))
10771077
return switch_unborn_to_new_branch(opts);
10781078
}

builtin/clone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,7 @@ static int checkout(void)
623623
if (option_no_checkout)
624624
return 0;
625625

626-
head = resolve_refdup("HEAD", sha1, 1, NULL);
626+
head = resolve_refdup("HEAD", RESOLVE_REF_READING, sha1, NULL);
627627
if (!head) {
628628
warning(_("remote HEAD refers to nonexistent ref, "
629629
"unable to checkout.\n"));

builtin/commit.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,7 +1513,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1,
15131513
rev.diffopt.break_opt = 0;
15141514
diff_setup_done(&rev.diffopt);
15151515

1516-
head = resolve_ref_unsafe("HEAD", junk_sha1, 0, NULL);
1516+
head = resolve_ref_unsafe("HEAD", 0, junk_sha1, NULL);
15171517
if (!strcmp(head, "HEAD"))
15181518
head = _("detached HEAD");
15191519
else
@@ -1809,8 +1809,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
18091809
ref_transaction_update(transaction, "HEAD", sha1,
18101810
current_head
18111811
? current_head->object.sha1 : NULL,
1812-
0, !!current_head, &err) ||
1813-
ref_transaction_commit(transaction, sb.buf, &err)) {
1812+
0, !!current_head, sb.buf, &err) ||
1813+
ref_transaction_commit(transaction, &err)) {
18141814
rollback_index_files();
18151815
die("%s", err.buf);
18161816
}

builtin/fetch.c

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -404,23 +404,37 @@ static int s_update_ref(const char *action,
404404
{
405405
char msg[1024];
406406
char *rla = getenv("GIT_REFLOG_ACTION");
407-
static struct ref_lock *lock;
407+
struct ref_transaction *transaction;
408+
struct strbuf err = STRBUF_INIT;
409+
int ret, df_conflict = 0;
408410

409411
if (dry_run)
410412
return 0;
411413
if (!rla)
412414
rla = default_rla.buf;
413415
snprintf(msg, sizeof(msg), "%s: %s", rla, action);
414-
lock = lock_any_ref_for_update(ref->name,
415-
check_old ? ref->old_sha1 : NULL,
416-
0, NULL);
417-
if (!lock)
418-
return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
419-
STORE_REF_ERROR_OTHER;
420-
if (write_ref_sha1(lock, ref->new_sha1, msg) < 0)
421-
return errno == ENOTDIR ? STORE_REF_ERROR_DF_CONFLICT :
422-
STORE_REF_ERROR_OTHER;
416+
417+
transaction = ref_transaction_begin(&err);
418+
if (!transaction ||
419+
ref_transaction_update(transaction, ref->name, ref->new_sha1,
420+
ref->old_sha1, 0, check_old, msg, &err))
421+
goto fail;
422+
423+
ret = ref_transaction_commit(transaction, &err);
424+
if (ret) {
425+
df_conflict = (ret == TRANSACTION_NAME_CONFLICT);
426+
goto fail;
427+
}
428+
429+
ref_transaction_free(transaction);
430+
strbuf_release(&err);
423431
return 0;
432+
fail:
433+
ref_transaction_free(transaction);
434+
error("%s", err.buf);
435+
strbuf_release(&err);
436+
return df_conflict ? STORE_REF_ERROR_DF_CONFLICT
437+
: STORE_REF_ERROR_OTHER;
424438
}
425439

426440
#define REFCOL_WIDTH 10

builtin/fmt-merge-msg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out,
602602

603603
/* get current branch */
604604
current_branch = current_branch_to_free =
605-
resolve_refdup("HEAD", head_sha1, 1, NULL);
605+
resolve_refdup("HEAD", RESOLVE_REF_READING, head_sha1, NULL);
606606
if (!current_branch)
607607
die("No current branch");
608608
if (starts_with(current_branch, "refs/heads/"))

builtin/for-each-ref.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,8 @@ static void populate_value(struct refinfo *ref)
635635

636636
if (need_symref && (ref->flag & REF_ISSYMREF) && !ref->symref) {
637637
unsigned char unused1[20];
638-
ref->symref = resolve_refdup(ref->refname, unused1, 1, NULL);
638+
ref->symref = resolve_refdup(ref->refname, RESOLVE_REF_READING,
639+
unused1, NULL);
639640
if (!ref->symref)
640641
ref->symref = "";
641642
}
@@ -694,7 +695,8 @@ static void populate_value(struct refinfo *ref)
694695
const char *head;
695696
unsigned char sha1[20];
696697

697-
head = resolve_ref_unsafe("HEAD", sha1, 1, NULL);
698+
head = resolve_ref_unsafe("HEAD", RESOLVE_REF_READING,
699+
sha1, NULL);
698700
if (!strcmp(ref->refname, head))
699701
v->s = "*";
700702
else
@@ -838,6 +840,11 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
838840
struct refinfo *ref;
839841
int cnt;
840842

843+
if (flag & REF_BAD_NAME) {
844+
warning("ignoring ref with broken name %s", refname);
845+
return 0;
846+
}
847+
841848
if (*cb->grab_pattern) {
842849
const char **pattern;
843850
int namelen = strlen(refname);

builtin/fsck.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ static int fsck_head_link(void)
556556
if (verbose)
557557
fprintf(stderr, "Checking HEAD link\n");
558558

559-
head_points_at = resolve_ref_unsafe("HEAD", head_sha1, 0, &flag);
559+
head_points_at = resolve_ref_unsafe("HEAD", 0, head_sha1, &flag);
560560
if (!head_points_at)
561561
return error("Invalid HEAD");
562562
if (!strcmp(head_points_at, "HEAD"))

0 commit comments

Comments
 (0)