summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2020-03-28 16:28:35 +1100
committerJesse Duffield <jessedduffield@gmail.com>2020-03-29 11:37:29 +1100
commit624ae45ebb3f54499a25c4eba0844fa971277c34 (patch)
treeca20f93742858b2b4231d083e5b6abdab61d69ba /pkg/commands
parent2756b82f5733c2099c43279ebb1a962101411142 (diff)
allow scoped mode where the commits/reflog/stash panels are scoped to a file
WIP restrict certain actions in scoped mode WIP
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/commit_list_builder.go22
-rw-r--r--pkg/commands/git.go61
-rw-r--r--pkg/commands/git_test.go2
3 files changed, 71 insertions, 14 deletions
diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go
index 965bcd4e0..c216cec7b 100644
--- a/pkg/commands/commit_list_builder.go
+++ b/pkg/commands/commit_list_builder.go
@@ -83,15 +83,20 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
}
}
+type GetCommitsOptions struct {
+ Limit bool
+ LogScope string
+}
+
// GetCommits obtains the commits of the current branch
-func (c *CommitListBuilder) GetCommits(limit bool) ([]*Commit, error) {
+func (c *CommitListBuilder) GetCommits(options GetCommitsOptions) ([]*Commit, error) {
commits := []*Commit{}
var rebasingCommits []*Commit
rebaseMode, err := c.GitCommand.RebaseMode()
if err != nil {
return nil, err
}
- if rebaseMode != "" {
+ if rebaseMode != "" && options.LogScope == "" {
// here we want to also prepend the commits that we're in the process of rebasing
rebasingCommits, err = c.getRebasingCommits(rebaseMode)
if err != nil {
@@ -103,7 +108,7 @@ func (c *CommitListBuilder) GetCommits(limit bool) ([]*Commit, error) {
}
unpushedCommits := c.getUnpushedCommits()
- cmd := c.getLogCmd(limit)
+ cmd := c.getLogCmd(options)
err = RunLineOutputCmd(cmd, func(line string) (bool, error) {
commit := c.extractCommitFromLine(line)
@@ -294,11 +299,16 @@ func (c *CommitListBuilder) getUnpushedCommits() map[string]bool {
}
// getLog gets the git log.
-func (c *CommitListBuilder) getLogCmd(limit bool) *exec.Cmd {
+func (c *CommitListBuilder) getLogCmd(options GetCommitsOptions) *exec.Cmd {
limitFlag := ""
- if limit {
+ if options.Limit {
limitFlag = "-300"
}
- return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix ", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20))
+ scopeFlag := ""
+ if options.LogScope != "" {
+ scopeFlag = fmt.Sprintf(" -- %s", c.OSCommand.Quote(options.LogScope))
+ }
+
+ return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix %s", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20, scopeFlag))
}
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index eb765f4fa..84e8d50a4 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -156,9 +156,7 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam
return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil
}
-// GetStashEntries stash entries
-func (c *GitCommand) GetStashEntries() []*StashEntry {
- // if we directly put this string in RunCommandWithOutput the compiler complains because it thinks it's a format string
+func (c *GitCommand) getStashEntriesWithoutScope() []*StashEntry {
unescaped := "git stash list --pretty='%gs'"
rawString, _ := c.OSCommand.RunCommandWithOutput(unescaped)
stashEntries := []*StashEntry{}
@@ -168,6 +166,45 @@ func (c *GitCommand) GetStashEntries() []*StashEntry {
return stashEntries
}
+// GetStashEntries stash entries
+func (c *GitCommand) GetStashEntries(scope string) []*StashEntry {
+ if scope == "" {
+ return c.getStashEntriesWithoutScope()
+ }
+
+ unescaped := fmt.Sprintf("git stash list --name-only")
+ rawString, err := c.OSCommand.RunCommandWithOutput(unescaped)
+ if err != nil {
+ return c.getStashEntriesWithoutScope()
+ }
+ stashEntries := []*StashEntry{}
+ var currentStashEntry *StashEntry
+ lines := utils.SplitLines(rawString)
+ isAStash := func(line string) bool { return strings.HasPrefix(line, "stash@{") }
+ re := regexp.MustCompile(`stash@\{(\d+)\}`)
+
+outer:
+ for i := 0; i < len(lines); i++ {
+ if !isAStash(lines[i]) {
+ continue
+ }
+ match := re.FindStringSubmatch(lines[i])
+ idx, err := strconv.Atoi(match[1])
+ if err != nil {
+ return c.getStashEntriesWithoutScope()
+ }
+ currentStashEntry = stashEntryFromLine(lines[i], idx)
+ for i+1 < len(lines) && !isAStash(lines[i+1]) {
+ i++
+ if lines[i] == scope {
+ stashEntries = append(stashEntries, currentStashEntry)
+ continue outer
+ }
+ }
+ }
+ return stashEntries
+}
+
func stashEntryFromLine(line string, index int) *StashEntry {
return &StashEntry{
Name: line,
@@ -568,8 +605,12 @@ func (c *GitCommand) Ignore(filename string) error {
return c.OSCommand.AppendLineToFile(".gitignore", filename)
}
-func (c *GitCommand) ShowCmdStr(sha string) string {
- return fmt.Sprintf("git show --color=%s --no-renames --stat -p %s", c.colorArg(), sha)
+func (c *GitCommand) ShowCmdStr(sha string, scope string) string {
+ scopeArg := ""
+ if scope != "" {
+ scopeArg = fmt.Sprintf(" -- %s", c.OSCommand.Quote(scope))
+ }
+ return fmt.Sprintf("git show --color=%s --no-renames --stat -p %s %s", c.colorArg(), sha, scopeArg)
}
func (c *GitCommand) GetBranchGraphCmdStr(branchName string) string {
@@ -1121,11 +1162,17 @@ func (c *GitCommand) FetchRemote(remoteName string) error {
// GetReflogCommits only returns the new reflog commits since the given lastReflogCommit
// if none is passed (i.e. it's value is nil) then we get all the reflog commits
-func (c *GitCommand) GetReflogCommits(lastReflogCommit *Commit) ([]*Commit, bool, error) {
+
+func (c *GitCommand) GetReflogCommits(lastReflogCommit *Commit, scope string) ([]*Commit, bool, error) {
commits := make([]*Commit, 0)
re := regexp.MustCompile(`(\w+).*HEAD@\{([^\}]+)\}: (.*)`)
- cmd := c.OSCommand.ExecutableFromString("git reflog --abbrev=20 --date=unix")
+ scopeArg := ""
+ if scope != "" {
+ scopeArg = fmt.Sprintf(" -- %s", c.OSCommand.Quote(scope))
+ }
+
+ cmd := c.OSCommand.ExecutableFromString(fmt.Sprintf("git reflog --abbrev=20 --date=unix %s", scopeArg))
onlyObtainedNewReflogCommits := false
err := RunLineOutputCmd(cmd, func(line string) (bool, error) {
match := re.FindStringSubmatch(line)
diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go
index 56e2923cd..c8b5bf271 100644
--- a/pkg/commands/git_test.go
+++ b/pkg/commands/git_test.go
@@ -312,7 +312,7 @@ func TestGitCommandGetStashEntries(t *testing.T) {
gitCmd := NewDummyGitCommand()
gitCmd.OSCommand.command = s.command
- s.test(gitCmd.GetStashEntries())
+ s.test(gitCmd.GetStashEntries(""))
})
}
}