summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-04-28 10:37:02 +0200
committerStefan Haller <stefan@haller-berlin.de>2024-04-30 13:50:46 +0200
commitb7673577a20c04b7fe711363b1fdc270030fdae6 (patch)
tree80706e71bb4c818e32e32948675b98ccc601131a
parent00c55d5711832a87f35b822ca87ceb1ab66a7e37 (diff)
Enable the commit graph in the divergence view
-rw-r--r--pkg/gui/context/sub_commits_context.go2
-rw-r--r--pkg/gui/presentation/commits.go90
-rw-r--r--pkg/gui/presentation/commits_test.go179
3 files changed, 252 insertions, 19 deletions
diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go
index b37be8667..f540dba87 100644
--- a/pkg/gui/context/sub_commits_context.go
+++ b/pkg/gui/context/sub_commits_context.go
@@ -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,
)
diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go
index cff36bf30..c385d3407 100644
--- a/pkg/gui/presentation/commits.go
+++ b/pkg/gui/presentation/commits.go
@@ -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)
-
- 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 ""
+ 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{}
+
+ _, 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]
diff --git a/pkg/gui/presentation/commits_test.go b/pkg/gui/presentation/commits_test.go
index 0438b105c..53101cb6d 100644
--- a/pkg/gui/presentation/commits_test.go
+++ b/pkg/gui/presentation/commits_test.go
@@ -360,6 +360,185 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
`),
},
{
+ 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{
{Name: "commit1", Hash: "hash1", UnixTimestamp: 1577844184, AuthorName: "Jesse Duffield"},