summaryrefslogtreecommitdiffstats
path: root/pkg/gui/presentation
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-04-30 12:34:05 +0200
committerStefan Haller <stefan@haller-berlin.de>2024-06-03 13:59:43 +0200
commit373b1970cab78b639bbdb5e5a7c684735f4d95a7 (patch)
tree6424f684f9f53ed24c44a69c66ccbb9fe725686a /pkg/gui/presentation
parent5b613f5bc78c44351945cbc3ffdf9e5950c04bd8 (diff)
Show divergence from base branch in branches list
Diffstat (limited to 'pkg/gui/presentation')
-rw-r--r--pkg/gui/presentation/branches.go58
-rw-r--r--pkg/gui/presentation/branches_test.go73
2 files changed, 105 insertions, 26 deletions
diff --git a/pkg/gui/presentation/branches.go b/pkg/gui/presentation/branches.go
index 0e48a3935..aab51fe61 100644
--- a/pkg/gui/presentation/branches.go
+++ b/pkg/gui/presentation/branches.go
@@ -155,32 +155,38 @@ func BranchStatus(
return style.FgCyan.Sprintf("%s %s", itemOperationStr, utils.Loader(now, userConfig.Gui.Spinner))
}
- if !branch.IsTrackingRemote() {
- return ""
- }
-
- if branch.UpstreamGone {
- return style.FgRed.Sprint(tr.UpstreamGone)
- }
-
- if branch.MatchesUpstream() {
- return style.FgGreen.Sprint("✓")
- }
- if branch.RemoteBranchNotStoredLocally() {
- return style.FgMagenta.Sprint("?")
- }
-
- if branch.IsBehindForPull() && branch.IsAheadForPull() {
- return style.FgYellow.Sprintf("↓%s↑%s", branch.BehindForPull, branch.AheadForPull)
- }
- if branch.IsBehindForPull() {
- return style.FgYellow.Sprintf("↓%s", branch.BehindForPull)
- }
- if branch.IsAheadForPull() {
- return style.FgYellow.Sprintf("↑%s", branch.AheadForPull)
- }
-
- return ""
+ result := ""
+ if branch.IsTrackingRemote() {
+ if branch.UpstreamGone {
+ result = style.FgRed.Sprint(tr.UpstreamGone)
+ } else if branch.MatchesUpstream() {
+ result = style.FgGreen.Sprint("✓")
+ } else if branch.RemoteBranchNotStoredLocally() {
+ result = style.FgMagenta.Sprint("?")
+ } else if branch.IsBehindForPull() && branch.IsAheadForPull() {
+ result = style.FgYellow.Sprintf("↓%s↑%s", branch.BehindForPull, branch.AheadForPull)
+ } else if branch.IsBehindForPull() {
+ result = style.FgYellow.Sprintf("↓%s", branch.BehindForPull)
+ } else if branch.IsAheadForPull() {
+ result = style.FgYellow.Sprintf("↑%s", branch.AheadForPull)
+ }
+ }
+
+ if userConfig.Gui.ShowDivergenceFromBaseBranch != "none" {
+ behind := branch.BehindBaseBranch.Load()
+ if behind != 0 {
+ if result != "" {
+ result += " "
+ }
+ if userConfig.Gui.ShowDivergenceFromBaseBranch == "arrowAndNumber" {
+ result += style.FgCyan.Sprintf("↓%d", behind)
+ } else {
+ result += style.FgCyan.Sprintf("↓")
+ }
+ }
+ }
+
+ return result
}
func SetCustomBranches(customBranchColors map[string]string) {
diff --git a/pkg/gui/presentation/branches_test.go b/pkg/gui/presentation/branches_test.go
index db4868970..ba79f16ce 100644
--- a/pkg/gui/presentation/branches_test.go
+++ b/pkg/gui/presentation/branches_test.go
@@ -2,6 +2,7 @@ package presentation
import (
"fmt"
+ "sync/atomic"
"testing"
"time"
@@ -15,6 +16,11 @@ import (
"github.com/xo/terminfo"
)
+func makeAtomic(v int32) (result atomic.Int32) {
+ result.Store(v)
+ return //nolint: nakedret
+}
+
func Test_getBranchDisplayStrings(t *testing.T) {
scenarios := []struct {
branch *models.Branch
@@ -23,6 +29,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth int
useIcons bool
checkedOutByWorktree bool
+ showDivergenceCfg string
expected []string
}{
// First some tests for when the view is wide enough so that everything fits:
@@ -33,6 +40,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 100,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_name"},
},
{
@@ -42,6 +50,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 100,
useIcons: false,
checkedOutByWorktree: true,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_name (worktree)"},
},
{
@@ -51,6 +60,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 100,
useIcons: true,
checkedOutByWorktree: true,
+ showDivergenceCfg: "none",
expected: []string{"1m", "󰘬", "branch_name 󰌹"},
},
{
@@ -66,6 +76,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 100,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_name ✓"},
},
{
@@ -81,15 +92,65 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 100,
useIcons: false,
checkedOutByWorktree: true,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_name (worktree) ↓5↑3"},
},
{
+ branch: &models.Branch{
+ Name: "branch_name",
+ Recency: "1m",
+ BehindBaseBranch: makeAtomic(2),
+ },
+ itemOperation: types.ItemOperationNone,
+ fullDescription: false,
+ viewWidth: 100,
+ useIcons: false,
+ checkedOutByWorktree: false,
+ showDivergenceCfg: "onlyArrow",
+ expected: []string{"1m", "branch_name ↓"},
+ },
+ {
+ branch: &models.Branch{
+ Name: "branch_name",
+ Recency: "1m",
+ UpstreamRemote: "origin",
+ AheadForPull: "0",
+ BehindForPull: "0",
+ BehindBaseBranch: makeAtomic(2),
+ },
+ itemOperation: types.ItemOperationNone,
+ fullDescription: false,
+ viewWidth: 100,
+ useIcons: false,
+ checkedOutByWorktree: false,
+ showDivergenceCfg: "arrowAndNumber",
+ expected: []string{"1m", "branch_name ✓ ↓2"},
+ },
+ {
+ branch: &models.Branch{
+ Name: "branch_name",
+ Recency: "1m",
+ UpstreamRemote: "origin",
+ AheadForPull: "3",
+ BehindForPull: "5",
+ BehindBaseBranch: makeAtomic(2),
+ },
+ itemOperation: types.ItemOperationNone,
+ fullDescription: false,
+ viewWidth: 100,
+ useIcons: false,
+ checkedOutByWorktree: false,
+ showDivergenceCfg: "arrowAndNumber",
+ expected: []string{"1m", "branch_name ↓5↑3 ↓2"},
+ },
+ {
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
itemOperation: types.ItemOperationPushing,
fullDescription: false,
viewWidth: 100,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_name Pushing |"},
},
{
@@ -108,6 +169,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 100,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "12345678", "branch_name ✓", "origin branch_name", "commit title"},
},
@@ -119,6 +181,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 14,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_na…"},
},
{
@@ -128,6 +191,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 14,
useIcons: false,
checkedOutByWorktree: true,
+ showDivergenceCfg: "none",
expected: []string{"1m", "bra… (worktree)"},
},
{
@@ -137,6 +201,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 14,
useIcons: true,
checkedOutByWorktree: true,
+ showDivergenceCfg: "none",
expected: []string{"1m", "󰘬", "branc… 󰌹"},
},
{
@@ -152,6 +217,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 14,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_… ✓"},
},
{
@@ -167,6 +233,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 30,
useIcons: false,
checkedOutByWorktree: true,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branch_na… (worktree) ↓5↑3"},
},
{
@@ -176,6 +243,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 20,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "branc… Pushing |"},
},
{
@@ -185,6 +253,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: -1,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "abc Pushing |"},
},
{
@@ -194,6 +263,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: -1,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "ab Pushing |"},
},
{
@@ -203,6 +273,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: -1,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "a Pushing |"},
},
{
@@ -221,6 +292,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
viewWidth: 20,
useIcons: false,
checkedOutByWorktree: false,
+ showDivergenceCfg: "none",
expected: []string{"1m", "12345678", "bran… ✓", "origin branch_name", "commit title"},
},
}
@@ -232,6 +304,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
for i, s := range scenarios {
icons.SetNerdFontsVersion(lo.Ternary(s.useIcons, "3", ""))
+ c.UserConfig.Gui.ShowDivergenceFromBaseBranch = s.showDivergenceCfg
worktrees := []*models.Worktree{}
if s.checkedOutByWorktree {