diff options
author | Patrick Steinhardt <ps@pks.im> | 2020-01-17 08:32:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-17 08:32:37 +0100 |
commit | 47ac1187aaa53050c46056a4daf9a01916263da4 (patch) | |
tree | 4fc528463747aa24fcc09d21d005271995b46b37 | |
parent | a129941ac162e81f59d57737e2debcc9e456858d (diff) | |
parent | 852c83ee44d6d53137f12443c9f82f70bbabbadc (diff) | |
download | libgit2-47ac1187aaa53050c46056a4daf9a01916263da4.tar.gz |
Merge pull request #5360 from josharian/fix-5357
refs: refuse to delete HEAD
-rw-r--r-- | src/refs.c | 5 | ||||
-rw-r--r-- | tests/iterator/workdir.c | 3 | ||||
-rw-r--r-- | tests/refs/delete.c | 11 | ||||
-rw-r--r-- | tests/refs/list.c | 4 | ||||
-rw-r--r-- | tests/refs/races.c | 14 | ||||
-rw-r--r-- | tests/resources/testrepo/.gitted/refs/symref | 1 |
6 files changed, 28 insertions, 10 deletions
diff --git a/src/refs.c b/src/refs.c index 29dd1bdeb..633d83abd 100644 --- a/src/refs.c +++ b/src/refs.c @@ -145,6 +145,11 @@ int git_reference_delete(git_reference *ref) const git_oid *old_id = NULL; const char *old_target = NULL; + if (!strcmp(ref->name, "HEAD")) { + git_error_set(GIT_ERROR_REFERENCE, "cannot delete HEAD"); + return GIT_ERROR; + } + if (ref->type == GIT_REFERENCE_DIRECT) old_id = &ref->target.oid; else diff --git a/tests/iterator/workdir.c b/tests/iterator/workdir.c index 926cc6af0..72f8bf42c 100644 --- a/tests/iterator/workdir.c +++ b/tests/iterator/workdir.c @@ -620,6 +620,7 @@ void test_iterator_workdir__filesystem2(void) "heads/subtrees", "heads/test", "heads/testrepo-worktree", + "symref", "tags/e90810b", "tags/foo/bar", "tags/foo/foo/bar", @@ -632,7 +633,7 @@ void test_iterator_workdir__filesystem2(void) cl_git_pass(git_iterator_for_filesystem( &i, "testrepo/.git/refs", NULL)); - expect_iterator_items(i, 16, expect_base, 16, expect_base); + expect_iterator_items(i, 17, expect_base, 17, expect_base); git_iterator_free(i); } diff --git a/tests/refs/delete.c b/tests/refs/delete.c index a33449641..3e99a7959 100644 --- a/tests/refs/delete.c +++ b/tests/refs/delete.c @@ -105,3 +105,14 @@ void test_refs_delete__remove(void) cl_git_fail(git_reference_lookup(&ref, g_repo, packed_test_head_name)); } + +void test_refs_delete__head(void) +{ + git_reference *ref; + + /* Check that it is not possible to delete HEAD */ + + cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); + cl_git_fail(git_reference_delete(ref)); + git_reference_free(ref); +} diff --git a/tests/refs/list.c b/tests/refs/list.c index 3e8c82c94..725d38161 100644 --- a/tests/refs/list.c +++ b/tests/refs/list.c @@ -36,7 +36,7 @@ void test_refs_list__all(void) /* We have exactly 12 refs in total if we include the packed ones: * there is a reference that exists both in the packfile and as * loose, but we only list it once */ - cl_assert_equal_i((int)ref_list.count, 18); + cl_assert_equal_i((int)ref_list.count, 19); git_strarray_free(&ref_list); } @@ -51,7 +51,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten "144344043ba4d4a405da03de3844aa829ae8be0e\n"); cl_git_pass(git_reference_list(&ref_list, g_repo)); - cl_assert_equal_i((int)ref_list.count, 18); + cl_assert_equal_i((int)ref_list.count, 19); git_strarray_free(&ref_list); } diff --git a/tests/refs/races.c b/tests/refs/races.c index fbecf4a75..04a1bc17b 100644 --- a/tests/refs/races.c +++ b/tests/refs/races.c @@ -74,8 +74,8 @@ void test_refs_races__delete(void) git_reference_free(ref); /* We cannot delete a symbolic value that doesn't match */ - cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); - cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, refname)); + cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref")); + cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "refs/symref", other_refname, 1, NULL, refname)); cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); git_reference_free(ref); @@ -131,19 +131,19 @@ void test_refs_races__switch_symbolic_to_oid(void) git_oid_fromstr(&other_id, other_commit_id); /* Removing a symbolic ref when it's currently direct should fail */ - cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); - cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL)); + cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref")); + cl_git_pass(git_reference_create(&ref2, g_repo, "refs/symref", &id, 1, NULL)); cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); git_reference_free(ref); git_reference_free(ref2); - cl_git_pass(git_reference_symbolic_create(&ref, g_repo, "HEAD", refname, 1, NULL)); + cl_git_pass(git_reference_symbolic_create(&ref, g_repo, "refs/symref", refname, 1, NULL)); git_reference_free(ref); /* Updating a symbolic ref when it's currently direct should fail */ - cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD")); - cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL)); + cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref")); + cl_git_pass(git_reference_create(&ref2, g_repo, "refs/symref", &id, 1, NULL)); cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL)); git_reference_free(ref); diff --git a/tests/resources/testrepo/.gitted/refs/symref b/tests/resources/testrepo/.gitted/refs/symref new file mode 100644 index 000000000..cb089cd89 --- /dev/null +++ b/tests/resources/testrepo/.gitted/refs/symref @@ -0,0 +1 @@ +ref: refs/heads/master |