summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-01-16 14:46:53 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-03-17 19:13:40 +1100
commit1dd7307fde033dae5fececac15810a99e26c3d91 (patch)
tree4e851c9e3229a6fe3b4191f6311d05d7a9142960 /pkg/commands
parenta90b6efded49abcfa2516db794d7875b0396f558 (diff)
start moving commit panel handlers into controller
more and more move rebase commit refreshing into existing abstraction and more and more WIP and more handling clicks properly fix merge conflicts update cheatsheet lots more preparation to start moving things into controllers WIP better typing expand on remotes controller moving more code into controllers
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/git.go6
-rw-r--r--pkg/commands/git_commands/common.go6
-rw-r--r--pkg/commands/git_commands/remote.go2
-rw-r--r--pkg/commands/git_commands/sync.go10
-rw-r--r--pkg/commands/git_commands/tag.go2
-rw-r--r--pkg/commands/git_test.go8
-rw-r--r--pkg/commands/oscommands/cmd_obj.go17
-rw-r--r--pkg/commands/oscommands/cmd_obj_runner.go29
8 files changed, 66 insertions, 14 deletions
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index f6812e254..3880e0dfc 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -5,6 +5,7 @@ import (
"os"
"path/filepath"
"strings"
+ "sync"
"github.com/go-errors/errors"
@@ -56,6 +57,7 @@ func NewGitCommand(
cmn *common.Common,
osCommand *oscommands.OSCommand,
gitConfig git_config.IGitConfig,
+ syncMutex *sync.Mutex,
) (*GitCommand, error) {
if err := navigateToRepoRootDirectory(os.Stat, os.Chdir); err != nil {
return nil, err
@@ -77,6 +79,7 @@ func NewGitCommand(
gitConfig,
dotGitDir,
repo,
+ syncMutex,
), nil
}
@@ -86,6 +89,7 @@ func NewGitCommandAux(
gitConfig git_config.IGitConfig,
dotGitDir string,
repo *gogit.Repository,
+ syncMutex *sync.Mutex,
) *GitCommand {
cmd := NewGitCmdObjBuilder(cmn.Log, osCommand.Cmd)
@@ -95,7 +99,7 @@ func NewGitCommandAux(
// on the one struct.
// common ones are: cmn, osCommand, dotGitDir, configCommands
configCommands := git_commands.NewConfigCommands(cmn, gitConfig, repo)
- gitCommon := git_commands.NewGitCommon(cmn, cmd, osCommand, dotGitDir, repo, configCommands)
+ gitCommon := git_commands.NewGitCommon(cmn, cmd, osCommand, dotGitDir, repo, configCommands, syncMutex)
statusCommands := git_commands.NewStatusCommands(gitCommon)
fileLoader := loaders.NewFileLoader(cmn, cmd, configCommands)
diff --git a/pkg/commands/git_commands/common.go b/pkg/commands/git_commands/common.go
index a045be75a..85f0d2118 100644
--- a/pkg/commands/git_commands/common.go
+++ b/pkg/commands/git_commands/common.go
@@ -1,6 +1,8 @@
package git_commands
import (
+ "sync"
+
gogit "github.com/jesseduffield/go-git/v5"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/common"
@@ -13,6 +15,8 @@ type GitCommon struct {
dotGitDir string
repo *gogit.Repository
config *ConfigCommands
+ // mutex for doing things like push/pull/fetch
+ syncMutex *sync.Mutex
}
func NewGitCommon(
@@ -22,6 +26,7 @@ func NewGitCommon(
dotGitDir string,
repo *gogit.Repository,
config *ConfigCommands,
+ syncMutex *sync.Mutex,
) *GitCommon {
return &GitCommon{
Common: cmn,
@@ -30,5 +35,6 @@ func NewGitCommon(
dotGitDir: dotGitDir,
repo: repo,
config: config,
+ syncMutex: syncMutex,
}
}
diff --git a/pkg/commands/git_commands/remote.go b/pkg/commands/git_commands/remote.go
index 3116c764a..1245a8cf0 100644
--- a/pkg/commands/git_commands/remote.go
+++ b/pkg/commands/git_commands/remote.go
@@ -40,7 +40,7 @@ func (self *RemoteCommands) UpdateRemoteUrl(remoteName string, updatedUrl string
func (self *RemoteCommands) DeleteRemoteBranch(remoteName string, branchName string) error {
command := fmt.Sprintf("git push %s --delete %s", self.cmd.Quote(remoteName), self.cmd.Quote(branchName))
- return self.cmd.New(command).PromptOnCredentialRequest().Run()
+ return self.cmd.New(command).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
// CheckRemoteBranchExists Returns remote branch
diff --git a/pkg/commands/git_commands/sync.go b/pkg/commands/git_commands/sync.go
index 8a6933522..fb1aa9648 100644
--- a/pkg/commands/git_commands/sync.go
+++ b/pkg/commands/git_commands/sync.go
@@ -47,7 +47,7 @@ func (self *SyncCommands) PushCmdObj(opts PushOpts) (oscommands.ICmdObj, error)
cmdStr += " " + self.cmd.Quote(opts.UpstreamBranch)
}
- cmdObj := self.cmd.New(cmdStr).PromptOnCredentialRequest()
+ cmdObj := self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex)
return cmdObj, nil
}
@@ -83,7 +83,7 @@ func (self *SyncCommands) Fetch(opts FetchOptions) error {
} else {
cmdObj.PromptOnCredentialRequest()
}
- return cmdObj.Run()
+ return cmdObj.WithMutex(self.syncMutex).Run()
}
type PullOptions struct {
@@ -108,15 +108,15 @@ func (self *SyncCommands) Pull(opts PullOptions) error {
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
// has 'pull.rebase = interactive' configured.
- return self.cmd.New(cmdStr).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest().Run()
+ return self.cmd.New(cmdStr).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
func (self *SyncCommands) FastForward(branchName string, remoteName string, remoteBranchName string) error {
cmdStr := fmt.Sprintf("git fetch %s %s:%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName), self.cmd.Quote(branchName))
- return self.cmd.New(cmdStr).PromptOnCredentialRequest().Run()
+ return self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
func (self *SyncCommands) FetchRemote(remoteName string) error {
cmdStr := fmt.Sprintf("git fetch %s", self.cmd.Quote(remoteName))
- return self.cmd.New(cmdStr).PromptOnCredentialRequest().Run()
+ return self.cmd.New(cmdStr).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
diff --git a/pkg/commands/git_commands/tag.go b/pkg/commands/git_commands/tag.go
index 94b0d8ac1..5abad0dc5 100644
--- a/pkg/commands/git_commands/tag.go
+++ b/pkg/commands/git_commands/tag.go
@@ -27,5 +27,5 @@ func (self *TagCommands) Delete(tagName string) error {
}
func (self *TagCommands) Push(remoteName string, tagName string) error {
- return self.cmd.New(fmt.Sprintf("git push %s %s", self.cmd.Quote(remoteName), self.cmd.Quote(tagName))).PromptOnCredentialRequest().Run()
+ return self.cmd.New(fmt.Sprintf("git push %s %s", self.cmd.Quote(remoteName), self.cmd.Quote(tagName))).PromptOnCredentialRequest().WithMutex(self.syncMutex).Run()
}
diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go
index 684696a8c..77436130d 100644
--- a/pkg/commands/git_test.go
+++ b/pkg/commands/git_test.go
@@ -3,6 +3,7 @@ package commands
import (
"fmt"
"os"
+ "sync"
"testing"
"time"
@@ -211,7 +212,12 @@ func TestNewGitCommand(t *testing.T) {
s := s
t.Run(s.testName, func(t *testing.T) {
s.setup()
- s.test(NewGitCommand(utils.NewDummyCommon(), oscommands.NewDummyOSCommand(), git_config.NewFakeGitConfig(nil)))
+ s.test(
+ NewGitCommand(utils.NewDummyCommon(),
+ oscommands.NewDummyOSCommand(),
+ git_config.NewFakeGitConfig(nil),
+ &sync.Mutex{},
+ ))
})
}
}
diff --git a/pkg/commands/oscommands/cmd_obj.go b/pkg/commands/oscommands/cmd_obj.go
index 3e55359de..7960bfa99 100644
--- a/pkg/commands/oscommands/cmd_obj.go
+++ b/pkg/commands/oscommands/cmd_obj.go
@@ -2,6 +2,7 @@ package oscommands
import (
"os/exec"
+ "sync"
)
// A command object is a general way to represent a command to be run on the
@@ -50,6 +51,9 @@ type ICmdObj interface {
PromptOnCredentialRequest() ICmdObj
FailOnCredentialRequest() ICmdObj
+ WithMutex(mutex *sync.Mutex) ICmdObj
+ Mutex() *sync.Mutex
+
GetCredentialStrategy() CredentialStrategy
}
@@ -70,6 +74,9 @@ type CmdObj struct {
// if set to true, it means we might be asked to enter a username/password by this command.
credentialStrategy CredentialStrategy
+
+ // can be set so that we don't run certain commands simultaneously
+ mutex *sync.Mutex
}
type CredentialStrategy int
@@ -132,6 +139,16 @@ func (self *CmdObj) IgnoreEmptyError() ICmdObj {
return self
}
+func (self *CmdObj) Mutex() *sync.Mutex {
+ return self.mutex
+}
+
+func (self *CmdObj) WithMutex(mutex *sync.Mutex) ICmdObj {
+ self.mutex = mutex
+
+ return self
+}
+
func (self *CmdObj) ShouldIgnoreEmptyError() bool {
return self.ignoreEmptyError
}
diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go
index e1a38d80f..9522bc627 100644
--- a/pkg/commands/oscommands/cmd_obj_runner.go
+++ b/pkg/commands/oscommands/cmd_obj_runner.go
@@ -34,6 +34,11 @@ type cmdObjRunner struct {
var _ ICmdObjRunner = &cmdObjRunner{}
func (self *cmdObjRunner) Run(cmdObj ICmdObj) error {
+ if cmdObj.Mutex() != nil {
+ cmdObj.Mutex().Lock()
+ defer cmdObj.Mutex().Unlock()
+ }
+
if cmdObj.GetCredentialStrategy() != NONE {
return self.runWithCredentialHandling(cmdObj)
}
@@ -42,27 +47,36 @@ func (self *cmdObjRunner) Run(cmdObj ICmdObj) error {
return self.runAndStream(cmdObj)
}
- _, err := self.RunWithOutput(cmdObj)
+ _, err := self.RunWithOutputAux(cmdObj)
return err
}
func (self *cmdObjRunner) RunWithOutput(cmdObj ICmdObj) (string, error) {
- if cmdObj.ShouldStreamOutput() {
- err := self.runAndStream(cmdObj)
+ if cmdObj.Mutex() != nil {
+ cmdObj.Mutex().Lock()
+ defer cmdObj.Mutex().Unlock()
+ }
+
+ if cmdObj.GetCredentialStrategy() != NONE {
+ err := self.runWithCredentialHandling(cmdObj)
// for now we're not capturing output, just because it would take a little more
// effort and there's currently no use case for it. Some commands call RunWithOutput
// but ignore the output, hence why we've got this check here.
return "", err
}
- if cmdObj.GetCredentialStrategy() != NONE {
- err := self.runWithCredentialHandling(cmdObj)
+ if cmdObj.ShouldStreamOutput() {
+ err := self.runAndStream(cmdObj)
// for now we're not capturing output, just because it would take a little more
// effort and there's currently no use case for it. Some commands call RunWithOutput
// but ignore the output, hence why we've got this check here.
return "", err
}
+ return self.RunWithOutputAux(cmdObj)
+}
+
+func (self *cmdObjRunner) RunWithOutputAux(cmdObj ICmdObj) (string, error) {
self.log.WithField("command", cmdObj.ToString()).Debug("RunCommand")
if cmdObj.ShouldLog() {
@@ -77,6 +91,11 @@ func (self *cmdObjRunner) RunWithOutput(cmdObj ICmdObj) (string, error) {
}
func (self *cmdObjRunner) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error {
+ if cmdObj.Mutex() != nil {
+ cmdObj.Mutex().Lock()
+ defer cmdObj.Mutex().Unlock()
+ }
+
if cmdObj.GetCredentialStrategy() != NONE {
return errors.New("cannot call RunAndProcessLines with credential strategy. If you're seeing this then a contributor to Lazygit has accidentally called this method! Please raise an issue")
}