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:
parent
5b7dd9e43c
commit
61ccc1efd2
@ -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 != ""
|
||||
}
|
||||
|
@ -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
|
||||
|
201
pkg/gui/presentation/commits_test.go
Normal file
201
pkg/gui/presentation/commits_test.go
Normal 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)
|
||||
})
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user