Enable the commit graph in the divergence view

This commit is contained in:
Stefan Haller 2024-04-28 10:37:02 +02:00
parent 00c55d5711
commit b7673577a2
3 changed files with 251 additions and 18 deletions

View file

@ -75,7 +75,7 @@ func NewSubCommitsContext(
endIdx,
// Don't show the graph in the left/right view; we'd like to, but
// it's too complicated:
shouldShowGraph(c) && viewModel.GetRefToShowDivergenceFrom() == "",
shouldShowGraph(c),
git_commands.NewNullBisectInfo(),
false,
)

View file

@ -24,6 +24,7 @@ import (
type pipeSetCacheKey struct {
commitHash string
commitCount int
divergence models.Divergence
}
var (
@ -78,24 +79,76 @@ func GetCommitListDisplayStrings(
// 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 := max(startIdx, rebaseOffset)
if len(commits) > 0 && commits[0].Divergence != models.DivergenceNone {
// Showing a divergence log; we know we don't have any rebasing
// commits in this case. But we need to render separate graphs for
// the Local and Remote sections.
allGraphLines := []string{}
pipeSets := loadPipesets(commits[rebaseOffset:])
pipeSetOffset := max(startIdx-rebaseOffset, 0)
graphPipeSets := pipeSets[pipeSetOffset:max(endIdx-rebaseOffset, 0)]
graphCommits := commits[graphOffset:endIdx]
graphLines := graph.RenderAux(
graphPipeSets,
graphCommits,
selectedCommitHash,
)
getGraphLine = func(idx int) string {
if idx >= graphOffset {
return graphLines[idx-graphOffset]
} else {
return ""
_, localSectionStart, found := lo.FindIndexOf(
commits, func(c *models.Commit) bool { return c.Divergence == models.DivergenceLeft })
if !found {
localSectionStart = len(commits)
}
if localSectionStart > 0 {
// we have some remote commits
pipeSets := loadPipesets(commits[:localSectionStart])
if startIdx < localSectionStart {
// some of the remote commits are visible
start := startIdx
end := min(endIdx, localSectionStart)
graphPipeSets := pipeSets[start:end]
graphCommits := commits[start:end]
graphLines := graph.RenderAux(
graphPipeSets,
graphCommits,
selectedCommitHash,
)
allGraphLines = append(allGraphLines, graphLines...)
}
}
if localSectionStart < len(commits) {
// we have some local commits
pipeSets := loadPipesets(commits[localSectionStart:])
if localSectionStart < endIdx {
// some of the local commits are visible
graphOffset := max(startIdx, localSectionStart)
pipeSetOffset := max(startIdx-localSectionStart, 0)
graphPipeSets := pipeSets[pipeSetOffset : endIdx-localSectionStart]
graphCommits := commits[graphOffset:endIdx]
graphLines := graph.RenderAux(
graphPipeSets,
graphCommits,
selectedCommitHash,
)
allGraphLines = append(allGraphLines, graphLines...)
}
}
getGraphLine = func(idx int) string {
return allGraphLines[idx-startIdx]
}
} else {
// 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 := max(startIdx, rebaseOffset)
pipeSets := loadPipesets(commits[rebaseOffset:])
pipeSetOffset := max(startIdx-rebaseOffset, 0)
graphPipeSets := pipeSets[pipeSetOffset:max(endIdx-rebaseOffset, 0)]
graphCommits := commits[graphOffset:endIdx]
graphLines := graph.RenderAux(
graphPipeSets,
graphCommits,
selectedCommitHash,
)
getGraphLine = func(idx int) string {
if idx >= graphOffset {
return graphLines[idx-graphOffset]
} else {
return ""
}
}
}
} else {
@ -205,6 +258,7 @@ func loadPipesets(commits []*models.Commit) [][]*graph.Pipe {
cacheKey := pipeSetCacheKey{
commitHash: commits[0].Hash,
commitCount: len(commits),
divergence: commits[0].Divergence,
}
pipeSets, ok := pipeSetCache[cacheKey]

View file

@ -359,6 +359,185 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
hash3 commit3
`),
},
{
testName: "graph in divergence view - all commits visible",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit4", Hash: "hash4l", Parents: []string{"hash5l"}, Divergence: models.DivergenceLeft},
{Name: "commit5", Hash: "hash5l", Parents: []string{"hash6l"}, Divergence: models.DivergenceLeft},
},
startIdx: 0,
endIdx: 8,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash1r commit1
hash2r commit2
hash3r commit3
hash1l commit1
hash2l commit2
hash3l commit3
hash4l commit4
hash5l commit5
`),
},
{
testName: "graph in divergence view - not all remote commits visible",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit4", Hash: "hash4l", Parents: []string{"hash5l"}, Divergence: models.DivergenceLeft},
{Name: "commit5", Hash: "hash5l", Parents: []string{"hash6l"}, Divergence: models.DivergenceLeft},
},
startIdx: 2,
endIdx: 8,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash3r commit3
hash1l commit1
hash2l commit2
hash3l commit3
hash4l commit4
hash5l commit5
`),
},
{
testName: "graph in divergence view - not all local commits",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit4", Hash: "hash4l", Parents: []string{"hash5l"}, Divergence: models.DivergenceLeft},
{Name: "commit5", Hash: "hash5l", Parents: []string{"hash6l"}, Divergence: models.DivergenceLeft},
},
startIdx: 0,
endIdx: 5,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash1r commit1
hash2r commit2
hash3r commit3
hash1l commit1
hash2l commit2
`),
},
{
testName: "graph in divergence view - no remote commits visible",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit4", Hash: "hash4l", Parents: []string{"hash5l"}, Divergence: models.DivergenceLeft},
{Name: "commit5", Hash: "hash5l", Parents: []string{"hash6l"}, Divergence: models.DivergenceLeft},
},
startIdx: 4,
endIdx: 8,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash2l commit2
hash3l commit3
hash4l commit4
hash5l commit5
`),
},
{
testName: "graph in divergence view - no local commits visible",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit4", Hash: "hash4l", Parents: []string{"hash5l"}, Divergence: models.DivergenceLeft},
{Name: "commit5", Hash: "hash5l", Parents: []string{"hash6l"}, Divergence: models.DivergenceLeft},
},
startIdx: 0,
endIdx: 2,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash1r commit1
hash2r commit2
`),
},
{
testName: "graph in divergence view - no remote commits present",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1l", Parents: []string{"hash2l"}, Divergence: models.DivergenceLeft},
{Name: "commit2", Hash: "hash2l", Parents: []string{"hash3l", "hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit3", Hash: "hash3l", Parents: []string{"hash4l"}, Divergence: models.DivergenceLeft},
{Name: "commit4", Hash: "hash4l", Parents: []string{"hash5l"}, Divergence: models.DivergenceLeft},
{Name: "commit5", Hash: "hash5l", Parents: []string{"hash6l"}, Divergence: models.DivergenceLeft},
},
startIdx: 0,
endIdx: 5,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash1l commit1
hash2l commit2
hash3l commit3
hash4l commit4
hash5l commit5
`),
},
{
testName: "graph in divergence view - no local commits present",
commits: []*models.Commit{
{Name: "commit1", Hash: "hash1r", Parents: []string{"hash2r"}, Divergence: models.DivergenceRight},
{Name: "commit2", Hash: "hash2r", Parents: []string{"hash3r", "hash5r"}, Divergence: models.DivergenceRight},
{Name: "commit3", Hash: "hash3r", Parents: []string{"hash4r"}, Divergence: models.DivergenceRight},
},
startIdx: 0,
endIdx: 3,
showGraph: true,
bisectInfo: git_commands.NewNullBisectInfo(),
cherryPickedCommitHashSet: set.New[string](),
showYouAreHereLabel: false,
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
expected: formatExpected(`
hash1r commit1
hash2r commit2
hash3r commit3
`),
},
{
testName: "custom time format",
commits: []*models.Commit{