summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2021-12-29 14:33:38 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-01-04 09:07:15 +1100
commit43a4fa970dfceb7868959ff4da48d5507fa2f234 (patch)
treedaff776e59aebeb9b814a7918a9db75d4443175f
parent192a548c9957807d9d5c9c4700dffe02c1f55f03 (diff)
WIP
-rw-r--r--pkg/app/app.go4
-rw-r--r--pkg/commands/branches.go45
-rw-r--r--pkg/commands/branches_test.go2
-rw-r--r--pkg/commands/commits.go33
-rw-r--r--pkg/commands/files.go49
-rw-r--r--pkg/commands/git.go47
-rw-r--r--pkg/commands/git_cmd_obj_builder.go47
-rw-r--r--pkg/commands/git_cmd_obj_runner.go49
-rw-r--r--pkg/commands/loading_branches.go90
-rw-r--r--pkg/commands/loading_commit_files.go2
-rw-r--r--pkg/commands/loading_commits.go61
-rw-r--r--pkg/commands/loading_files.go2
-rw-r--r--pkg/commands/loading_reflog_commits.go4
-rw-r--r--pkg/commands/loading_remotes.go2
-rw-r--r--pkg/commands/loading_stash.go4
-rw-r--r--pkg/commands/loading_tags.go2
-rw-r--r--pkg/commands/oscommands/cmd_obj.go31
-rw-r--r--pkg/commands/oscommands/cmd_obj_builder.go72
-rw-r--r--pkg/commands/oscommands/cmd_obj_runner.go79
-rw-r--r--pkg/commands/oscommands/os.go150
-rw-r--r--pkg/commands/oscommands/os_test.go4
-rw-r--r--pkg/commands/patch_rebases.go6
-rw-r--r--pkg/commands/rebasing.go39
-rw-r--r--pkg/commands/remotes.go14
-rw-r--r--pkg/commands/stash_entries.go10
-rw-r--r--pkg/commands/submodules.go37
-rw-r--r--pkg/commands/sync.go10
-rw-r--r--pkg/commands/tags.go8
-rw-r--r--pkg/gui/commits_panel.go4
-rw-r--r--pkg/gui/custom_commands.go8
-rw-r--r--pkg/gui/diffing.go2
-rw-r--r--pkg/gui/files_panel.go6
-rw-r--r--pkg/gui/git_flow.go6
-rw-r--r--pkg/gui/gpg.go4
-rw-r--r--pkg/gui/rebase_options_panel.go2
-rw-r--r--pkg/gui/recent_repos_panel.go2
-rw-r--r--pkg/gui/stash_panel.go2
-rw-r--r--pkg/gui/sub_commits_panel.go2
-rw-r--r--pkg/gui/submodules_panel.go7
-rw-r--r--pkg/integration/integration.go6
-rw-r--r--pkg/updates/updates.go4
41 files changed, 539 insertions, 419 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go
index 747f5205f..4fcbdc5b8 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -151,7 +151,7 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
}
func (app *App) validateGitVersion() error {
- output, err := app.OSCommand.RunWithOutput(app.OSCommand.NewCmdObj("git --version"))
+ output, err := app.OSCommand.Cmd.New("git --version").RunWithOutput()
// if we get an error anywhere here we'll show the same status
minVersionError := errors.New(app.Tr.MinGitVersionError)
if err != nil {
@@ -236,7 +236,7 @@ func (app *App) setupRepo() (bool, error) {
os.Exit(1)
}
- if err := app.OSCommand.Run(app.OSCommand.NewCmdObj("git init")); err != nil {
+ if err := app.OSCommand.Cmd.New("git init").Run(); err != nil {
return false, err
}
}
diff --git a/pkg/commands/branches.go b/pkg/commands/branches.go
index 274168311..e3c40d343 100644
--- a/pkg/commands/branches.go
+++ b/pkg/commands/branches.go
@@ -11,19 +11,19 @@ import (
// NewBranch create new branch
func (c *GitCommand) NewBranch(name string, base string) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git checkout -b %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(base))))
+ return c.Cmd.New(fmt.Sprintf("git checkout -b %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(base))).Run()
}
// CurrentBranchName get the current branch name and displayname.
// the first returned string is the name and the second is the displayname
// e.g. name is 123asdf and displayname is '(HEAD detached at 123asdf)'
func (c *GitCommand) CurrentBranchName() (string, string, error) {
- branchName, err := c.RunWithOutput(c.NewCmdObj("git symbolic-ref --short HEAD"))
+ branchName, err := c.Cmd.New("git symbolic-ref --short HEAD").RunWithOutput()
if err == nil && branchName != "HEAD\n" {
trimmedBranchName := strings.TrimSpace(branchName)
return trimmedBranchName, trimmedBranchName, nil
}
- output, err := c.RunWithOutput(c.NewCmdObj("git branch --contains"))
+ output, err := c.Cmd.New("git branch --contains").RunWithOutput()
if err != nil {
return "", "", err
}
@@ -47,7 +47,7 @@ func (c *GitCommand) DeleteBranch(branch string, force bool) error {
command = "git branch -D"
}
- return c.OSCommand.Run(c.OSCommand.NewCmdObj(fmt.Sprintf("%s %s", command, c.OSCommand.Quote(branch))))
+ return c.Cmd.New(fmt.Sprintf("%s %s", command, c.OSCommand.Quote(branch))).Run()
}
// Checkout checks out a branch (or commit), with --force if you set the force arg to true
@@ -62,24 +62,23 @@ func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error {
forceArg = " --force"
}
- cmdObj := c.NewCmdObj(fmt.Sprintf("git checkout%s %s", forceArg, c.OSCommand.Quote(branch))).
+ return c.Cmd.New(fmt.Sprintf("git checkout%s %s", forceArg, c.OSCommand.Quote(branch))).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
- AddEnvVars(options.EnvVars...)
-
- return c.OSCommand.Run(cmdObj)
+ AddEnvVars(options.EnvVars...).
+ Run()
}
// GetBranchGraph gets the color-formatted graph of the log for the given branch
// Currently it limits the result to 100 commits, but when we get async stuff
// working we can do lazy loading
func (c *GitCommand) GetBranchGraph(branchName string) (string, error) {
- return c.OSCommand.RunWithOutput(c.GetBranchGraphCmdObj(branchName))
+ return c.GetBranchGraphCmdObj(branchName).RunWithOutput()
}
func (c *GitCommand) GetUpstreamForBranch(branchName string) (string, error) {
- output, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git rev-parse --abbrev-ref --symbolic-full-name %s@{u}", c.OSCommand.Quote(branchName))))
+ output, err := c.Cmd.New(fmt.Sprintf("git rev-parse --abbrev-ref --symbolic-full-name %s@{u}", c.OSCommand.Quote(branchName))).RunWithOutput()
return strings.TrimSpace(output), err
}
@@ -88,15 +87,15 @@ func (c *GitCommand) GetBranchGraphCmdObj(branchName string) oscommands.ICmdObj
templateValues := map[string]string{
"branchName": c.OSCommand.Quote(branchName),
}
- return c.NewCmdObj(utils.ResolvePlaceholderString(branchLogCmdTemplate, templateValues))
+ return c.Cmd.New(utils.ResolvePlaceholderString(branchLogCmdTemplate, templateValues))
}
func (c *GitCommand) SetUpstreamBranch(upstream string) error {
- return c.Run(c.NewCmdObj("git branch -u " + c.OSCommand.Quote(upstream)))
+ return c.Cmd.New("git branch -u " + c.OSCommand.Quote(upstream)).Run()
}
func (c *GitCommand) SetBranchUpstream(remoteName string, remoteBranchName string, branchName string) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git branch --set-upstream-to=%s/%s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))))
+ return c.Cmd.New(fmt.Sprintf("git branch --set-upstream-to=%s/%s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))).Run()
}
func (c *GitCommand) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
@@ -111,11 +110,11 @@ func (c *GitCommand) GetBranchUpstreamDifferenceCount(branchName string) (string
// current branch
func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
command := "git rev-list %s..%s --count"
- pushableCount, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf(command, to, from)))
+ pushableCount, err := c.Cmd.New(fmt.Sprintf(command, to, from)).RunWithOutput()
if err != nil {
return "?", "?"
}
- pullableCount, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf(command, from, to)))
+ pullableCount, err := c.Cmd.New(fmt.Sprintf(command, from, to)).RunWithOutput()
if err != nil {
return "?", "?"
}
@@ -135,37 +134,37 @@ func (c *GitCommand) Merge(branchName string, opts MergeOpts) error {
command = fmt.Sprintf("%s --ff-only", command)
}
- return c.OSCommand.Run(c.OSCommand.NewCmdObj(command))
+ return c.OSCommand.Cmd.New(command).Run()
}
// AbortMerge abort merge
func (c *GitCommand) AbortMerge() error {
- return c.Run(c.NewCmdObj("git merge --abort"))
+ return c.Cmd.New("git merge --abort").Run()
}
func (c *GitCommand) IsHeadDetached() bool {
- err := c.Run(c.NewCmdObj("git symbolic-ref -q HEAD"))
+ err := c.Cmd.New("git symbolic-ref -q HEAD").Run()
return err != nil
}
// ResetHardHead runs `git reset --hard`
func (c *GitCommand) ResetHard(ref string) error {
- return c.Run(c.NewCmdObj("git reset --hard " + c.OSCommand.Quote(ref)))
+ return c.Cmd.New("git reset --hard " + c.OSCommand.Quote(ref)).Run()
}
// ResetSoft runs `git reset --soft HEAD`
func (c *GitCommand) ResetSoft(ref string) error {
- return c.Run(c.NewCmdObj("git reset --soft " + c.OSCommand.Quote(ref)))
+ return c.Cmd.New("git reset --soft " + c.OSCommand.Quote(ref)).Run()
}
func (c *GitCommand) ResetMixed(ref string) error {
- return c.Run(c.NewCmdObj("git reset --mixed " + c.OSCommand.Quote(ref)))
+ return c.Cmd.New("git reset --mixed " + c.OSCommand.Quote(ref)).Run()
}
func (c *GitCommand) RenameBranch(oldName string, newName string) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git branch --move %s %s", c.OSCommand.Quote(oldName), c.OSCommand.Quote(newName))))
+ return c.Cmd.New(fmt.Sprintf("git branch --move %s %s", c.OSCommand.Quote(oldName), c.OSCommand.Quote(newName))).Run()
}
func (c *GitCommand) GetRawBranches() (string, error) {
- return c.RunWithOutput(c.NewCmdObj(`git for-each-ref --sort=-committerdate --format="%(HEAD)|%(refname:short)|%(upstream:short)|%(upstream:track)" refs/heads`))
+ return c.Cmd.New(`git for-each-ref --sort=-committerdate --format="%(HEAD)|%(refname:short)|%(upstream:short)|%(upstream:track)" refs/heads`).RunWithOutput()
}
diff --git a/pkg/commands/branches_test.go b/pkg/commands/branches_test.go
index 7064f4968..45cfb8315 100644
--- a/pkg/commands/branches_test.go
+++ b/pkg/commands/branches_test.go
@@ -210,7 +210,7 @@ func TestGitCommandGetAllBranchGraph(t *testing.T) {
return secureexec.Command("echo")
}
cmdStr := gitCmd.UserConfig.Git.AllBranchesLogCmd
- _, err := gitCmd.OSCommand.RunWithOutput(gitCmd.NewCmdObj(cmdStr))
+ _, err := gitCmd.Cmd.New(cmdStr).RunWithOutput()
assert.NoError(t, err)
}
diff --git a/pkg/commands/commits.go b/pkg/commands/commits.go
index 447e9adb8..689220529 100644
--- a/pkg/commands/commits.go
+++ b/pkg/commands/commits.go
@@ -10,18 +10,17 @@ import (
// RenameCommit renames the topmost commit with the given name
func (c *GitCommand) RenameCommit(name string) error {
- return c.Run(c.NewCmdObj("git commit --allow-empty --amend --only -m " + c.OSCommand.Quote(name)))
+ return c.Cmd.New("git commit --allow-empty --amend --only -m " + c.OSCommand.Quote(name)).Run()
}
// ResetToCommit reset to commit
func (c *GitCommand) ResetToCommit(sha string, strength string, envVars []string) error {
- cmdObj := c.NewCmdObj(fmt.Sprintf("git reset --%s %s", strength, sha)).
+ return c.Cmd.New(fmt.Sprintf("git reset --%s %s", strength, sha)).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
- AddEnvVars(envVars...)
-
- return c.OSCommand.Run(cmdObj)
+ AddEnvVars(envVars...).
+ Run()
}
func (c *GitCommand) CommitCmdObj(message string, flags string) oscommands.ICmdObj {
@@ -36,33 +35,33 @@ func (c *GitCommand) CommitCmdObj(message string, flags string) oscommands.ICmdO
flagsStr = fmt.Sprintf(" %s", flags)
}
- return c.NewCmdObj(fmt.Sprintf("git commit%s%s", flagsStr, lineArgs))
+ return c.Cmd.New(fmt.Sprintf("git commit%s%s", flagsStr, lineArgs))
}
// Get the subject of the HEAD commit
func (c *GitCommand) GetHeadCommitMessage() (string, error) {
- message, err := c.RunWithOutput(c.NewCmdObj("git log -1 --pretty=%s"))
+ message, err := c.Cmd.New("git log -1 --pretty=%s").RunWithOutput()
return strings.TrimSpace(message), err
}
func (c *GitCommand) GetCommitMessage(commitSha string) (string, error) {
cmdStr := "git rev-list --format=%B --max-count=1 " + commitSha
- messageWithHeader, err := c.RunWithOutput(c.NewCmdObj(cmdStr))
+ messageWithHeader, err := c.Cmd.New(cmdStr).RunWithOutput()
message := strings.Join(strings.SplitAfter(messageWithHeader, "\n")[1:], "\n")
return strings.TrimSpace(message), err
}
func (c *GitCommand) GetCommitMessageFirstLine(sha string) (string, error) {
- return c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git show --no-patch --pretty=format:%%s %s", sha)))
+ return c.Cmd.New(fmt.Sprintf("git show --no-patch --pretty=format:%%s %s", sha)).RunWithOutput()
}
// AmendHead amends HEAD with whatever is staged in your working tree
func (c *GitCommand) AmendHead() error {
- return c.OSCommand.Run(c.AmendHeadCmdObj())
+ return c.AmendHeadCmdObj().Run()
}
func (c *GitCommand) AmendHeadCmdObj() oscommands.ICmdObj {
- return c.NewCmdObj("git commit --amend --no-edit --allow-empty")
+ return c.Cmd.New("git commit --amend --no-edit --allow-empty")
}
func (c *GitCommand) ShowCmdObj(sha string, filterPath string) oscommands.ICmdObj {
@@ -73,16 +72,16 @@ func (c *GitCommand) ShowCmdObj(sha string, filterPath string) oscommands.ICmdOb
}
cmdStr := fmt.Sprintf("git show --submodule --color=%s --unified=%d --no-renames --stat -p %s %s", c.colorArg(), contextSize, sha, filterPathArg)
- return c.NewCmdObj(cmdStr)
+ return c.Cmd.New(cmdStr)
}
// Revert reverts the selected commit by sha
func (c *GitCommand) Revert(sha string) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git revert %s", sha)))
+ return c.Cmd.New(fmt.Sprintf("git revert %s", sha)).Run()
}
func (c *GitCommand) RevertMerge(sha string, parentNumber int) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git revert %s -m %d", sha, parentNumber)))
+ return c.Cmd.New(fmt.Sprintf("git revert %s -m %d", sha, parentNumber)).Run()
}
// CherryPickCommits begins an interactive rebase with the given shas being cherry picked onto HEAD
@@ -92,15 +91,15 @@ func (c *GitCommand) CherryPickCommits(commits []*models.Commit) error {
todo = "pick " + commit.Sha + " " + commit.Name + "\n" + todo
}
- cmd, err := c.PrepareInteractiveRebaseCommand("HEAD", todo, false)
+ cmdObj, err := c.PrepareInteractiveRebaseCommand("HEAD", todo, false)
if err != nil {
return err
}
- return c.OSCommand.Run(cmd)
+ return cmdObj.Run()
}
// CreateFixupCommit creates a commit that fixes up a previous commit
func (c *GitCommand) CreateFixupCommit(sha string) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git commit --fixup=%s", sha)))
+ return c.Cmd.New(fmt.Sprintf("git commit --fixup=%s", sha)).Run()
}
diff --git a/pkg/commands/files.go b/pkg/commands/files.go
index 28f37612f..da451e80c 100644
--- a/pkg/commands/files.go
+++ b/pkg/commands/files.go
@@ -25,26 +25,26 @@ func (c *GitCommand) CatFile(fileName string) (string, error) {
}
func (c *GitCommand) OpenMergeToolCmdObj() oscommands.ICmdObj {
- return c.NewCmdObj("git mergetool")
+ return c.Cmd.New("git mergetool")
}
func (c *GitCommand) OpenMergeTool() error {
- return c.Run(c.OpenMergeToolCmdObj())
+ return c.OpenMergeToolCmdObj().Run()
}
// StageFile stages a file
func (c *GitCommand) StageFile(fileName string) error {
- return c.Run(c.NewCmdObj("git add -- " + c.OSCommand.Quote(fileName)))
+ return c.Cmd.New("git add -- " + c.OSCommand.Quote(fileName)).Run()
}
// StageAll stages all files
func (c *GitCommand) StageAll() error {
- return c.Run(c.NewCmdObj("git add -A"))
+ return c.Cmd.New("git add -A").Run()
}
// UnstageAll unstages all files
func (c *GitCommand) UnstageAll() error {
- return c.Run(c.NewCmdObj("git reset"))
+ return c.Cmd.New("git reset").Run()
}
// UnStageFile unstages a file
@@ -57,8 +57,8 @@ func (c *GitCommand) UnStageFile(fileNames []string, reset bool) error {
}
for _, name := range fileNames {
- cmdObj := c.NewCmdObj(fmt.Sprintf(command, c.OSCommand.Quote(name)))
- if err := c.Run(cmdObj); err != nil {
+ err := c.Cmd.New(fmt.Sprintf(command, c.OSCommand.Quote(name))).Run()
+ if err != nil {
return err
}
}
@@ -122,22 +122,22 @@ func (c *GitCommand) DiscardAllFileChanges(file *models.File) error {
quotedFileName := c.OSCommand.Quote(file.Name)
if file.ShortStatus == "AA" {
- if err := c.Run(c.NewCmdObj("git checkout --ours -- " + quotedFileName)); err != nil {
+ if err := c.Cmd.New("git checkout --ours -- " + quotedFileName).Run(); err != nil {
return err
}
- if err := c.Run(c.NewCmdObj("git add -- " + quotedFileName)); err != nil {
+ if err := c.Cmd.New("git add -- " + quotedFileName).Run(); err != nil {
return err
}
return nil
}
if file.ShortStatus == "DU" {
- return c.Run(c.NewCmdObj("git rm -- " + quotedFileName))
+ return c.Cmd.New("git rm -- " + quotedFileName).Run()
}
// if the file isn't tracked, we assume you want to delete it
if file.HasStagedChanges || file.HasMergeConflicts {
- if err := c.Run(c.NewCmdObj("git reset -- " + quotedFileName)); err != nil {
+ if err := c.Cmd.New("git reset -- " + quotedFileName).Run(); err != nil {
return err
}
}
@@ -163,7 +163,7 @@ func (c *GitCommand) DiscardUnstagedDirChanges(node *filetree.FileNode) error {
}
quotedPath := c.OSCommand.Quote(node.GetPath())
- if err := c.Run(c.NewCmdObj("git checkout -- " + quotedPath)); err != nil {
+ if err := c.Cmd.New("git checkout -- " + quotedPath).Run(); err != nil {
return err
}
@@ -188,7 +188,7 @@ func (c *GitCommand) RemoveUntrackedDirFiles(node *filetree.FileNode) error {
// DiscardUnstagedFileChanges directly
func (c *GitCommand) DiscardUnstagedFileChanges(file *models.File) error {
quotedFileName := c.OSCommand.Quote(file.Name)
- return c.Run(c.NewCmdObj("git checkout -- " + quotedFileName))
+ return c.Cmd.New("git checkout -- " + quotedFileName).Run()
}
// Ignore adds a file to the gitignore for the repo
@@ -199,7 +199,7 @@ func (c *GitCommand) Ignore(filename string) error {
// WorktreeFileDiff returns the diff of a file
func (c *GitCommand) WorktreeFileDiff(file *models.File, plain bool, cached bool, ignoreWhitespace bool) string {
// for now we assume an error means the file was deleted
- s, _ := c.OSCommand.RunWithOutput(c.WorktreeFileDiffCmdObj(file, plain, cached, ignoreWhitespace))
+ s, _ := c.WorktreeFileDiffCmdObj(file, plain, cached, ignoreWhitespace).RunWithOutput()
return s
}
@@ -225,7 +225,7 @@ func (c *GitCommand) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cache
cmdStr := fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --color=%s %s %s %s %s", contextSize, colorArg, ignoreWhitespaceArg, cachedArg, trackedArg, quotedPath)
- return c.NewCmdObj(cmdStr)
+ return c.Cmd.New(cmdStr)
}
func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
@@ -240,14 +240,13 @@ func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
flagStr += " --" + flag
}
- return c.Run(c.NewCmdObj(fmt.Sprintf("git apply %s %s", flagStr, c.OSCommand.Quote(filepath))))
+ return c.Cmd.New(fmt.Sprintf("git apply %s %s", flagStr, c.OSCommand.Quote(filepath))).Run()
}
// ShowFileDiff get the diff of specified from and to. Typically this will be used for a single commit so it'll be 123abc^..123abc
// but when we're in diff mode it could be any 'from' to any 'to'. The reverse flag is also here thanks to diff mode.
func (c *GitCommand) ShowFileDiff(from string, to string, reverse bool, fileName string, plain bool) (string, error) {
- cmdObj := c.ShowFileDiffCmdObj(from, to, reverse, fileName, plain)
- return c.RunWithOutput(cmdObj)
+ return c.ShowFileDiffCmdObj(from, to, reverse, fileName, plain).RunWithOutput()
}
func (c *GitCommand) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) oscommands.ICmdObj {
@@ -262,12 +261,12 @@ func (c *GitCommand) ShowFileDiffCmdObj(from string, to string, reverse bool, fi
reverseFlag = " -R "
}
- return c.NewCmdObj(fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s %s %s %s -- %s", contextSize, colorArg, from, to, reverseFlag, c.OSCommand.Quote(fileName)))
+ return c.Cmd.New(fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s %s %s %s -- %s", contextSize, colorArg, from, to, reverseFlag, c.OSCommand.Quote(fileName)))
}
// CheckoutFile checks out the file for the given commit
func (c *GitCommand) CheckoutFile(commitSha, fileName string) error {
- return c.Run(c.NewCmdObj(fmt.Sprintf("git checkout %s -- %s", commitSha, c.OSCommand.Quote(fileName))))
+ return c.Cmd.New(fmt.Sprintf("git checkout %s -- %s", commitSha, c.OSCommand.Quote(fileName))).Run()
}
// DiscardOldFileChanges discards changes to a file from an old commit
@@ -277,7 +276,7 @@ func (c *GitCommand) DiscardOldFileChanges(commits []*models.Commit, commitIndex
}
// check if file exists in previous commit (this command returns an error if the file doesn't exist)
- if err := c.Run(c.NewCmdObj("git cat-file -e HEAD^:" + c.OSCommand.Quote(fileName))); err != nil {
+ if err := c.Cmd.New("git cat-file -e HEAD^:" + c.OSCommand.Quote(fileName)).Run(); err != nil {
if err := c.OSCommand.Remove(fileName); err != nil {
return err
}
@@ -300,17 +299,17 @@ func (c *GitCommand) DiscardOldFileChanges(commits []*models.Commit, commitIndex
// DiscardAnyUnstagedFileChanges discards any unstages file changes via `git checkout -- .`
func (c *GitCommand) DiscardAnyUnstagedFileChanges() error {
- return c.Run(c.NewCmdObj("git checkout -- ."))
+ return c.Cmd.New("git checkout -- .").Run()
}
// RemoveTrackedFiles will delete the given file(s) even if they are currently tracked
func (c *GitCommand) RemoveTrackedFiles(name string) error {
- return c.Run(c.NewCmdObj("git rm -r --cached -- " + c.OSCommand.Quote(name)))
+ return c.Cmd.New("git rm -r --cached -- " + c.OSCommand.Quote(name)).Run()
}
// RemoveUntrackedFiles runs `git clean -fd`
func (c *GitCommand) RemoveUntrackedFiles() error {
- return c.Run(c.NewCmdObj("git clean -fd"))
+ return c.Cmd.New("git clean -fd").Run()
}
// ResetAndClean removes all unstaged changes and removes all untracked files
@@ -350,7 +349,7 @@ func (c *GitCommand) EditFileCmdStr(filename string, lineNumber int) (string, er
editor = c.OSCommand.Getenv("EDITOR")
}
if editor == "" {
- if err := c.OSCommand.Run(c.NewCmdObj("which vi")); err == nil {
+ if err := c.OSCommand.Cmd.New("which vi").Run(); err == nil {
editor = "vi"
}
}
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index dd3879b82..b83fa1b73 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -6,7 +6,6 @@ import (
"os"
"path/filepath"
"strings"
- "time"
"github.com/go-errors/errors"
@@ -42,6 +41,8 @@ type GitCommand struct {
// Coincidentally at the moment it's the same view that OnRunCommand logs to
// but that need not always be the case.
GetCmdWriter func() io.Writer
+
+ Cmd oscommands.ICmdObjBuilder
}
// NewGitCommand it runs git commands
@@ -68,6 +69,8 @@ func NewGitCommand(
return nil, err
}
+ cmd := NewGitCmdObjBuilder(cmn.Log, osCommand.Cmd)
+
gitCommand := &GitCommand{
Common: cmn,
OSCommand: osCommand,
@@ -76,6 +79,7 @@ func NewGitCommand(
PushToCurrent: pushToCurrent,
GitConfig: gitConfig,
GetCmdWriter: func() io.Writer { return ioutil.Discard },
+ Cmd: cmd,
}
gitCommand.PatchManager = patch.NewPatchManager(gitCommand.Log, gitCommand.ApplyPatch, gitCommand.ShowFileDiff)
@@ -215,44 +219,5 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam
}
func VerifyInGitRepo(osCommand *oscommands.OSCommand) error {
- return osCommand.Run(osCommand.NewCmdObj("git rev-parse --git-dir"))
-}
-
-func (c *GitCommand) Run(cmdObj oscommands.ICmdObj) error {
- _, err := c.RunWithOutput(cmdObj)
- return err
-}
-
-func (c *GitCommand) RunWithOutput(cmdObj oscommands.ICmdObj) (string, error) {
- // TODO: have this retry logic in other places we run the command
- waitTime := 50 * time.Millisecond
- retryCount := 5
- attempt := 0
-
- for {
- output, err := c.OSCommand.RunWithOutput(cmdObj)
- if err != nil {
- // if we have an error based on the index lock, we should wait a bit and then retry
- if strings.Contains(output, ".git/index.lock") {
- c.Log.Error(output)
- c.Log.Info("index.lock prevented command from running. Retrying command after a small wait")
- attempt++
- time.Sleep(waitTime)
- if attempt < retryCount {
- continue
- }
- }
- }
- return output, err
- }
-}
-
-func (c *GitCommand) NewCmdObj(cmdStr string) oscommands.ICmdObj {
- return c.OSCommand.NewCmdObj(cmdStr).AddEnvVars("GIT_OPTIONAL_LOCKS=0")
-}
-
-func (c *GitCommand) NewCmdObjWithLog(cmdStr string) oscommands.ICmdObj {
- cmdObj := c.NewCmdObj(cmdStr)
- c.OSCommand.LogCmdObj(cmdObj)
- return cmdObj
+ return osCommand.Cmd.New("git rev-parse --git-dir").Run()
}
diff --git a/pkg/commands/git_cmd_obj_builder.go b/pkg/commands/git_cmd_obj_builder.go
new file mode 100644
index 000000000..487dd2303
--- /dev/null
+++ b/