]> git.ipfire.org Git - thirdparty/git.git/commitdiff
branch: protect branches checked out in all worktrees
authorAnders Kaseorg <andersk@mit.edu>
Wed, 1 Dec 2021 22:15:47 +0000 (14:15 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Dec 2021 06:18:25 +0000 (22:18 -0800)
Refuse to force-move a branch over the currently checked out branch of
any working tree, not just the current one.

Signed-off-by: Anders Kaseorg <andersk@mit.edu>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
branch.c
t/t3200-branch.sh

index c66b222abd4fbfe4af758bd452e176eb7858fff3..2cfe496d242794d9c979cc63707f65cd1906231c 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -199,7 +199,8 @@ int validate_branchname(const char *name, struct strbuf *ref)
  */
 int validate_new_branchname(const char *name, struct strbuf *ref, int force)
 {
-       const char *head;
+       struct worktree **worktrees;
+       const struct worktree *wt;
 
        if (!validate_branchname(name, ref))
                return 0;
@@ -208,9 +209,13 @@ int validate_new_branchname(const char *name, struct strbuf *ref, int force)
                die(_("a branch named '%s' already exists"),
                    ref->buf + strlen("refs/heads/"));
 
-       head = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
-       if (!is_bare_repository() && head && !strcmp(head, ref->buf))
-               die(_("cannot force update the current branch"));
+       worktrees = get_worktrees();
+       wt = find_shared_symref(worktrees, "HEAD", ref->buf);
+       if (wt && !wt->is_bare)
+               die(_("cannot force update the branch '%s'"
+                     "checked out at '%s'"),
+                   ref->buf + strlen("refs/heads/"), wt->path);
+       free_worktrees(worktrees);
 
        return 1;
 }
index e35e119beeabc58b96bd5f6f10cbd1695db0a868..8a619d785e4f7b031bcf437ca5c80086777e89b8 100755 (executable)
@@ -168,6 +168,13 @@ test_expect_success 'git branch -M foo bar should fail when bar is checked out'
        test_must_fail git branch -M bar foo
 '
 
+test_expect_success 'git branch -M foo bar should fail when bar is checked out in worktree' '
+       git branch -f bar &&
+       test_when_finished "git worktree remove wt && git branch -D wt" &&
+       git worktree add wt &&
+       test_must_fail git branch -M bar wt
+'
+
 test_expect_success 'git branch -M baz bam should succeed when baz is checked out' '
        git checkout -b baz &&
        git branch bam &&