Skip to content

Commit db0210d

Browse files
Martin Ågrengitster
authored andcommitted
refs: handle zero oid for pseudorefs
According to the documentation, it is possible to "specify 40 '0' or an empty string as <oldvalue> to make sure that the ref you are creating does not exist." But in the code for pseudorefs, we do not implement this, as demonstrated by the failing tests added in the previous commit. If we fail to read the old ref, we immediately die. But a failure to read would actually be a good thing if we have been given the zero oid. With the zero oid, allow -- and even require -- the ref-reading to fail. This implements the "make sure that the ref ... does not exist" part of the documentation and fixes both failing tests from the previous commit. Since we have a `strbuf err` for collecting errors, let's use it and signal an error to the caller instead of dying hard. Reported-by: Rafael Ascensão <[email protected]> Helped-by: Rafael Ascensão <[email protected]> Signed-off-by: Martin Ågren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 65eb8fc commit db0210d

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

refs.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,19 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
681681
if (old_oid) {
682682
struct object_id actual_old_oid;
683683

684-
if (read_ref(pseudoref, &actual_old_oid))
685-
die("could not read ref '%s'", pseudoref);
686-
if (oidcmp(&actual_old_oid, old_oid)) {
684+
if (read_ref(pseudoref, &actual_old_oid)) {
685+
if (!is_null_oid(old_oid)) {
686+
strbuf_addf(err, "could not read ref '%s'",
687+
pseudoref);
688+
rollback_lock_file(&lock);
689+
goto done;
690+
}
691+
} else if (is_null_oid(old_oid)) {
692+
strbuf_addf(err, "ref '%s' already exists",
693+
pseudoref);
694+
rollback_lock_file(&lock);
695+
goto done;
696+
} else if (oidcmp(&actual_old_oid, old_oid)) {
687697
strbuf_addf(err, "unexpected object ID when writing '%s'",
688698
pseudoref);
689699
rollback_lock_file(&lock);

t/t1400-update-ref.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,12 +503,12 @@ test_expect_success 'delete pseudoref with correct old value' '
503503
test_path_is_missing .git/PSEUDOREF
504504
'
505505

506-
test_expect_failure 'create pseudoref with old OID zero' '
506+
test_expect_success 'create pseudoref with old OID zero' '
507507
git update-ref PSEUDOREF $A $Z &&
508508
test $A = $(cat .git/PSEUDOREF)
509509
'
510510

511-
test_expect_failure 'do not overwrite pseudoref with old OID zero' '
511+
test_expect_success 'do not overwrite pseudoref with old OID zero' '
512512
test_when_finished git update-ref -d PSEUDOREF &&
513513
test_must_fail git update-ref PSEUDOREF $B $Z 2>err &&
514514
test $A = $(cat .git/PSEUDOREF) &&

0 commit comments

Comments
 (0)