diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2020-03-28 16:28:35 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2020-03-29 11:37:29 +1100 |
commit | 624ae45ebb3f54499a25c4eba0844fa971277c34 (patch) | |
tree | ca20f93742858b2b4231d083e5b6abdab61d69ba /pkg/commands | |
parent | 2756b82f5733c2099c43279ebb1a962101411142 (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.go | 22 | ||||
-rw-r--r-- | pkg/commands/git.go | 61 | ||||
-rw-r--r-- | pkg/commands/git_test.go | 2 |
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("")) }) } } |