diff options
-rw-r--r-- | include/git2/refs.h | 3 | ||||
-rw-r--r-- | src/refdb_fs.c | 5 | ||||
-rw-r--r-- | tests/refs/races.c | 13 |
3 files changed, 20 insertions, 1 deletions
diff --git a/include/git2/refs.h b/include/git2/refs.h index 8bc99e15e..7ebb209b2 100644 --- a/include/git2/refs.h +++ b/include/git2/refs.h @@ -97,6 +97,9 @@ GIT_EXTERN(int) git_reference_dwim(git_reference **out, git_repository *repo, co * of updating does not match the one passed through `current_value` * (i.e. if the ref has changed since the user read it). * + * If `current_value` is all zeros, this function will return GIT_EMODIFIED + * if the ref already exists. + * * @param out Pointer to the newly created reference * @param repo Repository where that reference will live * @param name The name of the reference diff --git a/src/refdb_fs.c b/src/refdb_fs.c index a5a6b3c0e..971dc021d 100644 --- a/src/refdb_fs.c +++ b/src/refdb_fs.c @@ -1145,8 +1145,11 @@ static int cmp_old_ref(int *cmp, git_refdb_backend *backend, const char *name, if (!old_id && !old_target) return 0; - if ((error = refdb_fs_backend__lookup(&old_ref, backend, name)) < 0) + if ((error = refdb_fs_backend__lookup(&old_ref, backend, name)) < 0) { + if (error == GIT_ENOTFOUND && old_id && git_oid_is_zero(old_id)) + return 0; goto out; + } /* If the types don't match, there's no way the values do */ if (old_id && old_ref->type != GIT_REFERENCE_DIRECT) { diff --git a/tests/refs/races.c b/tests/refs/races.c index 04a1bc17b..988072794 100644 --- a/tests/refs/races.c +++ b/tests/refs/races.c @@ -22,6 +22,19 @@ void test_refs_races__cleanup(void) cl_git_sandbox_cleanup(); } +void test_refs_races__create_matching_zero_old(void) +{ + git_reference *ref; + git_oid id, zero_id; + + git_oid_fromstr(&id, commit_id); + git_oid_fromstr(&zero_id, "0000000000000000000000000000000000000000"); + + cl_git_pass(git_reference_create_matching(&ref, g_repo, other_refname, &id, 1, &zero_id, NULL)); + + git_reference_free(ref); +} + void test_refs_races__create_matching(void) { git_reference *ref, *ref2, *ref3; |