summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-01-02 10:34:33 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-01-09 14:09:53 +1100
commitf503ff1ecbfda00dfa4e68e38d41aceaf9b4400c (patch)
treee113663684406ca893ebb9c223d1fddbc65abea9
parent4a1d23dc27f61e936fb3b582f02e2bba473c3b19 (diff)
start breaking up git struct
-rw-r--r--pkg/app/app.go14
-rw-r--r--pkg/commands/branches.go147
-rw-r--r--pkg/commands/branches_test.go42
-rw-r--r--pkg/commands/commits.go91
-rw-r--r--pkg/commands/commits_test.go12
-rw-r--r--pkg/commands/config.go58
-rw-r--r--pkg/commands/dummies.go21
-rw-r--r--pkg/commands/files.go353
-rw-r--r--pkg/commands/files_test.go594
-rw-r--r--pkg/commands/git.go166
-rw-r--r--pkg/commands/loaders/branches.go12
-rw-r--r--pkg/commands/loaders/commits.go20
-rw-r--r--pkg/commands/loaders/files.go11
-rw-r--r--pkg/commands/oscommands/cmd_obj.go41
-rw-r--r--pkg/commands/oscommands/cmd_obj_runner.go40
-rw-r--r--pkg/commands/oscommands/dummies.go4
-rw-r--r--pkg/commands/oscommands/exec_live.go31
-rw-r--r--pkg/commands/oscommands/exec_live_default.go11
-rw-r--r--pkg/commands/oscommands/exec_live_win.go10
-rw-r--r--pkg/commands/oscommands/gui_io.go49
-rw-r--r--pkg/commands/oscommands/os.go16
-rw-r--r--pkg/commands/patch_rebases.go150
-rw-r--r--pkg/commands/rebasing.go169
-rw-r--r--pkg/commands/rebasing_test.go73
-rw-r--r--pkg/commands/remotes.go62
-rw-r--r--pkg/commands/stash_entries.go70
-rw-r--r--pkg/commands/stash_entries_test.go26
-rw-r--r--pkg/commands/status.go43
-rw-r--r--pkg/commands/submodules.go92
-rw-r--r--pkg/commands/sync.go95
-rw-r--r--pkg/commands/sync_test.go2
-rw-r--r--pkg/commands/tags.go34
-rw-r--r--pkg/commands/working_tree.go347
-rw-r--r--pkg/commands/working_tree_test.go558
-rw-r--r--pkg/gui/branches_panel.go32
-rw-r--r--pkg/gui/cherry_picking.go2
-rw-r--r--pkg/gui/commit_files_panel.go30
-rw-r--r--pkg/gui/commit_message_panel.go2
-rw-r--r--pkg/gui/commits_panel.go50
-rw-r--r--pkg/gui/diff_context_size.go2
-rw-r--r--pkg/gui/diff_context_size_test.go6
-rw-r--r--pkg/gui/discard_changes_menu_panel.go8
-rw-r--r--pkg/gui/dummies.go3
-rw-r--r--pkg/gui/files_panel.go67
-rw-r--r--pkg/gui/global_handlers.go5
-rw-r--r--pkg/gui/gpg.go2
-rw-r--r--pkg/gui/gui.go34
-rw-r--r--pkg/gui/keybindings.go4
-rw-r--r--pkg/gui/layout.go2
-rw-r--r--pkg/gui/line_by_line_panel.go2
-rw-r--r--pkg/gui/list_context_config.go2
-rw-r--r--pkg/gui/merge_panel.go4
-rw-r--r--pkg/gui/modes.go6
-rw-r--r--pkg/gui/patch_building_panel.go20
-rw-r--r--pkg/gui/patch_options_panel.go24
-rw-r--r--pkg/gui/pty.go2
-rw-r--r--pkg/gui/pull_request_menu_panel.go2
-rw-r--r--pkg/gui/rebase_options_panel.go10
-rw-r--r--pkg/gui/recent_repos_panel.go2
-rw-r--r--pkg/gui/reflog_panel.go6
-rw-r--r--pkg/gui/remote_branches_panel.go6
-rw-r--r--pkg/gui/remotes_panel.go10
-rw-r--r--pkg/gui/reset_menu_panel.go2
-rw-r--r--pkg/gui/staging_panel.go6
-rw-r--r--pkg/gui/stash_panel.go57
-rw-r--r--pkg/gui/status_panel.go6
-rw-r--r--pkg/gui/sub_commits_panel.go2
-rw-r--r--pkg/gui/submodules_panel.go36
-rw-r--r--pkg/gui/tags_panel.go6
-rw-r--r--pkg/gui/undoing.go8
-rw-r--r--pkg/gui/workspace_reset_options_panel.go12
-rw-r--r--pkg/i18n/chinese.go5
-rw-r--r--pkg/i18n/dutch.go5
-rw-r--r--pkg/i18n/english.go10
-rw-r--r--pkg/i18n/polish.go5
-rw-r--r--pkg/utils/dummies.go5
76 files changed, 2225 insertions, 1749 deletions
diff --git a/pkg/app/app.go b/pkg/app/app.go
index c1a28ff1c..99218b0c8 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -32,7 +32,6 @@ type App struct {
closers []io.Closer
Config config.AppConfigurer
OSCommand *oscommands.OSCommand
- GitCommand *commands.GitCommand
Gui *gui.Gui
Updater *updates.Updater // may only need this on the Gui
ClientContext string
@@ -122,7 +121,7 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
return app, nil
}
- app.OSCommand = oscommands.NewOSCommand(app.Common, oscommands.GetPlatform())
+ app.OSCommand = oscommands.NewOSCommand(app.Common, oscommands.GetPlatform(), oscommands.NewNullGuiIO(log))
app.Updater, err = updates.NewUpdater(app.Common, config, app.OSCommand)
if err != nil {
@@ -134,16 +133,9 @@ func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
return app, err
}
- app.GitCommand, err = commands.NewGitCommand(
- app.Common,
- app.OSCommand,
- git_config.NewStdCachedGitConfig(app.Log),
- )
- if err != nil {
- return app, err
- }
+ gitConfig := git_config.NewStdCachedGitConfig(app.Log)
- app.Gui, err = gui.NewGui(app.Common, app.GitCommand, app.OSCommand, config, app.Updater, filterPath, showRecentRepos)
+ app.Gui, err = gui.NewGui(app.Common, config, gitConfig, app.Updater, filterPath, showRecentRepos)
if err != nil {
return app, err
}
diff --git a/pkg/commands/branches.go b/pkg/commands/branches.go
index 2276425cb..2980ae722 100644
--- a/pkg/commands/branches.go
+++ b/pkg/commands/branches.go
@@ -6,24 +6,47 @@ import (
"strings"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/utils"
)
-// NewBranch create new branch
-func (c *GitCommand) NewBranch(name string, base string) error {
- return c.Cmd.New(fmt.Sprintf("git checkout -b %s %s", c.OSCommand.Quote(name), c.OSCommand.Quote(base))).Run()
+// this takes something like:
+// * (HEAD detached at 264fc6f5)
+// remotes
+// and returns '264fc6f5' as the second match
+const CurrentBranchNameRegex = `(?m)^\*.*?([^ ]*?)\)?$`
+
+type BranchCommands struct {
+ *common.Common
+
+ cmd oscommands.ICmdObjBuilder
+}
+
+func NewBranchCommands(
+ common *common.Common,
+ cmd oscommands.ICmdObjBuilder,
+) *BranchCommands {
+ return &BranchCommands{
+ Common: common,
+ cmd: cmd,
+ }
+}
+
+// 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()
}
// CurrentBranchName get the current branch name and displayname.
// the first returned string is the name and the second is the displayname
// e.g. name is 123asdf and displayname is '(HEAD detached at 123asdf)'
-func (c *GitCommand) CurrentBranchName() (string, string, error) {
- branchName, err := c.Cmd.New("git symbolic-ref --short HEAD").DontLog().RunWithOutput()
+func (self *BranchCommands) CurrentBranchName() (string, string, error) {
+ branchName, err := self.cmd.New("git symbolic-ref --short HEAD").DontLog().RunWithOutput()
if err == nil && branchName != "HEAD\n" {
trimmedBranchName := strings.TrimSpace(branchName)
return trimmedBranchName, trimmedBranchName, nil
}
- output, err := c.Cmd.New("git branch --contains").DontLog().RunWithOutput()
+ output, err := self.cmd.New("git branch --contains").DontLog().RunWithOutput()
if err != nil {
return "", "", err
}
@@ -39,15 +62,15 @@ func (c *GitCommand) CurrentBranchName() (string, string, error) {
return "HEAD", "HEAD", nil
}
-// DeleteBranch delete branch
-func (c *GitCommand) DeleteBranch(branch string, force bool) error {
+// Delete delete branch
+func (self *BranchCommands) Delete(branch string, force bool) error {
command := "git branch -d"
if force {
command = "git branch -D"
}
- return c.Cmd.New(fmt.Sprintf("%s %s", command, c.OSCommand.Quote(branch))).Run()
+ return self.cmd.New(fmt.Sprintf("%s %s", command, self.cmd.Quote(branch))).Run()
}
// Checkout checks out a branch (or commit), with --force if you set the force arg to true
@@ -56,13 +79,13 @@ type CheckoutOptions struct {
EnvVars []string
}
-func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error {
+func (self *BranchCommands) Checkout(branch string, options CheckoutOptions) error {
forceArg := ""
if options.Force {
forceArg = " --force"
}
- return c.Cmd.New(fmt.Sprintf("git checkout%s %s", forceArg, c.OSCommand.Quote(branch))).
+ return self.cmd.New(fmt.Sprintf("git checkout%s %s", forceArg, self.cmd.Quote(branch))).
// prevents git from prompting us for input which would freeze the program
// TODO: see if this is actually needed here
AddEnvVars("GIT_TERMINAL_PROMPT=0").
@@ -70,104 +93,84 @@ func (c *GitCommand) Checkout(branch string, options CheckoutOptions) error {
Run()
}
-// GetBranchGraph gets the color-formatted graph of the log for the given branch
+// GetGraph gets the color-formatted graph of the log for the given branch
// Currently it limits the result to 100 commits, but when we get async stuff
// working we can do lazy loading
-func (c *GitCommand) GetBranchGraph(branchName string) (string, error) {
- return c.GetBranchGraphCmdObj(branchName).DontLog().RunWithOutput()
-}
-
-func (c *GitCommand) GetUpstreamForBranch(branchName string) (string, error) {
- output, err := c.Cmd.New(fmt.Sprintf("git rev-parse --abbrev-ref --symbolic-full-name %s@{u}", c.OSCommand.Quote(branchName))).DontLog().RunWithOutput()
- return strings.TrimSpace(output), err
+func (self *BranchCommands) GetGraph(branchName string) (string, error) {
+ return self.GetGraphCmdObj(branchName).DontLog().RunWithOutput()
}
-func (c *GitCommand) GetBranchGraphCmdObj(branchName string) oscommands.ICmdObj {
- branchLogCmdTemplate := c.UserConfig.Git.BranchLogCmd
+func (self *BranchCommands) GetGraphCmdObj(branchName string) oscommands.ICmdObj {
+ branchLogCmdTemplate := self.UserConfig.Git.BranchLogCmd
templateValues := map[string]string{
- "branchName": c.OSCommand.Quote(branchName),
+ "branchName": self.cmd.Quote(branchName),
}
- return c.Cmd.New(utils.ResolvePlaceholderString(branchLogCmdTemplate, templateValues)).DontLog()
+ return self.cmd.New(utils.ResolvePlaceholderString(branchLogCmdTemplate, templateValues)).DontLog()
}
-func (c *GitCommand) SetUpstreamBranch(upstream string) error {
- return c.Cmd.New("git branch -u " + c.OSCommand.Quote(upstream)).Run()
+func (self *BranchCommands) SetCurrentBranchUpstream(upstream string) error {
+ return self.cmd.New("git branch --set-upstream-to=" + self.cmd.Quote(upstream)).Run()
}
-func (c *GitCommand) SetBranchUpstream(remoteName string, remoteBranchName string, branchName string) error {
- 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 (self *BranchCommands) GetUpstream(branchName string) (string, error) {
+ output, err := self.cmd.New(fmt.Sprintf("git rev-parse --abbrev-ref --symbolic-full-name %s@{u}", self.cmd.Quote(branchName))).DontLog().RunWithOutput()
+ return strings.TrimSpace(output), err
}
-func (c *GitCommand) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
- return c.GetCommitDifferences("HEAD", "HEAD@{u}")
+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()
}
-func (c *GitCommand) GetBranchUpstreamDifferenceCount(branchName string) (string, string) {
- return c.GetCommitDifferences(branchName, branchName+"@{u}")
+func (self *BranchCommands) GetCurrentBranchUpstreamDifferenceCount() (string, string) {
+ return self.GetCommitDifferences("HEAD", "HEAD@{u}")
+}
+
+func (self *BranchCommands) GetUpstreamDifferenceCount(branchName string) (string, string) {
+ return self.GetCommitDifferences(branchName, branchName+"@{u}")
}
// GetCommitDifferences checks how many pushables/pullables there are for the
// current branch
-func (c *GitCommand) GetCommitDifferences(from, to string) (string, string) {
+func (self *BranchCommands) GetCommitDifferences(from, to string) (string, string) {
command := "git rev-list %s..%s --count"
- pushableCount, err := c.Cmd.New(fmt.Sprintf(command, to, from)).DontLog().RunWithOutput()
+ pushableCount, err := self.cmd.New(fmt.Sprintf(command, to, from)).DontLog().RunWithOutput()
if err != nil {
return "?", "?"
}
- pullableCount, err := c.Cmd.New(fmt.Sprintf(command, from, to)).DontLog().RunWithOutput()
+ pullableCount, err := self.cmd.New(fmt.Sprintf(command, from, to)).DontLog().RunWithOutput()
if err != nil {
return "?", "?"
}
return strings.TrimSpace(pushableCount), strings.TrimSpace(pullableCount)
}
+func (self *BranchCommands) IsHeadDetached() bool {
+ err := self.cmd.New("git symbolic-ref -q HEAD").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()
+}
+
+func (self *BranchCommands) GetRawBranches() (string, error) {
+ return self.cmd.New(`git for-each-ref --sort=-committerdate --format="%(HEAD)|%(refname:short)|%(upstream:short)|%(upstream:track)" refs/heads`).DontLog().RunWithOutput()
+}
+
type MergeOpts struct {
FastForwardOnly bool
}
-// Merge merge
-func (c *GitCommand) Merge(branchName string, opts MergeOpts) error {
+func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
mergeArg := ""
- if c.UserConfig.Git.Merging.Args != "" {
- mergeArg = " " + c.UserConfig.Git.Merging.Args
+ if self.UserConfig.Git.Merging.Args != "" {
+ mergeArg = " " + self.UserConfig.Git.Merging.Args
}
- command := fmt.Sprintf("git merge --no-edit%s %s", mergeArg, c.OSCommand.Quote(branchName))
+ command := fmt.Sprintf("git merge --no-edit%s %s", mergeArg, self.cmd.Quote(branchName))
if opts.FastForwardOnly {
command = fmt.Sprintf("%s --ff-only", command)
}
- return c.OSCommand.Cmd.New(command).Run()
-}
-
-// AbortMerge abort merge
-func (c *GitCommand) AbortMerge() error {
- return c.Cmd.New("git merge --abort").Run()
-}
-
-func (c *GitCommand) IsHeadDetached() bool {
- err := c.Cmd.New("git symbolic-ref -q HEAD").DontLog().Run()
- return err != nil
-}
-
-// ResetHardHead runs `git reset --hard`
-func (c *GitCommand) ResetHard(ref string) error {
- return c.Cmd.New("git reset --hard " + c.OSCommand.Quote(ref)).Run()
-}
-
-// ResetSoft runs `git reset --soft HEAD`
-func (c *GitCommand) ResetSoft(ref string) error {
- return c.Cmd.New("git reset --soft " + c.OSCommand.Quote(ref)).Run()
-}
-
-func (c *GitCommand) ResetMixed(ref string) error {
- return c.Cmd.New("git reset --mixed " + c.OSCommand.Quote(ref)).Run()
-}
-
-func (c *GitCommand) RenameBranch(oldName string, newName string) error {
- return c.Cmd.New(fmt.Sprintf("git branch --move %s %s", c.OSCommand.Quote(oldName), c.OSCommand.Quote(newName))).Run()
-}
-
-func (c *GitCommand) GetRawBranches() (string, error) {
- return c.Cmd.New(`git for-each-ref --sort=-committerdate --format="%(HEAD)|%(refname:short)|%(upstream:short)|%(upstream:track)" refs/heads`).DontLog().RunWithOutput()
+ return self.cmd.New(command).Run()
}
diff --git a/pkg/commands/branches_test.go b/pkg/commands/branches_test.go
index 633d4784e..6a2918a6b 100644
--- a/pkg/commands/branches_test.go
+++ b/pkg/commands/branches_test.go
@@ -42,7 +42,7 @@ func TestGitCommandGetCommitDifferences(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommandWithRunner(s.runner)
- pushables, pullables := gitCmd.GetCommitDifferences("HEAD", "@{u}")
+ pushables, pullables := gitCmd.Branch.GetCommitDifferences("HEAD", "@{u}")
assert.EqualValues(t, s.expectedPushables, pushables)
assert.EqualValues(t, s.expectedPullables, pullables)
s.runner.CheckForMissingCalls()
@@ -55,7 +55,7 @@ func TestGitCommandNewBranch(t *testing.T) {
Expect(`git checkout -b "test" "master"`, "", nil)
gitCmd := NewDummyGitCommandWithRunner(runner)
- assert.NoError(t, gitCmd.NewBranch("test", "master"))
+ assert.NoError(t, gitCmd.Branch.New("test", "master"))
runner.CheckForMissingCalls()
}
@@ -90,7 +90,7 @@ func TestGitCommandDeleteBranch(t *testing.T) {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommandWithRunner(s.runner)
- s.test(gitCmd.DeleteBranch("test", s.force))
+ s.test(gitCmd.Branch.Delete("test", s.force))
s.runner.CheckForMissingCalls()
})
}
@@ -101,7 +101,7 @@ func TestGitCommandMerge(t *testing.T) {
Expect(`git merge --no-edit "test"`, "", nil)
gitCmd := NewDummyGitCommandWithRunner(runner)
- assert.NoError(t, gitCmd.Merge("test", MergeOpts{}))
+ assert.NoError(t, gitCmd.Branch.Merge("test", MergeOpts{}))
runner.CheckForMissingCalls()
}
@@ -135,7 +135,7 @@ func TestGitCommandCheckout(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommandWithRunner(s.runner)
- s.test(gitCmd.Checkout("test", CheckoutOptions{Force: s.force}))
+ s.test(gitCmd.Branch.Checkout("test", CheckoutOptions{Force: s.force}))
s.runner.CheckForMissingCalls()
})
}
@@ -146,7 +146,7 @@ func TestGitCommandGetBranchGraph(t *testing.T) {
"log", "--graph", "--color=always", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium", "test", "--",
}, "", nil)
gitCmd := NewDummyGitCommandWithRunner(runner)
- _, err := gitCmd.GetBranchGraph("test")
+ _, err := gitCmd.Branch.GetGraph("test")
assert.NoError(t, err)
}
@@ -215,36 +215,8 @@ func TestGitCommandCurrentBranchName(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
gitCmd := NewDummyGitCommandWithRunner(s.runner)
- s.test(gitCmd.CurrentBranchName())
+ s.test(gitCmd.Branch.CurrentBranchName())
s.runner.CheckForMissingCalls()
})
}
}
-
-func TestGitCommandResetHard(t *testing.T) {
- type scenario struct {
- testName string
- ref string
- runner *oscommands.FakeCmdObjRunner
- test func(error)
- }
-
- scenarios := []scenario{
- {
- "valid case",
- "HEAD",
- oscommands.NewFakeRunner(t).
- Expect(`git reset --hard "HEAD"`, "", nil),
- func(err error) {
- assert.NoError(t, err)
- },
- },
- }
-
- for _, s := range scenarios {
- t.Run(s.testName, func(t *testing.T) {
- gitCmd := NewDummyGitCommandWithRunner(s.runner)
- s.test(gitCmd.ResetHard(s.ref))
- })
- }
-}
diff --git a/pkg/commands/commits.go b/pkg/commands/commits.go
index ec58de297..ba61df5a5 100644
--- a/pkg/commands/commits.go
+++ b/pkg/commands/commits.go
@@ -4,18 +4,34 @@ import (
"fmt"
"strings"
- "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/command