Skip to content

Commit 0fe700e

Browse files
René Scharfegitster
authored andcommitted
branch: skip commit checks when deleting symref branches
Before a branch is deleted, we check that it points to a valid commit. With -d we also check that the commit is a merged; this check is not done with -D. The reason for that is that commits pointed to by branches should never go missing; if they do then something broke and it's better to stop instead of adding to the mess. And a non-merged commit may contain changes that are worth preserving, so we require the stronger option -D instead of -d to get rid of them. If a branch consists of a symref, these concerns don't apply. Deleting such a branch can't make a commit become unreferenced, so we don't need to check if it is merged, or even if it is actually a valid commit. Skip them in that case. This allows us to delete dangling symref branches. Signed-off-by: Rene Scharfe <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 566c770 commit 0fe700e

File tree

2 files changed

+17
-2
lines changed

2 files changed

+17
-2
lines changed

builtin/branch.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,9 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
214214
die(_("Couldn't look up commit object for HEAD"));
215215
}
216216
for (i = 0; i < argc; i++, strbuf_release(&bname)) {
217+
const char *target;
218+
int flags = 0;
219+
217220
strbuf_branchname(&bname, argv[i]);
218221
if (kinds == REF_LOCAL_BRANCH && !strcmp(head, bname.buf)) {
219222
error(_("Cannot delete the branch '%s' "
@@ -225,15 +228,18 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
225228
free(name);
226229

227230
name = mkpathdup(fmt, bname.buf);
228-
if (read_ref(name, sha1)) {
231+
target = resolve_ref_unsafe(name, sha1, 0, &flags);
232+
if (!target ||
233+
(!(flags & REF_ISSYMREF) && is_null_sha1(sha1))) {
229234
error(remote_branch
230235
? _("remote branch '%s' not found.")
231236
: _("branch '%s' not found."), bname.buf);
232237
ret = 1;
233238
continue;
234239
}
235240

236-
if (check_branch_commit(bname.buf, name, sha1, head_rev, kinds,
241+
if (!(flags & REF_ISSYMREF) &&
242+
check_branch_commit(bname.buf, name, sha1, head_rev, kinds,
237243
force)) {
238244
ret = 1;
239245
continue;

t/t3200-branch.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,15 @@ test_expect_success 'deleting a symref' '
273273
test_i18ncmp expect actual
274274
'
275275

276+
test_expect_success 'deleting a dangling symref' '
277+
git symbolic-ref refs/heads/dangling-symref nowhere &&
278+
test_path_is_file .git/refs/heads/dangling-symref &&
279+
echo "Deleted branch dangling-symref (was 0000000)." >expect &&
280+
git branch -d dangling-symref >actual &&
281+
test_path_is_missing .git/refs/heads/dangling-symref &&
282+
test_i18ncmp expect actual
283+
'
284+
276285
test_expect_success 'renaming a symref is not allowed' \
277286
'
278287
git symbolic-ref refs/heads/master2 refs/heads/master &&

0 commit comments

Comments
 (0)