diff options
43 files changed, 675 insertions, 89 deletions
diff --git a/.gitignore b/.gitignore index 2053b9898..2fc9940dc 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,6 @@ # Hidden .* -# TODO -TODO.* - # Notes *.notes diff --git a/docs/Config.md b/docs/Config.md index c6f5cbbf9..d85637429 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -80,6 +80,7 @@ gui: showIcons: false # deprecated: use nerdFontsVersion instead nerdFontsVersion: "" # nerd fonts version to use ("2" or "3"); empty means don't show nerd font icons showFileIcons: true # for hiding file icons in the file views + commitHashLength: 8 # length of commit hash in commits view. 0 shows '*' if NF icons aren't enabled commandLogSize: 8 splitDiff: 'auto' # one of 'auto' | 'always' skipRewordInEditorWarning: false # for skipping the confirmation before launching the reword editor @@ -550,6 +551,15 @@ Example: ```yaml git: + commitPrefix: + pattern: "^\\w+\\/(\\w+-\\w+).*" + replace: '[$1] ' +``` + +If you want repository-specific prefixes, you can map them with `commitPrefixes`. If you have both `commitPrefixes` defined and an entry in `commitPrefixes` for the current repo, the `commitPrefixes` entry is given higher precedence. Repository folder names must be an exact match. + +```yaml +git: commitPrefixes: my_project: # This is repository folder name pattern: "^\\w+\\/(\\w+-\\w+).*" diff --git a/docs/Stacked_Branches.md b/docs/Stacked_Branches.md index 3e943e791..cd573be26 100644 --- a/docs/Stacked_Branches.md +++ b/docs/Stacked_Branches.md @@ -13,6 +13,6 @@ includes interactive rebases, so for example amending a commit in the first branch of the stack will "just work" in the sense that it keeps the other branches properly stacked onto it. -Lazygit visualizes the invidual branch heads in the stack by marking them with a +Lazygit visualizes the individual branch heads in the stack by marking them with a cyan asterisk (or a cyan branch symbol if you are using [nerd fonts](Config.md#display-nerd-fonts-icons)). @@ -8,7 +8,6 @@ require ( github.com/aybabtme/humanlog v0.4.1 github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21 github.com/creack/pty v1.1.11 - github.com/fsmiamoto/git-todo-parser v0.0.5 github.com/gdamore/tcell/v2 v2.7.4 github.com/go-errors/errors v1.5.1 github.com/gookit/color v1.4.2 @@ -34,6 +33,7 @@ require ( github.com/sirupsen/logrus v1.4.2 github.com/spf13/afero v1.9.5 github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad + github.com/stefanhaller/git-todo-parser v0.0.7-0.20240406123903-fd957137b6e2 github.com/stretchr/testify v1.8.1 github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 golang.org/x/exp v0.0.0-20220318154914-8dddf5d87bd8 @@ -84,8 +84,6 @@ github.com/fatih/color v1.7.1-0.20180516100307-2d684516a886/go.mod h1:Zm6kSWBoL9 github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= -github.com/fsmiamoto/git-todo-parser v0.0.5 h1:Bhzd/vz/6Qm3udfkd6NO9fWfD3TpwR9ucp3N75/J5I8= -github.com/fsmiamoto/git-todo-parser v0.0.5/go.mod h1:B+AgTbNE2BARvJqzXygThzqxLIaEWvwr2sxKYYb0Fas= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw= @@ -281,6 +279,8 @@ github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad h1:fiWzISvDn0Csy5H0iwgAuJGQTUpVfEMJJd4nRFXogbc= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= +github.com/stefanhaller/git-todo-parser v0.0.7-0.20240406123903-fd957137b6e2 h1:RTNWemd/9z9A5L/AggEP3OdhRz5dXETB/wdAlYF0SuM= +github.com/stefanhaller/git-todo-parser v0.0.7-0.20240406123903-fd957137b6e2/go.mod h1:HFt9hGqMzgQ+gVxMKcvTvGaFz4Y0yYycqqAp2V3wcJY= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= diff --git a/pkg/app/daemon/daemon.go b/pkg/app/daemon/daemon.go index e815b6e82..045491fce 100644 --- a/pkg/app/daemon/daemon.go +++ b/pkg/app/daemon/daemon.go @@ -8,11 +8,11 @@ import ( "os/exec" "strconv" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "github.com/stefanhaller/git-todo-parser/todo" ) // Sometimes lazygit will be invoked in daemon mode from a parent lazygit process. @@ -33,6 +33,7 @@ const ( DaemonKindUnknown DaemonKind = iota DaemonKindExitImmediately + DaemonKindRemoveUpdateRefsForCopiedBranch DaemonKindCherryPick DaemonKindMoveTodosUp DaemonKindMoveTodosDown @@ -53,14 +54,15 @@ func getInstruction() Instruction { jsonData := os.Getenv(DaemonInstructionEnvKey) mapping := map[DaemonKind]func(string) Instruction{ - DaemonKindExitImmediately: deserializeInstruction[*ExitImmediatelyInstruction], - DaemonKindCherryPick: deserializeInstruction[*CherryPickCommitsInstruction], - DaemonKindChangeTodoActions: deserializeInstruction[*ChangeTodoActionsInstruction], - DaemonKindMoveFixupCommitDown: deserializeInstruction[*MoveFixupCommitDownInstruction], - DaemonKindMoveTodosUp: deserializeInstruction[*MoveTodosUpInstruction], - DaemonKindMoveTodosDown: deserializeInstruction[*MoveTodosDownInstruction], - DaemonKindInsertBreak: deserializeInstruction[*InsertBreakInstruction], - DaemonKindWriteRebaseTodo: deserializeInstruction[*WriteRebaseTodoInstruction], + DaemonKindExitImmediately: deserializeInstruction[*ExitImmediatelyInstruction], + DaemonKindRemoveUpdateRefsForCopiedBranch: deserializeInstruction[*RemoveUpdateRefsForCopiedBranchInstruction], + DaemonKindCherryPick: deserializeInstruction[*CherryPickCommitsInstruction], + DaemonKindChangeTodoActions: deserializeInstruction[*ChangeTodoActionsInstruction], + DaemonKindMoveFixupCommitDown: deserializeInstruction[*MoveFixupCommitDownInstruction], + DaemonKindMoveTodosUp: deserializeInstruction[*MoveTodosUpInstruction], + DaemonKindMoveTodosDown: deserializeInstruction[*MoveTodosDownInstruction], + DaemonKindInsertBreak: deserializeInstruction[*InsertBreakInstruction], + DaemonKindWriteRebaseTodo: deserializeInstruction[*WriteRebaseTodoInstruction], } return mapping[getDaemonKind()](jsonData) @@ -157,6 +159,26 @@ func NewExitImmediatelyInstruction() Instruction { return &ExitImmediatelyInstruction{} } +type RemoveUpdateRefsForCopiedBranchInstruction struct{} + +func (self *RemoveUpdateRefsForCopiedBranchInstruction) Kind() DaemonKind { + return DaemonKindRemoveUpdateRefsForCopiedBranch +} + +func (self *RemoveUpdateRefsForCopiedBranchInstruction) SerializedInstructions() string { + return serializeInstruction(self) +} + +func (self *RemoveUpdateRefsForCopiedBranchInstruction) run(common *common.Common) error { + return handleInteractiveRebase(common, func(path string) error { + return nil + }) +} + +func NewRemoveUpdateRefsForCopiedBranchInstruction() Instruction { + return &RemoveUpdateRefsForCopiedBranchInstruction{} +} + type CherryPickCommitsInstruction struct { Todo string } diff --git a/pkg/app/daemon/rebase.go b/pkg/app/daemon/rebase.go index 0ca323c7d..8cc16d3b1 100644 --- a/pkg/app/daemon/rebase.go +++ b/pkg/app/daemon/rebase.go @@ -5,11 +5,12 @@ import ( "path/filepath" "strings" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/env" + "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "github.com/stefanhaller/git-todo-parser/todo" ) type TodoLine struct { @@ -44,6 +45,10 @@ func handleInteractiveRebase(common *common.Common, f func(path string) error) e path := os.Args[1] if strings.HasSuffix(path, "git-rebase-todo") { + err := utils.RemoveUpdateRefsForCopiedBranch(path, getCommentChar()) + if err != nil { + return err + } return f(path) } else if strings.HasSuffix(path, filepath.Join(gitDir(), "COMMIT_EDITMSG")) { // TODO: test // if we are rebasing and squashing, we'll see a COMMIT_EDITMSG diff --git a/pkg/commands/git_commands/commit_loader.go b/pkg/commands/git_commands/commit_loader.go index 50d9db709..48545edb9 100644 --- a/pkg/commands/git_commands/commit_loader.go +++ b/pkg/commands/git_commands/commit_loader.go @@ -11,13 +11,13 @@ import ( "strings" "sync" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/common" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "github.com/stefanhaller/git-todo-parser/todo" ) // context: diff --git a/pkg/commands/git_commands/commit_loader_test.go b/pkg/commands/git_commands/commit_loader_test.go index 38c03625f..7f60209a4 100644 --- a/pkg/commands/git_commands/commit_loader_test.go +++ b/pkg/commands/git_commands/commit_loader_test.go @@ -5,13 +5,13 @@ import ( "strings" "testing" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/go-errors/errors" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/stefanhaller/git-todo-parser/todo" "github.com/stretchr/testify/assert" ) diff --git a/pkg/commands/git_commands/diff.go b/pkg/commands/git_commands/diff.go index 9f81bb91d..979279914 100644 --- a/pkg/commands/git_commands/diff.go +++ b/pkg/commands/git_commands/diff.go @@ -1,6 +1,10 @@ package git_commands -import "github.com/jesseduffield/lazygit/pkg/commands/oscommands" +import ( + "fmt" + + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" +) type DiffCommands struct { *GitCommon @@ -13,10 +17,16 @@ func NewDiffCommands(gitCommon *GitCommon) *DiffCommands { } func (self *DiffCommands) DiffCmdObj(diffArgs []string) oscommands.ICmdObj { + extDiffCmd := self.UserConfig.Git.Paging.ExternalDiffCommand + useExtDiff := extDiffCmd != "" + return self.cmd.New( NewGitCmd("diff"). Config("diff.noprefix=false"). - Arg("--submodule", "--no-ext-diff", "--color"). + ConfigIf(useExtDiff, "diff.external="+extDiffCmd). + ArgIfElse(useExtDiff, "--ext-diff", "--no-ext-diff"). + Arg("--submodule"). + Arg(fmt.Sprintf("--color=%s", self.UserConfig.Git.Paging.ColorArg)). Arg(diffArgs...). Dir(self.repoPaths.worktreePath). ToArgv(), diff --git a/pkg/commands/git_commands/patch.go b/pkg/commands/git_commands/patch.go index fa8436101..3d18bf3e2 100644 --- a/pkg/commands/git_commands/patch.go +++ b/pkg/commands/git_commands/patch.go @@ -4,12 +4,12 @@ import ( "path/filepath" "time" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/go-errors/errors" "github.com/jesseduffield/lazygit/pkg/app/daemon" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/patch" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" + "github.com/stefanhaller/git-todo-parser/todo" ) type PatchCommands struct { diff --git a/pkg/commands/git_commands/rebase.go b/pkg/commands/git_commands/rebase.go index f7b8b43dc..040df0070 100644 --- a/pkg/commands/git_commands/rebase.go +++ b/pkg/commands/git_commands/rebase.go @@ -5,13 +5,13 @@ import ( "path/filepath" "strings" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/go-errors/errors" "github.com/jesseduffield/lazygit/pkg/app/daemon" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "github.com/stefanhaller/git-todo-parser/todo" ) type RebaseCommands struct { @@ -233,7 +233,7 @@ func (self *RebaseCommands) PrepareInteractiveRebaseCommand(opts PrepareInteract if opts.instruction != nil { cmdObj.AddEnvVars(daemon.ToEnvVars(opts.instruction)...) } else { - gitSequenceEditor = "true" + cmdObj.AddEnvVars(daemon.ToEnvVars(daemon.NewRemoveUpdateRefsForCopiedBranchInstruction())...) } cmdObj.AddEnvVars( diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go index 3346c4f35..7639dbad8 100644 --- a/pkg/commands/git_commands/working_tree.go +++ b/pkg/commands/git_commands/working_tree.go @@ -363,7 +363,7 @@ func (self *WorkingTreeCommands) ResetAndClean() error { return self.RemoveUntrackedFiles() } -// ResetHardHead runs `git reset --hard` +// ResetHard runs `git reset --hard` func (self *WorkingTreeCommands) ResetHard(ref string) error { cmdArgs := NewGitCmd("reset").Arg("--hard", ref). ToArgv() diff --git a/pkg/commands/models/commit.go b/pkg/commands/models/commit.go index 64b89db8f..95e3b9b18 100644 --- a/pkg/commands/models/commit.go +++ b/pkg/commands/models/commit.go @@ -3,8 +3,8 @@ package models import ( "fmt" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/stefanhaller/git-todo-parser/todo" ) // Special commit hash for empty tree object diff --git a/pkg/commands/oscommands/copy.go b/pkg/commands/oscommands/copy.go index aab460e47..c6d83e23b 100644 --- a/pkg/commands/oscommands/copy.go +++ b/pkg/commands/oscommands/copy.go @@ -1,7 +1,7 @@ package oscommands import ( - "fmt" + "errors" "io" "os" "path/filepath" @@ -86,7 +86,7 @@ func CopyDir(src string, dst string) (err error) { return err } if !si.IsDir() { - return fmt.Errorf("source is not a directory") + return errors.New("source is not a directory") } _, err = os.Stat(dst) diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 29b46e903..c22594461 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -123,6 +123,8 @@ type GuiConfig struct { NerdFontsVersion string `yaml:"nerdFontsVersion" jsonschema:"enum=2,enum=3,enum="` // If true (default), file icons are shown in the file views. Only relevant if NerdFontsVersion is not empty. ShowFileIcons bool `yaml:"showFileIcons"` + // Length of commit hash in commits view. 0 shows '*' if NF icons aren't on. + CommitHashLength int `yaml:"commitHashLength" jsonschema:"minimum=0"` // If true, show commit hashes alongside branch names in the branches view. ShowBranchCommitHash bool `yaml:"showBranchCommitHash"` // Height of the command log view @@ -220,6 +222,8 @@ type GitConfig struct { // If true, do not allow force pushes DisableForcePushing bool `yaml:"disableForcePushing"` // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix + CommitPrefix *CommitPrefixConfig `yaml:"commitPrefix"` + // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"` // If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀 // (This should really be under 'gui', not 'git') @@ -675,6 +679,7 @@ func GetDefaultConfig() *UserConfig { ShowIcons: false, NerdFontsVersion: "", ShowFileIcons: true, + CommitHashLength: 8, ShowBranchCommitHash: false, CommandLogSize: 8, SplitDiff: "auto", 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/controllers/helpers/working_tree_helper.go b/pkg/gui/controllers/helpers/working_tree_helper.go index edd7005e9..a97639795 100644 --- a/pkg/gui/controllers/helpers/working_tree_helper.go +++ b/pkg/gui/controllers/helpers/working_tree_helper.go @@ -220,9 +220,9 @@ func (self *WorkingTreeHelper) prepareFilesForCommit() error { func (self *WorkingTreeHelper) commitPrefixConfigForRepo() *config.CommitPrefixConfig { cfg, ok := self.c.UserConfig.Git.CommitPrefixes[self.c.Git().RepoPaths.RepoName()] - if !ok { - return nil + if ok { + return &cfg } - return &cfg + return self.c.UserConfig.Git.CommitPrefix } diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 1336f5237..1121e141e 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -4,7 +4,6 @@ import ( "fmt" "strings" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/go-errors/errors" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" @@ -16,6 +15,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" + "github.com/stefanhaller/git-todo-parser/todo" ) // after selecting the 200th commit, we'll load in all the rest diff --git a/pkg/gui/controllers/undo_controller.go b/pkg/gui/controllers/undo_controller.go index 96e9f3f11..8bd44a86d 100644 --- a/pkg/gui/controllers/undo_controller.go +++ b/pkg/gui/controllers/undo_controller.go @@ -16,7 +16,7 @@ import ( // we then do the reverse of what that reflog describes. // When we do this, we create a new reflog entry, and tag it as either an undo or redo // Then, next time we want to undo, we'll use those entries to know which user-initiated -// actions we can skip. E.g. if I do do three things, A, B, and C, and hit undo twice, +// actions we can skip. E.g. if I do three things, A, B, and C, and hit undo twice, // the reflog will read UUCBA, and when I read the first two undos, I know to skip the following // two user actions, meaning we end up undoing reflog entry C. Redoing works in a similar way. diff --git a/pkg/gui/filetree/build_tree_test.go b/pkg/gui/filetree/build_tree_test.go index ac36be9af..b2bf20f1d 100644 --- a/pkg/gui/filetree/build_tree_test.go +++ b/pkg/gui/filetree/build_tree_test.go @@ -127,7 +127,7 @@ func TestBuildTreeFromFiles(t *testing.T) { expected: &Node[models.File]{ Path: "", // it is a little strange that we're not bubbling up our merge conflict - // here but we are technically still in in tree mode and that's the rule + // here but we are technically still in tree mode and that's the rule Children: []*Node[models.File]{ { File: &models.File{Name: "a"}, diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index 1fc2c7d91..c385d3407 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -5,7 +5,6 @@ import ( "strings" "time" - "github.com/fsmiamoto/git-todo-parser/todo" "github.com/jesseduffield/generics/set" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" @@ -19,11 +18,13 @@ import ( "github.com/kyokomi/emoji/v2" "github.com/samber/lo" "github.com/sasha-s/go-deadlock" + "github.com/stefanhaller/git-todo-parser/todo" ) 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...) + } |