Unverified Commit 47ac1187 by Patrick Steinhardt Committed by GitHub

Merge pull request #5360 from josharian/fix-5357

refs: refuse to delete HEAD
parents a129941a 852c83ee
...@@ -145,6 +145,11 @@ int git_reference_delete(git_reference *ref) ...@@ -145,6 +145,11 @@ int git_reference_delete(git_reference *ref)
const git_oid *old_id = NULL; const git_oid *old_id = NULL;
const char *old_target = 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) if (ref->type == GIT_REFERENCE_DIRECT)
old_id = &ref->target.oid; old_id = &ref->target.oid;
else else
......
...@@ -620,6 +620,7 @@ void test_iterator_workdir__filesystem2(void) ...@@ -620,6 +620,7 @@ void test_iterator_workdir__filesystem2(void)
"heads/subtrees", "heads/subtrees",
"heads/test", "heads/test",
"heads/testrepo-worktree", "heads/testrepo-worktree",
"symref",
"tags/e90810b", "tags/e90810b",
"tags/foo/bar", "tags/foo/bar",
"tags/foo/foo/bar", "tags/foo/foo/bar",
...@@ -632,7 +633,7 @@ void test_iterator_workdir__filesystem2(void) ...@@ -632,7 +633,7 @@ void test_iterator_workdir__filesystem2(void)
cl_git_pass(git_iterator_for_filesystem( cl_git_pass(git_iterator_for_filesystem(
&i, "testrepo/.git/refs", NULL)); &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); git_iterator_free(i);
} }
......
...@@ -105,3 +105,14 @@ void test_refs_delete__remove(void) ...@@ -105,3 +105,14 @@ void test_refs_delete__remove(void)
cl_git_fail(git_reference_lookup(&ref, g_repo, packed_test_head_name)); 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);
}
...@@ -36,7 +36,7 @@ void test_refs_list__all(void) ...@@ -36,7 +36,7 @@ void test_refs_list__all(void)
/* We have exactly 12 refs in total if we include the packed ones: /* 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 * there is a reference that exists both in the packfile and as
* loose, but we only list it once */ * 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); git_strarray_free(&ref_list);
} }
...@@ -51,7 +51,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten ...@@ -51,7 +51,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten
"144344043ba4d4a405da03de3844aa829ae8be0e\n"); "144344043ba4d4a405da03de3844aa829ae8be0e\n");
cl_git_pass(git_reference_list(&ref_list, g_repo)); 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); git_strarray_free(&ref_list);
} }
...@@ -74,8 +74,8 @@ void test_refs_races__delete(void) ...@@ -74,8 +74,8 @@ void test_refs_races__delete(void)
git_reference_free(ref); git_reference_free(ref);
/* We cannot delete a symbolic value that doesn't match */ /* 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_lookup(&ref, g_repo, "refs/symref"));
cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, refname)); 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)); cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
git_reference_free(ref); git_reference_free(ref);
...@@ -131,19 +131,19 @@ void test_refs_races__switch_symbolic_to_oid(void) ...@@ -131,19 +131,19 @@ void test_refs_races__switch_symbolic_to_oid(void)
git_oid_fromstr(&other_id, other_commit_id); git_oid_fromstr(&other_id, other_commit_id);
/* Removing a symbolic ref when it's currently direct should fail */ /* 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_lookup(&ref, g_repo, "refs/symref"));
cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL)); cl_git_pass(git_reference_create(&ref2, g_repo, "refs/symref", &id, 1, NULL));
cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref)); cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
git_reference_free(ref); git_reference_free(ref);
git_reference_free(ref2); 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); git_reference_free(ref);
/* Updating a symbolic ref when it's currently direct should fail */ /* 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_lookup(&ref, g_repo, "refs/symref"));
cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL)); 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)); cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL));
git_reference_free(ref); git_reference_free(ref);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment