Skip to content

Commit 852c83e

Browse files
committed
refs: refuse to delete HEAD
This requires adding a new symbolic ref to the testrepo fixture. Some of the existing tests attempt to delete HEAD, expecting a different failure. Introduce and use a non-HEAD symbolic ref instead. Adjust a few other tests as needed. Fixes libgit2#5357
1 parent dea5ce3 commit 852c83e

File tree

6 files changed

+28
-10
lines changed

6 files changed

+28
-10
lines changed

src/refs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,11 @@ int git_reference_delete(git_reference *ref)
145145
const git_oid *old_id = NULL;
146146
const char *old_target = NULL;
147147

148+
if (!strcmp(ref->name, "HEAD")) {
149+
git_error_set(GIT_ERROR_REFERENCE, "cannot delete HEAD");
150+
return GIT_ERROR;
151+
}
152+
148153
if (ref->type == GIT_REFERENCE_DIRECT)
149154
old_id = &ref->target.oid;
150155
else

tests/iterator/workdir.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,7 @@ void test_iterator_workdir__filesystem2(void)
620620
"heads/subtrees",
621621
"heads/test",
622622
"heads/testrepo-worktree",
623+
"symref",
623624
"tags/e90810b",
624625
"tags/foo/bar",
625626
"tags/foo/foo/bar",
@@ -632,7 +633,7 @@ void test_iterator_workdir__filesystem2(void)
632633

633634
cl_git_pass(git_iterator_for_filesystem(
634635
&i, "testrepo/.git/refs", NULL));
635-
expect_iterator_items(i, 16, expect_base, 16, expect_base);
636+
expect_iterator_items(i, 17, expect_base, 17, expect_base);
636637
git_iterator_free(i);
637638
}
638639

tests/refs/delete.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,3 +105,14 @@ void test_refs_delete__remove(void)
105105

106106
cl_git_fail(git_reference_lookup(&ref, g_repo, packed_test_head_name));
107107
}
108+
109+
void test_refs_delete__head(void)
110+
{
111+
git_reference *ref;
112+
113+
/* Check that it is not possible to delete HEAD */
114+
115+
cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
116+
cl_git_fail(git_reference_delete(ref));
117+
git_reference_free(ref);
118+
}

tests/refs/list.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void test_refs_list__all(void)
3636
/* We have exactly 12 refs in total if we include the packed ones:
3737
* there is a reference that exists both in the packfile and as
3838
* loose, but we only list it once */
39-
cl_assert_equal_i((int)ref_list.count, 18);
39+
cl_assert_equal_i((int)ref_list.count, 19);
4040

4141
git_strarray_free(&ref_list);
4242
}
@@ -51,7 +51,7 @@ void test_refs_list__do_not_retrieve_references_which_name_end_with_a_lock_exten
5151
"144344043ba4d4a405da03de3844aa829ae8be0e\n");
5252

5353
cl_git_pass(git_reference_list(&ref_list, g_repo));
54-
cl_assert_equal_i((int)ref_list.count, 18);
54+
cl_assert_equal_i((int)ref_list.count, 19);
5555

5656
git_strarray_free(&ref_list);
5757
}

tests/refs/races.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ void test_refs_races__delete(void)
7474
git_reference_free(ref);
7575

7676
/* We cannot delete a symbolic value that doesn't match */
77-
cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
78-
cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "HEAD", other_refname, 1, NULL, refname));
77+
cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref"));
78+
cl_git_pass(git_reference_symbolic_create_matching(&ref2, g_repo, "refs/symref", other_refname, 1, NULL, refname));
7979
cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
8080

8181
git_reference_free(ref);
@@ -131,19 +131,19 @@ void test_refs_races__switch_symbolic_to_oid(void)
131131
git_oid_fromstr(&other_id, other_commit_id);
132132

133133
/* Removing a symbolic ref when it's currently direct should fail */
134-
cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
135-
cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL));
134+
cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref"));
135+
cl_git_pass(git_reference_create(&ref2, g_repo, "refs/symref", &id, 1, NULL));
136136
cl_git_fail_with(GIT_EMODIFIED, git_reference_delete(ref));
137137

138138
git_reference_free(ref);
139139
git_reference_free(ref2);
140140

141-
cl_git_pass(git_reference_symbolic_create(&ref, g_repo, "HEAD", refname, 1, NULL));
141+
cl_git_pass(git_reference_symbolic_create(&ref, g_repo, "refs/symref", refname, 1, NULL));
142142
git_reference_free(ref);
143143

144144
/* Updating a symbolic ref when it's currently direct should fail */
145-
cl_git_pass(git_reference_lookup(&ref, g_repo, "HEAD"));
146-
cl_git_pass(git_reference_create(&ref2, g_repo, "HEAD", &id, 1, NULL));
145+
cl_git_pass(git_reference_lookup(&ref, g_repo, "refs/symref"));
146+
cl_git_pass(git_reference_create(&ref2, g_repo, "refs/symref", &id, 1, NULL));
147147
cl_git_fail_with(GIT_EMODIFIED, git_reference_symbolic_set_target(&ref3, ref, other_refname, NULL));
148148

149149
git_reference_free(ref);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ref: refs/heads/master

0 commit comments

Comments
 (0)