summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorJoel Baranick <joel.baranick@ensighten.com>2022-09-01 11:25:41 -0700
committerJesse Duffield <jessedduffield@gmail.com>2023-07-30 18:35:21 +1000
commitf8ba899b8734db7dcf3ae57cc34939db18a1a414 (patch)
treee909f4582fed5afbead1b0f0717eab1846869195 /pkg/commands
parent52447e5d46cedda76926dbee36b867674335d508 (diff)
Initial addition of support for worktrees
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/git.go3
-rw-r--r--pkg/commands/git_commands/branch_loader.go12
-rw-r--r--pkg/commands/git_commands/worktree_loader.go80
-rw-r--r--pkg/commands/models/worktree.go21
4 files changed, 116 insertions, 0 deletions
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index 3a2349fd5..6e74daa52 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -50,6 +50,7 @@ type Loaders struct {
RemoteLoader *git_commands.RemoteLoader
StashLoader *git_commands.StashLoader
TagLoader *git_commands.TagLoader
+ Worktrees *git_commands.WorktreeLoader
}
func NewGitCommand(
@@ -133,6 +134,7 @@ func NewGitCommandAux(
commitLoader := git_commands.NewCommitLoader(cmn, cmd, dotGitDir, statusCommands.RebaseMode, gitCommon)
reflogCommitLoader := git_commands.NewReflogCommitLoader(cmn, cmd)
remoteLoader := git_commands.NewRemoteLoader(cmn, cmd, repo.Remotes)
+ worktreeLoader := git_commands.NewWorktreeLoader(cmn, cmd)
stashLoader := git_commands.NewStashLoader(cmn, cmd)
tagLoader := git_commands.NewTagLoader(cmn, cmd)
@@ -161,6 +163,7 @@ func NewGitCommandAux(
FileLoader: fileLoader,
ReflogCommitLoader: reflogCommitLoader,
RemoteLoader: remoteLoader,
+ Worktrees: worktreeLoader,
StashLoader: stashLoader,
TagLoader: tagLoader,
},
diff --git a/pkg/commands/git_commands/branch_loader.go b/pkg/commands/git_commands/branch_loader.go
index cb284f67f..bab24bfa7 100644
--- a/pkg/commands/git_commands/branch_loader.go
+++ b/pkg/commands/git_commands/branch_loader.go
@@ -2,6 +2,7 @@ package git_commands
import (
"fmt"
+ "os"
"regexp"
"strings"
@@ -117,6 +118,11 @@ outer:
}
func (self *BranchLoader) obtainBranches() []*models.Branch {
+ currentDir, err := os.Getwd()
+ if err != nil {
+ panic(err)
+ }
+
output, err := self.getRawBranches()
if err != nil {
panic(err)
@@ -138,6 +144,11 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
return nil, false
}
+ if len(split[6]) > 0 && split[6] != currentDir {
+ // Ignore line because it is a branch checked out in a different worktree
+ return nil, false
+ }
+
return obtainBranch(split), true
})
}
@@ -166,6 +177,7 @@ var branchFields = []string{
"upstream:track",
"subject",
fmt.Sprintf("objectname:short=%d", utils.COMMIT_HASH_SHORT_SIZE),
+ "worktreepath",
}
// Obtain branch information from parsed line output of getRawBranches()
diff --git a/pkg/commands/git_commands/worktree_loader.go b/pkg/commands/git_commands/worktree_loader.go
new file mode 100644
index 000000000..905754540
--- /dev/null
+++ b/pkg/commands/git_commands/worktree_loader.go
@@ -0,0 +1,80 @@
+package git_commands
+
+import (
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/jesseduffield/lazygit/pkg/common"
+)
+
+type WorktreeLoader struct {
+ *common.Common
+ cmd oscommands.ICmdObjBuilder
+}
+
+func NewWorktreeLoader(
+ common *common.Common,
+ cmd oscommands.ICmdObjBuilder,
+) *WorktreeLoader {
+ return &WorktreeLoader{
+ Common: common,
+ cmd: cmd,
+ }
+}
+
+func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) {
+ currentDir, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+
+ cmdArgs := NewGitCmd("worktree").Arg("list", "--porcelain", "-z").ToArgv()
+ worktreesOutput, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
+ if err != nil {
+ return nil, err
+ }
+
+ splitLines := strings.Split(worktreesOutput, "\x00")
+
+ var worktrees []*models.Worktree
+ var currentWorktree *models.Worktree
+ for _, splitLine := range splitLines {
+ if len(splitLine) == 0 && currentWorktree != nil {
+
+ worktrees = append(worktrees, currentWorktree)
+ currentWorktree = nil
+ continue
+ }
+ if strings.HasPrefix(splitLine, "worktree ") {
+ main := false
+ name := "main"
+ path := strings.SplitN(splitLine, " ", 2)[1]
+ if len(worktrees) == 0 {
+ main = true
+ } else {
+ name = filepath.Base(path)
+ }
+ currentWorktree = &models.Worktree{
+ Name: name,
+ Path: path,
+ Main: main,
+ Current: path == currentDir,
+ }
+ }
+ }
+
+ /*
+ worktree /Users/jbaranick/Source/lazygit
+ HEAD f6d6b5dec0432ffa953611700ab9b1ff0089f948
+ branch refs/heads/worktree_support
+
+ worktree /Users/jbaranick/Source/lazygit/.worktrees/worktree_tests
+ HEAD f6d6b5dec0432ffa953611700ab9b1ff0089f948
+ branch refs/heads/worktree_tests
+ */
+
+ return worktrees, nil
+}
diff --git a/pkg/commands/models/worktree.go b/pkg/commands/models/worktree.go
new file mode 100644
index 000000000..f38c67e07
--- /dev/null
+++ b/pkg/commands/models/worktree.go
@@ -0,0 +1,21 @@
+package models
+
+// Worktree : A git worktree
+type Worktree struct {
+ Name string
+ Main bool
+ Current bool
+ Path string
+}
+
+func (w *Worktree) RefName() string {
+ return w.Name
+}
+
+func (w *Worktree) ID() string {
+ return w.RefName()
+}
+
+func (w *Worktree) Description() string {
+ return w.RefName()
+}