mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 04:45:47 +02:00
Enable the commit graph in the divergence view
This commit is contained in:
parent
00c55d5711
commit
b7673577a2
3 changed files with 251 additions and 18 deletions
|
@ -75,7 +75,7 @@ func NewSubCommitsContext(
|
||||||
endIdx,
|
endIdx,
|
||||||
// Don't show the graph in the left/right view; we'd like to, but
|
// Don't show the graph in the left/right view; we'd like to, but
|
||||||
// it's too complicated:
|
// it's too complicated:
|
||||||
shouldShowGraph(c) && viewModel.GetRefToShowDivergenceFrom() == "",
|
shouldShowGraph(c),
|
||||||
git_commands.NewNullBisectInfo(),
|
git_commands.NewNullBisectInfo(),
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
|
|
|
@ -24,6 +24,7 @@ import (
|
||||||
type pipeSetCacheKey struct {
|
type pipeSetCacheKey struct {
|
||||||
commitHash string
|
commitHash string
|
||||||
commitCount int
|
commitCount int
|
||||||
|
divergence models.Divergence
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -78,24 +79,76 @@ func GetCommitListDisplayStrings(
|
||||||
// function expects to be passed the index of the commit in terms of the `commits` slice
|
// function expects to be passed the index of the commit in terms of the `commits` slice
|
||||||
var getGraphLine func(int) string
|
var getGraphLine func(int) string
|
||||||
if showGraph {
|
if showGraph {
|
||||||
// this is where the graph begins (may be beyond the TODO commits depending on startIdx,
|
if len(commits) > 0 && commits[0].Divergence != models.DivergenceNone {
|
||||||
// but we'll never include TODO commits as part of the graph because it'll be messy)
|
// Showing a divergence log; we know we don't have any rebasing
|
||||||
graphOffset := max(startIdx, rebaseOffset)
|
// commits in this case. But we need to render separate graphs for
|
||||||
|
// the Local and Remote sections.
|
||||||
|
allGraphLines := []string{}
|
||||||
|
|
||||||
pipeSets := loadPipesets(commits[rebaseOffset:])
|
_, localSectionStart, found := lo.FindIndexOf(
|
||||||
pipeSetOffset := max(startIdx-rebaseOffset, 0)
|
commits, func(c *models.Commit) bool { return c.Divergence == models.DivergenceLeft })
|
||||||
graphPipeSets := pipeSets[pipeSetOffset:max(endIdx-rebaseOffset, 0)]
|
if !found {
|
||||||
graphCommits := commits[graphOffset:endIdx]
|
localSectionStart = len(commits)
|
||||||
graphLines := graph.RenderAux(
|
}
|
||||||
graphPipeSets,
|
|
||||||
graphCommits,
|
if localSectionStart > 0 {
|
||||||
selectedCommitHash,
|
// we have some remote commits
|
||||||
)
|
pipeSets := loadPipesets(commits[:localSectionStart])
|
||||||
getGraphLine = func(idx int) string {
|
if startIdx < localSectionStart {
|
||||||
if idx >= graphOffset {
|
// some of the remote commits are visible
|
||||||
return graphLines[idx-graphOffset]
|
start := startIdx
|
||||||
} else {
|
end := min(endIdx, localSectionStart)
|
||||||
return ""
|
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 {
|
} else {
|
||||||
|
@ -205,6 +258,7 @@ func loadPipesets(commits []*models.Commit) [][]*graph.Pipe {
|
||||||
cacheKey := pipeSetCacheKey{
|
cacheKey := pipeSetCacheKey{
|
||||||
commitHash: commits[0].Hash,
|
commitHash: commits[0].Hash,
|
||||||
commitCount: len(commits),
|
commitCount: len(commits),
|
||||||
|
divergence: commits[0].Divergence,
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeSets, ok := pipeSetCache[cacheKey]
|
pipeSets, ok := pipeSetCache[cacheKey]
|
||||||
|
|
|
@ -359,6 +359,185 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||||
hash3 ◯ commit3
|
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",
|
testName: "custom time format",
|
||||||
commits: []*models.Commit{
|
commits: []*models.Commit{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue