summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2023-05-19 20:18:02 +1000
committerJesse Duffield <jessedduffield@gmail.com>2023-05-20 20:54:24 +1000
commit25f8b0337e1e023fd9575ecd46467810c9f49824 (patch)
treeda4937d66b110d6f69621c79d98c3d9ce9384b41
parent63ddc52a6b0b69b656b106ee5ae74dd736ac6317 (diff)
Add convenience builder for git commands
-rw-r--r--pkg/commands/git_commands/bisect.go26
-rw-r--r--pkg/commands/git_commands/branch.go104
-rw-r--r--pkg/commands/git_commands/commit.go139
-rw-r--r--pkg/commands/git_commands/commit_file_loader.go19
-rw-r--r--pkg/commands/git_commands/commit_loader.go78
-rw-r--r--pkg/commands/git_commands/file_loader.go16
-rw-r--r--pkg/commands/git_commands/flow.go9
-rw-r--r--pkg/commands/git_commands/git_command_builder.go54
-rw-r--r--pkg/commands/git_commands/git_command_builder_test.go56
-rw-r--r--pkg/commands/git_commands/patch.go4
-rw-r--r--pkg/commands/git_commands/rebase.go46
-rw-r--r--pkg/commands/git_commands/remote.go52
-rw-r--r--pkg/commands/git_commands/remote_loader.go3
-rw-r--r--pkg/commands/git_commands/stash.go98
-rw-r--r--pkg/commands/git_commands/stash_loader.go7
-rw-r--r--pkg/commands/git_commands/status.go4
-rw-r--r--pkg/commands/git_commands/submodule.go114
-rw-r--r--pkg/commands/git_commands/sync.go69
-rw-r--r--pkg/commands/git_commands/tag.go35
-rw-r--r--pkg/commands/git_commands/tag_loader.go3
-rw-r--r--pkg/commands/git_commands/version.go2
-rw-r--r--pkg/commands/git_commands/working_tree.go163
22 files changed, 713 insertions, 388 deletions
diff --git a/pkg/commands/git_commands/bisect.go b/pkg/commands/git_commands/bisect.go
index b09a50bf5..898151d9c 100644
--- a/pkg/commands/git_commands/bisect.go
+++ b/pkg/commands/git_commands/bisect.go
@@ -1,7 +1,6 @@
package git_commands
import (
- "fmt"
"os"
"path/filepath"
"strings"
@@ -98,13 +97,15 @@ func (self *BisectCommands) GetInfo() *BisectInfo {
}
func (self *BisectCommands) Reset() error {
- return self.cmd.New("git bisect reset").StreamOutput().Run()
+ cmdStr := NewGitCmd("bisect").Arg("reset").ToString()
+
+ return self.cmd.New(cmdStr).StreamOutput().Run()
}
func (self *BisectCommands) Mark(ref string, term string) error {
- return self.cmd.New(
- fmt.Sprintf("git bisect %s %s", term, ref),
- ).
+ cmdStr := NewGitCmd("bisect").Arg(term, ref).ToString()
+
+ return self.cmd.New(cmdStr).
IgnoreEmptyError().
StreamOutput().
Run()
@@ -115,7 +116,9 @@ func (self *BisectCommands) Skip(ref string) error {
}
func (self *BisectCommands) Start() error {
- return self.cmd.New("git bisect start").StreamOutput().Run()
+ cmdStr := NewGitCmd("bisect").Arg("start").ToString()
+
+ return self.cmd.New(cmdStr).StreamOutput().Run()
}
// tells us whether we've found our problem commit(s). We return a string slice of
@@ -137,7 +140,8 @@ func (self *BisectCommands) IsDone() (bool, []string, error) {
done := false
candidates := []string{}
- err := self.cmd.New(fmt.Sprintf("git rev-list %s", newSha)).RunAndProcessLines(func(line string) (bool, error) {
+ cmdStr := NewGitCmd("rev-list").Arg(newSha).ToString()
+ err := self.cmd.New(cmdStr).RunAndProcessLines(func(line string) (bool, error) {
sha := strings.TrimSpace(line)
if status, ok := info.statusMap[sha]; ok {
@@ -167,9 +171,11 @@ func (self *BisectCommands) IsDone() (bool, []string, error) {
// bisecting is actually a descendant of our current bisect commit. If it's not, we need to
// render the commits from the bad commit.
func (self *BisectCommands) ReachableFromStart(bisectInfo *BisectInfo) bool {
- err := self.cmd.New(
- fmt.Sprintf("git merge-base --is-ancestor %s %s", bisectInfo.GetNewSha(), bisectInfo.GetStartSha()),
- ).DontLog().Run()
+ cmdStr := NewGitCmd("merge-base").
+ Arg("--is-ancestor", bisectInfo.GetNewSha(), bisectInfo.GetStartSha()).
+ ToString()
+
+ err := self.cmd.New(cmdStr).DontLog().Run()
return err == nil
}
diff --git a/pkg/commands/git_commands/branch.go b/pkg/commands/git_commands/branch.go
index a71e365ea..0952e59e1 100644
--- a/pkg/commands/git_commands/branch.go
+++ b/pkg/commands/git_commands/branch.go
@@ -20,12 +20,20 @@ func NewBranchCommands(gitCommon *GitCommon) *BranchCommands {
// New creates a new branch
func (self *BranchCommands) New(name string, base string) error {
- return self.cmd.New(fmt.Sprintf("git checkout -b %s %s", self.cmd.Quote(name), self.cmd.Quote(base))).Run()
+ cmdStr := NewGitCmd("checkout").
+ Arg("-b", self.cmd.Quote(name), self.cmd.Quote(base)).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
// CurrentBranchInfo get the current branch information.
func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
- branchName, err := self.cmd.New("git symbolic-ref --short HEAD").DontLog().RunWithOutput()
+ branchName, err := self.cmd.New(
+ NewGitCmd("symbolic-ref").
+ Arg("--short", "HEAD").
+ ToString(),
+ ).DontLog().RunWithOutput()
if err == nil && branchName != "HEAD\n" {
trimmedBranchName := strings.TrimSpace(branchName)
return BranchInfo{
@@ -34,7 +42,11 @@ func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
DetachedHead: false,
}, nil
}
- output, err := self.cmd.New(`git branch --points-at=HEAD --format="%(HEAD)%00%(objectname)%00%(refname)"`).DontLog().RunWithOutput()
+ output, err := self.cmd.New(
+ NewGitCmd("branch").
+ Arg("--points-at=HEAD", "--format=\"%(HEAD)%00%(objectname)%00%(refname)\"").
+ ToString(),
+ ).DontLog().RunWithOutput()
if err != nil {
return BranchInfo{}, err
}
@@ -59,13 +71,12 @@ func (self *BranchCommands) CurrentBranchInfo() (BranchInfo, error) {
// Delete delete branch
func (self *BranchCommands) Delete(branch string, force bool) error {
- command := "git branch -d"
-
- if force {
- command = "git branch -D"
- }
+ cmdStr := NewGitCmd("branch").
+ ArgIfElse(force, "-D", "-d").
+ Arg(self.cmd.Quote(branch)).
+ ToString()
- return self.cmd.New(fmt.Sprintf("%s %s", command, self.cmd.Quote(branch))).Run()
+ return self.cmd.New(cmdStr).Run()
}
// Checkout checks out a branch (or commit), with --force if you set the force arg to true
@@ -75,12 +86,12 @@ type CheckoutOptions struct {
}
func (self *BranchCommands) Checkout(branch string, options CheckoutOptions) error {
- forceArg := ""
- if options.Force {
- forceArg = " --force"
- }
+ cmdStr := NewGitCmd("checkout").
+ ArgIf(options.Force, "--force").
+ Arg(self.cmd.Quote(branch)).
+ ToString()
- return self.cmd.New(fmt.Sprintf("git checkout%s %s", forceArg, self.cmd.Quote(branch))).
+ return self.cmd.New(cmdStr).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
@@ -104,15 +115,27 @@ func (self *BranchCommands) GetGraphCmdObj(branchName string) oscommands.ICmdObj
}
func (self *BranchCommands) SetCurrentBranchUpstream(remoteName string, remoteBranchName string) error {
- return self.cmd.New(fmt.Sprintf("git branch --set-upstream-to=%s/%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName))).Run()
+ cmdStr := NewGitCmd("branch").
+ Arg(fmt.Sprintf("--set-upstream-to=%s/%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName))).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
func (self *BranchCommands) SetUpstream(remoteName string, remoteBranchName string, branchName string) error {
- return self.cmd.New(fmt.Sprintf("git branch --set-upstream-to=%s/%s %s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName), self.cmd.Quote(branchName))).Run()
+ cmdStr := NewGitCmd("branch").
+ Arg(fmt.Sprintf("--set-upstream-to=%s/%s", self.cmd.Quote(remoteName), self.cmd.Quote(remoteBranchName))).
+ Arg(self.cmd.Quote(branchName)).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
func (self *BranchCommands) UnsetUpstream(branchName string) error {
- return self.cmd.New(fmt.Sprintf("git branch --unset-upstream %s", self.cmd.Quote(branchName))).Run()
+ cmdStr := NewGitCmd("branch").Arg("--unset-upstream", self.cmd.Quote(branchName)).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
func (self *BranchCommands) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
@@ -126,29 +149,49 @@ func (self *BranchCommands) GetUpstreamDifferenceCount(branchName string) (strin
// GetCommitDifferences checks how many pushables/pullables there are for the
// current branch
func (self *BranchCommands) GetCommitDifferences(from, to string) (string, string) {
- command := "git rev-list %s..%s --count"
- pushableCount, err := self.cmd.New(fmt.Sprintf(command, to, from)).DontLog().RunWithOutput()
+ pushableCount, err := self.countDifferences(to, from)
if err != nil {
return "?", "?"
}
- pullableCount, err := self.cmd.New(fmt.Sprintf(command, from, to)).DontLog().RunWithOutput()
+ pullableCount, err := self.countDifferences(from, to)
if err != nil {
return "?", "?"
}
return strings.TrimSpace(pushableCount), strings.TrimSpace(pullableCount)
}
+func (self *BranchCommands) countDifferences(from, to string) (string, error) {
+ cmdStr := NewGitCmd("rev-list").
+ Arg(fmt.Sprintf("%s..%s", from, to)).
+ Arg("--count").
+ ToString()
+
+ return self.cmd.New(cmdStr).DontLog().RunWithOutput()
+}
+
func (self *BranchCommands) IsHeadDetached() bool {
- err := self.cmd.New("git symbolic-ref -q HEAD").DontLog().Run()
+ cmdStr := NewGitCmd("symbolic-ref").Arg("-q", "HEAD").ToString()
+
+ err := self.cmd.New(cmdStr).DontLog().Run()
return err != nil
}
func (self *BranchCommands) Rename(oldName string, newName string) error {
- return self.cmd.New(fmt.Sprintf("git branch --move %s %s", self.cmd.Quote(oldName), self.cmd.Quote(newName))).Run()
+ cmdStr := NewGitCmd("branch").
+ Arg("--move", self.cmd.Quote(oldName), self.cmd.Quote(newName)).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
func (self *BranchCommands) GetRawBranches() (string, error) {
- return self.cmd.New(`git for-each-ref --sort=-committerdate --format="%(HEAD)%00%(refname:short)%00%(upstream:short)%00%(upstream:track)" refs/heads`).DontLog().RunWithOutput()
+ cmdStr := NewGitCmd("for-each-ref").
+ Arg("--sort=-committerdate").
+ Arg(`--format="%(HEAD)%00%(refname:short)%00%(upstream:short)%00%(upstream:track)"`).
+ Arg("refs/heads").
+ ToString()
+
+ return self.cmd.New(cmdStr).DontLog().RunWithOutput()
}
type MergeOpts struct {
@@ -156,15 +199,12 @@ type MergeOpts struct {
}
func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
- mergeArg := ""
- if self.UserConfig.Git.Merging.Args != "" {
- mergeArg = " " + self.UserConfig.Git.Merging.Args
- }
-
- command := fmt.Sprintf("git merge --no-edit%s %s", mergeArg, self.cmd.Quote(branchName))
- if opts.FastForwardOnly {
- command = fmt.Sprintf("%s --ff-only", command)
- }
+ command := NewGitCmd("merge").
+ Arg("--no-edit").
+ ArgIf(self.UserConfig.Git.Merging.Args != "", self.UserConfig.Git.Merging.Args).
+ ArgIf(opts.FastForwardOnly, "--ff-only").
+ Arg(self.cmd.Quote(branchName)).
+ ToString()
return self.cmd.New(command).Run()
}
diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go
index 0c5008e38..bca68c3ac 100644
--- a/pkg/commands/git_commands/commit.go
+++ b/pkg/commands/git_commands/commit.go
@@ -22,18 +22,27 @@ func NewCommitCommands(gitCommon *GitCommon) *CommitCommands {
// ResetAuthor resets the author of the topmost commit
func (self *CommitCommands) ResetAuthor() error {
- return self.cmd.New("git commit --allow-empty --only --no-edit --amend --reset-author").Run()
+ cmdStr := NewGitCmd("commit").
+ Arg("--allow-empty", "--only", "--no-edit", "--amend", "--reset-author").
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
// Sets the commit's author to the supplied value. Value is expected to be of the form 'Name <Email>'
func (self *CommitCommands) SetAuthor(value string) error {
- commandStr := fmt.Sprintf("git commit --allow-empty --only --no-edit --amend --author=%s", self.cmd.Quote(value))
- return self.cmd.New(commandStr).Run()
+ cmdStr := NewGitCmd("commit").
+ Arg("--allow-empty", "--only", "--no-edit", "--amend", "--author="+self.cmd.Quote(value)).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
// ResetToCommit reset to commit
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
- return self.cmd.New(fmt.Sprintf("git reset --%s %s", strength, sha)).
+ cmdStr := NewGitCmd("reset").Arg("--"+strength, sha).ToString()
+
+ return self.cmd.New(cmdStr).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
@@ -45,38 +54,52 @@ func (self *CommitCommands) CommitCmdObj(message string) oscommands.ICmdObj {
messageArgs := self.commitMessageArgs(message)
skipHookPrefix := self.UserConfig.Git.SkipHookPrefix
- noVerifyFlag := ""
- if skipHookPrefix != "" && strings.HasPrefix(message, skipHookPrefix) {
- noVerifyFlag = " --no-verify"
- }
- return self.cmd.New(fmt.Sprintf("git commit%s%s%s", noVerifyFlag, self.signoffFlag(), messageArgs))
+ cmdStr := NewGitCmd("commit").
+ ArgIf(skipHookPrefix != "" && strings.HasPrefix(message, skipHookPrefix), "--no-verify").
+ ArgIf(self.signoffFlag() != "", self.signoffFlag()).
+ Arg(messageArgs...).
+ ToString()
+
+ return self.cmd.New(cmdStr)
}
// RewordLastCommit rewords the topmost commit with the given message
func (self *CommitCommands) RewordLastCommit(message string) error {
messageArgs := self.commitMessageArgs(message)
- return self.cmd.New(fmt.Sprintf("git commit --allow-empty --amend --only%s", messageArgs)).Run()
+
+ cmdStr := NewGitCmd("commit").
+ Arg("--allow-empty", "--amend", "--only").
+ Arg(messageArgs...).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
-func (self *CommitCommands) commitMessageArgs(message string) string {
+func (self *CommitCommands) commitMessageArgs(message string) []string {
msg, description, _ := strings.Cut(message, "\n")
- descriptionArgs := ""
+ args := []string{"-m", self.cmd.Quote(msg)}
+
if description != "" {
- descriptionArgs = fmt.Sprintf(" -m %s", self.cmd.Quote(description))
+ args = append(args, "-m", self.cmd.Quote(description))
}
- return fmt.Sprintf(" -m %s%s", self.cmd.Quote(msg), descriptionArgs)
+ return args
}
// runs git commit without the -m argument meaning it will invoke the user's editor
func (self *CommitCommands) CommitEditorCmdObj() oscommands.ICmdObj {
- return self.cmd.New(fmt.Sprintf("git commit%s%s", self.signoffFlag(), self.verboseFlag()))
+ cmdStr := NewGitCmd("commit").
+ ArgIf(self.signoffFlag() != "", self.signoffFlag()).
+ ArgIf(self.verboseFlag() != "", self.verboseFlag()).
+ ToString()
+
+ return self.cmd.New(cmdStr)
}
func (self *CommitCommands) signoffFlag() string {
if self.UserConfig.Git.Commit.SignOff {
- return " --signoff"
+ return "--signoff"
} else {
return ""
}
@@ -85,9 +108,9 @@ func (self *CommitCommands) signoffFlag() string {
func (self *CommitCommands) verboseFlag() string {
switch self.config.UserConfig.Git.Commit.Verbose {
case "always":
- return " --verbose"
+ return "--verbose"
case "never":
- return " --no-verbose"
+ return "--no-verbose"
default:
return ""
}
@@ -95,19 +118,25 @@ func (self *CommitCommands) verboseFlag() string {
// Get the subject of the HEAD commit
func (self *CommitCommands) GetHeadCommitMessage() (string, error) {
- message, err := self.cmd.New("git log -1 --pretty=%s").DontLog().RunWithOutput()
+ cmdStr := NewGitCmd("log").Arg("-1", "--pretty=%s").ToString()
+
+ message, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
return strings.TrimSpace(message), err
}
func (self *CommitCommands) GetCommitMessage(commitSha string) (string, error) {
- cmdStr := "git rev-list --format=%B --max-count=1 " + commitSha
+ cmdStr := NewGitCmd("rev-list").
+ Arg("--format=%B", "--max-count=1", commitSha).
+ ToString()
+
messageWithHeader, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
message := strings.Join(strings.SplitAfter(messageWithHeader, "\n")[1:], "")
return strings.TrimSpace(message), err
}
func (self *CommitCommands) GetCommitDiff(commitSha string) (string, error) {
- cmdStr := "git show --no-color " + commitSha
+ cmdStr := NewGitCmd("show").Arg("--no-color", commitSha).ToString()
+
diff, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
return diff, err
}
@@ -118,7 +147,10 @@ type Author struct {
}
func (self *CommitCommands) GetCommitAuthor(commitSha string) (Author, error) {
- cmdStr := "git show --no-patch --pretty=format:'%an%x00%ae' " + commitSha
+ cmdStr := NewGitCmd("show").
+ Arg("--no-patch", "--pretty=format:'%an%x00%ae'", commitSha).
+ ToString()
+
output, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
if err != nil {
return Author{}, err
@@ -138,15 +170,21 @@ func (self *CommitCommands) GetCommitMessageFirstLine(sha string) (string, error
}
func (self *CommitCommands) GetCommitMessagesFirstLine(shas []string) (string, error) {
- return self.cmd.New(
- fmt.Sprintf("git show --no-patch --pretty=format:%%s %s", strings.Join(shas, " ")),
- ).DontLog().RunWithOutput()
+ cmdStr := NewGitCmd("show").
+ Arg("--no-patch", "--pretty=format:%s").
+ Arg(shas...).
+ ToString()
+
+ return self.cmd.New(cmdStr).DontLog().RunWithOutput()
}
func (self *CommitCommands) GetCommitsOneline(shas []string) (string, error) {
- return self.cmd.New(
- fmt.Sprintf("git show --no-patch --oneline %s", strings.Join(shas, " ")),
- ).DontLog().RunWithOutput()
+ cmdStr := NewGitCmd("show").
+ Arg("--no-patch", "--oneline").
+ Arg(shas...).
+ ToString()
+
+ return self.cmd.New(cmdStr).DontLog().RunWithOutput()
}
// AmendHead amends HEAD with whatever is staged in your working tree
@@ -155,42 +193,57 @@ func (self *CommitCommands) AmendHead() error {
}
func (self *CommitCommands) AmendHeadCmdObj() oscommands.ICmdObj {
- return self.cmd.New("git commit --amend --no-edit --allow-empty")
+ cmdStr := NewGitCmd("commit").
+ Arg("--amend", "--no-edit", "--allow-empty").
+ ToString()
+
+ return self.cmd.New(cmdStr)
}
func (self *CommitCommands) ShowCmdObj(sha string, filterPath string, ignoreWhitespace bool) oscommands.ICmdObj {
contextSize := self.UserConfig.Git.DiffContextSize
- filterPathArg := ""
- if filterPath != "" {
- filterPathArg = fmt.Sprintf(" -- %s", self.cmd.Quote(filterPath))
- }
- ignoreWhitespaceArg := ""
- if ignoreWhitespace {
- ignoreWhitespaceArg = " --ignore-all-space"
- }
- cmdStr := fmt.Sprintf("git show --submodule --color=%s --unified=%d --stat -p %s%s%s",
- self.UserConfig.Git.Paging.ColorArg, contextSize, sha, ignoreWhitespaceArg, filterPathArg)
+ cmdStr := NewGitCmd("show").
+ Arg("--submodule").
+ Arg("--color="+self.UserConfig.Git.Paging.ColorArg).
+ Arg(fmt.Sprintf("--unified=%d", contextSize)).
+ Arg("--stat").
+ Arg("-p").
+ Arg(sha).
+ ArgIf(ignoreWhitespace, "--ignore-all-space").
+ ArgIf(filterPath != "", "--", self.cmd.Quote(filterPath)).
+ ToString()
+
return self.cmd.New(cmdStr).DontLog()
}
// Revert reverts the selected commit by sha
func (self *CommitCommands) Revert(sha string) error {
- return self.cmd.New(fmt.Sprintf("git revert %s", sha)).Run()
+ cmdStr := NewGitCmd("revert").Arg(sha).ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
func (self *CommitCommands) RevertMerge(sha string, parentNumber int) error {
- return self.cmd.New(fmt.Sprintf("git revert %s -m %d", sha, parentNumber)).Run()
+ cmdStr := NewGitCmd("revert").Arg(sha, "-m", fmt.Sprintf("%d", parentNumber)).
+ ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
// CreateFixupCommit creates a commit that fixes up a previous commit
func (self *CommitCommands) CreateFixupCommit(sha string) error {
- return self.cmd.New(fmt.Sprintf("git commit --fixup=%s", sha)).Run()
+ cmdStr := NewGitCmd("commit").Arg("--fixup=" + sha).ToString()
+
+ return self.cmd.New(cmdStr).Run()
}
// a value of 0 means the head commit, 1 is the parent commit, etc
func (self *CommitCommands) GetCommitMessageFromHistory(value int) (string, error) {
- hash, _ := self.cmd.New(fmt.Sprintf("git log -1 --skip=%d --pretty=%%H", value)).DontLog().RunWithOutput()
+ cmdStr := NewGitCmd("log").Arg("-1", fmt.Sprintf("--skip=%d", value), "--pretty=%H").
+ ToString()
+
+ hash, _ := self.cmd.New(cmdStr).DontLog().RunWithOutput()
formattedHash := strings.TrimSpace(hash)
if len(formattedHash) == 0 {
return "", ErrInvalidCommitIndex
diff --git a/pkg/commands/git_commands/commit_file_loader.go b/pkg/commands/git_commands/commit_file_loader.go
index 0b606ae86..53ca046ba 100644
--- a/pkg/commands/git_commands/commit_file_loader.go
+++ b/pkg/commands/git_commands/commit_file_loader.go
@@ -1,7 +1,6 @@
package git_commands
import (
- "fmt"
"strings"
"github.com/jesseduffield/generics/slices"
@@ -25,12 +24,18 @@ func NewCommitFileLoader(common *common.Common, cmd oscommands.ICmdObjBuilder) *
// GetFilesInDiff get the specified commit files
func (self *CommitFileLoader) GetFilesInDiff(from string, to string, reverse bool) ([]*models.CommitFile, error) {
- reverseFlag := ""
- if reverse {
- reverseFlag = " -R "
- }
-
- filenames, err := self.cmd.New(fmt.Sprintf("git diff --submodule --no-ext-diff --name-status -z --no-renames %s %s %s", reverseFlag, from, to)).DontLog().RunWithOutput()
+ cmdStr := NewGitCmd("diff").
+ Arg("--submodule").
+ Arg("--no-ext-diff").
+ Arg("--name-status").
+ Arg("-z").
+ Arg("--no-renames").
+ ArgIf(reverse, "-R").
+ Arg(from).
+ Arg(to).
+ ToString()
+
+ filenames, err := self.cmd.New(cmdStr).DontLog().RunWithOutput()
if err != nil {
return nil, err
}
diff --git a/pkg/commands/git_commands/commit_loader.go b/pkg/commands/git_commands/commit_loader.go
index e68f56ebb..00a468ab2 100644
--- a/pkg/commands/git_commands/commit_loader.go
+++ b/pkg/commands/git_commands/commit_loader.go
@@ -201,12 +201,11 @@ func (self *CommitLoader) getHydratedRebasingCommits(rebaseMode enums.RebaseMode
// note that we're not filtering these as we do non-rebasing commits just because
// I suspect that will cause some damage
cmdObj := self.cmd.New(
- fmt.Sprintf(
- "git -c log.showSignature=false show %s --no-patch --oneline %s --abbrev=%d",
- strings.Join(commitShas, " "),
- prettyFormat,
- 20,
- ),
+ NewGitCmd("show").
+ Config("log.showSignature=false").
+ Arg("--no-patch", "--oneline", "--abbrev=20", prettyFormat).
+ Arg(commitShas...).
+ ToString(),
).DontLog()
fullCommits := map[string]*models.Commit{}
@@ -375,8 +374,11 @@ func (self *CommitLoader) getMergeBase(refName string) string {
// We pass all configured main branches to the merge-base call; git will
// return the base commit for the closest one.
- output, err := self.cmd.New(fmt.Sprintf("git merge-base %s %s",
- self.cmd.Quote(refName), *self.quotedMainBranches)).DontLog().RunWithOutput()
+
+ output, err := self.cmd.New(
+ NewGitCmd("merge-base").Arg(self.cmd.Quote(refName), *self.quotedMainBranches).
+ ToString(),
+ ).DontLog().RunWithOutput()
if err != nil {
// If there's an error, it must be because one of the main branches that
// used to exist when we called getExistingMainBranches() was deleted
@@ -391,7 +393,9 @@ func (self *CommitLoader) getExistingMainBranches() string {
lo.FilterMap(self.UserConfig.Git.MainBranches,
func(branchName string, _ int) (string, bool) {
quotedRef := self.cmd.Quote("refs/heads/" + branchName)
- if err := self.cmd.New(fmt.Sprintf("git rev-parse --verify --quiet %s", quotedRef)).DontLog().Run(); err != nil {
+ if err := self.cmd.New(
+ NewGitCmd("rev-parse").Arg("--verify", "--quiet", quotedRef).ToString(),
+ ).DontLog().Run(); err != nil {
return "", false
}
return quotedRef, true
@@ -413,9 +417,10 @@ func ignoringWarnings(commandOutput string) string {
func (self *CommitLoader) getFirstPushedCommit(refName string) (string, error) {
output, err := self.cmd.
New(
- fmt.Sprintf("git merge-base %s %s@{u}",
- self.cmd.Quote(refName),
- self.cmd.Quote(strings.TrimPrefix(refName, "refs/heads/"))),
+ NewGitCmd("merge-base").
+ Arg(self.cmd.Quote(refName)).
+ Arg(self.cmd.Quote(strings.TrimPrefix(refName, "refs/heads/")) + "@{u}").
+ ToString(),
).
DontLog().
RunWithOutput()
@@ -428,42 +433,23 @@ func (self *CommitLoader) getFirstPushedCommit(refName string) (string, error) {
// getLog gets the git log.
func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj {
- limitFlag := ""
- if opts.Limit {
- limitFlag = " -300"
- }
-
- followFlag := ""
- filterFlag := ""
- if opts.FilterPath != "" {
- followFlag = " --follow"
- filterFlag = fmt.Sprintf(" %s", self.cmd.Quote(opts.FilterPath))
- }
-
config := self.UserConfig.Git.Log
- orderFlag := ""
- if config.Order != "default" {
- orderFlag = " --" + config.Order
- }
- allFlag := ""
- if opts.All {
- allFlag = " --all"
- }
-
- return self.cmd.New(
- fmt.Sprintf(
- "git log %s%s%s --oneline %s%s --abbrev=%d%s --no-show-signature --%s",
- self.cmd.Quote(opts.RefName),
- orderFlag,
- allFlag,
- prettyFormat,
- limitFlag,
- 40,
- followFlag,
- filterFlag,
- ),
- ).DontLog()
+ cmdStr := NewGitCmd("log").
+ Arg(self.cmd.Quote(opts.RefName)).
+ ArgIf(config.Order != "default", "--"+config.Order).
+ ArgIf(opts.All, "--all").
+ Arg("--oneline").
+ Arg(prettyFormat).
+ Arg("--abbrev=40").
+ ArgIf(opts.Limit, "-300").
+ ArgIf(opts.FilterPath != "", "--follow").
+ Arg("--no-show-signature").
+ Arg("--").
+ ArgIf(opts.FilterPath != "", self.cmd.Quote(opts.FilterPath)).
+ ToString()
+
+ return self.cmd.New(cmdStr).DontLog()
}
const prettyFormat = `--pretty=format:"%H%x00%at%x00%aN%x00%ae%x00%d%x00%p%x00%s"`
diff --git a/pkg/commands/git_commands/file_loader.go b/pkg/commands/git_commands/file_loader.go
index 9f33b811a..dbd625683 100644
--- a/pkg/commands/git_commands/file_loader.go
+++ b/pkg/commands/git_commands/file_loader.go
@@ -42,7 +42,7 @@ func (self *FileLoader) GetStatusFiles(opts GetStatusFileOptions) []*models.File
}
untrackedFilesArg := fmt.Sprintf("--untracked-files=%s", untrackedFilesSetting)
- statuses, err := self.GitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
+ statuses, err := self.gitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
if err != nil {
self.Log.Error(err)
}
@@ -81,13 +81,15 @@ type FileStatus struct {
PreviousName string
}
-func (c *FileLoader) GitStatus(opts GitStatusOptions) ([]FileStatus, error) {
- noRenamesFlag := ""
- if opts.NoRenames {
- noRenamesFlag = " --no-renames"
- }
+func (c *FileLoader) gitStatus(opts GitStatusOptions) ([]FileStatus, error) {
+ cmdStr := NewGitCmd("status").
+ Arg(opts.UntrackedFilesArg).
+ Arg("--porcelain").
+ Arg("-z").
+ ArgIf(opts.NoRenames, "--no-renames").
+ ToString()
- statusLines, _, err := c.cmd.New(fmt.Sprintf("git status %s --porcelain -z%s", opts.UntrackedFilesArg, noRenamesFlag)).DontLog().RunWithOutputs()
+ statusLines, _, err := c.cmd.New(cmdStr).DontLog().RunWithOutputs()
if err != nil {
return []FileStatus{}, err
}
diff --git a/pkg/commands/git_commands/flow.go b/pkg/commands/git_commands/flow.go
index fd97707ec..fab67d81b 100644
--- a/pkg/commands/git_commands/flow.go
+++ b/pkg/commands/git_commands/flow.go
@@ -34,6 +34,7 @@ func (self *FlowCommands) FinishCmdObj(branchName string) (oscommands.ICmdObj, e
branchType := ""
for _, line := range strings.Split(strings.TrimSpace(prefixes), "\n") {
if strings.HasPrefix(line, "gitflow.prefix.") && strings.HasSuffix(line, prefix) {
+
regex := regexp.MustCompile("gitflow.prefix.([^ ]*) .*")
matches := regex.FindAllStringSubmatch(line, 1)
@@ -48,9 +49,13 @@ func (self *FlowCommands) FinishCmdObj(branchName string) (oscommands.ICmdObj, e
return nil, errors.New(self.Tr.NotAGitFlowBranch)
}
- return self.cmd.New("git flow " + branchType + " finish " + suffix), nil
+ cmdStr := NewGitCmd("flow").Arg(branchType, "finish", suffix).ToString()
+
+ return self.cmd.New(cmdStr), nil
}
func (self *FlowCommands) StartCmdObj(branchType string, name string) oscommands.ICmdObj {
- return self.cmd.New("git flow " + branchType +