Skip to content

Commit 548d486

Browse files
authored
Section headers for rebase todos and actual commits (#4463)
- **PR Description** During interactive rebase, or when stopping with conflicts in a cherry-pick or revert, show section headers for the todo items and the actual commits. This makes it much clearer where the current head commit is. Get rid of the "<-- YOU ARE HERE" marker that we would previously show; it is no longer needed. (We still show the "<-- CONFLICT" marker though.) For example: ``` ╭─[4]─Commits - Reflog───────────────────────────╮ │--- Pending rebase todos --- │ │6562f903 pick CI commit 03 │ │--- Commits --- │ │56a04448 CI ◯ commit 02 │ │6d0c0e41 CI ◯ commit 01 │ ```
2 parents 0dab37a + 74054c9 commit 548d486

File tree

56 files changed

+324
-134
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+324
-134
lines changed

pkg/commands/git_commands/commit_loader.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ func (self *CommitLoader) getSequencerCommits() []*models.Commit {
496496
commits = utils.Prepend(commits, &models.Commit{
497497
Hash: t.Commit,
498498
Name: t.Msg,
499-
Status: models.StatusRebasing,
499+
Status: models.StatusCherryPickingOrReverting,
500500
Action: t.Command,
501501
})
502502
}

pkg/commands/models/commit.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const (
1818
StatusPushed
1919
StatusMerged
2020
StatusRebasing
21+
StatusCherryPickingOrReverting
2122
StatusConflicted
2223
StatusReflog
2324
)

pkg/gui/context/list_context_trait.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ type ListContextTrait struct {
2626
func (self *ListContextTrait) IsListContext() {}
2727

2828
func (self *ListContextTrait) FocusLine() {
29+
self.Context.FocusLine()
30+
2931
// Doing this at the end of the layout function because we need the view to be
3032
// resized before we focus the line, otherwise if we're in accordion mode
3133
// the view could be squashed and won't how to adjust the cursor/origin.

pkg/gui/context/local_commits_context.go

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package context
22

33
import (
4+
"fmt"
45
"log"
56
"strings"
67
"time"
@@ -40,7 +41,6 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
4041
}
4142
}
4243

43-
showYouAreHereLabel := c.Model().WorkingTreeStateAtLastCommitRefresh.CanShowTodos()
4444
hasRebaseUpdateRefsConfig := c.Git().Config.GetRebaseUpdateRefs()
4545

4646
return presentation.GetCommitListDisplayStrings(
@@ -62,10 +62,54 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
6262
endIdx,
6363
shouldShowGraph(c),
6464
c.Model().BisectInfo,
65-
showYouAreHereLabel,
6665
)
6766
}
6867

68+
getNonModelItems := func() []*NonModelItem {
69+
result := []*NonModelItem{}
70+
if c.Model().WorkingTreeStateAtLastCommitRefresh.CanShowTodos() {
71+
if c.Model().WorkingTreeStateAtLastCommitRefresh.Rebasing {
72+
result = append(result, &NonModelItem{
73+
Index: 0,
74+
Content: fmt.Sprintf("--- %s ---", c.Tr.PendingRebaseTodosSectionHeader),
75+
})
76+
}
77+
78+
if c.Model().WorkingTreeStateAtLastCommitRefresh.CherryPicking ||
79+
c.Model().WorkingTreeStateAtLastCommitRefresh.Reverting {
80+
_, firstCherryPickOrRevertTodo, found := lo.FindIndexOf(
81+
c.Model().Commits, func(c *models.Commit) bool {
82+
return c.Status == models.StatusCherryPickingOrReverting ||
83+
c.Status == models.StatusConflicted
84+
})
85+
if !found {
86+
firstCherryPickOrRevertTodo = 0
87+
}
88+
label := lo.Ternary(c.Model().WorkingTreeStateAtLastCommitRefresh.CherryPicking,
89+
c.Tr.PendingCherryPicksSectionHeader,
90+
c.Tr.PendingRevertsSectionHeader)
91+
result = append(result, &NonModelItem{
92+
Index: firstCherryPickOrRevertTodo,
93+
Content: fmt.Sprintf("--- %s ---", label),
94+
})
95+
}
96+
97+
_, firstRealCommit, found := lo.FindIndexOf(
98+
c.Model().Commits, func(c *models.Commit) bool {
99+
return !c.IsTODO()
100+
})
101+
if !found {
102+
firstRealCommit = 0
103+
}
104+
result = append(result, &NonModelItem{
105+
Index: firstRealCommit,
106+
Content: fmt.Sprintf("--- %s ---", c.Tr.CommitsSectionHeader),
107+
})
108+
}
109+
110+
return result
111+
}
112+
69113
ctx := &LocalCommitsContext{
70114
LocalCommitsViewModel: viewModel,
71115
SearchTrait: NewSearchTrait(c),
@@ -82,6 +126,7 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext {
82126
ListRenderer: ListRenderer{
83127
list: viewModel,
84128
getDisplayStrings: getDisplayStrings,
129+
getNonModelItems: getNonModelItems,
85130
},
86131
c: c,
87132
refreshViewportOnChange: true,

pkg/gui/context/simple_context.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ func (self *SimpleContext) HandleFocusLost(opts types.OnFocusLostOpts) {
5454
}
5555
}
5656

57+
func (self *SimpleContext) FocusLine() {
58+
}
59+
5760
func (self *SimpleContext) HandleRender() {
5861
if self.handleRenderFunc != nil {
5962
self.handleRenderFunc()

pkg/gui/context/sub_commits_context.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ func NewSubCommitsContext(
7777
endIdx,
7878
shouldShowGraph(c),
7979
git_commands.NewNullBisectInfo(),
80-
false,
8180
)
8281
}
8382

pkg/gui/presentation/commits.go

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ func GetCommitListDisplayStrings(
5656
endIdx int,
5757
showGraph bool,
5858
bisectInfo *git_commands.BisectInfo,
59-
showYouAreHereLabel bool,
6059
) [][]string {
6160
mutex.Lock()
6261
defer mutex.Unlock()
@@ -185,11 +184,6 @@ func GetCommitListDisplayStrings(
185184
for i, commit := range filteredCommits {
186185
unfilteredIdx := i + startIdx
187186
bisectStatus = getBisectStatus(unfilteredIdx, commit.Hash, bisectInfo, bisectBounds)
188-
isYouAreHereCommit := false
189-
if showYouAreHereLabel && (commit.Status == models.StatusConflicted || unfilteredIdx == rebaseOffset) {
190-
isYouAreHereCommit = true
191-
showYouAreHereLabel = false
192-
}
193187
isMarkedBaseCommit := commit.Hash != "" && commit.Hash == markedBaseCommit
194188
if isMarkedBaseCommit {
195189
willBeRebased = true
@@ -211,7 +205,6 @@ func GetCommitListDisplayStrings(
211205
fullDescription,
212206
bisectStatus,
213207
bisectInfo,
214-
isYouAreHereCommit,
215208
))
216209
}
217210
return lines
@@ -364,7 +357,6 @@ func displayCommit(
364357
fullDescription bool,
365358
bisectStatus BisectStatus,
366359
bisectInfo *git_commands.BisectInfo,
367-
isYouAreHereCommit bool,
368360
) []string {
369361
bisectString := getBisectStatusText(bisectStatus, bisectInfo)
370362

@@ -427,14 +419,8 @@ func displayCommit(
427419
}
428420

429421
mark := ""
430-
if isYouAreHereCommit {
431-
color := style.FgYellow
432-
text := common.Tr.YouAreHere
433-
if commit.Status == models.StatusConflicted {
434-
color = style.FgRed
435-
text = common.Tr.ConflictLabel
436-
}
437-
youAreHere := color.Sprintf("<-- %s ---", text)
422+
if commit.Status == models.StatusConflicted {
423+
youAreHere := style.FgRed.Sprintf("<-- %s ---", common.Tr.ConflictLabel)
438424
mark = fmt.Sprintf("%s ", youAreHere)
439425
} else if isMarkedBaseCommit {
440426
rebaseFromHere := style.FgYellow.Sprint(common.Tr.MarkedCommitMarker)
@@ -505,7 +491,7 @@ func getHashColor(
505491
hashColor = style.FgYellow
506492
case models.StatusMerged:
507493
hashColor = style.FgGreen
508-
case models.StatusRebasing, models.StatusConflicted:
494+
case models.StatusRebasing, models.StatusCherryPickingOrReverting, models.StatusConflicted:
509495
hashColor = style.FgBlue
510496
case models.StatusReflog:
511497
hashColor = style.FgBlue

pkg/gui/presentation/commits_test.go

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
4040
endIdx int
4141
showGraph bool
4242
bisectInfo *git_commands.BisectInfo
43-
showYouAreHereLabel bool
4443
expected string
4544
focus bool
4645
}{
@@ -223,12 +222,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
223222
showGraph: true,
224223
bisectInfo: git_commands.NewNullBisectInfo(),
225224
cherryPickedCommitHashSet: set.New[string](),
226-
showYouAreHereLabel: true,
227225
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
228226
expected: formatExpected(`
229227
hash1 pick commit1
230228
hash2 pick commit2
231-
hash3 ◯ <-- YOU ARE HERE --- commit3
229+
hash3 ◯ commit3
232230
hash4 ◯ commit4
233231
hash5 ◯ commit5
234232
`),
@@ -247,11 +245,10 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
247245
showGraph: true,
248246
bisectInfo: git_commands.NewNullBisectInfo(),
249247
cherryPickedCommitHashSet: set.New[string](),
250-
showYouAreHereLabel: true,
251248
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
252249
expected: formatExpected(`
253250
hash2 pick commit2
254-
hash3 ◯ <-- YOU ARE HERE --- commit3
251+
hash3 ◯ commit3
255252
hash4 ◯ commit4
256253
hash5 ◯ commit5
257254
`),
@@ -270,7 +267,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
270267
showGraph: true,
271268
bisectInfo: git_commands.NewNullBisectInfo(),
272269
cherryPickedCommitHashSet: set.New[string](),
273-
showYouAreHereLabel: true,
274270
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
275271
expected: formatExpected(`
276272
hash4 ◯ commit4
@@ -291,7 +287,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
291287
showGraph: true,
292288
bisectInfo: git_commands.NewNullBisectInfo(),
293289
cherryPickedCommitHashSet: set.New[string](),
294-
showYouAreHereLabel: true,
295290
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
296291
expected: formatExpected(`
297292
hash1 pick commit1
@@ -312,7 +307,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
312307
showGraph: true,
313308
bisectInfo: git_commands.NewNullBisectInfo(),
314309
cherryPickedCommitHashSet: set.New[string](),
315-
showYouAreHereLabel: true,
316310
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
317311
expected: formatExpected(`
318312
hash5 ◯ commit5
@@ -332,33 +326,12 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
332326
showGraph: true,
333327
bisectInfo: git_commands.NewNullBisectInfo(),
334328
cherryPickedCommitHashSet: set.New[string](),
335-
showYouAreHereLabel: true,
336329
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
337330
expected: formatExpected(`
338331
hash1 pick commit1
339332
hash2 pick commit2
340333
`),
341334
},
342-
{
343-
testName: "don't show YOU ARE HERE label when not asked for (e.g. in branches panel)",
344-
commits: []*models.Commit{
345-
{Name: "commit1", Hash: "hash1", Parents: []string{"hash2"}, Action: todo.Pick},
346-
{Name: "commit2", Hash: "hash2", Parents: []string{"hash3"}},
347-
{Name: "commit3", Hash: "hash3", Parents: []string{"hash4"}},
348-
},
349-
startIdx: 0,
350-
endIdx: 3,
351-
showGraph: true,
352-
bisectInfo: git_commands.NewNullBisectInfo(),
353-
cherryPickedCommitHashSet: set.New[string](),
354-
showYouAreHereLabel: false,
355-
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
356-
expected: formatExpected(`
357-
hash1 pick commit1
358-
hash2 ◯ commit2
359-
hash3 ◯ commit3
360-
`),
361-
},
362335
{
363336
testName: "graph in divergence view - all commits visible",
364337
commits: []*models.Commit{
@@ -376,7 +349,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
376349
showGraph: true,
377350
bisectInfo: git_commands.NewNullBisectInfo(),
378351
cherryPickedCommitHashSet: set.New[string](),
379-
showYouAreHereLabel: false,
380352
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
381353
expected: formatExpected(`
382354
↓ hash1r ◯ commit1
@@ -406,7 +378,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
406378
showGraph: true,
407379
bisectInfo: git_commands.NewNullBisectInfo(),
408380
cherryPickedCommitHashSet: set.New[string](),
409-
showYouAreHereLabel: false,
410381
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
411382
expected: formatExpected(`
412383
↓ hash3r ◯ │ commit3
@@ -434,7 +405,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
434405
showGraph: true,
435406
bisectInfo: git_commands.NewNullBisectInfo(),
436407
cherryPickedCommitHashSet: set.New[string](),
437-
showYouAreHereLabel: false,
438408
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
439409
expected: formatExpected(`
440410
↓ hash1r ◯ commit1
@@ -461,7 +431,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
461431
showGraph: true,
462432
bisectInfo: git_commands.NewNullBisectInfo(),
463433
cherryPickedCommitHashSet: set.New[string](),
464-
showYouAreHereLabel: false,
465434
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
466435
expected: formatExpected(`
467436
↑ hash2l ⏣─╮ commit2
@@ -487,7 +456,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
487456
showGraph: true,
488457
bisectInfo: git_commands.NewNullBisectInfo(),
489458
cherryPickedCommitHashSet: set.New[string](),
490-
showYouAreHereLabel: false,
491459
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
492460
expected: formatExpected(`
493461
↓ hash1r ◯ commit1
@@ -508,7 +476,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
508476
showGraph: true,
509477
bisectInfo: git_commands.NewNullBisectInfo(),
510478
cherryPickedCommitHashSet: set.New[string](),
511-
showYouAreHereLabel: false,
512479
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
513480
expected: formatExpected(`
514481
↑ hash1l ◯ commit1
@@ -530,7 +497,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
530497
showGraph: true,
531498
bisectInfo: git_commands.NewNullBisectInfo(),
532499
cherryPickedCommitHashSet: set.New[string](),
533-
showYouAreHereLabel: false,
534500
now: time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC),
535501
expected: formatExpected(`
536502
↓ hash1r ◯ commit1
@@ -596,7 +562,6 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
596562
s.endIdx,
597563
s.showGraph,
598564
s.bisectInfo,
599-
s.showYouAreHereLabel,
600565
)
601566

602567
renderedLines, _ := utils.RenderDisplayStrings(result, nil)

pkg/gui/types/context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ type Context interface {
105105

106106
HandleFocus(opts OnFocusOpts)
107107
HandleFocusLost(opts OnFocusLostOpts)
108+
FocusLine()
108109
HandleRender()
109110
HandleRenderToMain()
110111
}
@@ -173,7 +174,6 @@ type IListContext interface {
173174
ViewIndexToModelIndex(int) int
174175
ModelIndexToViewIndex(int) int
175176

176-
FocusLine()
177177
IsListContext() // used for type switch
178178
RangeSelectEnabled() bool
179179
RenderOnlyVisibleLines() bool

pkg/gui/view_helpers.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,5 +136,12 @@ func (gui *Gui) postRefreshUpdate(c types.Context) {
136136

137137
if gui.currentViewName() == c.GetViewName() {
138138
c.HandleFocus(types.OnFocusOpts{})
139+
} else {
140+
// The FocusLine call is included in the HandleFocus method which we
141+
// call for focused views above; but we need to call it here for
142+
// non-focused views to ensure that an inactive selection is painted
143+
// correctly, and that integration tests see the up to date selection
144+
// state.
145+
c.FocusLine()
139146
}
140147
}

0 commit comments

Comments
 (0)