summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2021-12-30 17:19:01 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-01-04 09:07:15 +1100
commit9b2b0fc1226ebe0858fcbed59d87bcaae8c8a2e9 (patch)
tree8d7a9e4c321e40a9b0dab0f2260ec4131fb0eefe /pkg
parent96c2887fd0c1ca95e6b3d55756be8d424f8d905a (diff)
WIP
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/branches.go7
-rw-r--r--pkg/commands/branches_test.go222
-rw-r--r--pkg/commands/dummies.go9
-rw-r--r--pkg/commands/files.go6
-rw-r--r--pkg/commands/git.go8
-rw-r--r--pkg/commands/loaders/branches.go26
-rw-r--r--pkg/commands/loaders/commit_files.go57
-rw-r--r--pkg/commands/loaders/commits.go15
-rw-r--r--pkg/commands/loaders/commits_test.go2
-rw-r--r--pkg/commands/loaders/files.go (renamed from pkg/commands/loading_files.go)40
-rw-r--r--pkg/commands/loaders/files_test.go203
-rw-r--r--pkg/commands/loading_commit_files.go43
-rw-r--r--pkg/commands/loading_files_test.go227
-rw-r--r--pkg/commands/oscommands/dummies.go2
-rw-r--r--pkg/commands/oscommands/fake_cmd_obj_runner.go28
-rw-r--r--pkg/commands/oscommands/os.go2
-rw-r--r--pkg/commands/oscommands/os_test.go2
-rw-r--r--pkg/commands/stash_entries.go11
-rw-r--r--pkg/gui/commit_files_panel.go3
-rw-r--r--pkg/gui/commits_panel.go4
-rw-r--r--pkg/gui/files_panel.go5
-rw-r--r--pkg/gui/sub_commits_panel.go2
22 files changed, 453 insertions, 471 deletions
diff --git a/pkg/commands/branches.go b/pkg/commands/branches.go
index e3c40d343..ef1838e9e 100644
--- a/pkg/commands/branches.go
+++ b/pkg/commands/branches.go
@@ -127,9 +127,12 @@ type MergeOpts struct {
// Merge merge
func (c *GitCommand) Merge(branchName string, opts MergeOpts) error {
- mergeArgs := c.UserConfig.Git.Merging.Args
+ mergeArg := ""
+ if c.UserConfig.Git.Merging.Args != "" {
+ mergeArg = " " + c.UserConfig.Git.Merging.Args
+ }
- command := fmt.Sprintf("git merge --no-edit %s %s", mergeArgs, c.OSCommand.Quote(branchName))
+ command := fmt.Sprintf("git merge --no-edit%s %s", mergeArg, c.OSCommand.Quote(branchName))
if opts.FastForwardOnly {
command = fmt.Sprintf("%s --ff-only", command)
}
diff --git a/pkg/commands/branches_test.go b/pkg/commands/branches_test.go
index 45cfb8315..58a3e1cc4 100644
--- a/pkg/commands/branches_test.go
+++ b/pkg/commands/branches_test.go
@@ -1,120 +1,85 @@
package commands
import (
- "os/exec"
"testing"
- "github.com/jesseduffield/lazygit/pkg/secureexec"
- "github.com/jesseduffield/lazygit/pkg/test"
+ "github.com/go-errors/errors"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/stretchr/testify/assert"
)
-// TestGitCommandGetCommitDifferences is a function.
func TestGitCommandGetCommitDifferences(t *testing.T) {
type scenario struct {
- testName string
- command func(string, ...string) *exec.Cmd
- test func(string, string)
+ testName string
+ runner *oscommands.FakeCmdObjRunner
+ expectedPushables string
+ expectedPullables string
}
scenarios := []scenario{
{
"Can't retrieve pushable count",
- func(string, ...string) *exec.Cmd {
- return secureexec.Command("test")
- },
- func(pushableCount string, pullableCount string) {
- assert.EqualValues(t, "?", pushableCount)
- assert.EqualValues(t, "?", pullableCount)
- },
+ oscommands.NewFakeRunner(t).
+ Expect("git rev-list @{u}..HEAD --count", "", errors.New("error")),
+ "?", "?",
},
{
"Can't retrieve pullable count",
- func(cmd string, args ...string) *exec.Cmd {
- if args[1] == "HEAD..@{u}" {
- return secureexec.Command("test")
- }
-
- return secureexec.Command("echo")
- },
- func(pushableCount string, pullableCount string) {
- assert.EqualValues(t, "?", pushableCount)
- assert.EqualValues(t, "?", pullableCount)
- },
+ oscommands.NewFakeRunner(t).
+ Expect("git rev-list @{u}..HEAD --count", "1\n", nil).
+ Expect("git rev-list HEAD..@{u} --count", "", errors.New("error")),
+ "?", "?",
},
{
"Retrieve pullable and pushable count",
- func(cmd string, args ...string) *exec.Cmd {
- if args[1] == "HEAD..@{u}" {
- return secureexec.Command("echo", "10")
- }
-
- return secureexec.Command("echo", "11")
- },
- func(pushableCount string, pullableCount string) {
- assert.EqualValues(t, "11", pushableCount)
- assert.EqualValues(t, "10", pullableCount)
- },
+ oscommands.NewFakeRunner(t).
+ Expect("git rev-list @{u}..HEAD --count", "1\n", nil).
+ Expect("git rev-list HEAD..@{u} --count", "2\n", nil),
+ "1", "2",
},
}
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = s.command
- s.test(gitCmd.GetCommitDifferences("HEAD", "@{u}"))
+ gitCmd := NewDummyGitCommandWithRunner(s.runner)
+ pushables, pullables := gitCmd.GetCommitDifferences("HEAD", "@{u}")
+ assert.EqualValues(t, s.expectedPushables, pushables)
+ assert.EqualValues(t, s.expectedPullables, pullables)
+ s.runner.CheckForMissingCalls()
})
}
}
-// TestGitCommandNewBranch is a function.
func TestGitCommandNewBranch(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"checkout", "-b", "test", "master"}, args)
-
- return secureexec.Command("echo")
- }
+ runner := oscommands.NewFakeRunner(t).
+ Expect(`git checkout -b "test" "master"`, "", nil)
+ gitCmd := NewDummyGitCommandWithRunner(runner)
assert.NoError(t, gitCmd.NewBranch("test", "master"))
+ runner.CheckForMissingCalls()
}
-// TestGitCommandDeleteBranch is a function.
func TestGitCommandDeleteBranch(t *testing.T) {
type scenario struct {
testName string
- branch string
force bool
- command func(string, ...string) *exec.Cmd
+ runner *oscommands.FakeCmdObjRunner
test func(error)
}
scenarios := []scenario{
{
"Delete a branch",
- "test",
false,
- func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"branch", "-d", "test"}, args)
-
- return secureexec.Command("echo")
- },
+ oscommands.NewFakeRunner(t).Expect(`git branch -d "test"`, "", nil),
func(err error) {
assert.NoError(t, err)
},
},
{
"Force delete a branch",
- "test",
true,
- func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"branch", "-D", "test"}, args)
-
- return secureexec.Command("echo")
- },
+ oscommands.NewFakeRunner(t).Expect(`git branch -D "test"`, "", nil),
func(err error) {
assert.NoError(t, err)
},
@@ -123,31 +88,27 @@ func TestGitCommandDeleteBranch(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = s.command
- s.test(gitCmd.DeleteBranch(s.branch, s.force))
+ gitCmd := NewDummyGitCommandWithRunner(s.runner)
+
+ s.test(gitCmd.DeleteBranch("test", s.force))
+ s.runner.CheckForMissingCalls()
})
}
}
-// TestGitCommandMerge is a function.
func TestGitCommandMerge(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"merge", "--no-edit", "test"}, args)
-
- return secureexec.Command("echo")
- }
+ runner := oscommands.NewFakeRunner(t).
+ Expect(`git merge --no-edit "test"`, "", nil)
+ gitCmd := NewDummyGitCommandWithRunner(runner)
assert.NoError(t, gitCmd.Merge("test", MergeOpts{}))
+ runner.CheckForMissingCalls()
}
-// TestGitCommandCheckout is a function.
func TestGitCommandCheckout(t *testing.T) {
type scenario struct {
testName string
- command func(string, ...string) *exec.Cmd
+ runner *oscommands.FakeCmdObjRunner
test func(error)
force bool
}
@@ -155,12 +116,7 @@ func TestGitCommandCheckout(t *testing.T) {
scenarios := []scenario{
{
"Checkout",
- func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"checkout", "test"}, args)
-
- return secureexec.Command("echo")
- },
+ oscommands.NewFakeRunner(t).Expect(`git checkout "test"`, "", nil),
func(err error) {
assert.NoError(t, err)
},
@@ -168,12 +124,7 @@ func TestGitCommandCheckout(t *testing.T) {
},
{
"Checkout forced",
- func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"checkout", "--force", "test"}, args)
-
- return secureexec.Command("echo")
- },
+ oscommands.NewFakeRunner(t).Expect(`git checkout --force "test"`, "", nil),
func(err error) {
assert.NoError(t, err)
},
@@ -183,52 +134,43 @@ func TestGitCommandCheckout(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = s.command
+ gitCmd := NewDummyGitCommandWithRunner(s.runner)
s.test(gitCmd.Checkout("test", CheckoutOptions{Force: s.force}))
+ s.runner.CheckForMissingCalls()
})
}
}
-// TestGitCommandGetBranchGraph is a function.
func TestGitCommandGetBranchGraph(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"log", "--graph", "--color=always", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium", "test", "--"}, args)
- return secureexec.Command("echo")
- }
+ runner := oscommands.NewFakeRunner(t).ExpectArgs([]string{
+ "git", "log", "--graph", "--color=always", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium", "test", "--",
+ }, "", nil)
+ gitCmd := NewDummyGitCommandWithRunner(runner)
_, err := gitCmd.GetBranchGraph("test")
assert.NoError(t, err)
}
func TestGitCommandGetAllBranchGraph(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
- assert.EqualValues(t, []string{"log", "--graph", "--all", "--color=always", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium"}, args)
- return secureexec.Command("echo")
- }
+ runner := oscommands.NewFakeRunner(t).ExpectArgs([]string{
+ "git", "log", "--graph", "--all", "--color=always", "--abbrev-commit", "--decorate", "--date=relative", "--pretty=medium",
+ }, "", nil)
+ gitCmd := NewDummyGitCommandWithRunner(runner)
cmdStr := gitCmd.UserConfig.Git.AllBranchesLogCmd
_, err := gitCmd.Cmd.New(cmdStr).RunWithOutput()
assert.NoError(t, err)
}
-// TestGitCommandCurrentBranchName is a function.
func TestGitCommandCurrentBranchName(t *testing.T) {
type scenario struct {
testName string
- command func(string, ...string) *exec.Cmd
+ runner *oscommands.FakeCmdObjRunner
test func(string, string, error)
}
scenarios := []scenario{
{
"says we are on the master branch if we are",
- func(cmd string, args ...string) *exec.Cmd {
- assert.Equal(t, "git", cmd)
- return secureexec.Command("echo", "master")
- },
+ oscommands.NewFakeRunner(t).Expect(`git symbolic-ref --short HEAD`, "master", nil),
func(name string, displayname string, err error) {
assert.NoError(t, err)
assert.EqualValues(t, "master", name)
@@ -237,20 +179,9 @@ func TestGitCommandCurrentBranchName(t *testing.T) {
},
{
"falls back to git `git branch --contains` if symbolic-ref fails",
- func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
-
- switch args[0] {
- case "symbolic-ref":
- assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args)
- return secureexec.Command("test")
- case "branch":
- assert.EqualValues(t, []string{"branch", "--contains"}, args)
- return secureexec.Command("echo", "* master")
- }
-
- return nil
- },
+ oscommands.NewFakeRunner(t).
+ Expect(`git symbolic-ref --short HEAD`, "", errors.New("error")).
+ Expect(`git branch --contains`, "* master", nil),
func(name string, displayname string, err error) {
assert.NoError(t, err)
assert.EqualValues(t, "master", name)
@@ -259,20 +190,9 @@ func TestGitCommandCurrentBranchName(t *testing.T) {
},
{
"handles a detached head",
- func(cmd string, args ...string) *exec.Cmd {
- assert.EqualValues(t, "git", cmd)
-
- switch args[0] {
- case "symbolic-ref":
- assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args)
- return secureexec.Command("test")
- case "branch":
- assert.EqualValues(t, []string{"branch", "--contains"}, args)
- return secureexec.Command("echo", "* (HEAD detached at 123abcd)")
- }
-
- return nil
- },
+ oscommands.NewFakeRunner(t).
+ Expect(`git symbolic-ref --short HEAD`, "", errors.New("error")).
+ Expect(`git branch --contains`, "* (HEAD detached at 123abcd)", nil),
func(name string, displayname string, err error) {
assert.NoError(t, err)
assert.EqualValues(t, "123abcd", name)
@@ -281,10 +201,9 @@ func TestGitCommandCurrentBranchName(t *testing.T) {
},
{
"bubbles up error if there is one",
- func(cmd string, args ...string) *exec.Cmd {
- assert.Equal(t, "git", cmd)
- return secureexec.Command("test")
- },
+ oscommands.NewFakeRunner(t).
+ Expect(`git symbolic-ref --short HEAD`, "", errors.New("error")).
+ Expect(`git branch --contains`, "", errors.New("error")),
func(name string, displayname string, err error) {
assert.Error(t, err)
assert.EqualValues(t, "", name)
@@ -295,19 +214,18 @@ func TestGitCommandCurrentBranchName(t *testing.T) {
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
- gitCmd := NewDummyGitCommand()
- gitCmd.OSCommand.Command = s.command
+ gitCmd := NewDummyGitCommandWithRunner(s.runner)
s.test(gitCmd.CurrentBranchName())
+ s.runner.CheckForMissingCalls()
})
}
}
-// TestGitCommandResetHard is a function.
func TestGitCommandResetHard(t *testing.T) {
type scenario struct {
testName string
ref string
- command func(string, ...string) *exec.Cmd
+ runner *oscommands.FakeCmdObjRunner
test func(error)
}
@@ -315,23 +233,17 @@ func TestGitCommandResetHard(t *testing.T) {
{
"valid case",
"HEAD",
- test.CreateMockCommand(t, []*test.CommandSwapper{
- {
- Expect: `git reset --hard HEAD`,
- Replace: "echo",
- },
- }),
+ oscommands.NewFakeRunner(t).
+ Expect(`git reset --hard "HEAD"`, "", nil),
func(err error) {
assert.NoError(t, err)
},
},
}
- gitCmd := NewDummyGitCommand()
-
for _, s := range scenarios {
t.Run(s.testName, func(t *testing.T) {
- gitCmd.OSCommand.Command = s.command
+ gitCmd := NewDummyGitCommandWithRunner(s.runner)
s.test(gitCmd.ResetHard(s.ref))
})
}
diff --git a/pkg/commands/dummies.go b/pkg/commands/dummies.go
index c17179c8e..126007baa 100644
--- a/pkg/commands/dummies.go
+++ b/pkg/commands/dummies.go
@@ -23,3 +23,12 @@ func NewDummyGitCommandWithOSCommand(osCommand *oscommands.OSCommand) *GitComman
GetCmdWriter: func() io.Writer { return ioutil.Discard },
}
}
+
+func NewDummyGitCommandWithRunner(runner oscommands.ICmdObjRunner) *GitCommand {
+ builder := oscommands.NewDummyCmdObjBuilder(runner)
+ gitCommand := NewDummyGitCommand()
+ gitCommand.Cmd = builder
+ gitCommand.OSCommand.Cmd = builder
+
+ return gitCommand
+}
diff --git a/pkg/commands/files.go b/pkg/commands/files.go
index da451e80c..2d118c749 100644
--- a/pkg/commands/files.go
+++ b/pkg/commands/files.go
@@ -9,6 +9,7 @@ import (
"time"
"github.com/go-errors/errors"
+ "github.com/jesseduffield/lazygit/pkg/commands/loaders"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
@@ -75,7 +76,10 @@ func (c *GitCommand) BeforeAndAfterFileForRename(file *models.File) (*models.Fil
// all files, passing the --no-renames flag and then recursively call the function
// again for the before file and after file.
- filesWithoutRenames := c.GetStatusFiles(GetStatusFileOptions{NoRenames: true})
+ filesWithoutRenames := loaders.
+ NewFileLoader(c.Common, c.Cmd, c.GitConfig).
+ GetStatusFiles(loaders.GetStatusFileOptions{NoRenames: true})
+
var beforeFile *models.File
var afterFile *models.File
for _, f := range filesWithoutRenames {
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index 950042780..90fd7b262 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -223,3 +223,11 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam
func VerifyInGitRepo(osCommand *oscommands.OSCommand) error {
return osCommand.Cmd.New("git rev-parse --git-dir").Run()
}
+
+func (c *GitCommand) GetDotGitDir() string {
+ return c.DotGitDir
+}
+
+func (c *GitCommand) GetCmd() oscommands.ICmdObjBuilder {
+ return c.Cmd
+}
diff --git a/pkg/commands/loaders/branches.go b/pkg/commands/loaders/branches.go
index fc3c15fc9..60e4f7aac 100644
--- a/pkg/commands/loaders/branches.go
+++ b/pkg/commands/loaders/branches.go
@@ -4,7 +4,6 @@ import (
"regexp"
"strings"
- "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/utils"
@@ -29,9 +28,14 @@ type BranchLoader struct {
reflogCommits []*models.Commit
}
+type BranchLoaderGitCommand interface {
+ GetRawBranches() (string, error)
+ CurrentBranchName() (string, string, error)
+}
+
func NewBranchLoader(
cmn *common.Common,
- gitCommand *commands.GitCommand,
+ gitCommand BranchLoaderGitCommand,
reflogCommits []*models.Commit,
) *BranchLoader {
return &BranchLoader{
@@ -43,10 +47,10 @@ func NewBranchLoader(
}
// Load the list of branches for the current repo
-func (b *BranchLoader) Load() []*models.Branch {
- branches := b.obtainBranches()
+func (self *BranchLoader) Load() []*models.Branch {
+ branches := self.obtainBranches()
- reflogBranches := b.obtainReflogBranches()
+ reflogBranches := self.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)
@@ -78,7 +82,7 @@ outer:
}
}
if !foundHead {
- currentBranchName, currentBranchDisplayName, err := b.getCurrentBranchName()
+ currentBranchName, currentBranchDisplayName, err := self.getCurrentBranchName()
if err != nil {
panic(err)
}
@@ -87,8 +91,8 @@ outer:
return branches
}
-func (b *BranchLoader) obtainBranches() []*models.Branch {
- output, err := b.getRawBranches()
+func (self *BranchLoader) obtainBranches() []*models.Branch {
+ output, err := self.getRawBranches()
if err != nil {
panic(err)
}
@@ -150,11 +154,11 @@ func (b *BranchLoader) obtainBranches() []*models.Branch {
// TODO: only look at the new reflog commits, and otherwise store the recencies in
// int form against the branch to recalculate the time ago
-func (b *BranchLoader) obtainReflogBranches() []*models.Branch {
+func (self *BranchLoader) obtainReflogBranches() []*models.Branch {
foundBranchesMap := map[string]bool{}
re := regexp.MustCompile(`checkout: moving from ([\S]+) to ([\S]+)`)
- reflogBranches := make([]*models.Branch, 0, len(b.reflogCommits))
- for _, commit := range b.reflogCommits {
+ reflogBranches := make([]*models.Branch, 0, len(self.reflogCommits))
+ for _, commit := range self.reflogCommits {
if match := re.FindStringSubmatch(commit.Name); len(match) == 3 {
recency := utils.UnixToTimeAgo(commit.UnixTimestamp)
for _, branchName := range match[1:] {
diff --git a/pkg/commands/loaders/commit_files.go b/pkg/commands/loaders/commit_files.go
new file mode 100644
index 000000000..1b65737ec
--- /dev/null
+++ b/pkg/commands/loaders/commit_files.go
@@ -0,0 +1,57 @@
+package loaders
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/jesseduffield/lazygit/pkg/common"
+)
+
+type CommitFileLoader struct {
+ *common.Common
+ cmd oscommands.ICmdObjBuilder
+}
+
+func NewCommitFileLoader(common *common.Common, cmd oscommands.ICmdObjBuilder) *CommitFileLoader {
+ return &CommitFileLoader{
+ Common: common,
+ cmd: cmd,
+ }
+}
+
+// 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)).RunWithOutput()
+ if err != nil {
+ return nil, err
+ }
+
+ return self.getCommitFilesFromFilenames(filenames), nil
+}
+
+// filenames string is something like "file1\nfile2\nfile3"
+func (self *CommitFileLoader) getCommitFilesFromFilenames(filenames string) []*models.CommitFile {
+ commitFiles := make([]*models.CommitFile, 0)
+
+ lines := strings.Split(strings.TrimRight(filenames, "\x00"), "\x00")
+ n := len(lines)
+ for i := 0; i < n-1; i += 2 {
+ // typical result looks like 'A my_file' meaning my_file was added
+ changeStatus := lines[i]
+ name := lines[i+1]
+
+ commitFiles = append(commitFiles, &models.CommitFile{
+ Name: name,
+ ChangeStatus: changeStatus,
+ })
+ }
+
+ return commitFiles
+}
diff --git a/pkg/commands/loaders/commits.go b/pkg/commands/loaders/commits.go
index bbd520c81..6f2336e3a 100644
--- a/pkg/commands/loaders/commits.go
+++ b/pkg/commands/loaders/commits.go
@@ -9,7 +9,6 @@ import (
"strconv"
"strings"
- "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
@@ -37,20 +36,26 @@ type CommitLoader struct {
dotGitDir string
}
+type CommitLoaderGitCommand interface {
+ CurrentBranchName() (string, string, error)
+ RebaseMode() (enums.RebaseMode, error)
+ GetCmd() oscommands.ICmdObjBuilder
+ GetDotGitDir() string
+}
+
// making our dependencies explicit for the sake of easier testing
func NewCommitLoader(
cmn *common.Common,
- gitCommand *commands.GitCommand,
- osCommand *oscommands.OSCommand,
+ gitCommand CommitLoaderGitCommand,
) *CommitLoader {
return &CommitLoader{
Common: cmn,
- cmd: gitCommand.Cmd,
+ cmd: gitCommand.GetCmd(),
getCurrentBranchName: gitCommand.CurrentBranchName,
getRebaseMode: gitCommand.RebaseMode,
readFile: ioutil.ReadFile,
walkFiles: filepath.Walk,
- dotGitDir: gitCommand.DotGitDir,
+ dotGitDir: gitCommand.GetDotGitDir(),
}
}
diff --git a/pkg/commands/loaders/commits_test.go b/pkg/commands/loaders/commits_test.go
index f793567f7..5491fb4a5 100644
--- a/pkg/commands/loaders/commits_test.go
+++ b/pkg/commands/loaders/commits_test.go
@@ -189,7 +189,7 @@ func TestGetCommits(t *testing.T) {
t.Run(scenario.testName, func(t *testing.T) {
builder := &CommitLoader{
Common: utils.NewDummyCommon(),
- cmd: oscommands.NewCmdObjBuilderDummy(scenario.runner),
+ cmd: oscommands.NewDummyCmdObjBuilder(scenario.runner),
getCurrentBranchName: func() (string, string, error) {
return scenario.currentBranchName, scenario.currentBranchName, nil
},
diff --git a/pkg/commands/loading_files.go b/pkg/commands/loaders/files.go
index e28613c07..a1964a2b9 100644
--- a/pkg/commands/loading_files.go
+++ b/pkg/commands/loaders/files.go
@@ -1,36 +1,54 @@
-package commands
+package loaders
import (
"fmt"
"strings"
+ "github.com/jesseduffield/lazygit/pkg/commands/git_config"
"github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/utils"
)
-// GetStatusFiles git status files
+type FileLoader struct {
+ *common.Common
+ cmd oscommands.ICmdObjBuilder
+ gitConfig git_config.IGitConfig
+ getFileType func(string) string
+}
+
+func NewFileLoader(cmn *common.Common, cmd oscommands.ICmdObjBuilder, gitConfig git_config.IGitConfig) *FileLoader {
+ return &FileLoader{
+ Common: cmn,
+ cmd: cmd,
+ gitConfig: gitConfig,
+ getFileType: oscommands.FileType,
+ }
+}
+
type GetStatusFileOptions struct {
NoRenames bool
}
-func (c *GitCommand) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
+func (self *FileLoader) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
// check if config wants us ignoring untracked files
- untrackedFilesSetting := c.GitConfig.Get("status.showUntrackedFiles")
+ untrackedFilesSetting := self.gitConfig.Get("status.showUntrackedFiles")
if untrackedFilesSetting == "" {
untrackedFilesSetting = "all"
}
untrackedFilesArg := fmt.Sprintf("--untracked-files=%s", untrackedFilesSetting)
- statuses, err := c.GitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
+ statuses, err := self.GitStatus(GitStatusOptions{NoRenames: opts.NoRenames, UntrackedFilesArg: untrackedFilesArg})
if err != nil {
- c.Log.Error(err)
+ self.Log.Error(err)
}
files := []*models.File{}
for _, status := range statuses {
if strings.HasPrefix(status.StatusString, "warning") {
- c.Log.Warningf("warning when calling git status: %s", status.StatusString)
+ self.Log.Warningf("warning when calling git status: %s", status.StatusString)
continue
}
change := status.Change
@@ -52,7 +70,7 @@ func (c *GitCommand) GetStatusFiles(opts GetStatusFileOptions) []*models.File {
Added: unstagedChange == "A" || untracked,
HasMergeConflicts: hasMergeConflicts,
HasInlineMergeConflicts: hasInlineMergeConflicts,
- Type: c.OSCommand.FileType(status.Name),
+ Type: self.getFileType(status.Name),
ShortStatus: change,
}
files = append(files, file)
@@ -74,13 +92,13 @@ type FileStatus struct {
PreviousName string
}
-func (c *GitCommand) GitStatus(opts GitStatusOptions) ([]FileStatus, error) {
+func (c *FileLoader) GitStatus(opts GitStatusOptions) ([]FileStatus, error) {
noRenamesFlag := ""
if opts.NoRenames {
- noRenamesFlag = "--no-renames"
+ noRenamesFlag = " --no-renames"
}
- statusLines, err := c.Cmd.New(fmt.Sprintf("git status %s --porcelain -z %s", opts.UntrackedFilesArg, noRenamesFlag)).RunWithOutput()
+ statusLines, err := c.cmd.New(fmt.Sprintf("git status %s --porcelain -z%s", opts.UntrackedFilesArg, noRenamesFlag)).RunWithOutput()
if err != nil {
return []FileStatus{}, err
}
diff --git a/pkg/commands/loaders/files_test.go b/pkg/commands/loaders/files_test.go
new file mode 100644
index 000000000..1613290bb
--- /dev/null
+++ b/pkg/commands/loaders/files_test.go
@@ -0,0 +1,203 @@
+package loaders
+
+import (
+ "testing"
+
+ "github.com/jesseduffield/lazygit/pkg/commands/git_config"
+ "github.com/jesseduffield/lazygit/pkg/commands/models"
+ "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/jesseduffield/lazygit/pkg/utils"
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGitCommandGetStatusFiles(t *testing.T) {
+ type scenario struct {
+ testName string
+ runner oscommands.ICmdObjRunner
+ expectedFiles []*models.File
+ }
+
+ scenarios := []scenario{
+ {
+ "No files found",
+ oscommands.NewFakeRunner(t).
+ Expect(`git status --untracked-files=yes --porcelain -z`, "", nil),
+ []*models.File{},
+ },
+ {
+ "Several files found",
+