branch: allow deleting dangling branches with --force
git branch only allows deleting branches that point to valid commits. Skip that check if --force is given, as the caller is indicating with it that they know what they are doing and accept the consequences. This allows deleting dangling branches, which previously had to be reset to a valid start-point using --force first. Reported-by: Ulrich Windl <Ulrich.Windl@rz.uni-regensburg.de> Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe committed
Aug 27, 2021 at 20:35 UTC
597a97748924e8ce0b829f668acc8f7a6849b05f
3 files changed
+16
-2
Documentation/git-branch.txt
+2
-1
@@ -118,7 +118,8 @@ OPTIONS
118
Reset <branchname> to <startpoint>, even if <branchname> exists
119
already. Without `-f`, 'git branch' refuses to change an existing branch.
120
In combination with `-d` (or `--delete`), allow deleting the
121
- branch irrespective of its merged status. In combination with
121
+ branch irrespective of its merged status, or whether it even
122
+ points to a valid commit. In combination with
123
`-m` (or `--move`), allow renaming the branch even if the new
124
branch name already exists, the same applies for `-c` (or `--copy`).
125
builtin/branch.c
+1
-1
@@ -168,7 +168,7 @@ static int check_branch_commit(const char *branchname, const char *refname,
168
int kinds, int force)
169
{
170
struct commit *rev = lookup_commit_reference(the_repository, oid);
171
- if (!rev) {
171
+ if (!force && !rev) {
172
error(_("Couldn't look up commit object for '%s'"), refname);
173
return -1;
174
}
t/t3200-branch.sh
+13
@@ -1272,6 +1272,19 @@ test_expect_success 'attempt to delete a branch merged to its base' '
1272
test_must_fail git branch -d my10
1273
'
1274
1275
+test_expect_success 'branch --delete --force removes dangling branch' '
1276
+ git checkout main &&
1277
+ test_commit unstable &&
1278
+ hash=$(git rev-parse HEAD) &&
1279
+ objpath=$(echo $hash | sed -e "s|^..|.git/objects/&/|") &&
1280
+ git branch --no-track dangling &&
1281
+ mv $objpath $objpath.x &&
1282
+ test_when_finished "mv $objpath.x $objpath" &&
1283
+ git branch --delete --force dangling &&
1284
+ git for-each-ref refs/heads/dangling >actual &&
1285
+ test_must_be_empty actual
1286
+'
1287
+
1288
test_expect_success 'use --edit-description' '
1289
write_script editor <<-\EOF &&
1290
echo "New contents" >"$1"