mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-15 11:56:37 +02:00
WIP
This commit is contained in:
parent
192a548c99
commit
43a4fa970d
@ -151,7 +151,7 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *App) validateGitVersion() 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
|
// if we get an error anywhere here we'll show the same status
|
||||||
minVersionError := errors.New(app.Tr.MinGitVersionError)
|
minVersionError := errors.New(app.Tr.MinGitVersionError)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -236,7 +236,7 @@ func (app *App) setupRepo() (bool, error) {
|
|||||||
|
|
||||||
os.Exit(1)
|
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
|
return false, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,19 +11,19 @@ import (
|
|||||||
|
|
||||||
// NewBranch create new branch
|
// NewBranch create new branch
|
||||||
func (c *GitCommand) NewBranch(name string, base string) error {
|
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.
|
// CurrentBranchName get the current branch name and displayname.
|
||||||
// the first returned string is the name and the second is the 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)'
|
// e.g. name is 123asdf and displayname is '(HEAD detached at 123asdf)'
|
||||||
func (c *GitCommand) CurrentBranchName() (string, string, error) {
|
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" {
|
if err == nil && branchName != "HEAD\n" {
|
||||||
trimmedBranchName := strings.TrimSpace(branchName)
|
trimmedBranchName := strings.TrimSpace(branchName)
|
||||||
return trimmedBranchName, trimmedBranchName, nil
|
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 {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
@ -47,7 +47,7 @@ func (c *GitCommand) DeleteBranch(branch string, force bool) error {
|
|||||||
command = "git branch -D"
|
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
|
// 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"
|
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
|
// prevents git from prompting us for input which would freeze the program
|
||||||
// TODO: see if this is actually needed here
|
// TODO: see if this is actually needed here
|
||||||
AddEnvVars("GIT_TERMINAL_PROMPT=0").
|
AddEnvVars("GIT_TERMINAL_PROMPT=0").
|
||||||
AddEnvVars(options.EnvVars...)
|
AddEnvVars(options.EnvVars...).
|
||||||
|
Run()
|
||||||
return c.OSCommand.Run(cmdObj)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBranchGraph gets the color-formatted graph of the log for the given branch
|
// 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
|
// Currently it limits the result to 100 commits, but when we get async stuff
|
||||||
// working we can do lazy loading
|
// working we can do lazy loading
|
||||||
func (c *GitCommand) GetBranchGraph(branchName string) (string, error) {
|
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) {
|
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
|
return strings.TrimSpace(output), err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,15 +87,15 @@ func (c *GitCommand) GetBranchGraphCmdObj(branchName string) oscommands.ICmdObj
|
|||||||
templateValues := map[string]string{
|
templateValues := map[string]string{
|
||||||
"branchName": c.OSCommand.Quote(branchName),
|
"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 {
|
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 {
|
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) {
|
func (c *GitCommand) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
|
||||||
@ -111,11 +110,11 @@ func (c *GitCommand) GetBranchUpstreamDifferenceCount(branchName string) (string
|
|||||||
// current branch
|
// current branch
|
||||||
func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
|
func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
|
||||||
command := "git rev-list %s..%s --count"
|
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 {
|
if err != nil {
|
||||||
return "?", "?"
|
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 {
|
if err != nil {
|
||||||
return "?", "?"
|
return "?", "?"
|
||||||
}
|
}
|
||||||
@ -135,37 +134,37 @@ func (c *GitCommand) Merge(branchName string, opts MergeOpts) error {
|
|||||||
command = fmt.Sprintf("%s --ff-only", command)
|
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
|
// AbortMerge abort merge
|
||||||
func (c *GitCommand) AbortMerge() error {
|
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 {
|
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
|
return err != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetHardHead runs `git reset --hard`
|
// ResetHardHead runs `git reset --hard`
|
||||||
func (c *GitCommand) ResetHard(ref string) error {
|
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`
|
// ResetSoft runs `git reset --soft HEAD`
|
||||||
func (c *GitCommand) ResetSoft(ref string) error {
|
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 {
|
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 {
|
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) {
|
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()
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ func TestGitCommandGetAllBranchGraph(t *testing.T) {
|
|||||||
return secureexec.Command("echo")
|
return secureexec.Command("echo")
|
||||||
}
|
}
|
||||||
cmdStr := gitCmd.UserConfig.Git.AllBranchesLogCmd
|
cmdStr := gitCmd.UserConfig.Git.AllBranchesLogCmd
|
||||||
_, err := gitCmd.OSCommand.RunWithOutput(gitCmd.NewCmdObj(cmdStr))
|
_, err := gitCmd.Cmd.New(cmdStr).RunWithOutput()
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,18 +10,17 @@ import (
|
|||||||
|
|
||||||
// RenameCommit renames the topmost commit with the given name
|
// RenameCommit renames the topmost commit with the given name
|
||||||
func (c *GitCommand) RenameCommit(name string) error {
|
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
|
// ResetToCommit reset to commit
|
||||||
func (c *GitCommand) ResetToCommit(sha string, strength string, envVars []string) error {
|
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
|
// prevents git from prompting us for input which would freeze the program
|
||||||
// TODO: see if this is actually needed here
|
// TODO: see if this is actually needed here
|
||||||
AddEnvVars("GIT_TERMINAL_PROMPT=0").
|
AddEnvVars("GIT_TERMINAL_PROMPT=0").
|
||||||
AddEnvVars(envVars...)
|
AddEnvVars(envVars...).
|
||||||
|
Run()
|
||||||
return c.OSCommand.Run(cmdObj)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) CommitCmdObj(message string, flags string) oscommands.ICmdObj {
|
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)
|
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
|
// Get the subject of the HEAD commit
|
||||||
func (c *GitCommand) GetHeadCommitMessage() (string, error) {
|
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
|
return strings.TrimSpace(message), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) GetCommitMessage(commitSha string) (string, error) {
|
func (c *GitCommand) GetCommitMessage(commitSha string) (string, error) {
|
||||||
cmdStr := "git rev-list --format=%B --max-count=1 " + commitSha
|
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")
|
message := strings.Join(strings.SplitAfter(messageWithHeader, "\n")[1:], "\n")
|
||||||
return strings.TrimSpace(message), err
|
return strings.TrimSpace(message), err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) GetCommitMessageFirstLine(sha string) (string, error) {
|
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
|
// AmendHead amends HEAD with whatever is staged in your working tree
|
||||||
func (c *GitCommand) AmendHead() error {
|
func (c *GitCommand) AmendHead() error {
|
||||||
return c.OSCommand.Run(c.AmendHeadCmdObj())
|
return c.AmendHeadCmdObj().Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) AmendHeadCmdObj() oscommands.ICmdObj {
|
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 {
|
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)
|
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
|
// Revert reverts the selected commit by sha
|
||||||
func (c *GitCommand) Revert(sha string) error {
|
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 {
|
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
|
// 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
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.OSCommand.Run(cmd)
|
return cmdObj.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateFixupCommit creates a commit that fixes up a previous commit
|
// CreateFixupCommit creates a commit that fixes up a previous commit
|
||||||
func (c *GitCommand) CreateFixupCommit(sha string) error {
|
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()
|
||||||
}
|
}
|
||||||
|
@ -25,26 +25,26 @@ func (c *GitCommand) CatFile(fileName string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) OpenMergeToolCmdObj() oscommands.ICmdObj {
|
func (c *GitCommand) OpenMergeToolCmdObj() oscommands.ICmdObj {
|
||||||
return c.NewCmdObj("git mergetool")
|
return c.Cmd.New("git mergetool")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) OpenMergeTool() error {
|
func (c *GitCommand) OpenMergeTool() error {
|
||||||
return c.Run(c.OpenMergeToolCmdObj())
|
return c.OpenMergeToolCmdObj().Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StageFile stages a file
|
// StageFile stages a file
|
||||||
func (c *GitCommand) StageFile(fileName string) error {
|
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
|
// StageAll stages all files
|
||||||
func (c *GitCommand) StageAll() error {
|
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
|
// UnstageAll unstages all files
|
||||||
func (c *GitCommand) UnstageAll() error {
|
func (c *GitCommand) UnstageAll() error {
|
||||||
return c.Run(c.NewCmdObj("git reset"))
|
return c.Cmd.New("git reset").Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnStageFile unstages a file
|
// UnStageFile unstages a file
|
||||||
@ -57,8 +57,8 @@ func (c *GitCommand) UnStageFile(fileNames []string, reset bool) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range fileNames {
|
for _, name := range fileNames {
|
||||||
cmdObj := c.NewCmdObj(fmt.Sprintf(command, c.OSCommand.Quote(name)))
|
err := c.Cmd.New(fmt.Sprintf(command, c.OSCommand.Quote(name))).Run()
|
||||||
if err := c.Run(cmdObj); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -122,22 +122,22 @@ func (c *GitCommand) DiscardAllFileChanges(file *models.File) error {
|
|||||||
quotedFileName := c.OSCommand.Quote(file.Name)
|
quotedFileName := c.OSCommand.Quote(file.Name)
|
||||||
|
|
||||||
if file.ShortStatus == "AA" {
|
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
|
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 err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if file.ShortStatus == "DU" {
|
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 the file isn't tracked, we assume you want to delete it
|
||||||
if file.HasStagedChanges || file.HasMergeConflicts {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -163,7 +163,7 @@ func (c *GitCommand) DiscardUnstagedDirChanges(node *filetree.FileNode) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
quotedPath := c.OSCommand.Quote(node.GetPath())
|
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
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +188,7 @@ func (c *GitCommand) RemoveUntrackedDirFiles(node *filetree.FileNode) error {
|
|||||||
// DiscardUnstagedFileChanges directly
|
// DiscardUnstagedFileChanges directly
|
||||||
func (c *GitCommand) DiscardUnstagedFileChanges(file *models.File) error {
|
func (c *GitCommand) DiscardUnstagedFileChanges(file *models.File) error {
|
||||||
quotedFileName := c.OSCommand.Quote(file.Name)
|
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
|
// 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
|
// WorktreeFileDiff returns the diff of a file
|
||||||
func (c *GitCommand) WorktreeFileDiff(file *models.File, plain bool, cached bool, ignoreWhitespace bool) string {
|
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
|
// 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
|
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)
|
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 {
|
func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
|
||||||
@ -240,14 +240,13 @@ func (c *GitCommand) ApplyPatch(patch string, flags ...string) error {
|
|||||||
flagStr += " --" + flag
|
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
|
// 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.
|
// 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) {
|
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.ShowFileDiffCmdObj(from, to, reverse, fileName, plain).RunWithOutput()
|
||||||
return c.RunWithOutput(cmdObj)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) oscommands.ICmdObj {
|
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 "
|
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
|
// CheckoutFile checks out the file for the given commit
|
||||||
func (c *GitCommand) CheckoutFile(commitSha, fileName string) error {
|
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
|
// 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)
|
// 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 {
|
if err := c.OSCommand.Remove(fileName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -300,17 +299,17 @@ func (c *GitCommand) DiscardOldFileChanges(commits []*models.Commit, commitIndex
|
|||||||
|
|
||||||
// DiscardAnyUnstagedFileChanges discards any unstages file changes via `git checkout -- .`
|
// DiscardAnyUnstagedFileChanges discards any unstages file changes via `git checkout -- .`
|
||||||
func (c *GitCommand) DiscardAnyUnstagedFileChanges() error {
|
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
|
// RemoveTrackedFiles will delete the given file(s) even if they are currently tracked
|
||||||
func (c *GitCommand) RemoveTrackedFiles(name string) error {
|
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`
|
// RemoveUntrackedFiles runs `git clean -fd`
|
||||||
func (c *GitCommand) RemoveUntrackedFiles() error {
|
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
|
// 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")
|
editor = c.OSCommand.Getenv("EDITOR")
|
||||||
}
|
}
|
||||||
if 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"
|
editor = "vi"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/go-errors/errors"
|
"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
|
// Coincidentally at the moment it's the same view that OnRunCommand logs to
|
||||||
// but that need not always be the case.
|
// but that need not always be the case.
|
||||||
GetCmdWriter func() io.Writer
|
GetCmdWriter func() io.Writer
|
||||||
|
|
||||||
|
Cmd oscommands.ICmdObjBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewGitCommand it runs git commands
|
// NewGitCommand it runs git commands
|
||||||
@ -68,6 +69,8 @@ func NewGitCommand(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd := NewGitCmdObjBuilder(cmn.Log, osCommand.Cmd)
|
||||||
|
|
||||||
gitCommand := &GitCommand{
|
gitCommand := &GitCommand{
|
||||||
Common: cmn,
|
Common: cmn,
|
||||||
OSCommand: osCommand,
|
OSCommand: osCommand,
|
||||||
@ -76,6 +79,7 @@ func NewGitCommand(
|
|||||||
PushToCurrent: pushToCurrent,
|
PushToCurrent: pushToCurrent,
|
||||||
GitConfig: gitConfig,
|
GitConfig: gitConfig,
|
||||||
GetCmdWriter: func() io.Writer { return ioutil.Discard },
|
GetCmdWriter: func() io.Writer { return ioutil.Discard },
|
||||||
|
Cmd: cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
gitCommand.PatchManager = patch.NewPatchManager(gitCommand.Log, gitCommand.ApplyPatch, gitCommand.ShowFileDiff)
|
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 {
|
func VerifyInGitRepo(osCommand *oscommands.OSCommand) error {
|
||||||
return osCommand.Run(osCommand.NewCmdObj("git rev-parse --git-dir"))
|
return osCommand.Cmd.New("git rev-parse --git-dir").Run()
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
47
pkg/commands/git_cmd_obj_builder.go
Normal file
47
pkg/commands/git_cmd_obj_builder.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// all we're doing here is wrapping the default command object builder with
|
||||||
|
// some git-specific stuff: e.g. adding a git-specific env var
|
||||||
|
|
||||||
|
type gitCmdObjBuilder struct {
|
||||||
|
innerBuilder *oscommands.CmdObjBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ oscommands.ICmdObjBuilder = &gitCmdObjBuilder{}
|
||||||
|
|
||||||
|
func NewGitCmdObjBuilder(log *logrus.Entry, innerBuilder *oscommands.CmdObjBuilder) *gitCmdObjBuilder {
|
||||||
|
// the price of having a convenient interface where we can say .New(...).Run() is that our builder now depends on our runner, so when we want to wrap the default builder/runner in new functionality we need to jump through some hoops. We could avoid the use of a decorator function here by just exporting the runner field on the default builder but that would be misleading because we don't want anybody using that to run commands (i.e. we want there to be a single API used across the codebase)
|
||||||
|
updatedBuilder := innerBuilder.CloneWithNewRunner(func(runner oscommands.ICmdObjRunner) oscommands.ICmdObjRunner {
|
||||||
|
return &gitCmdObjRunner{
|
||||||
|
log: log,
|
||||||
|
innerRunner: runner,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return &gitCmdObjBuilder{
|
||||||
|
innerBuilder: updatedBuilder,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultEnvVar = "GIT_OPTIONAL_LOCKS=0"
|
||||||
|
|
||||||
|
func (self *gitCmdObjBuilder) New(cmdStr string) oscommands.ICmdObj {
|
||||||
|
return self.innerBuilder.New(cmdStr).AddEnvVars(defaultEnvVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *gitCmdObjBuilder) NewFromArgs(args []string) oscommands.ICmdObj {
|
||||||
|
return self.innerBuilder.NewFromArgs(args).AddEnvVars(defaultEnvVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *gitCmdObjBuilder) NewShell(cmdStr string) oscommands.ICmdObj {
|
||||||
|
return self.innerBuilder.NewShell(cmdStr).AddEnvVars(defaultEnvVar)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *gitCmdObjBuilder) Quote(str string) string {
|
||||||
|
return self.innerBuilder.Quote(str)
|
||||||
|
}
|
49
pkg/commands/git_cmd_obj_runner.go
Normal file
49
pkg/commands/git_cmd_obj_runner.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
// here we're wrapping the default command runner in some git-specific stuff e.g. retry logic if we get an error due to the presence of .git/index.lock
|
||||||
|
|
||||||
|
type gitCmdObjRunner struct {
|
||||||
|
log *logrus.Entry
|
||||||
|
innerRunner oscommands.ICmdObjRunner
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *gitCmdObjRunner) Run(cmdObj oscommands.ICmdObj) error {
|
||||||
|
_, err := self.RunWithOutput(cmdObj)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *gitCmdObjRunner) 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 := self.innerRunner.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") {
|
||||||
|
self.log.Error(output)
|
||||||
|
self.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 (self *gitCmdObjRunner) RunLineOutputCmd(cmdObj oscommands.ICmdObj, onLine func(line string) (bool, error)) error {
|
||||||
|
return self.innerRunner.RunLineOutputCmd(cmdObj, onLine)
|
||||||
|
}
|
@ -42,6 +42,51 @@ func NewBranchListBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Build the list of branches for the current repo
|
||||||
|
func (b *BranchListBuilder) Build() []*models.Branch {
|
||||||
|
branches := b.obtainBranches()
|
||||||
|
|
||||||
|
reflogBranches := b.obtainReflogBranches()
|
||||||
|
|
||||||
|
// loop through reflog branches. If there is a match, merge them, then remove it from the branches and keep it in the reflog branches
|
||||||
|
branchesWithRecency := make([]*models.Branch, 0)
|
||||||
|
outer:
|
||||||
|
for _, reflogBranch := range reflogBranches {
|
||||||
|
for j, branch := range branches {
|
||||||
|
if branch.Head {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.EqualFold(reflogBranch.Name, branch.Name) {
|
||||||
|
branch.Recency = reflogBranch.Recency
|
||||||
|
branchesWithRecency = append(branchesWithRecency, branch)
|
||||||
|
branches = append(branches[0:j], branches[j+1:]...)
|
||||||
|
continue outer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
branches = append(branchesWithRecency, branches...)
|
||||||
|
|
||||||
|
foundHead := false
|
||||||
|
for i, branch := range branches {
|
||||||
|
if branch.Head {
|
||||||
|
foundHead = true
|
||||||
|
branch.Recency = " *"
|
||||||
|
branches = append(branches[0:i], branches[i+1:]...)
|
||||||
|
branches = append([]*models.Branch{branch}, branches...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !foundHead {
|
||||||
|
currentBranchName, currentBranchDisplayName, err := b.getCurrentBranchName()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
branches = append([]*models.Branch{{Name: currentBranchName, DisplayName: currentBranchDisplayName, Head: true, Recency: " *"}}, branches...)
|
||||||
|
}
|
||||||
|
return branches
|
||||||
|
}
|
||||||
|
|
||||||
func (b *BranchListBuilder) obtainBranches() []*models.Branch {
|
func (b *BranchListBuilder) obtainBranches() []*models.Branch {
|
||||||
output, err := b.getRawBranches()
|
output, err := b.getRawBranches()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -103,51 +148,6 @@ func (b *BranchListBuilder) obtainBranches() []*models.Branch {
|
|||||||
return branches
|
return branches
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build the list of branches for the current repo
|
|
||||||
func (b *BranchListBuilder) Build() []*models.Branch {
|
|
||||||
branches := b.obtainBranches()
|
|
||||||
|
|
||||||
reflogBranches := b.obtainReflogBranches()
|
|
||||||
|
|
||||||
// loop through reflog branches. If there is a match, merge them, then remove it from the branches and keep it in the reflog branches
|
|
||||||
branchesWithRecency := make([]*models.Branch, 0)
|
|
||||||
outer:
|
|
||||||
for _, reflogBranch := range reflogBranches {
|
|
||||||
for j, branch := range branches {
|
|
||||||
if branch.Head {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if strings.EqualFold(reflogBranch.Name, branch.Name) {
|
|
||||||
branch.Recency = reflogBranch.Recency
|
|
||||||
branchesWithRecency = append(branchesWithRecency, branch)
|
|
||||||
branches = append(branches[0:j], branches[j+1:]...)
|
|
||||||
continue outer
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
branches = append(branchesWithRecency, branches...)
|
|
||||||
|
|
||||||
foundHead := false
|
|
||||||
for i, branch := range branches {
|
|
||||||
if branch.Head {
|
|
||||||
foundHead = true
|
|
||||||
branch.Recency = " *"
|
|
||||||
branches = append(branches[0:i], branches[i+1:]...)
|
|
||||||
branches = append([]*models.Branch{branch}, branches...)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundHead {
|
|
||||||
currentBranchName, currentBranchDisplayName, err := b.getCurrentBranchName()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
branches = append([]*models.Branch{{Name: currentBranchName, DisplayName: currentBranchDisplayName, Head: true, Recency: " *"}}, branches...)
|
|
||||||
}
|
|
||||||
return branches
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: only look at the new reflog commits, and otherwise store the recencies in
|
// TODO: only look at the new reflog commits, and otherwise store the recencies in
|
||||||
// int form against the branch to recalculate the time ago
|
// int form against the branch to recalculate the time ago
|
||||||
func (b *BranchListBuilder) obtainReflogBranches() []*models.Branch {
|
func (b *BranchListBuilder) obtainReflogBranches() []*models.Branch {
|
||||||
|
@ -14,7 +14,7 @@ func (c *GitCommand) GetFilesInDiff(from string, to string, reverse bool) ([]*mo
|
|||||||
reverseFlag = " -R "
|
reverseFlag = " -R "
|
||||||
}
|
}
|
||||||
|
|
||||||
filenames, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git diff --submodule --no-ext-diff --name-status -z --no-renames %s %s %s", reverseFlag, from, to)))
|
filenames, err := c.Cmd.New(fmt.Sprintf("git diff --submodule --no-ext-diff --name-status -z --no-renames %s %s %s", reverseFlag, from, to)).RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,8 @@ import (
|
|||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/common"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||||
"github.com/jesseduffield/lazygit/pkg/i18n"
|
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// context:
|
// context:
|
||||||
@ -29,24 +28,28 @@ const SEPARATION_CHAR = "|"
|
|||||||
|
|
||||||
// CommitListBuilder returns a list of Branch objects for the current repo
|
// CommitListBuilder returns a list of Branch objects for the current repo
|
||||||
type CommitListBuilder struct {
|
type CommitListBuilder struct {
|
||||||
Log *logrus.Entry
|
*common.Common
|
||||||
GitCommand *GitCommand
|
cmd oscommands.ICmdObjBuilder
|
||||||
OSCommand *oscommands.OSCommand
|
|
||||||
Tr *i18n.TranslationSet
|
getCurrentBranchName func() (string, string, error)
|
||||||
|
getRebaseMode func() (string, error)
|
||||||
|
readFile func(filename string) ([]byte, error)
|
||||||
|
dotGitDir string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommitListBuilder builds a new commit list builder
|
// NewCommitListBuilder builds a new commit list builder
|
||||||
func NewCommitListBuilder(
|
func NewCommitListBuilder(
|
||||||
log *logrus.Entry,
|
cmn *common.Common,
|
||||||
gitCommand *GitCommand,
|
gitCommand *GitCommand,
|
||||||
osCommand *oscommands.OSCommand,
|
osCommand *oscommands.OSCommand,
|
||||||
tr *i18n.TranslationSet,
|
|
||||||
) *CommitListBuilder {
|
) *CommitListBuilder {
|
||||||
return &CommitListBuilder{
|
return &CommitListBuilder{
|
||||||
Log: log,
|
Common: cmn,
|
||||||
GitCommand: gitCommand,
|
cmd: gitCommand.Cmd,
|
||||||
OSCommand: osCommand,
|
getCurrentBranchName: gitCommand.CurrentBranchName,
|
||||||
Tr: tr,
|
getRebaseMode: gitCommand.RebaseMode,
|
||||||
|
dotGitDir: gitCommand.DotGitDir,
|
||||||
|
readFile: ioutil.ReadFile,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,7 +109,7 @@ func (c *CommitListBuilder) MergeRebasingCommits(commits []*models.Commit) ([]*m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rebaseMode, err := c.GitCommand.RebaseMode()
|
rebaseMode, err := c.getRebaseMode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -131,7 +134,7 @@ func (c *CommitListBuilder) MergeRebasingCommits(commits []*models.Commit) ([]*m
|
|||||||
func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Commit, error) {
|
func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Commit, error) {
|
||||||
commits := []*models.Commit{}
|
commits := []*models.Commit{}
|
||||||
var rebasingCommits []*models.Commit
|
var rebasingCommits []*models.Commit
|
||||||
rebaseMode, err := c.GitCommand.RebaseMode()
|
rebaseMode, err := c.getRebaseMode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -152,9 +155,7 @@ func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Commit
|
|||||||
passedFirstPushedCommit = true
|
passedFirstPushedCommit = true
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdObj := c.getLogCmd(opts)
|
err = c.getLogCmd(opts).RunLineOutputCmd(func(line string) (bool, error) {
|
||||||
|
|
||||||
err = c.OSCommand.RunLineOutputCmd(cmdObj, func(line string) (bool, error) {
|
|
||||||
if canExtractCommit(line) {
|
if canExtractCommit(line) {
|
||||||
commit := c.extractCommitFromLine(line)
|
commit := c.extractCommitFromLine(line)
|
||||||
if commit.Sha == firstPushedCommit {
|
if commit.Sha == firstPushedCommit {
|
||||||
@ -200,7 +201,7 @@ func (c *CommitListBuilder) getHydratedRebasingCommits(rebaseMode string) ([]*mo
|
|||||||
|
|
||||||
// note that we're not filtering these as we do non-rebasing commits just because
|
// note that we're not filtering these as we do non-rebasing commits just because
|
||||||
// I suspect that will cause some damage
|
// I suspect that will cause some damage
|
||||||
cmdObj := c.OSCommand.NewCmdObj(
|
cmdObj := c.cmd.New(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"git show %s --no-patch --oneline %s --abbrev=%d",
|
"git show %s --no-patch --oneline %s --abbrev=%d",
|
||||||
strings.Join(commitShas, " "),
|
strings.Join(commitShas, " "),
|
||||||
@ -211,7 +212,7 @@ func (c *CommitListBuilder) getHydratedRebasingCommits(rebaseMode string) ([]*mo
|
|||||||
|
|
||||||
hydratedCommits := make([]*models.Commit, 0, len(commits))
|
hydratedCommits := make([]*models.Commit, 0, len(commits))
|
||||||
i := 0
|
i := 0
|
||||||
err = c.OSCommand.RunLineOutputCmd(cmdObj, func(line string) (bool, error) {
|
err = cmdObj.RunLineOutputCmd(func(line string) (bool, error) {
|
||||||
if canExtractCommit(line) {
|
if canExtractCommit(line) {
|
||||||
commit := c.extractCommitFromLine(line)
|
commit := c.extractCommitFromLine(line)
|
||||||
matchingCommit := commits[i]
|
matchingCommit := commits[i]
|
||||||
@ -242,7 +243,7 @@ func (c *CommitListBuilder) getRebasingCommits(rebaseMode string) ([]*models.Com
|
|||||||
|
|
||||||
func (c *CommitListBuilder) getNormalRebasingCommits() ([]*models.Commit, error) {
|
func (c *CommitListBuilder) getNormalRebasingCommits() ([]*models.Commit, error) {
|
||||||
rewrittenCount := 0
|
rewrittenCount := 0
|
||||||
bytesContent, err := ioutil.ReadFile(filepath.Join(c.GitCommand.DotGitDir, "rebase-apply/rewritten"))
|
bytesContent, err := c.readFile(filepath.Join(c.dotGitDir, "rebase-apply/rewritten"))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
content := string(bytesContent)
|
content := string(bytesContent)
|
||||||
rewrittenCount = len(strings.Split(content, "\n"))
|
rewrittenCount = len(strings.Split(content, "\n"))
|
||||||
@ -250,7 +251,7 @@ func (c *CommitListBuilder) getNormalRebasingCommits() ([]*models.Commit, error)
|
|||||||
|
|
||||||
// we know we're rebasing, so lets get all the files whose names have numbers
|
// we know we're rebasing, so lets get all the files whose names have numbers
|
||||||
commits := []*models.Commit{}
|
commits := []*models.Commit{}
|
||||||
err = filepath.Walk(filepath.Join(c.GitCommand.DotGitDir, "rebase-apply"), func(path string, f os.FileInfo, err error) error {
|
err = filepath.Walk(filepath.Join(c.dotGitDir, "rebase-apply"), func(path string, f os.FileInfo, err error) error {
|
||||||
if rewrittenCount > 0 {
|
if rewrittenCount > 0 {
|
||||||
rewrittenCount--
|
rewrittenCount--
|
||||||
return nil
|
return nil
|
||||||
@ -262,7 +263,7 @@ func (c *CommitListBuilder) getNormalRebasingCommits() ([]*models.Commit, error)
|
|||||||
if !re.MatchString(f.Name()) {
|
if !re.MatchString(f.Name()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
bytesContent, err := ioutil.ReadFile(path)
|
bytesContent, err := c.readFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -294,7 +295,7 @@ func (c *CommitListBuilder) getNormalRebasingCommits() ([]*models.Commit, error)
|
|||||||
// and extracts out the sha and names of commits that we still have to go
|
// and extracts out the sha and names of commits that we still have to go
|
||||||
// in the rebase:
|
// in the rebase:
|
||||||
func (c *CommitListBuilder) getInteractiveRebasingCommits() ([]*models.Commit, error) {
|
func (c *CommitListBuilder) getInteractiveRebasingCommits() ([]*models.Commit, error) {
|
||||||
bytesContent, err := ioutil.ReadFile(filepath.Join(c.GitCommand.DotGitDir, "rebase-merge/git-rebase-todo"))
|
bytesContent, err := c.readFile(filepath.Join(c.dotGitDir, "rebase-merge/git-rebase-todo"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Log.Error(fmt.Sprintf("error occurred reading git-rebase-todo: %s", err.Error()))
|
c.Log.Error(fmt.Sprintf("error occurred reading git-rebase-todo: %s", err.Error()))
|
||||||
// we assume an error means the file doesn't exist so we just return
|
// we assume an error means the file doesn't exist so we just return
|
||||||
@ -362,7 +363,7 @@ func (c *CommitListBuilder) setCommitMergedStatuses(refName string, commits []*m
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *CommitListBuilder) getMergeBase(refName string) (string, error) {
|
func (c *CommitListBuilder) getMergeBase(refName string) (string, error) {
|
||||||
currentBranch, _, err := c.GitCommand.CurrentBranchName()
|
currentBranch, _, err := c.getCurrentBranchName()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -373,7 +374,7 @@ func (c *CommitListBuilder) getMergeBase(refName string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// swallowing error because it's not a big deal; probably because there are no commits yet
|
// swallowing error because it's not a big deal; probably because there are no commits yet
|
||||||
output, _ := c.OSCommand.RunWithOutput(c.OSCommand.NewCmdObj(fmt.Sprintf("git merge-base %s %s", c.OSCommand.Quote(refName), c.OSCommand.Quote(baseBranch))))
|
output, _ := c.cmd.New(fmt.Sprintf("git merge-base %s %s", c.cmd.Quote(refName), c.cmd.Quote(baseBranch))).RunWithOutput()
|
||||||
return ignoringWarnings(output), nil
|
return ignoringWarnings(output), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +391,7 @@ func ignoringWarnings(commandOutput string) string {
|
|||||||
// getFirstPushedCommit returns the first commit SHA which has been pushed to the ref's upstream.
|
// getFirstPushedCommit returns the first commit SHA which has been pushed to the ref's upstream.
|
||||||
// all commits above this are deemed unpushed and marked as such.
|
// all commits above this are deemed unpushed and marked as such.
|
||||||
func (c *CommitListBuilder) getFirstPushedCommit(refName string) (string, error) {
|
func (c *CommitListBuilder) getFirstPushedCommit(refName string) (string, error) {
|
||||||
output, err := c.OSCommand.RunWithOutput(c.OSCommand.NewCmdObj(fmt.Sprintf("git merge-base %s %s@{u}", c.OSCommand.Quote(refName), c.OSCommand.Quote(refName))))
|
output, err := c.cmd.New(fmt.Sprintf("git merge-base %s %s@{u}", c.cmd.Quote(refName), c.cmd.Quote(refName))).RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@ -407,10 +408,10 @@ func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj
|
|||||||
|
|
||||||
filterFlag := ""
|
filterFlag := ""
|
||||||
if opts.FilterPath != "" {
|
if opts.FilterPath != "" {
|
||||||
filterFlag = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(opts.FilterPath))
|
filterFlag = fmt.Sprintf(" --follow -- %s", c.cmd.Quote(opts.FilterPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
config := c.GitCommand.UserConfig.Git.Log
|
config := c.UserConfig.Git.Log
|
||||||
|
|
||||||
orderFlag := "--" + config.Order
|
orderFlag := "--" + config.Order
|
||||||
allFlag := ""
|
allFlag := ""
|
||||||
@ -418,10 +419,10 @@ func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj
|
|||||||
allFlag = " --all"
|
allFlag = " --all"
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.OSCommand.NewCmdObj(
|
return c.cmd.New(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"git log %s %s %s --oneline %s %s --abbrev=%d %s",
|
"git log %s %s %s --oneline %s %s --abbrev=%d %s",
|
||||||
c.OSCommand.Quote(opts.RefName),
|
c.cmd.Quote(opts.RefName),
|
||||||
orderFlag,
|
orderFlag,
|
||||||
allFlag,
|
allFlag,
|
||||||
prettyFormat,
|
prettyFormat,
|
||||||
|
@ -80,7 +80,7 @@ func (c *GitCommand) GitStatus(opts GitStatusOptions) ([]FileStatus, error) {
|
|||||||
noRenamesFlag = "--no-renames"
|
noRenamesFlag = "--no-renames"
|
||||||
}
|
}
|
||||||
|
|
||||||
statusLines, err := c.RunWithOutput(c.NewCmdObj(fmt.Sprintf("git status %s --porcelain -z %s", opts.UntrackedFilesArg, noRenamesFlag)))
|
statusLines, err := c.Cmd.New(fmt.Sprintf("git status %s --porcelain -z %s", opts.UntrackedFilesArg, noRenamesFlag)).RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []FileStatus{}, err
|
return []FileStatus{}, err
|
||||||
}
|
}
|
||||||
|
@ -18,9 +18,9 @@ func (c *GitCommand) GetReflogCommits(lastReflogCommit *models.Commit, filterPat
|
|||||||
filterPathArg = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(filterPath))
|
filterPathArg = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(filterPath))
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdObj := c.OSCommand.NewCmdObj(fmt.Sprintf(`git log -g --abbrev=20 --format="%%h %%ct %%gs" %s`, filterPathArg))
|
cmdObj := c.OSCommand.Cmd.New(fmt.Sprintf(`git log -g --abbrev=20 --format="%%h %%ct %%gs" %s`, filterPathArg))
|
||||||
onlyObtainedNewReflogCommits := false
|
onlyObtainedNewReflogCommits := false
|
||||||
err := c.OSCommand.RunLineOutputCmd(cmdObj, func(line string) (bool, error) {
|
err := cmdObj.RunLineOutputCmd(func(line string) (bool, error) {
|
||||||
fields := strings.SplitN(line, " ", 3)
|
fields := strings.SplitN(line, " ", 3)
|
||||||
if len(fields) <= 2 {
|
if len(fields) <= 2 {
|
||||||
return false, nil
|
return false, nil
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *GitCommand) GetRemotes() ([]*models.Remote, error) {
|
func (c *GitCommand) GetRemotes() ([]*models.Remote, error) {
|
||||||
remoteBranchesStr, err := c.RunWithOutput(c.NewCmdObj("git branch -r"))
|
remoteBranchesStr, err := c.Cmd.New("git branch -r").RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *GitCommand) getUnfilteredStashEntries() []*models.StashEntry {
|
func (c *GitCommand) getUnfilteredStashEntries() []*models.StashEntry {
|
||||||
rawString, _ := c.RunWithOutput(c.NewCmdObj("git stash list --pretty='%gs'"))
|
rawString, _ := c.Cmd.New("git stash list --pretty='%gs'").RunWithOutput()
|
||||||
stashEntries := []*models.StashEntry{}
|
stashEntries := []*models.StashEntry{}
|
||||||
for i, line := range utils.SplitLines(rawString) {
|
for i, line := range utils.SplitLines(rawString) {
|
||||||
stashEntries = append(stashEntries, stashEntryFromLine(line, i))
|
stashEntries = append(stashEntries, stashEntryFromLine(line, i))
|
||||||
@ -24,7 +24,7 @@ func (c *GitCommand) GetStashEntries(filterPath string) []*models.StashEntry {
|
|||||||
return c.getUnfilteredStashEntries()
|
return c.getUnfilteredStashEntries()
|
||||||
}
|
}
|
||||||
|
|
||||||
rawString, err := c.RunWithOutput(c.NewCmdObj("git stash list --name-only"))
|
rawString, err := c.Cmd.New("git stash list --name-only").RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.getUnfilteredStashEntries()
|
return c.getUnfilteredStashEntries()
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import (
|
|||||||
func (c *GitCommand) GetTags() ([]*models.Tag, error) {
|
func (c *GitCommand) GetTags() ([]*models.Tag, error) {
|
||||||
// get remote branches, sorted by creation date (descending)
|
// get remote branches, sorted by creation date (descending)
|
||||||
// see: https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortltkeygt
|
// see: https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortltkeygt
|
||||||
remoteBranchesStr, err := c.OSCommand.RunWithOutput(c.NewCmdObj(`git tag --list --sort=-creatordate`))
|
remoteBranchesStr, err := c.Cmd.New(`git tag --list --sort=-creatordate`).RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -5,18 +5,27 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// A command object is a general way to represent a command to be run on the
|
// A command object is a general way to represent a command to be run on the
|
||||||
// command line. If you want to log the command you'll use .ToString() and
|
// command line.
|
||||||
// if you want to run it you'll use .GetCmd()
|
|
||||||
type ICmdObj interface {
|
type ICmdObj interface {
|
||||||
GetCmd() *exec.Cmd
|
GetCmd() *exec.Cmd
|
||||||
ToString() string
|
ToString() string
|
||||||
AddEnvVars(...string) ICmdObj
|
AddEnvVars(...string) ICmdObj
|
||||||
GetEnvVars() []string
|
GetEnvVars() []string
|
||||||
|
|
||||||
|
Run() error
|
||||||
|
RunWithOutput() (string, error)
|
||||||
|
RunLineOutputCmd(onLine func(line string) (bool, error)) error
|
||||||
|
|
||||||
|
// logs command
|
||||||
|
Log() ICmdObj
|
||||||
}
|
}
|
||||||
|
|
||||||
type CmdObj struct {
|
type CmdObj struct {
|
||||||
cmdStr string
|
cmdStr string
|
||||||
cmd *exec.Cmd
|
cmd *exec.Cmd
|
||||||
|
|
||||||
|
runner ICmdObjRunner
|
||||||
|
logCommand func(ICmdObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CmdObj) GetCmd() *exec.Cmd {
|
func (self *CmdObj) GetCmd() *exec.Cmd {
|
||||||
@ -36,3 +45,21 @@ func (self *CmdObj) AddEnvVars(vars ...string) ICmdObj {
|
|||||||
func (self *CmdObj) GetEnvVars() []string {
|
func (self *CmdObj) GetEnvVars() []string {
|
||||||
return self.cmd.Env
|
return self.cmd.Env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *CmdObj) Log() ICmdObj {
|
||||||
|
self.logCommand(self)
|
||||||
|
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObj) Run() error {
|
||||||
|
return self.runner.Run(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObj) RunWithOutput() (string, error) {
|
||||||
|
return self.runner.RunWithOutput(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObj) RunLineOutputCmd(onLine func(line string) (bool, error)) error {
|
||||||
|
return self.runner.RunLineOutputCmd(self, onLine)
|
||||||
|
}
|
||||||
|
72
pkg/commands/oscommands/cmd_obj_builder.go
Normal file
72
pkg/commands/oscommands/cmd_obj_builder.go
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
package oscommands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/mgutz/str"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ICmdObjBuilder interface {
|
||||||
|
// New returns a new command object based on the string provided
|
||||||
|
New(cmdStr string) ICmdObj
|
||||||
|
// NewShell takes a string like `git commit` and returns an executable shell command for it e.g. `sh -c 'git commit'`
|
||||||
|
NewShell(commandStr string) ICmdObj
|
||||||
|
// NewFromArgs takes a slice of strings like []string{"git", "commit"} and returns a new command object. This can be useful when you don't want to worry about whitespace and quoting and stuff.
|
||||||
|
NewFromArgs(args []string) ICmdObj
|
||||||
|
// Quote wraps a string in quotes with any necessary escaping applied. The reason for bundling this up with the other methods in this interface is that we basically always need to make use of this when creating new command objects.
|
||||||
|
Quote(str string) string
|
||||||
|
}
|
||||||
|
|
||||||
|
// poor man's version of explicitly saying that struct X implements interface Y
|
||||||
|
var _ ICmdObjBuilder = &CmdObjBuilder{}
|
||||||
|
|
||||||
|
type CmdObjBuilder struct {
|
||||||
|
runner ICmdObjRunner
|
||||||
|
logCmdObj func(ICmdObj)
|
||||||
|
// TODO: see if you can just remove this entirely and use secureexec.Command,
|
||||||
|
// now that we're mocking out the runner itself.
|
||||||
|
command func(string, ...string) *exec.Cmd
|
||||||
|
platform *Platform
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObjBuilder) New(cmdStr string) ICmdObj {
|
||||||
|
args := str.ToArgv(cmdStr)
|
||||||
|
cmd := self.command(args[0], args[1:]...)
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
|
||||||
|
return &CmdObj{
|
||||||
|
cmdStr: cmdStr,
|
||||||
|
cmd: cmd,
|
||||||
|
runner: self.runner,
|
||||||
|
logCommand: self.logCmdObj,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObjBuilder) NewFromArgs(args []string) ICmdObj {
|
||||||
|
cmd := self.command(args[0], args[1:]...)
|
||||||
|
cmd.Env = os.Environ()
|
||||||
|
|
||||||
|
return &CmdObj{
|
||||||
|
cmdStr: strings.Join(args, " "),
|
||||||
|
cmd: cmd,
|
||||||
|
runner: self.runner,
|
||||||
|
logCommand: self.logCmdObj,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObjBuilder) NewShell(commandStr string) ICmdObj {
|
||||||
|
return self.NewFromArgs([]string{self.platform.Shell, self.platform.ShellArg, commandStr})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObjBuilder) CloneWithNewRunner(decorate func(ICmdObjRunner) ICmdObjRunner) *CmdObjBuilder {
|
||||||
|
decoratedRunner := decorate(self.runner)
|
||||||
|
|
||||||
|
return &CmdObjBuilder{
|
||||||
|
runner: decoratedRunner,
|
||||||
|
logCmdObj: self.logCmdObj,
|
||||||
|
command: self.command,
|
||||||
|
platform: self.platform,
|
||||||
|
}
|
||||||
|
}
|
79
pkg/commands/oscommands/cmd_obj_runner.go
Normal file
79
pkg/commands/oscommands/cmd_obj_runner.go
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
package oscommands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
|
||||||
|
"github.com/go-errors/errors"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
|
"github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ICmdObjRunner interface {
|
||||||
|
Run(cmdObj ICmdObj) error
|
||||||
|
RunWithOutput(cmdObj ICmdObj) (string, error)
|
||||||
|
RunLineOutputCmd(cmdObj ICmdObj, onLine func(line string) (bool, error)) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type RunExpectation func(ICmdObj) (string, error)
|
||||||
|
|
||||||
|
type RealRunner struct {
|
||||||
|
log *logrus.Entry
|
||||||
|
logCmdObj func(ICmdObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *RealRunner) Run(cmdObj ICmdObj) error {
|
||||||
|
_, err := self.RunWithOutput(cmdObj)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *RealRunner) RunWithOutput(cmdObj ICmdObj) (string, error) {
|
||||||
|
self.logCmdObj(cmdObj)
|
||||||
|
output, err := sanitisedCommandOutput(cmdObj.GetCmd().CombinedOutput())
|
||||||
|
if err != nil {
|
||||||
|
self.log.WithField("command", cmdObj.ToString()).Error(output)
|
||||||
|
}
|
||||||
|
return output, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *RealRunner) RunLineOutputCmd(cmdObj ICmdObj, onLine func(line string) (bool, error)) error {
|
||||||
|
cmd := cmdObj.GetCmd()
|
||||||
|
stdoutPipe, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(stdoutPipe)
|
||||||
|
scanner.Split(bufio.ScanLines)
|
||||||
|
if err := cmd.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for scanner.Scan() {
|
||||||
|
line := scanner.Text()
|
||||||
|
stop, err := onLine(line)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if stop {
|
||||||
|
_ = cmd.Process.Kill()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = cmd.Wait()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
||||||
|
outputString := string(output)
|
||||||
|
if err != nil {
|
||||||
|
// errors like 'exit status 1' are not very useful so we'll create an error
|
||||||
|
// from the combined output
|
||||||
|
if outputString == "" {
|
||||||
|
return "", utils.WrapError(err)
|
||||||
|
}
|
||||||
|
return outputString, errors.New(outputString)
|
||||||
|
}
|
||||||
|
return outputString, nil
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package oscommands
|
package oscommands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -16,7 +15,6 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/common"
|
"github.com/jesseduffield/lazygit/pkg/common"
|
||||||
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
"github.com/jesseduffield/lazygit/pkg/secureexec"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
"github.com/mgutz/str"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Platform stores the os state
|
// Platform stores the os state
|
||||||
@ -55,7 +53,7 @@ type OSCommand struct {
|
|||||||
|
|
||||||
removeFile func(string) error
|
removeFile func(string) error
|
||||||
|
|
||||||
IRunner
|
Cmd *CmdObjBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: make these fields private
|
// TODO: make these fields private
|
||||||
@ -90,15 +88,20 @@ func NewCmdLogEntry(cmdStr string, span string, commandLine bool) CmdLogEntry {
|
|||||||
|
|
||||||
// NewOSCommand os command runner
|
// NewOSCommand os command runner
|
||||||
func NewOSCommand(common *common.Common) *OSCommand {
|
func NewOSCommand(common *common.Common) *OSCommand {
|
||||||
|
command := secureexec.Command
|
||||||
|
platform := getPlatform()
|
||||||
|
|
||||||
c := &OSCommand{
|
c := &OSCommand{
|
||||||
Common: common,
|
Common: common,
|
||||||
Platform: getPlatform(),
|
Platform: platform,
|
||||||
Command: secureexec.Command,
|
Command: command,
|
||||||
Getenv: os.Getenv,
|
Getenv: os.Getenv,
|
||||||
removeFile: os.RemoveAll,
|
removeFile: os.RemoveAll,
|
||||||
}
|
}
|
||||||
|
|
||||||
c.IRunner = &RealRunner{c: c}
|
runner := &RealRunner{log: common.Log, logCmdObj: c.LogCmdObj}
|
||||||
|
c.Cmd = &CmdObjBuilder{runner: runner, command: command, logCmdObj: c.LogCmdObj, platform: platform}
|
||||||
|
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,8 +165,7 @@ func (c *OSCommand) OpenFile(filename string) error {
|
|||||||
"filename": c.Quote(filename),
|
"filename": c.Quote(filename),
|
||||||
}
|
}
|
||||||
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
||||||
err := c.Run(c.NewShellCmdObjFromString(command))
|
return c.Cmd.NewShell(command).Run()
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenLink opens a file with the given
|
// OpenLink opens a file with the given
|
||||||
@ -175,14 +177,17 @@ func (c *OSCommand) OpenLink(link string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
command := utils.ResolvePlaceholderString(commandTemplate, templateValues)
|
||||||
err := c.Run(c.NewShellCmdObjFromString(command))
|
return c.Cmd.NewShell(command).Run()
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quote wraps a message in platform-specific quotation marks
|
// Quote wraps a message in platform-specific quotation marks
|
||||||
func (c *OSCommand) Quote(message string) string {
|
func (c *OSCommand) Quote(message string) string {
|
||||||
|
return c.Cmd.Quote(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CmdObjBuilder) Quote(message string) string {
|
||||||
var quote string
|
var quote string
|
||||||
if c.Platform.OS == "windows" {
|
if self.platform.OS == "windows" {
|
||||||
quote = `\"`
|
quote = `\"`
|
||||||
message = strings.NewReplacer(
|
message = strings.NewReplacer(
|
||||||
`"`, `"'"'"`,
|
`"`, `"'"'"`,
|
||||||
@ -289,7 +294,7 @@ func (c *OSCommand) PipeCommands(commandStrings ...string) error {
|
|||||||
logCmdStr += " | "
|
logCmdStr += " | "
|
||||||
}
|
}
|
||||||
logCmdStr += str
|
logCmdStr += str
|
||||||
cmds[i] = c.NewCmdObj(str).GetCmd()
|
cmds[i] = c.Cmd.New(str).GetCmd()
|
||||||
}
|
}
|
||||||
c.LogCommand(logCmdStr, true)
|
c.LogCommand(logCmdStr, true)
|
||||||
|
|
||||||
@ -365,127 +370,6 @@ func (c *OSCommand) RemoveFile(path string) error {
|
|||||||
return c.removeFile(path)
|
return c.removeFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// builders
|
|
||||||
|
|
||||||
func (c *OSCommand) NewCmdObj(cmdStr string) ICmdObj {
|
|
||||||
args := str.ToArgv(cmdStr)
|
|
||||||
cmd := c.Command(args[0], args[1:]...)
|
|
||||||
cmd.Env = os.Environ()
|
|
||||||
|
|
||||||
return &CmdObj{
|
|
||||||
cmdStr: cmdStr,
|
|
||||||
cmd: cmd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *OSCommand) NewCmdObjFromArgs(args []string) ICmdObj {
|
|
||||||
cmd := c.Command(args[0], args[1:]...)
|
|
||||||
cmd.Env = os.Environ()
|
|
||||||
|
|
||||||
return &CmdObj{
|
|
||||||
cmdStr: strings.Join(args, " "),
|
|
||||||
cmd: cmd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewShellCmdObjFromString takes a string like `git commit` and returns an executable shell command for it
|
|
||||||
func (c *OSCommand) NewShellCmdObjFromString(commandStr string) ICmdObj {
|
|
||||||
quotedCommand := ""
|
|
||||||
// Windows does not seem to like quotes around the command
|
|
||||||
if c.Platform.OS == "windows" {
|
|
||||||
quotedCommand = strings.NewReplacer(
|
|
||||||
"^", "^^",
|
|
||||||
"&", "^&",
|
|
||||||
"|", "^|",
|
|
||||||
"<", "^<",
|
|
||||||
">", "^>",
|
|
||||||
"%", "^%",
|
|
||||||
).Replace(commandStr)
|
|
||||||
} else {
|
|
||||||
quotedCommand = c.Quote(commandStr)
|
|
||||||
}
|
|
||||||
|
|
||||||
shellCommand := fmt.Sprintf("%s %s %s", c.Platform.Shell, c.Platform.ShellArg, quotedCommand)
|
|
||||||
return c.NewCmdObj(shellCommand)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: pick one of NewShellCmdObjFromString2 and ShellCommandFromString to use. I'm not sure
|
|
||||||
// which one actually is better, but I suspect it's NewShellCmdObjFromString2
|
|
||||||
func (c *OSCommand) NewShellCmdObjFromString2(command string) ICmdObj {
|
|
||||||
return c.NewCmdObjFromArgs([]string{c.Platform.Shell, c.Platform.ShellArg, command})
|
|
||||||
}
|
|
||||||
|
|
||||||
// runners
|
|
||||||
|
|
||||||
type IRunner interface {
|
|
||||||
Run(cmdObj ICmdObj) error
|
|
||||||
RunWithOutput(cmdObj ICmdObj) (string, error)
|
|
||||||
RunLineOutputCmd(cmdObj ICmdObj, onLine func(line string) (bool, error)) error
|
|
||||||
}
|
|
||||||
|
|
||||||
type RunExpectation func(ICmdObj) (string, error)
|
|
||||||
|
|
||||||
type RealRunner struct {
|
|
||||||
c *OSCommand
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *RealRunner) Run(cmdObj ICmdObj) error {
|
|
||||||
_, err := self.RunWithOutput(cmdObj)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *RealRunner) RunWithOutput(cmdObj ICmdObj) (string, error) {
|
|
||||||
self.c.LogCmdObj(cmdObj)
|
|
||||||
output, err := sanitisedCommandOutput(cmdObj.GetCmd().CombinedOutput())
|
|
||||||
if err != nil {
|
|
||||||
self.c.Log.WithField("command", cmdObj.ToString()).Error(output)
|
|
||||||
}
|
|
||||||
return output, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *RealRunner) RunLineOutputCmd(cmdObj ICmdObj, onLine func(line string) (bool, error)) error {
|
|
||||||
cmd := cmdObj.GetCmd()
|
|
||||||
stdoutPipe, err := cmd.StdoutPipe()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
scanner := bufio.NewScanner(stdoutPipe)
|
|
||||||
scanner.Split(bufio.ScanLines)
|
|
||||||
if err := cmd.Start(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for scanner.Scan() {
|
|
||||||
line := scanner.Text()
|
|
||||||
stop, err := onLine(line)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if stop {
|
|
||||||
_ = cmd.Process.Kill()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ = cmd.Wait()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func sanitisedCommandOutput(output []byte, err error) (string, error) {
|
|
||||||
outputString := string(output)
|
|
||||||
if err != nil {
|
|
||||||
// errors like 'exit status 1' are not very useful so we'll create an error
|
|
||||||
// from the combined output
|
|
||||||
if outputString == "" {
|
|
||||||
return "", utils.WrapError(err)
|
|
||||||
}
|
|
||||||
return outputString, errors.New(outputString)
|
|
||||||
}
|
|
||||||
return outputString, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTempDir() string {
|
func GetTempDir() string {
|
||||||
return filepath.Join(os.TempDir(), "lazygit")
|
return filepath.Join(os.TempDir(), "lazygit")
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ func TestOSCommandRunWithOutput(t *testing.T) {
|
|||||||
|
|
||||||
for _, s := range scenarios {
|
for _, s := range scenarios {
|
||||||
c := NewDummyOSCommand()
|
c := NewDummyOSCommand()
|
||||||
s.test(NewDummyOSCommand().RunWithOutput(c.NewCmdObj(s.command)))
|
s.test(c.Cmd.New(s.command).RunWithOutput())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ func TestOSCommandRun(t *testing.T) {
|
|||||||
|
|
||||||
for _, s := range scenarios {
|
for _, s := range scenarios {
|
||||||
c := NewDummyOSCommand()
|
c := NewDummyOSCommand()
|
||||||
s.test(c.Run(c.NewCmdObj(s.command)))
|
s.test(c.Cmd.New(s.command)).Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,12 +85,12 @@ func (c *GitCommand) MovePatchToSelectedCommit(commits []*models.Commit, sourceC
|
|||||||
todo = a + " " + commit.Sha + " " + commit.Name + "\n" + todo
|
todo = a + " " + commit.Sha + " " + commit.Name + "\n" + todo
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, err := c.PrepareInteractiveRebaseCommand(commits[baseIndex].Sha, todo, true)
|
cmdObj, err := c.PrepareInteractiveRebaseCommand(commits[baseIndex].Sha, todo, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.OSCommand.Run(cmd); err != nil {
|
if err := cmdObj.Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,7 +217,7 @@ func (c *GitCommand) PullPatchIntoNewCommit(commits []*models.Commit, commitIdx
|
|||||||
|
|
||||||
head_message, _ := c.GetHeadCommitMessage()
|
head_message, _ := c.GetHeadCommitMessage()
|
||||||
new_message := fmt.Sprintf("Split from \"%s\"", head_message)
|
new_message := fmt.Sprintf("Split from \"%s\"", head_message)
|
||||||
err := c.OSCommand.Run(c.CommitCmdObj(new_message, ""))
|
err := c.CommitCmdObj(new_message, "").Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -33,12 +33,12 @@ func (c *GitCommand) MoveCommitDown(commits []*models.Commit, index int) error {
|
|||||||
todo = "pick " + commit.Sha + " " + commit.Name + "\n" + todo
|
todo = "pick " + commit.Sha + " " + commit.Name + "\n" + todo
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, err := c.PrepareInteractiveRebaseCommand(commits[index+2].Sha, todo, true)
|
cmdObj, err := c.PrepareInteractiveRebaseCommand(commits[index+2].Sha, todo, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.OSCommand.Run(cmd)
|
return cmdObj.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) InteractiveRebase(commits []*models.Commit, index int, action string) error {
|
func (c *GitCommand) InteractiveRebase(commits []*models.Commit, index int, action string) error {
|
||||||
@ -47,12 +47,12 @@ func (c *GitCommand) InteractiveRebase(commits []*models.Commit, index int, acti
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, err := c.PrepareInteractiveRebaseCommand(sha, todo, true)
|
cmdObj, err := c.PrepareInteractiveRebaseCommand(sha, todo, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.OSCommand.Run(cmd)
|
return cmdObj.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrepareInteractiveRebaseCommand returns the cmd for an interactive rebase
|
// PrepareInteractiveRebaseCommand returns the cmd for an interactive rebase
|
||||||
@ -69,7 +69,7 @@ func (c *GitCommand) PrepareInteractiveRebaseCommand(baseSha string, todo string
|
|||||||
cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty %s", baseSha)
|
cmdStr := fmt.Sprintf("git rebase --interactive --autostash --keep-empty %s", baseSha)
|
||||||
c.Log.WithField("command", cmdStr).Info("RunCommand")
|
c.Log.WithField("command", cmdStr).Info("RunCommand")
|
||||||
|
|
||||||
cmdObj := c.NewCmdObj(cmdStr)
|
cmdObj := c.Cmd.New(cmdStr)
|
||||||
|
|
||||||
gitSequenceEditor := ex
|
gitSequenceEditor := ex
|
||||||
if todo == "" {
|
if todo == "" {
|
||||||
@ -217,26 +217,22 @@ func (c *GitCommand) BeginInteractiveRebaseForCommit(commits []*models.Commit, c
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd, err := c.PrepareInteractiveRebaseCommand(sha, todo, true)
|
cmdObj, err := c.PrepareInteractiveRebaseCommand(sha, todo, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.OSCommand.Run(cmd); err != nil {
|
return cmdObj.Run()
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RebaseBranch interactive rebases onto a branch
|
// RebaseBranch interactive rebases onto a branch
|
||||||
func (c *GitCommand) RebaseBranch(branchName string) error {
|
func (c *GitCommand) RebaseBranch(branchName string) error {
|
||||||
cmd, err := c.PrepareInteractiveRebaseCommand(branchName, "", false)
|
cmdObj, err := c.PrepareInteractiveRebaseCommand(branchName, "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.OSCommand.Run(cmd)
|
return cmdObj.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenericMerge takes a commandType of "merge" or "rebase" and a command of "abort", "skip" or "continue"
|
// GenericMerge takes a commandType of "merge" or "rebase" and a command of "abort", "skip" or "continue"
|
||||||
@ -271,13 +267,14 @@ func (c *GitCommand) GenericMergeOrRebaseAction(commandType string, command stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) runSkipEditorCommand(command string) error {
|
func (c *GitCommand) runSkipEditorCommand(command string) error {
|
||||||
cmdObj := c.OSCommand.NewCmdObj(command)
|
cmdObj := c.OSCommand.Cmd.New(command)
|
||||||
lazyGitPath := c.OSCommand.GetLazygitPath()
|
lazyGitPath := c.OSCommand.GetLazygitPath()
|
||||||
cmdObj.AddEnvVars(
|
return cmdObj.
|
||||||
"LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY",
|
AddEnvVars(
|
||||||
"GIT_EDITOR="+lazyGitPath,
|
"LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY",
|
||||||
"EDITOR="+lazyGitPath,
|
"GIT_EDITOR="+lazyGitPath,
|
||||||
"VISUAL="+lazyGitPath,
|
"EDITOR="+lazyGitPath,
|
||||||
)
|
"VISUAL="+lazyGitPath,
|
||||||
return c.OSCommand.Run(cmdObj)
|
).
|
||||||
|
Run()
|
||||||
}
|
}
|
||||||
|
@ -7,24 +7,24 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *GitCommand) AddRemote(name string, url string) error {
|
func (c *GitCommand) AddRemote(name string, url string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote add %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(url))))
|
return c.Cmd.New(fmt.Sprintf("git remote add %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(url))).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) RemoveRemote(name string) error {
|
func (c *GitCommand) RemoveRemote(name string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote remove %s", c.OSCommand.Quote(name))))
|
return c.Cmd.New(fmt.Sprintf("git remote remove %s", c.OSCommand.Quote(name))).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) RenameRemote(oldRemoteName string, newRemoteName string) error {
|
func (c *GitCommand) RenameRemote(oldRemoteName string, newRemoteName string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote rename %s %s", c.OSCommand.Quote(oldRemoteName), c.OSCommand.Quote(newRemoteName))))
|
return c.Cmd.New(fmt.Sprintf("git remote rename %s %s", c.OSCommand.Quote(oldRemoteName), c.OSCommand.Quote(newRemoteName))).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) UpdateRemoteUrl(remoteName string, updatedUrl string) error {
|
func (c *GitCommand) UpdateRemoteUrl(remoteName string, updatedUrl string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git remote set-url %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(updatedUrl))))
|
return c.Cmd.New(fmt.Sprintf("git remote set-url %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(updatedUrl))).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) DeleteRemoteBranch(remoteName string, branchName string, promptUserForCredential func(string) string) error {
|
func (c *GitCommand) DeleteRemoteBranch(remoteName string, branchName string, promptUserForCredential func(string) string) error {
|
||||||
command := fmt.Sprintf("git push %s --delete %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(branchName))
|
command := fmt.Sprintf("git push %s --delete %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(branchName))
|
||||||
cmdObj := c.NewCmdObj(command)
|
cmdObj := c.Cmd.New(command)
|
||||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,10 +34,10 @@ func (c *GitCommand) DetectUnamePass(cmdObj oscommands.ICmdObj, promptUserForCre
|
|||||||
|
|
||||||
// CheckRemoteBranchExists Returns remote branch
|
// CheckRemoteBranchExists Returns remote branch
|
||||||
func (c *GitCommand) CheckRemoteBranchExists(branchName string) bool {
|
func (c *GitCommand) CheckRemoteBranchExists(branchName string) bool {
|
||||||
_, err := c.RunWithOutput(c.NewCmdObj(
|
_, err := c.Cmd.New(
|
||||||
fmt.Sprintf("git show-ref --verify -- refs/remotes/origin/%s",
|
fmt.Sprintf("git show-ref --verify -- refs/remotes/origin/%s",
|
||||||
c.OSCommand.Quote(branchName),
|
c.OSCommand.Quote(branchName),
|
||||||
)))
|
)).RunWithOutput()
|
||||||
|
|
||||||
return err == nil
|
return err == nil
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import "fmt"
|
|||||||
|
|
||||||
// StashDo modify stash
|
// StashDo modify stash
|
||||||
func (c *GitCommand) StashDo(index int, method string) error {
|
func (c *GitCommand) StashDo(index int, method string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git stash %s stash@{%d}", method, index)))
|
return c.Cmd.New(fmt.Sprintf("git stash %s stash@{%d}", method, index)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// StashSave save stash
|
// StashSave save stash
|
||||||
// TODO: before calling this, check if there is anything to save
|
// TODO: before calling this, check if there is anything to save
|
||||||
func (c *GitCommand) StashSave(message string) error {
|
func (c *GitCommand) StashSave(message string) error {
|
||||||
return c.Run(c.NewCmdObj("git stash save " + c.OSCommand.Quote(message)))
|
return c.Cmd.New("git stash save " + c.OSCommand.Quote(message)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetStashEntryDiff stash diff
|
// GetStashEntryDiff stash diff
|
||||||
@ -22,7 +22,7 @@ func (c *GitCommand) ShowStashEntryCmdStr(index int) string {
|
|||||||
// shoutouts to Joe on https://stackoverflow.com/questions/14759748/stashing-only-staged-changes-in-git-is-it-possible
|
// shoutouts to Joe on https://stackoverflow.com/questions/14759748/stashing-only-staged-changes-in-git-is-it-possible
|
||||||
func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
||||||
// wrap in 'writing', which uses a mutex
|
// wrap in 'writing', which uses a mutex
|
||||||
if err := c.Run(c.NewCmdObj("git stash --keep-index")); err != nil {
|
if err := c.Cmd.New("git stash --keep-index").Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Run(c.NewCmdObj("git stash apply stash@{1}")); err != nil {
|
if err := c.Cmd.New("git stash apply stash@{1}").Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ func (c *GitCommand) StashSaveStagedChanges(message string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Run(c.NewCmdObj("git stash drop stash@{1}")); err != nil {
|
if err := c.Cmd.New("git stash drop stash@{1}").Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,28 +71,28 @@ func (c *GitCommand) SubmoduleStash(submodule *models.SubmoduleConfig) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.Run(c.NewCmdObj("git -C " + c.OSCommand.Quote(submodule.Path) + " stash --include-untracked"))
|
return c.Cmd.New("git -C " + c.OSCommand.Quote(submodule.Path) + " stash --include-untracked").Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleReset(submodule *models.SubmoduleConfig) error {
|
func (c *GitCommand) SubmoduleReset(submodule *models.SubmoduleConfig) error {
|
||||||
return c.Run(c.NewCmdObj("git submodule update --init --force -- " + c.OSCommand.Quote(submodule.Path)))
|
return c.Cmd.New("git submodule update --init --force -- " + c.OSCommand.Quote(submodule.Path)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleUpdateAll() error {
|
func (c *GitCommand) SubmoduleUpdateAll() error {
|
||||||
// not doing an --init here because the user probably doesn't want that
|
// not doing an --init here because the user probably doesn't want that
|
||||||
return c.Run(c.NewCmdObj("git submodule update --force"))
|
return c.Cmd.New("git submodule update --force").Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
||||||
// based on https://gist.github.com/myusuf3/7f645819ded92bda6677
|
// based on https://gist.github.com/myusuf3/7f645819ded92bda6677
|
||||||
|
|
||||||
if err := c.Run(c.NewCmdObj("git submodule deinit --force -- " + c.OSCommand.Quote(submodule.Path))); err != nil {
|
if err := c.Cmd.New("git submodule deinit --force -- " + c.OSCommand.Quote(submodule.Path)).Run(); err != nil {
|
||||||
if strings.Contains(err.Error(), "did not match any file(s) known to git") {
|
if strings.Contains(err.Error(), "did not match any file(s) known to git") {
|
||||||
if err := c.Run(c.NewCmdObj("git config --file .gitmodules --remove-section submodule." + c.OSCommand.Quote(submodule.Name))); err != nil {
|
if err := c.Cmd.New("git config --file .gitmodules --remove-section submodule." + c.OSCommand.Quote(submodule.Name)).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Run(c.NewCmdObj("git config --remove-section submodule." + c.OSCommand.Quote(submodule.Name))); err != nil {
|
if err := c.Cmd.New("git config --remove-section submodule." + c.OSCommand.Quote(submodule.Name)).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Run(c.NewCmdObj("git rm --force -r " + submodule.Path)); err != nil {
|
if err := c.Cmd.New("git rm --force -r " + submodule.Path).Run(); err != nil {
|
||||||
// if the directory isn't there then that's fine
|
// if the directory isn't there then that's fine
|
||||||
c.Log.Error(err)
|
c.Log.Error(err)
|
||||||
}
|
}
|
||||||
@ -111,23 +111,24 @@ func (c *GitCommand) SubmoduleDelete(submodule *models.SubmoduleConfig) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleAdd(name string, path string, url string) error {
|
func (c *GitCommand) SubmoduleAdd(name string, path string, url string) error {
|
||||||
return c.OSCommand.Run(
|
return c.Cmd.
|
||||||
c.OSCommand.NewCmdObj(
|
New(
|
||||||
fmt.Sprintf(
|
fmt.Sprintf(
|
||||||
"git submodule add --force --name %s -- %s %s ",
|
"git submodule add --force --name %s -- %s %s ",
|
||||||
c.OSCommand.Quote(name),
|
c.OSCommand.Quote(name),
|
||||||
c.OSCommand.Quote(url),
|
c.OSCommand.Quote(url),
|
||||||
c.OSCommand.Quote(path),
|
c.OSCommand.Quote(path),
|
||||||
)))
|
)).
|
||||||
|
Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleUpdateUrl(name string, path string, newUrl string) error {
|
func (c *GitCommand) SubmoduleUpdateUrl(name string, path string, newUrl string) error {
|
||||||
// the set-url command is only for later git versions so we're doing it manually here
|
// the set-url command is only for later git versions so we're doing it manually here
|
||||||
if err := c.Run(c.NewCmdObj("git config --file .gitmodules submodule." + c.OSCommand.Quote(name) + ".url " + c.OSCommand.Quote(newUrl))); err != nil {
|
if err := c.Cmd.New("git config --file .gitmodules submodule." + c.OSCommand.Quote(name) + ".url " + c.OSCommand.Quote(newUrl)).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.Run(c.NewCmdObj("git submodule sync -- " + c.OSCommand.Quote(path))); err != nil {
|
if err := c.Cmd.New("git submodule sync -- " + c.OSCommand.Quote(path)).Run(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,27 +136,27 @@ func (c *GitCommand) SubmoduleUpdateUrl(name string, path string, newUrl string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleInit(path string) error {
|
func (c *GitCommand) SubmoduleInit(path string) error {
|
||||||
return c.Run(c.NewCmdObj("git submodule init -- " + c.OSCommand.Quote(path)))
|
return c.Cmd.New("git submodule init -- " + c.OSCommand.Quote(path)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleUpdate(path string) error {
|
func (c *GitCommand) SubmoduleUpdate(path string) error {
|
||||||
return c.Run(c.NewCmdObj("git submodule update --init -- " + c.OSCommand.Quote(path)))
|
return c.Cmd.New("git submodule update --init -- " + c.OSCommand.Quote(path)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleBulkInitCmdObj() oscommands.ICmdObj {
|
func (c *GitCommand) SubmoduleBulkInitCmdObj() oscommands.ICmdObj {
|
||||||
return c.NewCmdObj("git submodule init")
|
return c.Cmd.New("git submodule init")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleBulkUpdateCmdObj() oscommands.ICmdObj {
|
func (c *GitCommand) SubmoduleBulkUpdateCmdObj() oscommands.ICmdObj {
|
||||||
return c.NewCmdObj("git submodule update")
|
return c.Cmd.New("git submodule update")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleForceBulkUpdateCmdObj() oscommands.ICmdObj {
|
func (c *GitCommand) SubmoduleForceBulkUpdateCmdObj() oscommands.ICmdObj {
|
||||||
return c.NewCmdObj("git submodule update --force")
|
return c.Cmd.New("git submodule update --force")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) SubmoduleBulkDeinitCmdObj() oscommands.ICmdObj {
|
func (c *GitCommand) SubmoduleBulkDeinitCmdObj() oscommands.ICmdObj {
|
||||||
return c.NewCmdObj("git submodule deinit --all --force")
|
return c.Cmd.New("git submodule deinit --all --force")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) ResetSubmodules(submodules []*models.SubmoduleConfig) error {
|
func (c *GitCommand) ResetSubmodules(submodules []*models.SubmoduleConfig) error {
|
||||||
|
@ -37,7 +37,7 @@ func (c *GitCommand) Push(opts PushOpts) error {
|
|||||||
cmdStr += " " + c.OSCommand.Quote(opts.UpstreamBranch)
|
cmdStr += " " + c.OSCommand.Quote(opts.UpstreamBranch)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdObj := c.NewCmdObj(cmdStr)
|
cmdObj := c.Cmd.New(cmdStr)
|
||||||
return c.DetectUnamePass(cmdObj, opts.PromptUserForCredential)
|
return c.DetectUnamePass(cmdObj, opts.PromptUserForCredential)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func (c *GitCommand) Fetch(opts FetchOptions) error {
|
|||||||
cmdStr = fmt.Sprintf("%s %s", cmdStr, c.OSCommand.Quote(opts.BranchName))
|
cmdStr = fmt.Sprintf("%s %s", cmdStr, c.OSCommand.Quote(opts.BranchName))
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdObj := c.NewCmdObj(cmdStr)
|
cmdObj := c.Cmd.New(cmdStr)
|
||||||
return c.DetectUnamePass(cmdObj, func(question string) string {
|
return c.DetectUnamePass(cmdObj, func(question string) string {
|
||||||
if opts.PromptUserForCredential != nil {
|
if opts.PromptUserForCredential != nil {
|
||||||
return opts.PromptUserForCredential(question)
|
return opts.PromptUserForCredential(question)
|
||||||
@ -94,18 +94,18 @@ func (c *GitCommand) Pull(opts PullOptions) error {
|
|||||||
|
|
||||||
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
|
// setting GIT_SEQUENCE_EDITOR to ':' as a way of skipping it, in case the user
|
||||||
// has 'pull.rebase = interactive' configured.
|
// has 'pull.rebase = interactive' configured.
|
||||||
cmdObj := c.NewCmdObj(cmdStr).AddEnvVars("GIT_SEQUENCE_EDITOR=:")
|
cmdObj := c.Cmd.New(cmdStr).AddEnvVars("GIT_SEQUENCE_EDITOR=:")
|
||||||
return c.DetectUnamePass(cmdObj, opts.PromptUserForCredential)
|
return c.DetectUnamePass(cmdObj, opts.PromptUserForCredential)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) FastForward(branchName string, remoteName string, remoteBranchName string, promptUserForCredential func(string) string) error {
|
func (c *GitCommand) FastForward(branchName string, remoteName string, remoteBranchName string, promptUserForCredential func(string) string) error {
|
||||||
cmdStr := fmt.Sprintf("git fetch %s %s:%s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))
|
cmdStr := fmt.Sprintf("git fetch %s %s:%s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(remoteBranchName), c.OSCommand.Quote(branchName))
|
||||||
cmdObj := c.NewCmdObj(cmdStr)
|
cmdObj := c.Cmd.New(cmdStr)
|
||||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) FetchRemote(remoteName string, promptUserForCredential func(string) string) error {
|
func (c *GitCommand) FetchRemote(remoteName string, promptUserForCredential func(string) string) error {
|
||||||
cmdStr := fmt.Sprintf("git fetch %s", c.OSCommand.Quote(remoteName))
|
cmdStr := fmt.Sprintf("git fetch %s", c.OSCommand.Quote(remoteName))
|
||||||
cmdObj := c.NewCmdObj(cmdStr)
|
cmdObj := c.Cmd.New(cmdStr)
|
||||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,19 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *GitCommand) CreateLightweightTag(tagName string, commitSha string) error {
|
func (c *GitCommand) CreateLightweightTag(tagName string, commitSha string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git tag -- %s %s", c.OSCommand.Quote(tagName), commitSha)))
|
return c.Cmd.New(fmt.Sprintf("git tag -- %s %s", c.OSCommand.Quote(tagName), commitSha)).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) CreateAnnotatedTag(tagName, commitSha, msg string) error {
|
func (c *GitCommand) CreateAnnotatedTag(tagName, commitSha, msg string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git tag %s %s -m %s", tagName, commitSha, c.OSCommand.Quote(msg))))
|
return c.Cmd.New(fmt.Sprintf("git tag %s %s -m %s", tagName, commitSha, c.OSCommand.Quote(msg))).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) DeleteTag(tagName string) error {
|
func (c *GitCommand) DeleteTag(tagName string) error {
|
||||||
return c.Run(c.NewCmdObj(fmt.Sprintf("git tag -d %s", c.OSCommand.Quote(tagName))))
|
return c.Cmd.New(fmt.Sprintf("git tag -d %s", c.OSCommand.Quote(tagName))).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GitCommand) PushTag(remoteName string, tagName string, promptUserForCredential func(string) string) error {
|
func (c *GitCommand) PushTag(remoteName string, tagName string, promptUserForCredential func(string) string) error {
|
||||||
cmdStr := fmt.Sprintf("git push %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(tagName))
|
cmdStr := fmt.Sprintf("git push %s %s", c.OSCommand.Quote(remoteName), c.OSCommand.Quote(tagName))
|
||||||
cmdObj := c.NewCmdObj(cmdStr)
|
cmdObj := c.Cmd.New(cmdStr)
|
||||||
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
return c.DetectUnamePass(cmdObj, promptUserForCredential)
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
|
|||||||
gui.Mutexes.BranchCommitsMutex.Lock()
|
gui.Mutexes.BranchCommitsMutex.Lock()
|
||||||
defer gui.Mutexes.BranchCommitsMutex.Unlock()
|
defer gui.Mutexes.BranchCommitsMutex.Unlock()
|
||||||
|
|
||||||
builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
|
builder := commands.NewCommitListBuilder(gui.Common, gui.GitCommand, gui.OSCommand)
|
||||||
|
|
||||||
commits, err := builder.GetCommits(
|
commits, err := builder.GetCommits(
|
||||||
commands.GetCommitsOptions{
|
commands.GetCommitsOptions{
|
||||||
@ -142,7 +142,7 @@ func (gui *Gui) refreshRebaseCommits() error {
|
|||||||
gui.Mutexes.BranchCommitsMutex.Lock()
|
gui.Mutexes.BranchCommitsMutex.Lock()
|
||||||
defer gui.Mutexes.BranchCommitsMutex.Unlock()
|
defer gui.Mutexes.BranchCommitsMutex.Unlock()
|
||||||
|
|
||||||
builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
|
builder := commands.NewCommitListBuilder(gui.Common, gui.GitCommand, gui.OSCommand)
|
||||||
|
|
||||||
updatedCommits, err := builder.MergeRebasingCommits(gui.State.Commits)
|
updatedCommits, err := builder.MergeRebasingCommits(gui.State.Commits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -203,7 +203,7 @@ func (gui *Gui) menuPromptFromCommand(prompt config.CustomCommandPrompt, promptR
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run and save output
|
// Run and save output
|
||||||
message, err := gui.GitCommand.RunWithOutput(gui.GitCommand.NewCmdObj(cmdStr))
|
message, err := gui.GitCommand.Cmd.New(cmdStr).RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
@ -244,7 +244,7 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
|
|||||||
}
|
}
|
||||||
|
|
||||||
if customCommand.Subprocess {
|
if customCommand.Subprocess {
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(gui.OSCommand.NewShellCmdObjFromString2(cmdStr))
|
return gui.runSubprocessWithSuspenseAndRefresh(gui.OSCommand.Cmd.NewShell(cmdStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingText := customCommand.LoadingText
|
loadingText := customCommand.LoadingText
|
||||||
@ -252,8 +252,8 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
|
|||||||
loadingText = gui.Tr.LcRunningCustomCommandStatus
|
loadingText = gui.Tr.LcRunningCustomCommandStatus
|
||||||
}
|
}
|
||||||
return gui.WithWaitingStatus(loadingText, func() error {
|
return gui.WithWaitingStatus(loadingText, func() error {
|
||||||
cmdObj := gui.OSCommand.NewShellCmdObjFromString(cmdStr)
|
err := gui.OSCommand.WithSpan(gui.Tr.Spans.CustomCommand).Cmd.NewShell(cmdStr).Run()
|
||||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.CustomCommand).Run(cmdObj); err != nil {
|
if err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
return gui.refreshSidePanels(refreshOptions{})
|
return gui.refreshSidePanels(refreshOptions{})
|
||||||
|
@ -13,7 +13,7 @@ func (gui *Gui) exitDiffMode() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderDiff() error {
|
func (gui *Gui) renderDiff() error {
|
||||||
cmdObj := gui.OSCommand.NewCmdObj(
|
cmdObj := gui.OSCommand.Cmd.New(
|
||||||
fmt.Sprintf("git diff --submodule --no-ext-diff --color %s", gui.diffStr()),
|
fmt.Sprintf("git diff --submodule --no-ext-diff --color %s", gui.diffStr()),
|
||||||
)
|
)
|
||||||
task := NewRunPtyTask(cmdObj.GetCmd())
|
task := NewRunPtyTask(cmdObj.GetCmd())
|
||||||
|
@ -465,7 +465,7 @@ func (gui *Gui) handleCommitEditorPress() error {
|
|||||||
cmdStr := "git " + strings.Join(args, " ")
|
cmdStr := "git " + strings.Join(args, " ")
|
||||||
|
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||||
gui.GitCommand.WithSpan(gui.Tr.Spans.Commit).NewCmdObjWithLog(cmdStr),
|
gui.GitCommand.WithSpan(gui.Tr.Spans.Commit).Cmd.New(cmdStr).Log(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,7 +511,7 @@ func (gui *Gui) editFileAtLine(filename string, lineNumber int) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||||
gui.OSCommand.WithSpan(gui.Tr.Spans.EditFile).NewShellCmdObjFromString(cmdStr),
|
gui.OSCommand.WithSpan(gui.Tr.Spans.EditFile).Cmd.NewShell(cmdStr),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,7 +923,7 @@ func (gui *Gui) handleCustomCommand() error {
|
|||||||
|
|
||||||
gui.OnRunCommand(oscommands.NewCmdLogEntry(command, gui.Tr.Spans.CustomCommand, true))
|
gui.OnRunCommand(oscommands.NewCmdLogEntry(command, gui.Tr.Spans.CustomCommand, true))
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||||
gui.OSCommand.NewShellCmdObjFromString2(command),
|
gui.OSCommand.Cmd.NewShell(command),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -32,7 +32,7 @@ func (gui *Gui) gitFlowFinishBranch(gitFlowConfig string, branchName string) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||||
gui.GitCommand.WithSpan(gui.Tr.Spans.GitFlowFinish).NewCmdObjWithLog("git flow " + branchType + " finish " + suffix),
|
gui.GitCommand.WithSpan(gui.Tr.Spans.GitFlowFinish).Cmd.New("git flow " + branchType + " finish " + suffix).Log(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ func (gui *Gui) handleCreateGitFlowMenu() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get config
|
// get config
|
||||||
gitFlowConfig, err := gui.GitCommand.RunWithOutput(gui.GitCommand.NewCmdObj("git config --local --get-regexp gitflow"))
|
gitFlowConfig, err := gui.GitCommand.Cmd.New("git config --local --get-regexp gitflow").RunWithOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return gui.createErrorPanel("You need to install git-flow and enable it in this repo to use git-flow features")
|
return gui.createErrorPanel("You need to install git-flow and enable it in this repo to use git-flow features")
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ func (gui *Gui) handleCreateGitFlowMenu() error {
|
|||||||
title: title,
|
title: title,
|
||||||
handleConfirm: func(name string) error {
|
handleConfirm: func(name string) error {
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(
|
return gui.runSubprocessWithSuspenseAndRefresh(
|
||||||
gui.GitCommand.WithSpan(gui.Tr.Spans.GitFlowStart).NewCmdObjWithLog("git flow " + branchType + " start " + name),
|
gui.GitCommand.WithSpan(gui.Tr.Spans.GitFlowStart).Cmd.New("git flow " + branchType + " start " + name).Log(),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
func (gui *Gui) withGpgHandling(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
func (gui *Gui) withGpgHandling(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
||||||
useSubprocess := gui.GitCommand.UsingGpg()
|
useSubprocess := gui.GitCommand.UsingGpg()
|
||||||
if useSubprocess {
|
if useSubprocess {
|
||||||
success, err := gui.runSubprocessWithSuspense(gui.OSCommand.NewShellCmdObjFromString(cmdObj.ToString()))
|
success, err := gui.runSubprocessWithSuspense(gui.OSCommand.Cmd.NewShell(cmdObj.ToString()))
|
||||||
if success && onSuccess != nil {
|
if success && onSuccess != nil {
|
||||||
if err := onSuccess(); err != nil {
|
if err := onSuccess(); err != nil {
|
||||||
return err
|
return err
|
||||||
@ -33,7 +33,7 @@ func (gui *Gui) withGpgHandling(cmdObj oscommands.ICmdObj, waitingStatus string,
|
|||||||
|
|
||||||
func (gui *Gui) RunAndStream(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
func (gui *Gui) RunAndStream(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
||||||
return gui.WithWaitingStatus(waitingStatus, func() error {
|
return gui.WithWaitingStatus(waitingStatus, func() error {
|
||||||
cmdObj := gui.OSCommand.NewShellCmdObjFromString(cmdObj.ToString())
|
cmdObj := gui.OSCommand.Cmd.NewShell(cmdObj.ToString())
|
||||||
cmdObj.AddEnvVars("TERM=dumb")
|
cmdObj.AddEnvVars("TERM=dumb")
|
||||||
cmdWriter := gui.getCmdWriter()
|
cmdWriter := gui.getCmdWriter()
|
||||||
cmd := cmdObj.GetCmd()
|
cmd := cmdObj.GetCmd()
|
||||||
|
@ -58,7 +58,7 @@ func (gui *Gui) genericMergeCommand(command string) error {
|
|||||||
|
|
||||||
// it's impossible for a rebase to require a commit so we'll use a subprocess only if it's a merge
|
// it's impossible for a rebase to require a commit so we'll use a subprocess only if it's a merge
|
||||||
if status == commands.REBASE_MODE_MERGING && command != REBASE_OPTION_ABORT && gui.UserConfig.Git.Merging.ManualCommit {
|
if status == commands.REBASE_MODE_MERGING && command != REBASE_OPTION_ABORT && gui.UserConfig.Git.Merging.ManualCommit {
|
||||||
sub := gitCommand.NewCmdObj("git " + commandType + " --" + command)
|
sub := gitCommand.Cmd.New("git " + commandType + " --" + command)
|
||||||
if sub != nil {
|
if sub != nil {
|
||||||
return gui.runSubprocessWithSuspenseAndRefresh(sub)
|
return gui.runSubprocessWithSuspenseAndRefresh(sub)
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ func (gui *Gui) handleCreateRecentReposMenu() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleShowAllBranchLogs() error {
|
func (gui *Gui) handleShowAllBranchLogs() error {
|
||||||
cmdObj := gui.OSCommand.NewCmdObj(
|
cmdObj := gui.OSCommand.Cmd.New(
|
||||||
gui.UserConfig.Git.AllBranchesLogCmd,
|
gui.UserConfig.Git.AllBranchesLogCmd,
|
||||||
)
|
)
|
||||||
task := NewRunPtyTask(cmdObj.GetCmd())
|
task := NewRunPtyTask(cmdObj.GetCmd())
|
||||||
|
@ -22,7 +22,7 @@ func (gui *Gui) stashRenderToMain() error {
|
|||||||
if stashEntry == nil {
|
if stashEntry == nil {
|
||||||
task = NewRenderStringTask(gui.Tr.NoStashEntries)
|
task = NewRenderStringTask(gui.Tr.NoStashEntries)
|
||||||
} else {
|
} else {
|
||||||
cmdObj := gui.OSCommand.NewCmdObj(
|
cmdObj := gui.OSCommand.Cmd.New(
|
||||||
gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index),
|
gui.GitCommand.ShowStashEntryCmdStr(stashEntry.Index),
|
||||||
)
|
)
|
||||||
task = NewRunPtyTask(cmdObj.GetCmd())
|
task = NewRunPtyTask(cmdObj.GetCmd())
|
||||||
|
@ -75,7 +75,7 @@ func (gui *Gui) handleViewSubCommitFiles() error {
|
|||||||
|
|
||||||
func (gui *Gui) switchToSubCommitsContext(refName string) error {
|
func (gui *Gui) switchToSubCommitsContext(refName string) error {
|
||||||
// need to populate my sub commits
|
// need to populate my sub commits
|
||||||
builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr)
|
builder := commands.NewCommitListBuilder(gui.Common, gui.GitCommand, gui.OSCommand)
|
||||||
|
|
||||||
commits, err := builder.GetCommits(
|
commits, err := builder.GetCommits(
|
||||||
commands.GetCommitsOptions{
|
commands.GetCommitsOptions{
|
||||||
|
@ -214,7 +214,8 @@ func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
|||||||
displayStrings: []string{gui.Tr.LcBulkInitSubmodules, style.FgGreen.Sprint(gui.GitCommand.SubmoduleBulkInitCmdObj().ToString())},
|
displayStrings: []string{gui.Tr.LcBulkInitSubmodules, style.FgGreen.Sprint(gui.GitCommand.SubmoduleBulkInitCmdObj().ToString())},
|
||||||
onPress: func() error {
|
onPress: func() error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkInitialiseSubmodules).Run(gui.GitCommand.SubmoduleBulkInitCmdObj()); err != nil {
|
err := gui.GitCommand.WithSpan(gui.Tr.Spans.BulkInitialiseSubmodules).SubmoduleBulkInitCmdObj().Run()
|
||||||
|
if err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +227,7 @@ func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
|||||||
displayStrings: []string{gui.Tr.LcBulkUpdateSubmodules, style.FgYellow.Sprint(gui.GitCommand.SubmoduleBulkUpdateCmdObj().ToString())},
|
displayStrings: []string{gui.Tr.LcBulkUpdateSubmodules, style.FgYellow.Sprint(gui.GitCommand.SubmoduleBulkUpdateCmdObj().ToString())},
|
||||||
onPress: func() error {
|
onPress: func() error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkUpdateSubmodules).Run(gui.GitCommand.SubmoduleBulkUpdateCmdObj()); err != nil {
|
if err := gui.GitCommand.WithSpan(gui.Tr.Spans.BulkUpdateSubmodules).SubmoduleBulkUpdateCmdObj().Run(); err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +251,7 @@ func (gui *Gui) handleBulkSubmoduleActionsMenu() error {
|
|||||||
displayStrings: []string{gui.Tr.LcBulkDeinitSubmodules, style.FgRed.Sprint(gui.GitCommand.SubmoduleBulkDeinitCmdObj().ToString())},
|
displayStrings: []string{gui.Tr.LcBulkDeinitSubmodules, style.FgRed.Sprint(gui.GitCommand.SubmoduleBulkDeinitCmdObj().ToString())},
|
||||||
onPress: func() error {
|
onPress: func() error {
|
||||||
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
return gui.WithWaitingStatus(gui.Tr.LcRunningCommand, func() error {
|
||||||
if err := gui.OSCommand.WithSpan(gui.Tr.Spans.BulkDeinitialiseSubmodules).Run(gui.GitCommand.SubmoduleBulkDeinitCmdObj()); err != nil {
|
if err := gui.GitCommand.WithSpan(gui.Tr.Spans.BulkDeinitialiseSubmodules).SubmoduleBulkDeinitCmdObj().Run(); err != nil {
|
||||||
return gui.surfaceError(err)
|
return gui.surfaceError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ func RunTests(
|
|||||||
testDir := filepath.Join(rootDir, "test", "integration")
|
testDir := filepath.Join(rootDir, "test", "integration")
|
||||||
|
|
||||||
osCommand := oscommands.NewDummyOSCommand()
|
osCommand := oscommands.NewDummyOSCommand()
|
||||||
err = osCommand.Run(osCommand.NewCmdObj("go build -o " + tempLazygitPath()))
|
err = osCommand.Cmd.New("go build -o " + tempLazygitPath()).Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -319,7 +319,7 @@ func generateSnapshot(dir string) (string, error) {
|
|||||||
|
|
||||||
for _, cmdStr := range cmdStrs {
|
for _, cmdStr := range cmdStrs {
|
||||||
// ignoring error for now. If there's an error it could be that there are no results
|
// ignoring error for now. If there's an error it could be that there are no results
|
||||||
output, _ := osCommand.RunWithOutput(osCommand.NewCmdObj(cmdStr))
|
output, _ := osCommand.Cmd.New(cmdStr).RunWithOutput()
|
||||||
|
|
||||||
snapshot += output + "\n"
|
snapshot += output + "\n"
|
||||||
}
|
}
|
||||||
@ -428,7 +428,7 @@ func getLazygitCommand(testPath string, rootDir string, record bool, speed float
|
|||||||
|
|
||||||
cmdStr := fmt.Sprintf("%s -debug --use-config-dir=%s --path=%s %s", tempLazygitPath(), configDir, actualDir, extraCmdArgs)
|
cmdStr := fmt.Sprintf("%s -debug --use-config-dir=%s --path=%s %s", tempLazygitPath(), configDir, actualDir, extraCmdArgs)
|
||||||
|
|
||||||
cmdObj := osCommand.NewCmdObj(cmdStr)
|
cmdObj := osCommand.Cmd.New(cmdStr)
|
||||||
cmdObj.AddEnvVars(fmt.Sprintf("SPEED=%f", speed))
|
cmdObj.AddEnvVars(fmt.Sprintf("SPEED=%f", speed))
|
||||||
|
|
||||||
if record {
|
if record {
|
||||||
|
@ -295,8 +295,8 @@ func (u *Updater) downloadAndInstall(rawUrl string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u.Log.Info("untarring tarball/unzipping zip file")
|
u.Log.Info("untarring tarball/unzipping zip file")
|
||||||
cmdObj := u.OSCommand.NewCmdObj(fmt.Sprintf("tar -zxf %s %s", u.OSCommand.Quote(zipPath), "lazygit"))
|
err = u.OSCommand.Cmd.New(fmt.Sprintf("tar -zxf %s %s", u.OSCommand.Quote(zipPath), "lazygit")).Run()
|
||||||
if err := u.OSCommand.Run(cmdObj); err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user