1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-03-29 22:07:13 +02:00

exclude interactive rebase TODO commits from commit graph

This commit is contained in:
Jesse Duffield 2022-01-22 12:56:57 +11:00
parent 5b7dd9e43c
commit 61ccc1efd2
3 changed files with 278 additions and 36 deletions

View File

@ -40,3 +40,9 @@ func (c *Commit) Description() string {
func (c *Commit) IsMerge() bool {
return len(c.Parents) > 1
}
// returns true if this commit is not actually in the git log but instead
// is from a TODO file for an interactive rebase.
func (c *Commit) IsTODO() bool {
return c.Action != ""
}

View File

@ -49,6 +49,76 @@ func GetCommitListDisplayStrings(
return nil
}
if startIdx > len(commits) {
return nil
}
// this is where my non-TODO commits begin
rebaseOffset := indexOfFirstNonTODOCommit(commits)
end := utils.Min(startIdx+length, len(commits))
filteredCommits := commits[startIdx:end]
// function expects to be passed the index of the commit in terms of the `commits` slice
var getGraphLine func(int) string
if showGraph {
// this is where the graph begins (may be beyond the TODO commits depending on startIdx,
// but we'll never include TODO commits as part of the graph because it'll be messy)
graphOffset := utils.Max(startIdx, rebaseOffset)
pipeSets := loadPipesets(commits[rebaseOffset:])
pipeSetOffset := utils.Max(startIdx-rebaseOffset, 0)
graphPipeSets := pipeSets[pipeSetOffset:utils.Max(end-rebaseOffset, 0)]
graphCommits := commits[graphOffset:end]
graphLines := graph.RenderAux(
graphPipeSets,
graphCommits,
selectedCommitSha,
)
getGraphLine = func(idx int) string {
if idx >= graphOffset {
return graphLines[idx-graphOffset]
} else {
return ""
}
}
} else {
getGraphLine = func(idx int) string { return "" }
}
lines := make([][]string, 0, len(filteredCommits))
bisectProgress := BeforeNewCommit
var bisectStatus BisectStatus
for i, commit := range filteredCommits {
bisectStatus, bisectProgress = getBisectStatus(commit.Sha, bisectInfo, bisectProgress)
lines = append(lines, displayCommit(
commit,
cherryPickedCommitShaMap,
diffName,
parseEmoji,
getGraphLine(i+startIdx),
fullDescription,
bisectStatus,
bisectInfo,
))
}
return lines
}
// precondition: slice is not empty
func indexOfFirstNonTODOCommit(commits []*models.Commit) int {
for i, commit := range commits {
if !commit.IsTODO() {
return i
}
}
// shouldn't land here
return 0
}
func loadPipesets(commits []*models.Commit) [][]*graph.Pipe {
// given that our cache key is a commit sha and a commit count, it's very important that we don't actually try to render pipes
// when dealing with things like filtered commits.
cacheKey := pipeSetCacheKey{
@ -67,42 +137,7 @@ func GetCommitListDisplayStrings(
pipeSetCache[cacheKey] = pipeSets
}
if startIdx > len(commits) {
return nil
}
end := startIdx + length
if end > len(commits)-1 {
end = len(commits) - 1
}
filteredCommits := commits[startIdx : end+1]
var getGraphLine func(int) string
if showGraph {
filteredPipeSets := pipeSets[startIdx : end+1]
graphLines := graph.RenderAux(filteredPipeSets, filteredCommits, selectedCommitSha)
getGraphLine = func(idx int) string { return graphLines[idx] }
} else {
getGraphLine = func(idx int) string { return "" }
}
lines := make([][]string, 0, len(filteredCommits))
bisectProgress := BeforeNewCommit
var bisectStatus BisectStatus
for i, commit := range filteredCommits {
bisectStatus, bisectProgress = getBisectStatus(commit.Sha, bisectInfo, bisectProgress)
lines = append(lines, displayCommit(
commit,
cherryPickedCommitShaMap,
diffName,
parseEmoji,
getGraphLine(i),
fullDescription,
bisectStatus,
bisectInfo,
))
}
return lines
return pipeSets
}
// similar to the git_commands.BisectStatus but more gui-focused

View File

@ -0,0 +1,201 @@
package presentation
import (
"strings"
"testing"
"github.com/gookit/color"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/stretchr/testify/assert"
"github.com/xo/terminfo"
)
func init() {
color.ForceSetColorLevel(terminfo.ColorLevelNone)
}
func formatExpected(expected string) string {
return strings.TrimSpace(strings.ReplaceAll(expected, "\t", ""))
}
func TestGetCommitListDisplayStrings(t *testing.T) {
scenarios := []struct {
testName string
commits []*models.Commit
fullDescription bool
cherryPickedCommitShaMap map[string]bool
diffName string
parseEmoji bool
selectedCommitSha string
startIdx int
length int
showGraph bool
bisectInfo *git_commands.BisectInfo
expected string
}{
{
testName: "no commits",
commits: []*models.Commit{},
startIdx: 0,
length: 1,
showGraph: false,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: "",
},
{
testName: "some commits",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1"},
{Name: "commit2", Sha: "sha2"},
},
startIdx: 0,
length: 2,
showGraph: false,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha1 commit1
sha2 commit2
`),
},
{
testName: "showing graph",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1", Parents: []string{"sha2", "sha3"}},
{Name: "commit2", Sha: "sha2", Parents: []string{"sha3"}},
{Name: "commit3", Sha: "sha3", Parents: []string{"sha4"}},
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
},
startIdx: 0,
length: 5,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha1 commit1
sha2 commit2
sha3 commit3
sha4 commit4
sha5 commit5
`),
},
{
testName: "showing graph, including rebase commits",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1", Parents: []string{"sha2", "sha3"}, Action: "pick"},
{Name: "commit2", Sha: "sha2", Parents: []string{"sha3"}, Action: "pick"},
{Name: "commit3", Sha: "sha3", Parents: []string{"sha4"}},
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
},
startIdx: 0,
length: 5,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha1 pick commit1
sha2 pick commit2
sha3 commit3
sha4 commit4
sha5 commit5
`),
},
{
testName: "showing graph, including rebase commits, with offset",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1", Parents: []string{"sha2", "sha3"}, Action: "pick"},
{Name: "commit2", Sha: "sha2", Parents: []string{"sha3"}, Action: "pick"},
{Name: "commit3", Sha: "sha3", Parents: []string{"sha4"}},
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
},
startIdx: 1,
length: 10,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha2 pick commit2
sha3 commit3
sha4 commit4
sha5 commit5
`),
},
{
testName: "startIdx is passed TODO commits",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1", Parents: []string{"sha2", "sha3"}, Action: "pick"},
{Name: "commit2", Sha: "sha2", Parents: []string{"sha3"}, Action: "pick"},
{Name: "commit3", Sha: "sha3", Parents: []string{"sha4"}},
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
},
startIdx: 3,
length: 2,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha4 commit4
sha5 commit5
`),
},
{
testName: "only showing TODO commits",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1", Parents: []string{"sha2", "sha3"}, Action: "pick"},
{Name: "commit2", Sha: "sha2", Parents: []string{"sha3"}, Action: "pick"},
{Name: "commit3", Sha: "sha3", Parents: []string{"sha4"}},
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
},
startIdx: 0,
length: 2,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha1 pick commit1
sha2 pick commit2
`),
},
{
testName: "no TODO commits, towards bottom",
commits: []*models.Commit{
{Name: "commit1", Sha: "sha1", Parents: []string{"sha2", "sha3"}},
{Name: "commit2", Sha: "sha2", Parents: []string{"sha3"}},
{Name: "commit3", Sha: "sha3", Parents: []string{"sha4"}},
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
},
startIdx: 4,
length: 2,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
expected: formatExpected(`
sha5 commit5
`),
},
}
for _, s := range scenarios {
s := s
t.Run(s.testName, func(t *testing.T) {
result := GetCommitListDisplayStrings(
s.commits,
s.fullDescription,
s.cherryPickedCommitShaMap,
s.diffName,
s.parseEmoji,
s.selectedCommitSha,
s.startIdx,
s.length,
s.showGraph,
s.bisectInfo,
)
renderedResult := utils.RenderDisplayStrings(result)
t.Logf("\n%s", renderedResult)
assert.EqualValues(t, s.expected, renderedResult)
})
}
}