Subject: [PATCH v2 11/12] worktree.c: test if branch being bisected in another worktree

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Wed, 20 Apr 2016 20:24:52 +0700

Similar to the rebase case, we want to detect if "HEAD" in some worktree
is being bisected because

1) we do not want to checkout this branch in another worktree, after
   bisect is done it will want to go back to this branch

2) we do not want to delete the branch is either or git bisect will
   fail to return to the (long gone) branch

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 t/t2025-worktree-add.sh | 13 +++++++++++++
 worktree.c              | 19 +++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh
index da54327..8f53944 100755
--- a/t/t2025-worktree-add.sh
+++ b/t/t2025-worktree-add.sh
@@ -263,4 +263,17 @@ test_expect_success 'check out from current worktree branch ok' '
 	)
 '
 
+test_expect_success 'checkout a branch under bisect' '
+	git worktree add under-bisect &&
+	(
+		cd under-bisect &&
+		git bisect start &&
+		git bisect bad &&
+		git bisect good HEAD~2 &&
+		git worktree list | grep "under-bisect.*detached HEAD" &&
+		test_must_fail git worktree add new-bisect under-bisect &&
+		! test -d new-bisect
+	)
+'
+
 test_done
diff --git a/worktree.c b/worktree.c
index dc380a2..7b66071 100644
--- a/worktree.c
+++ b/worktree.c
@@ -226,6 +226,21 @@ static int is_worktree_being_rebased(const struct worktree *wt,
 	return found_rebase;
 }
 
+static int is_worktree_being_bisected(const struct worktree *wt,
+				      const char *target)
+{
+	struct wt_status_state state;
+	int found_rebase;
+
+	memset(&state, 0, sizeof(state));
+	found_rebase = wt_status_check_bisect(wt, &state) &&
+		state.branch &&
+		starts_with(target, "refs/heads/") &&
+		!strcmp(state.branch, target + strlen("refs/heads/"));
+	free(state.branch);
+	return found_rebase;
+}
+
 const struct worktree *find_shared_symref(const char *symref,
 					  const char *target,
 					  int ignore_current_worktree)
@@ -251,6 +266,10 @@ const struct worktree *find_shared_symref(const char *symref,
 				existing = wt;
 				break;
 			}
+			if (is_worktree_being_bisected(wt, target)) {
+				existing = wt;
+				break;
+			}
 		}
 
 		strbuf_reset(&path);
-- 
2.8.0.rc0.210.gd302cd2