mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-12 00:26:24 -04:00
The worktrees tab now displays the checked-out branch (or detached HEAD state) for each worktree, making it much easier to see which worktree holds which branch. This is useful when you need to "unlock" a branch that's occupied by another worktree: you can now clearly see which worktrees are on a branch vs detached, without having to select each one individually. Also rename the "(main)" label to "(main worktree)" to avoid confusion with the common "main" branch name, and move it after the branch column.
121 lines
3 KiB
Go
121 lines
3 KiB
Go
package worktree
|
|
|
|
import (
|
|
"github.com/jesseduffield/lazygit/pkg/config"
|
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
|
)
|
|
|
|
var Crud = NewIntegrationTest(NewIntegrationTestArgs{
|
|
Description: "From the worktrees view, add a work tree, switch to it, switch back, and remove it",
|
|
ExtraCmdArgs: []string{},
|
|
Skip: false,
|
|
SetupConfig: func(config *config.AppConfig) {},
|
|
SetupRepo: func(shell *Shell) {
|
|
shell.NewBranch("mybranch")
|
|
shell.CreateFileAndAdd("README.md", "hello world")
|
|
shell.Commit("initial commit")
|
|
},
|
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
|
t.Views().Branches().
|
|
Lines(
|
|
Contains("mybranch"),
|
|
)
|
|
|
|
t.Views().Status().
|
|
Lines(
|
|
Contains("repo → mybranch"),
|
|
)
|
|
|
|
t.Views().Worktrees().
|
|
Focus().
|
|
Lines(
|
|
Contains("(main worktree)"),
|
|
).
|
|
Press(keys.Universal.New).
|
|
Tap(func() {
|
|
t.ExpectPopup().Menu().
|
|
Title(Equals("Worktree")).
|
|
Select(Contains(`Create worktree from ref`).DoesNotContain(("detached"))).
|
|
Confirm()
|
|
|
|
t.ExpectPopup().Prompt().
|
|
Title(Equals("New worktree base ref")).
|
|
InitialText(Equals("mybranch")).
|
|
Confirm()
|
|
|
|
t.ExpectPopup().Prompt().
|
|
Title(Equals("New worktree path")).
|
|
Type("../linked-worktree").
|
|
Confirm()
|
|
|
|
t.ExpectPopup().Prompt().
|
|
Title(Equals("New branch name (leave blank to checkout mybranch)")).
|
|
Type("newbranch").
|
|
Confirm()
|
|
}).
|
|
Lines(
|
|
Contains("linked-worktree").IsSelected(),
|
|
Contains("(main worktree)"),
|
|
).
|
|
// confirm we're still in the same view
|
|
IsFocused()
|
|
|
|
// status panel includes the worktree if it's a linked worktree
|
|
t.Views().Status().
|
|
Lines(
|
|
Contains("repo(linked-worktree) → newbranch"),
|
|
)
|
|
|
|
t.Views().Branches().
|
|
Lines(
|
|
Contains("newbranch"),
|
|
Contains("mybranch"),
|
|
)
|
|
|
|
t.Views().Worktrees().
|
|
// confirm we can't remove the current worktree
|
|
Press(keys.Universal.Remove).
|
|
Tap(func() {
|
|
t.ExpectPopup().Alert().
|
|
Title(Equals("Error")).
|
|
Content(Equals("You cannot remove the current worktree!")).
|
|
Confirm()
|
|
}).
|
|
// confirm we cannot remove the main worktree
|
|
NavigateToLine(Contains("(main worktree)")).
|
|
Press(keys.Universal.Remove).
|
|
Tap(func() {
|
|
t.ExpectPopup().Alert().
|
|
Title(Equals("Error")).
|
|
Content(Equals("You cannot remove the main worktree!")).
|
|
Confirm()
|
|
}).
|
|
// switch back to main worktree
|
|
Press(keys.Universal.Select).
|
|
Lines(
|
|
Contains("(main worktree)").IsSelected(),
|
|
Contains("linked-worktree"),
|
|
)
|
|
|
|
t.Views().Branches().
|
|
Lines(
|
|
Contains("mybranch"),
|
|
Contains("newbranch"),
|
|
)
|
|
|
|
t.Views().Worktrees().
|
|
// remove linked worktree
|
|
NavigateToLine(Contains("linked-worktree")).
|
|
Press(keys.Universal.Remove).
|
|
Tap(func() {
|
|
t.ExpectPopup().Confirmation().
|
|
Title(Equals("Remove worktree")).
|
|
Content(Contains("Are you sure you want to remove worktree 'linked-worktree'?")).
|
|
Confirm()
|
|
}).
|
|
Lines(
|
|
Contains("(main worktree)").IsSelected(),
|
|
)
|
|
},
|
|
})
|