mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-10-05 21:46:49 -04:00
Refuse to fast-forward a branch being rebased or bisected in a worktree
The worktree loader associates a worktree that is mid-rebase or mid-bisect with the branch involved, even though its HEAD is detached. Fast-forwarding such a branch therefore ran the fast-forward in that worktree. This moved the detached HEAD and put the upstream commits into the rebase in progress, while the branch stayed where it was. Remember in the worktree model when its branch comes from a rebase or bisect, and refuse to fast-forward the branch in that case. Updating only the ref is no option for a rebase; the rebase writes the branch when it finishes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5990946a23
commit
ef00e18247
@@ -140,12 +140,14 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
|
||||
rebasedBranch, ok := self.rebasedBranch(worktree)
|
||||
if ok {
|
||||
worktree.Branch = rebasedBranch
|
||||
worktree.IsRebasingOrBisecting = true
|
||||
continue
|
||||
}
|
||||
|
||||
bisectedBranch, ok := self.bisectedBranch(worktree)
|
||||
if ok {
|
||||
worktree.Branch = bisectedBranch
|
||||
worktree.IsRebasingOrBisecting = true
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ type Worktree struct {
|
||||
// * the worktree is mid-rebase on the branch
|
||||
// * the worktree is mid-bisect on the branch
|
||||
Branch string
|
||||
// If true, the worktree is mid-rebase or mid-bisect on Branch, so its HEAD
|
||||
// is detached rather than pointing at the branch
|
||||
IsRebasingOrBisecting bool
|
||||
// The HEAD sha of the worktree. Always populated (even when Branch is set).
|
||||
// Used for display when Branch is empty (detached HEAD state).
|
||||
Head string
|
||||
|
||||
@@ -457,6 +457,17 @@ func (self *BranchesHelper) FastForwardBranches(branches []*models.Branch) error
|
||||
})
|
||||
anyCheckedOut := lo.SomeBy(toForward, func(f *branchToForward) bool { return f.worktree != nil })
|
||||
|
||||
// Updating that worktree would move its detached HEAD, which belongs to the
|
||||
// rebase or bisect, and leave the branch alone
|
||||
for _, f := range toForward {
|
||||
if f.worktree != nil && f.worktree.IsRebasingOrBisecting {
|
||||
return errors.New(utils.ResolvePlaceholderString(
|
||||
self.c.Tr.FwdBranchRebasingOrBisecting,
|
||||
map[string]string{"branchName": f.branch.Name, "worktreeName": f.worktree.Name},
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
return self.withFastForwardingStatus(branches, func(task gocui.Task) error {
|
||||
defer func() {
|
||||
if anyCheckedOut {
|
||||
|
||||
@@ -376,6 +376,7 @@ type TranslationSet struct {
|
||||
FwdCommitsToPush string
|
||||
FwdLocalOnlyCommits string
|
||||
FwdUncommittedChanges string
|
||||
FwdBranchRebasingOrBisecting string
|
||||
PullRequestNoUpstream string
|
||||
PullRequestChecksPassing string
|
||||
PullRequestChecksPending string
|
||||
@@ -1551,6 +1552,7 @@ func EnglishTranslationSet() *TranslationSet {
|
||||
FwdCommitsToPush: "Cannot fast-forward a branch with commits to push",
|
||||
FwdLocalOnlyCommits: "Cannot fast-forward '{{.branchName}}' because it has commits which were never on its remote branch",
|
||||
FwdUncommittedChanges: "Cannot fast-forward '{{.branchName}}' because the worktree it is checked out in has uncommitted changes",
|
||||
FwdBranchRebasingOrBisecting: "Cannot fast-forward '{{.branchName}}' because it is being rebased or bisected in worktree {{.worktreeName}}",
|
||||
PullRequestNoUpstream: "Cannot open a pull request for a branch with no upstream",
|
||||
PullRequestChecksPassing: "Passing",
|
||||
PullRequestChecksPending: "Pending",
|
||||
|
||||
@@ -39,12 +39,10 @@ var FastForwardBranchBeingRebasedInWorktree = NewIntegrationTest(NewIntegrationT
|
||||
NavigateToLine(Contains("master")).
|
||||
Press(keys.Branches.FastForward)
|
||||
|
||||
/* EXPECTED:
|
||||
t.ExpectPopup().Alert().
|
||||
Title(Equals("Error")).
|
||||
Content(Equals("Cannot fast-forward 'master' because it is being rebased or bisected in worktree linked-worktree")).
|
||||
Confirm()
|
||||
ACTUAL: */
|
||||
|
||||
t.Views().Worktrees().
|
||||
Focus().
|
||||
@@ -57,11 +55,6 @@ var FastForwardBranchBeingRebasedInWorktree = NewIntegrationTest(NewIntegrationT
|
||||
Lines(
|
||||
Contains("─── Pending rebase todos"),
|
||||
Contains("─── Commits"),
|
||||
/* EXPECTED:
|
||||
Contains("two"),
|
||||
Contains("one"),
|
||||
ACTUAL: */
|
||||
Contains("three"),
|
||||
Contains("two"),
|
||||
Contains("one"),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user