Skip to content

Commit 14ace5b

Browse files
pcloudsgitster
authored andcommitted
branch: do not rename a branch under bisect or rebase
The branch name in that case could be saved in rebase's head_name or bisect's BISECT_START files. Ideally we should try to update them as well. But it's trickier (*). Let's play safe and see if the user complains about inconveniences before doing that. (*) If we do it, bisect and rebase need to provide an API to rename branches. We can't do it in worktree.c or builtin/branch.c because when other people change rebase/bisect code, they may not be aware of this code and accidentally break it (e.g. rename the branch file, or refer to the branch in new files). It's a lot more work. Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 04a3dfb commit 14ace5b

File tree

4 files changed

+40
-4
lines changed

4 files changed

+40
-4
lines changed

builtin/branch.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,29 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
524524
ref_array_clear(&array);
525525
}
526526

527+
static void reject_rebase_or_bisect_branch(const char *target)
528+
{
529+
struct worktree **worktrees = get_worktrees();
530+
int i;
531+
532+
for (i = 0; worktrees[i]; i++) {
533+
struct worktree *wt = worktrees[i];
534+
535+
if (!wt->is_detached)
536+
continue;
537+
538+
if (is_worktree_being_rebased(wt, target))
539+
die(_("Branch %s is being rebased at %s"),
540+
target, wt->path);
541+
542+
if (is_worktree_being_bisected(wt, target))
543+
die(_("Branch %s is being bisected at %s"),
544+
target, wt->path);
545+
}
546+
547+
free_worktrees(worktrees);
548+
}
549+
527550
static void rename_branch(const char *oldname, const char *newname, int force)
528551
{
529552
struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT;
@@ -553,6 +576,8 @@ static void rename_branch(const char *oldname, const char *newname, int force)
553576

554577
validate_new_branchname(newname, &newref, force, clobber_head_ok);
555578

579+
reject_rebase_or_bisect_branch(oldref.buf);
580+
556581
strbuf_addf(&logmsg, "Branch: renamed %s to %s",
557582
oldref.buf, newref.buf);
558583

t/t2025-worktree-add.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ test_expect_success 'not allow to delete a branch under rebase' '
254254
)
255255
'
256256

257+
test_expect_success 'rename a branch under rebase not allowed' '
258+
test_must_fail git branch -M under-rebase rebase-with-new-name
259+
'
260+
257261
test_expect_success 'check out from current worktree branch ok' '
258262
(
259263
cd under-rebase &&
@@ -276,4 +280,8 @@ test_expect_success 'checkout a branch under bisect' '
276280
)
277281
'
278282

283+
test_expect_success 'rename a branch under bisect not allowed' '
284+
test_must_fail git branch -M under-bisect bisect-with-new-name
285+
'
286+
279287
test_done

worktree.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ const char *get_worktree_git_dir(const struct worktree *wt)
216216
return git_common_path("worktrees/%s", wt->id);
217217
}
218218

219-
static int is_worktree_being_rebased(const struct worktree *wt,
220-
const char *target)
219+
int is_worktree_being_rebased(const struct worktree *wt,
220+
const char *target)
221221
{
222222
struct wt_status_state state;
223223
int found_rebase;
@@ -234,8 +234,8 @@ static int is_worktree_being_rebased(const struct worktree *wt,
234234
return found_rebase;
235235
}
236236

237-
static int is_worktree_being_bisected(const struct worktree *wt,
238-
const char *target)
237+
int is_worktree_being_bisected(const struct worktree *wt,
238+
const char *target)
239239
{
240240
struct wt_status_state state;
241241
int found_rebase;

worktree.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ extern void free_worktrees(struct worktree **);
4242
extern const struct worktree *find_shared_symref(const char *symref,
4343
const char *target);
4444

45+
int is_worktree_being_rebased(const struct worktree *wt, const char *target);
46+
int is_worktree_being_bisected(const struct worktree *wt, const char *target);
47+
4548
/*
4649
* Similar to git_path() but can produce paths for a specified
4750
* worktree instead of current one

0 commit comments

Comments
 (0)