Thread (25 messages) 25 messages, 3 authors, 2016-06-16

Re: [PATCH v3] branch -d: refuse deleting a branch which is currently checked out

From: Eric Sunshine <hidden>
Date: 2016-06-15 23:09:05

On Tue, Mar 29, 2016 at 5:38 AM, Kazuki Yamaguchi [off-list ref] wrote:
When a branch is checked out by current working tree, deleting the
branch is forbidden. However when the branch is checked out only by
other working trees, deleting incorrectly succeeds.
Use find_shared_symref() to check if the branch is in use, not just
comparing with the current working tree's HEAD.

Helped-by: Eric Sunshine [off-list ref]
Signed-off-by: Kazuki Yamaguchi <redacted>
---
Changes from v2:
- Amended commit message
- Dropped "which is" from error message
Thanks, this version addresses my previous review comments and is:

    Reviewed-by: Eric Sunshine [off-list ref]
quoted hunk ↗ jump to hunk
The previous versions of the patch are:
- [v1] http://thread.gmane.org/gmane.comp.version-control.git/289413/focus=289932
- [v2] http://thread.gmane.org/gmane.comp.version-control.git/289413/focus=290027

 builtin/branch.c  | 22 ++++++++++++++--------
 t/t3200-branch.sh |  6 ++++++
 2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/builtin/branch.c b/builtin/branch.c
index 7b45b6bd6b80..8885d9f8e2cd 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -20,6 +20,7 @@
 #include "utf8.h"
 #include "wt-status.h"
 #include "ref-filter.h"
+#include "worktree.h"

 static const char * const builtin_branch_usage[] = {
        N_("git branch [<options>] [-r | -a] [--merged | --no-merged]"),
@@ -215,16 +216,21 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
                int flags = 0;

                strbuf_branchname(&bname, argv[i]);
-               if (kinds == FILTER_REFS_BRANCHES && !strcmp(head, bname.buf)) {
-                       error(_("Cannot delete the branch '%s' "
-                             "which you are currently on."), bname.buf);
-                       ret = 1;
-                       continue;
-               }
-
                free(name);
-
                name = mkpathdup(fmt, bname.buf);
+
+               if (kinds == FILTER_REFS_BRANCHES) {
+                       char *worktree = find_shared_symref("HEAD", name);
+                       if (worktree) {
+                               error(_("Cannot delete branch '%s' "
+                                       "checked out at '%s'"),
+                                     bname.buf, worktree);
+                               free(worktree);
+                               ret = 1;
+                               continue;
+                       }
+               }
+
                target = resolve_ref_unsafe(name,
                                            RESOLVE_REF_READING
                                            | RESOLVE_REF_NO_RECURSE
diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh
index a89724849065..508007fd3772 100755
--- a/t/t3200-branch.sh
+++ b/t/t3200-branch.sh
@@ -403,6 +403,12 @@ test_expect_success 'test deleting branch without config' '
        test_i18ncmp expect actual
 '

+test_expect_success 'deleting currently checked out branch fails' '
+       git worktree add -b my7 my7 &&
+       test_must_fail git -C my7 branch -d my7 &&
+       test_must_fail git branch -d my7
+'
+
 test_expect_success 'test --track without .fetch entries' '
        git branch --track my8 &&
        test "$(git config branch.my8.remote)" &&
--
2.8.0.rc4.17.g02aa164.dirty
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help