mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 04:15:48 +02:00
Add convenience builder for git commands
This commit is contained in:
parent
63ddc52a6b
commit
25f8b0337e
22 changed files with 711 additions and 386 deletions
|
@ -4,7 +4,6 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
|
@ -33,7 +32,7 @@ func NewWorkingTreeCommands(
|
|||
}
|
||||
|
||||
func (self *WorkingTreeCommands) OpenMergeToolCmdObj() oscommands.ICmdObj {
|
||||
return self.cmd.New("git mergetool")
|
||||
return self.cmd.New(NewGitCmd("mergetool").ToString())
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) OpenMergeTool() error {
|
||||
|
@ -49,30 +48,37 @@ func (self *WorkingTreeCommands) StageFiles(paths []string) error {
|
|||
quotedPaths := slices.Map(paths, func(path string) string {
|
||||
return self.cmd.Quote(path)
|
||||
})
|
||||
return self.cmd.New(fmt.Sprintf("git add -- %s", strings.Join(quotedPaths, " "))).Run()
|
||||
|
||||
cmdStr := NewGitCmd("add").Arg("--").Arg(quotedPaths...).ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// StageAll stages all files
|
||||
func (self *WorkingTreeCommands) StageAll() error {
|
||||
return self.cmd.New("git add -A").Run()
|
||||
cmdStr := NewGitCmd("add").Arg("-A").ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// UnstageAll unstages all files
|
||||
func (self *WorkingTreeCommands) UnstageAll() error {
|
||||
return self.cmd.New("git reset").Run()
|
||||
return self.cmd.New(NewGitCmd("reset").ToString()).Run()
|
||||
}
|
||||
|
||||
// UnStageFile unstages a file
|
||||
// we accept an array of filenames for the cases where a file has been renamed i.e.
|
||||
// we accept the current name and the previous name
|
||||
func (self *WorkingTreeCommands) UnStageFile(fileNames []string, reset bool) error {
|
||||
command := "git rm --cached --force -- %s"
|
||||
if reset {
|
||||
command = "git reset HEAD -- %s"
|
||||
}
|
||||
|
||||
for _, name := range fileNames {
|
||||
err := self.cmd.New(fmt.Sprintf(command, self.cmd.Quote(name))).Run()
|
||||
var cmdStr string
|
||||
if reset {
|
||||
cmdStr = NewGitCmd("reset").Arg("HEAD", "--", self.cmd.Quote(name)).ToString()
|
||||
} else {
|
||||
cmdStr = NewGitCmd("rm").Arg("--cached", "--force", "--", self.cmd.Quote(name)).ToString()
|
||||
}
|
||||
|
||||
err := self.cmd.New(cmdStr).Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -137,22 +143,31 @@ func (self *WorkingTreeCommands) DiscardAllFileChanges(file *models.File) error
|
|||
quotedFileName := self.cmd.Quote(file.Name)
|
||||
|
||||
if file.ShortStatus == "AA" {
|
||||
if err := self.cmd.New("git checkout --ours -- " + quotedFileName).Run(); err != nil {
|
||||
if err := self.cmd.New(
|
||||
NewGitCmd("checkout").Arg("--ours", "--", quotedFileName).ToString(),
|
||||
).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := self.cmd.New("git add -- " + quotedFileName).Run(); err != nil {
|
||||
|
||||
if err := self.cmd.New(
|
||||
NewGitCmd("add").Arg("--", quotedFileName).ToString(),
|
||||
).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if file.ShortStatus == "DU" {
|
||||
return self.cmd.New("git rm -- " + quotedFileName).Run()
|
||||
return self.cmd.New(
|
||||
NewGitCmd("rm").Arg("rm", "--", quotedFileName).ToString(),
|
||||
).Run()
|
||||
}
|
||||
|
||||
// if the file isn't tracked, we assume you want to delete it
|
||||
if file.HasStagedChanges || file.HasMergeConflicts {
|
||||
if err := self.cmd.New("git reset -- " + quotedFileName).Run(); err != nil {
|
||||
if err := self.cmd.New(
|
||||
NewGitCmd("reset").Arg("--", quotedFileName).ToString(),
|
||||
).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +199,8 @@ func (self *WorkingTreeCommands) DiscardUnstagedDirChanges(node IFileNode) error
|
|||
}
|
||||
|
||||
quotedPath := self.cmd.Quote(node.GetPath())
|
||||
if err := self.cmd.New("git checkout -- " + quotedPath).Run(); err != nil {
|
||||
cmdStr := NewGitCmd("checkout").Arg("--", quotedPath).ToString()
|
||||
if err := self.cmd.New(cmdStr).Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -209,7 +225,8 @@ func (self *WorkingTreeCommands) RemoveUntrackedDirFiles(node IFileNode) error {
|
|||
// DiscardUnstagedFileChanges directly
|
||||
func (self *WorkingTreeCommands) DiscardUnstagedFileChanges(file *models.File) error {
|
||||
quotedFileName := self.cmd.Quote(file.Name)
|
||||
return self.cmd.New("git checkout -- " + quotedFileName).Run()
|
||||
cmdStr := NewGitCmd("checkout").Arg("--", quotedFileName).ToString()
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// Ignore adds a file to the gitignore for the repo
|
||||
|
@ -230,30 +247,28 @@ func (self *WorkingTreeCommands) WorktreeFileDiff(file *models.File, plain bool,
|
|||
}
|
||||
|
||||
func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain bool, cached bool, ignoreWhitespace bool) oscommands.ICmdObj {
|
||||
cachedArg := ""
|
||||
trackedArg := "--"
|
||||
colorArg := self.UserConfig.Git.Paging.ColorArg
|
||||
quotedPath := self.cmd.Quote(node.GetPath())
|
||||
quotedPrevPath := ""
|
||||
ignoreWhitespaceArg := ""
|
||||
contextSize := self.UserConfig.Git.DiffContextSize
|
||||
if cached {
|
||||
cachedArg = " --cached"
|
||||
}
|
||||
if !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile() {
|
||||
trackedArg = "--no-index -- /dev/null"
|
||||
}
|
||||
if plain {
|
||||
colorArg = "never"
|
||||
}
|
||||
if ignoreWhitespace {
|
||||
ignoreWhitespaceArg = " --ignore-all-space"
|
||||
}
|
||||
if prevPath := node.GetPreviousPath(); prevPath != "" {
|
||||
quotedPrevPath = " " + self.cmd.Quote(prevPath)
|
||||
}
|
||||
|
||||
cmdStr := fmt.Sprintf("git diff --submodule --no-ext-diff --unified=%d --color=%s%s%s %s %s%s", contextSize, colorArg, ignoreWhitespaceArg, cachedArg, trackedArg, quotedPath, quotedPrevPath)
|
||||
contextSize := self.UserConfig.Git.DiffContextSize
|
||||
prevPath := node.GetPreviousPath()
|
||||
noIndex := !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile()
|
||||
|
||||
cmdStr := NewGitCmd("diff").
|
||||
Arg("--submodule").
|
||||
Arg("--no-ext-diff").
|
||||
Arg(fmt.Sprintf("--unified=%d", contextSize)).
|
||||
Arg(fmt.Sprintf("--color=%s", colorArg)).
|
||||
ArgIf(ignoreWhitespace, "--ignore-all-space").
|
||||
ArgIf(cached, "--cached").
|
||||
ArgIf(noIndex, "--no-index").
|
||||
Arg("--").
|
||||
ArgIf(noIndex, "/dev/null").
|
||||
Arg(self.cmd.Quote(node.GetPath())).
|
||||
ArgIf(prevPath != "", self.cmd.Quote(prevPath)).
|
||||
ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).DontLog()
|
||||
}
|
||||
|
@ -296,49 +311,59 @@ func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bo
|
|||
func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool,
|
||||
ignoreWhitespace bool,
|
||||
) oscommands.ICmdObj {
|
||||
colorArg := self.UserConfig.Git.Paging.ColorArg
|
||||
contextSize := self.UserConfig.Git.DiffContextSize
|
||||
|
||||
colorArg := self.UserConfig.Git.Paging.ColorArg
|
||||
if plain {
|
||||
colorArg = "never"
|
||||
}
|
||||
|
||||
reverseFlag := ""
|
||||
if reverse {
|
||||
reverseFlag = " -R"
|
||||
}
|
||||
cmdStr := NewGitCmd("diff").
|
||||
Arg("--submodule").
|
||||
Arg("--no-ext-diff").
|
||||
Arg(fmt.Sprintf("--unified=%d", contextSize)).
|
||||
Arg("--no-renames").
|
||||
Arg(fmt.Sprintf("--color=%s", colorArg)).
|
||||
Arg(from).
|
||||
Arg(to).
|
||||
ArgIf(reverse, "-R").
|
||||
ArgIf(ignoreWhitespace, "--ignore-all-space").
|
||||
Arg("--").
|
||||
Arg(self.cmd.Quote(fileName)).
|
||||
ToString()
|
||||
|
||||
ignoreWhitespaceFlag := ""
|
||||
if ignoreWhitespace {
|
||||
ignoreWhitespaceFlag = " --ignore-all-space"
|
||||
}
|
||||
|
||||
return self.cmd.
|
||||
New(
|
||||
fmt.Sprintf(
|
||||
"git diff --submodule --no-ext-diff --unified=%d --no-renames --color=%s%s%s%s%s -- %s",
|
||||
contextSize, colorArg, pad(from), pad(to), reverseFlag, ignoreWhitespaceFlag, self.cmd.Quote(fileName)),
|
||||
).
|
||||
DontLog()
|
||||
return self.cmd.New(cmdStr).DontLog()
|
||||
}
|
||||
|
||||
// CheckoutFile checks out the file for the given commit
|
||||
func (self *WorkingTreeCommands) CheckoutFile(commitSha, fileName string) error {
|
||||
return self.cmd.New(fmt.Sprintf("git checkout %s -- %s", commitSha, self.cmd.Quote(fileName))).Run()
|
||||
cmdStr := NewGitCmd("checkout").Arg(commitSha, "--", self.cmd.Quote(fileName)).
|
||||
ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// DiscardAnyUnstagedFileChanges discards any unstages file changes via `git checkout -- .`
|
||||
// DiscardAnyUnstagedFileChanges discards any unstaged file changes via `git checkout -- .`
|
||||
func (self *WorkingTreeCommands) DiscardAnyUnstagedFileChanges() error {
|
||||
return self.cmd.New("git checkout -- .").Run()
|
||||
cmdStr := NewGitCmd("checkout").Arg("--", ".").
|
||||
ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// RemoveTrackedFiles will delete the given file(s) even if they are currently tracked
|
||||
func (self *WorkingTreeCommands) RemoveTrackedFiles(name string) error {
|
||||
return self.cmd.New("git rm -r --cached -- " + self.cmd.Quote(name)).Run()
|
||||
cmdStr := NewGitCmd("rm").Arg("-r", "--cached", "--", self.cmd.Quote(name)).
|
||||
ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// RemoveUntrackedFiles runs `git clean -fd`
|
||||
func (self *WorkingTreeCommands) RemoveUntrackedFiles() error {
|
||||
return self.cmd.New("git clean -fd").Run()
|
||||
cmdStr := NewGitCmd("clean").Arg("-fd").ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// ResetAndClean removes all unstaged changes and removes all untracked files
|
||||
|
@ -363,23 +388,23 @@ func (self *WorkingTreeCommands) ResetAndClean() error {
|
|||
|
||||
// ResetHardHead runs `git reset --hard`
|
||||
func (self *WorkingTreeCommands) ResetHard(ref string) error {
|
||||
return self.cmd.New("git reset --hard " + self.cmd.Quote(ref)).Run()
|
||||
cmdStr := NewGitCmd("reset").Arg("--hard", self.cmd.Quote(ref)).
|
||||
ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
// ResetSoft runs `git reset --soft HEAD`
|
||||
func (self *WorkingTreeCommands) ResetSoft(ref string) error {
|
||||
return self.cmd.New("git reset --soft " + self.cmd.Quote(ref)).Run()
|
||||
cmdStr := NewGitCmd("reset").Arg("--soft", self.cmd.Quote(ref)).
|
||||
ToString()
|
||||
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) ResetMixed(ref string) error {
|
||||
return self.cmd.New("git reset --mixed " + self.cmd.Quote(ref)).Run()
|
||||
}
|
||||
cmdStr := NewGitCmd("reset").Arg("--mixed", self.cmd.Quote(ref)).
|
||||
ToString()
|
||||
|
||||
// so that we don't have unnecessary space in our commands we use this helper function to prepend spaces to args so that in the format string we can go '%s%s%s' and if any args are missing we won't have gaps.
|
||||
func pad(str string) string {
|
||||
if str == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return " " + str
|
||||
return self.cmd.New(cmdStr).Run()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue