From f3164afa1efe5e3b412217e4d26b01e0be53b3f4 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 7 Jul 2025 14:49:25 +0200 Subject: [PATCH 01/11] Fix keybinding display for local branches sort order to indicate it's a menu --- pkg/gui/controllers/branches_controller.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 241070ef6..454216df7 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -140,6 +140,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty Key: opts.GetKey(opts.Config.Branches.SortOrder), Handler: self.createSortMenu, Description: self.c.Tr.SortOrder, + OpensMenu: true, }, { Key: opts.GetKey(opts.Config.Commits.ViewResetOptions), From 8d7bfd131ef1b951dd0b69a03787b0eab77196dd Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 7 Jul 2025 14:57:12 +0200 Subject: [PATCH 02/11] Move IgnoreWhitespaceInDiffView to user config When toggling the value in the UI we simply overwrite the value in UserConfig; this would be bad if there was ever a chance that we want to write the user config back to disk, but it is very unlikely that we can do that, because currently we have no way to tell which parts of the config come from the global config file and which ones come from a repo-local one. --- docs/Config.md | 3 +++ pkg/commands/git_commands/commit.go | 2 +- pkg/commands/git_commands/commit_test.go | 2 +- pkg/commands/git_commands/diff.go | 2 +- pkg/commands/git_commands/stash.go | 2 +- pkg/commands/git_commands/stash_test.go | 2 +- pkg/commands/git_commands/working_tree.go | 4 ++-- pkg/commands/git_commands/working_tree_test.go | 4 ++-- pkg/config/app_config.go | 11 +++++------ pkg/config/user_config.go | 3 +++ pkg/gui/controllers/helpers/diff_helper.go | 2 +- pkg/gui/controllers/toggle_whitespace_action.go | 3 +-- schema/config.json | 5 +++++ 13 files changed, 27 insertions(+), 18 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 925ceb1b3..3742c4090 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -366,6 +366,9 @@ git: allBranchesLogCmds: - git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium + # If true, git diffs are rendered with the `--ignore-all-space` flag, which ignores whitespace changes. Can be toggled from within Lazygit with ``. + ignoreWhitespaceInDiffView: false + # If true, do not spawn a separate process when using GPG overrideGpg: false diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go index 3568dbb33..2aed0f06d 100644 --- a/pkg/commands/git_commands/commit.go +++ b/pkg/commands/git_commands/commit.go @@ -268,7 +268,7 @@ func (self *CommitCommands) ShowCmdObj(hash string, filterPath string) *oscomman Arg("--decorate"). Arg("-p"). Arg(hash). - ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space"). + ArgIf(self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). ArgIf(filterPath != "", "--", filterPath). Dir(self.repoPaths.worktreePath). diff --git a/pkg/commands/git_commands/commit_test.go b/pkg/commands/git_commands/commit_test.go index a00a4ff23..3ce414a83 100644 --- a/pkg/commands/git_commands/commit_test.go +++ b/pkg/commands/git_commands/commit_test.go @@ -320,8 +320,8 @@ func TestCommitShowCmdObj(t *testing.T) { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() userConfig.Git.Paging.ExternalDiffCommand = s.extDiffCmd + userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState := &config.AppState{} - appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState.DiffContextSize = s.contextSize appState.RenameSimilarityThreshold = s.similarityThreshold diff --git a/pkg/commands/git_commands/diff.go b/pkg/commands/git_commands/diff.go index 16bb76275..8da1b103d 100644 --- a/pkg/commands/git_commands/diff.go +++ b/pkg/commands/git_commands/diff.go @@ -21,7 +21,7 @@ func NewDiffCommands(gitCommon *GitCommon) *DiffCommands { func (self *DiffCommands) DiffCmdObj(diffArgs []string) *oscommands.CmdObj { extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand useExtDiff := extDiffCmd != "" - ignoreWhitespace := self.AppState.IgnoreWhitespaceInDiffView + ignoreWhitespace := self.UserConfig().Git.IgnoreWhitespaceInDiffView return self.cmd.New( NewGitCmd("diff"). diff --git a/pkg/commands/git_commands/stash.go b/pkg/commands/git_commands/stash.go index a0097e87e..585b1f277 100644 --- a/pkg/commands/git_commands/stash.go +++ b/pkg/commands/git_commands/stash.go @@ -88,7 +88,7 @@ func (self *StashCommands) ShowStashEntryCmdObj(index int) *oscommands.CmdObj { Arg("-u"). Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)). Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)). - ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space"). + ArgIf(self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). Arg(fmt.Sprintf("refs/stash@{%d}", index)). Dir(self.repoPaths.worktreePath). diff --git a/pkg/commands/git_commands/stash_test.go b/pkg/commands/git_commands/stash_test.go index 4d54ea521..fc34e2c93 100644 --- a/pkg/commands/git_commands/stash_test.go +++ b/pkg/commands/git_commands/stash_test.go @@ -144,8 +144,8 @@ func TestStashStashEntryCmdObj(t *testing.T) { for _, s := range scenarios { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() + userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState := &config.AppState{} - appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState.DiffContextSize = s.contextSize appState.RenameSimilarityThreshold = s.similarityThreshold repoPaths := RepoPaths{ diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go index a5faa801b..e521b38ca 100644 --- a/pkg/commands/git_commands/working_tree.go +++ b/pkg/commands/git_commands/working_tree.go @@ -272,7 +272,7 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain Arg("--submodule"). Arg(fmt.Sprintf("--unified=%d", contextSize)). Arg(fmt.Sprintf("--color=%s", colorArg)). - ArgIf(!plain && self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space"). + ArgIf(!plain && self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). ArgIf(cached, "--cached"). ArgIf(noIndex, "--no-index"). @@ -314,7 +314,7 @@ func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reve Arg(from). Arg(to). ArgIf(reverse, "-R"). - ArgIf(!plain && self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space"). + ArgIf(!plain && self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). Arg("--"). Arg(fileName). Dir(self.repoPaths.worktreePath). diff --git a/pkg/commands/git_commands/working_tree_test.go b/pkg/commands/git_commands/working_tree_test.go index bbe3d7720..1191e5a0c 100644 --- a/pkg/commands/git_commands/working_tree_test.go +++ b/pkg/commands/git_commands/working_tree_test.go @@ -327,8 +327,8 @@ func TestWorkingTreeDiff(t *testing.T) { for _, s := range scenarios { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() + userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState := &config.AppState{} - appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState.DiffContextSize = s.contextSize appState.RenameSimilarityThreshold = s.similarityThreshold repoPaths := RepoPaths{ @@ -396,8 +396,8 @@ func TestWorkingTreeShowFileDiff(t *testing.T) { for _, s := range scenarios { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() + userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState := &config.AppState{} - appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace appState.DiffContextSize = s.contextSize repoPaths := RepoPaths{ worktreePath: "/path/to/worktree", diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 90c6c1013..521cad07d 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -676,12 +676,11 @@ type AppState struct { // For backwards compatibility we keep the old name in yaml files. ShellCommandsHistory []string `yaml:"customcommandshistory"` - HideCommandLog bool - IgnoreWhitespaceInDiffView bool - DiffContextSize uint64 - RenameSimilarityThreshold int - LocalBranchSortOrder string - RemoteBranchSortOrder string + HideCommandLog bool + DiffContextSize uint64 + RenameSimilarityThreshold int + LocalBranchSortOrder string + RemoteBranchSortOrder string // One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default' // 'topo-order' makes it easier to read the git log graph, but commits may not diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 179410aa9..8f6ed2187 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -264,6 +264,8 @@ type GitConfig struct { BranchLogCmd string `yaml:"branchLogCmd"` // Commands used to display git log of all branches in the main window, they will be cycled in order of appearance (array of strings) AllBranchesLogCmds []string `yaml:"allBranchesLogCmds"` + // If true, git diffs are rendered with the `--ignore-all-space` flag, which ignores whitespace changes. Can be toggled from within Lazygit with ``. + IgnoreWhitespaceInDiffView bool `yaml:"ignoreWhitespaceInDiffView"` // If true, do not spawn a separate process when using GPG OverrideGpg bool `yaml:"overrideGpg"` // If true, do not allow force pushes @@ -808,6 +810,7 @@ func GetDefaultConfig() *UserConfig { AutoStageResolvedConflicts: true, BranchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --", AllBranchesLogCmds: []string{"git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium"}, + IgnoreWhitespaceInDiffView: false, DisableForcePushing: false, CommitPrefixes: map[string][]CommitPrefixConfig(nil), BranchPrefix: "", diff --git a/pkg/gui/controllers/helpers/diff_helper.go b/pkg/gui/controllers/helpers/diff_helper.go index 95c820d37..9a08f15ec 100644 --- a/pkg/gui/controllers/helpers/diff_helper.go +++ b/pkg/gui/controllers/helpers/diff_helper.go @@ -144,7 +144,7 @@ func (self *DiffHelper) WithDiffModeCheck(f func()) { } func (self *DiffHelper) IgnoringWhitespaceSubTitle() string { - if self.c.GetAppState().IgnoreWhitespaceInDiffView { + if self.c.UserConfig().Git.IgnoreWhitespaceInDiffView { return self.c.Tr.IgnoreWhitespaceDiffViewSubTitle } diff --git a/pkg/gui/controllers/toggle_whitespace_action.go b/pkg/gui/controllers/toggle_whitespace_action.go index 4d491e79b..a1ac0c8da 100644 --- a/pkg/gui/controllers/toggle_whitespace_action.go +++ b/pkg/gui/controllers/toggle_whitespace_action.go @@ -25,8 +25,7 @@ func (self *ToggleWhitespaceAction) Call() error { return errors.New(self.c.Tr.IgnoreWhitespaceNotSupportedHere) } - self.c.GetAppState().IgnoreWhitespaceInDiffView = !self.c.GetAppState().IgnoreWhitespaceInDiffView - self.c.SaveAppStateAndLogError() + self.c.UserConfig().Git.IgnoreWhitespaceInDiffView = !self.c.UserConfig().Git.IgnoreWhitespaceInDiffView self.c.Context().CurrentSide().HandleFocus(types.OnFocusOpts{}) return nil diff --git a/schema/config.json b/schema/config.json index e21b7bb66..194cb8e9c 100644 --- a/schema/config.json +++ b/schema/config.json @@ -359,6 +359,11 @@ "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium" ] }, + "ignoreWhitespaceInDiffView": { + "type": "boolean", + "description": "If true, git diffs are rendered with the `--ignore-all-space` flag, which ignores whitespace changes. Can be toggled from within Lazygit with `\u003cc-w\u003e`.", + "default": false + }, "overrideGpg": { "type": "boolean", "description": "If true, do not spawn a separate process when using GPG", From f318e45e9db625e3b6d5fe3475b4b69718d58565 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 7 Jul 2025 15:16:51 +0200 Subject: [PATCH 03/11] Move DiffContextSize and RenameSimilarityThreshold to user config --- docs/Config.md | 6 +++++ pkg/commands/git_commands/commit.go | 4 +-- pkg/commands/git_commands/commit_test.go | 7 +++-- pkg/commands/git_commands/diff.go | 2 +- pkg/commands/git_commands/file_loader.go | 2 +- pkg/commands/git_commands/file_loader_test.go | 13 +++------- pkg/commands/git_commands/stash.go | 4 +-- pkg/commands/git_commands/stash_test.go | 7 +++-- pkg/commands/git_commands/working_tree.go | 6 ++--- .../git_commands/working_tree_test.go | 12 ++++----- pkg/config/app_config.go | 26 ++++++++----------- pkg/config/user_config.go | 6 +++++ .../controllers/commits_files_controller.go | 4 +-- .../controllers/context_lines_controller.go | 11 ++++---- .../rename_similarity_threshold_controller.go | 11 ++++---- pkg/gui/controllers/staging_controller.go | 4 +-- schema/config.json | 12 +++++++++ 17 files changed, 73 insertions(+), 64 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 3742c4090..25f9fcbd3 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -369,6 +369,12 @@ git: # If true, git diffs are rendered with the `--ignore-all-space` flag, which ignores whitespace changes. Can be toggled from within Lazygit with ``. ignoreWhitespaceInDiffView: false + # The number of lines of context to show around each diff hunk. Can be changed from within Lazygit with the `{` and `}` keys. + diffContextSize: 3 + + # The threshold for considering a file to be renamed, in percent. Can be changed from within Lazygit with the `(` and `)` keys. + renameSimilarityThreshold: 50 + # If true, do not spawn a separate process when using GPG overrideGpg: false diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go index 2aed0f06d..f021a90bf 100644 --- a/pkg/commands/git_commands/commit.go +++ b/pkg/commands/git_commands/commit.go @@ -254,7 +254,7 @@ func (self *CommitCommands) AmendHeadCmdObj() *oscommands.CmdObj { } func (self *CommitCommands) ShowCmdObj(hash string, filterPath string) *oscommands.CmdObj { - contextSize := self.AppState.DiffContextSize + contextSize := self.UserConfig().Git.DiffContextSize extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand cmdArgs := NewGitCmd("show"). @@ -269,7 +269,7 @@ func (self *CommitCommands) ShowCmdObj(hash string, filterPath string) *oscomman Arg("-p"). Arg(hash). ArgIf(self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). - Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). + Arg(fmt.Sprintf("--find-renames=%d%%", self.UserConfig().Git.RenameSimilarityThreshold)). ArgIf(filterPath != "", "--", filterPath). Dir(self.repoPaths.worktreePath). ToArgv() diff --git a/pkg/commands/git_commands/commit_test.go b/pkg/commands/git_commands/commit_test.go index 3ce414a83..112cf6b77 100644 --- a/pkg/commands/git_commands/commit_test.go +++ b/pkg/commands/git_commands/commit_test.go @@ -321,15 +321,14 @@ func TestCommitShowCmdObj(t *testing.T) { userConfig := config.GetDefaultConfig() userConfig.Git.Paging.ExternalDiffCommand = s.extDiffCmd userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace - appState := &config.AppState{} - appState.DiffContextSize = s.contextSize - appState.RenameSimilarityThreshold = s.similarityThreshold + userConfig.Git.DiffContextSize = s.contextSize + userConfig.Git.RenameSimilarityThreshold = s.similarityThreshold runner := oscommands.NewFakeRunner(t).ExpectGitArgs(s.expected, "", nil) repoPaths := RepoPaths{ worktreePath: "/path/to/worktree", } - instance := buildCommitCommands(commonDeps{userConfig: userConfig, appState: appState, runner: runner, repoPaths: &repoPaths}) + instance := buildCommitCommands(commonDeps{userConfig: userConfig, appState: &config.AppState{}, runner: runner, repoPaths: &repoPaths}) assert.NoError(t, instance.ShowCmdObj("1234567890", s.filterPath).Run()) runner.CheckForMissingCalls() diff --git a/pkg/commands/git_commands/diff.go b/pkg/commands/git_commands/diff.go index 8da1b103d..5f1db045f 100644 --- a/pkg/commands/git_commands/diff.go +++ b/pkg/commands/git_commands/diff.go @@ -31,7 +31,7 @@ func (self *DiffCommands) DiffCmdObj(diffArgs []string) *oscommands.CmdObj { Arg("--submodule"). Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)). ArgIf(ignoreWhitespace, "--ignore-all-space"). - Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)). + Arg(fmt.Sprintf("--unified=%d", self.UserConfig().Git.DiffContextSize)). Arg(diffArgs...). Dir(self.repoPaths.worktreePath). ToArgv(), diff --git a/pkg/commands/git_commands/file_loader.go b/pkg/commands/git_commands/file_loader.go index 92a011f63..19c07ece1 100644 --- a/pkg/commands/git_commands/file_loader.go +++ b/pkg/commands/git_commands/file_loader.go @@ -175,7 +175,7 @@ func (self *FileLoader) gitStatus(opts GitStatusOptions) ([]FileStatus, error) { ArgIfElse( opts.NoRenames, "--no-renames", - fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold), + fmt.Sprintf("--find-renames=%d%%", self.UserConfig().Git.RenameSimilarityThreshold), ). ToArgv() diff --git a/pkg/commands/git_commands/file_loader_test.go b/pkg/commands/git_commands/file_loader_test.go index 233bfb855..80373eef1 100644 --- a/pkg/commands/git_commands/file_loader_test.go +++ b/pkg/commands/git_commands/file_loader_test.go @@ -198,17 +198,12 @@ func TestFileGetStatusFiles(t *testing.T) { t.Run(s.testName, func(t *testing.T) { cmd := oscommands.NewDummyCmdObjBuilder(s.runner) - appState := &config.AppState{} - appState.RenameSimilarityThreshold = s.similarityThreshold - - userConfig := &config.UserConfig{ - Gui: config.GuiConfig{ - ShowNumstatInFilesView: s.showNumstatInFilesView, - }, - } + userConfig := &config.UserConfig{} + userConfig.Gui.ShowNumstatInFilesView = s.showNumstatInFilesView + userConfig.Git.RenameSimilarityThreshold = s.similarityThreshold loader := &FileLoader{ - GitCommon: buildGitCommon(commonDeps{appState: appState, userConfig: userConfig}), + GitCommon: buildGitCommon(commonDeps{appState: &config.AppState{}, userConfig: userConfig}), cmd: cmd, config: &FakeFileLoaderConfig{showUntrackedFiles: "yes"}, getFileType: func(string) string { return "file" }, diff --git a/pkg/commands/git_commands/stash.go b/pkg/commands/git_commands/stash.go index 585b1f277..86dccff24 100644 --- a/pkg/commands/git_commands/stash.go +++ b/pkg/commands/git_commands/stash.go @@ -87,9 +87,9 @@ func (self *StashCommands) ShowStashEntryCmdObj(index int) *oscommands.CmdObj { Arg("--stat"). Arg("-u"). Arg(fmt.Sprintf("--color=%s", self.UserConfig().Git.Paging.ColorArg)). - Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)). + Arg(fmt.Sprintf("--unified=%d", self.UserConfig().Git.DiffContextSize)). ArgIf(self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). - Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). + Arg(fmt.Sprintf("--find-renames=%d%%", self.UserConfig().Git.RenameSimilarityThreshold)). Arg(fmt.Sprintf("refs/stash@{%d}", index)). Dir(self.repoPaths.worktreePath). ToArgv() diff --git a/pkg/commands/git_commands/stash_test.go b/pkg/commands/git_commands/stash_test.go index fc34e2c93..0311f791d 100644 --- a/pkg/commands/git_commands/stash_test.go +++ b/pkg/commands/git_commands/stash_test.go @@ -145,13 +145,12 @@ func TestStashStashEntryCmdObj(t *testing.T) { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace - appState := &config.AppState{} - appState.DiffContextSize = s.contextSize - appState.RenameSimilarityThreshold = s.similarityThreshold + userConfig.Git.DiffContextSize = s.contextSize + userConfig.Git.RenameSimilarityThreshold = s.similarityThreshold repoPaths := RepoPaths{ worktreePath: "/path/to/worktree", } - instance := buildStashCommands(commonDeps{userConfig: userConfig, appState: appState, repoPaths: &repoPaths}) + instance := buildStashCommands(commonDeps{userConfig: userConfig, appState: &config.AppState{}, repoPaths: &repoPaths}) cmdStr := instance.ShowStashEntryCmdObj(s.index).Args() assert.Equal(t, s.expected, cmdStr) diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go index e521b38ca..deb9e6a59 100644 --- a/pkg/commands/git_commands/working_tree.go +++ b/pkg/commands/git_commands/working_tree.go @@ -260,7 +260,7 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain colorArg = "never" } - contextSize := self.AppState.DiffContextSize + contextSize := self.UserConfig().Git.DiffContextSize prevPath := node.GetPreviousPath() noIndex := !node.GetIsTracked() && !node.GetHasStagedChanges() && !cached && node.GetIsFile() extDiffCmd := self.UserConfig().Git.Paging.ExternalDiffCommand @@ -273,7 +273,7 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain Arg(fmt.Sprintf("--unified=%d", contextSize)). Arg(fmt.Sprintf("--color=%s", colorArg)). ArgIf(!plain && self.UserConfig().Git.IgnoreWhitespaceInDiffView, "--ignore-all-space"). - Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)). + Arg(fmt.Sprintf("--find-renames=%d%%", self.UserConfig().Git.RenameSimilarityThreshold)). ArgIf(cached, "--cached"). ArgIf(noIndex, "--no-index"). Arg("--"). @@ -293,7 +293,7 @@ func (self *WorkingTreeCommands) ShowFileDiff(from string, to string, reverse bo } func (self *WorkingTreeCommands) ShowFileDiffCmdObj(from string, to string, reverse bool, fileName string, plain bool) *oscommands.CmdObj { - contextSize := self.AppState.DiffContextSize + contextSize := self.UserConfig().Git.DiffContextSize colorArg := self.UserConfig().Git.Paging.ColorArg if plain { diff --git a/pkg/commands/git_commands/working_tree_test.go b/pkg/commands/git_commands/working_tree_test.go index 1191e5a0c..759eb1bbe 100644 --- a/pkg/commands/git_commands/working_tree_test.go +++ b/pkg/commands/git_commands/working_tree_test.go @@ -328,14 +328,13 @@ func TestWorkingTreeDiff(t *testing.T) { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace - appState := &config.AppState{} - appState.DiffContextSize = s.contextSize - appState.RenameSimilarityThreshold = s.similarityThreshold + userConfig.Git.DiffContextSize = s.contextSize + userConfig.Git.RenameSimilarityThreshold = s.similarityThreshold repoPaths := RepoPaths{ worktreePath: "/path/to/worktree", } - instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig, appState: appState, repoPaths: &repoPaths}) + instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig, appState: &config.AppState{}, repoPaths: &repoPaths}) result := instance.WorktreeFileDiff(s.file, s.plain, s.cached) assert.Equal(t, expectedResult, result) s.runner.CheckForMissingCalls() @@ -397,13 +396,12 @@ func TestWorkingTreeShowFileDiff(t *testing.T) { t.Run(s.testName, func(t *testing.T) { userConfig := config.GetDefaultConfig() userConfig.Git.IgnoreWhitespaceInDiffView = s.ignoreWhitespace - appState := &config.AppState{} - appState.DiffContextSize = s.contextSize + userConfig.Git.DiffContextSize = s.contextSize repoPaths := RepoPaths{ worktreePath: "/path/to/worktree", } - instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig, appState: appState, repoPaths: &repoPaths}) + instance := buildWorkingTreeCommands(commonDeps{runner: s.runner, userConfig: userConfig, appState: &config.AppState{}, repoPaths: &repoPaths}) result, err := instance.ShowFileDiff(s.from, s.to, s.reverse, "test.txt", s.plain) assert.NoError(t, err) diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 521cad07d..aaaf7adb3 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -676,11 +676,9 @@ type AppState struct { // For backwards compatibility we keep the old name in yaml files. ShellCommandsHistory []string `yaml:"customcommandshistory"` - HideCommandLog bool - DiffContextSize uint64 - RenameSimilarityThreshold int - LocalBranchSortOrder string - RemoteBranchSortOrder string + HideCommandLog bool + LocalBranchSortOrder string + RemoteBranchSortOrder string // One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default' // 'topo-order' makes it easier to read the git log graph, but commits may not @@ -694,16 +692,14 @@ type AppState struct { func getDefaultAppState() *AppState { return &AppState{ - LastUpdateCheck: 0, - RecentRepos: []string{}, - StartupPopupVersion: 0, - LastVersion: "", - DiffContextSize: 3, - RenameSimilarityThreshold: 50, - LocalBranchSortOrder: "recency", - RemoteBranchSortOrder: "alphabetical", - GitLogOrder: "", // should be "topo-order" eventually - GitLogShowGraph: "", // should be "always" eventually + LastUpdateCheck: 0, + RecentRepos: []string{}, + StartupPopupVersion: 0, + LastVersion: "", + LocalBranchSortOrder: "recency", + RemoteBranchSortOrder: "alphabetical", + GitLogOrder: "", // should be "topo-order" eventually + GitLogShowGraph: "", // should be "always" eventually } } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 8f6ed2187..39c67bc4b 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -266,6 +266,10 @@ type GitConfig struct { AllBranchesLogCmds []string `yaml:"allBranchesLogCmds"` // If true, git diffs are rendered with the `--ignore-all-space` flag, which ignores whitespace changes. Can be toggled from within Lazygit with ``. IgnoreWhitespaceInDiffView bool `yaml:"ignoreWhitespaceInDiffView"` + // The number of lines of context to show around each diff hunk. Can be changed from within Lazygit with the `{` and `}` keys. + DiffContextSize uint64 `yaml:"diffContextSize"` + // The threshold for considering a file to be renamed, in percent. Can be changed from within Lazygit with the `(` and `)` keys. + RenameSimilarityThreshold int `yaml:"renameSimilarityThreshold" jsonschema:"minimum=0,maximum=100"` // If true, do not spawn a separate process when using GPG OverrideGpg bool `yaml:"overrideGpg"` // If true, do not allow force pushes @@ -811,6 +815,8 @@ func GetDefaultConfig() *UserConfig { BranchLogCmd: "git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --", AllBranchesLogCmds: []string{"git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium"}, IgnoreWhitespaceInDiffView: false, + DiffContextSize: 3, + RenameSimilarityThreshold: 50, DisableForcePushing: false, CommitPrefixes: map[string][]CommitPrefixConfig(nil), BranchPrefix: "", diff --git a/pkg/gui/controllers/commits_files_controller.go b/pkg/gui/controllers/commits_files_controller.go index 42e515b08..02cc67eae 100644 --- a/pkg/gui/controllers/commits_files_controller.go +++ b/pkg/gui/controllers/commits_files_controller.go @@ -378,7 +378,7 @@ func (self *CommitFilesController) openDiffTool(node *filetree.CommitFileNode) e } func (self *CommitFilesController) toggleForPatch(selectedNodes []*filetree.CommitFileNode) error { - if self.c.AppState.DiffContextSize == 0 { + if self.c.UserConfig().Git.DiffContextSize == 0 { return fmt.Errorf(self.c.Tr.Actions.NotEnoughContextForCustomPatch, keybindings.Label(self.c.UserConfig().Keybinding.Universal.IncreaseContextInDiffView)) } @@ -472,7 +472,7 @@ func (self *CommitFilesController) enterCommitFile(node *filetree.CommitFileNode return self.handleToggleCommitFileDirCollapsed(node) } - if self.c.AppState.DiffContextSize == 0 { + if self.c.UserConfig().Git.DiffContextSize == 0 { return fmt.Errorf(self.c.Tr.Actions.NotEnoughContextForCustomPatch, keybindings.Label(self.c.UserConfig().Keybinding.Universal.IncreaseContextInDiffView)) } diff --git a/pkg/gui/controllers/context_lines_controller.go b/pkg/gui/controllers/context_lines_controller.go index b26a8e632..5e0f9d606 100644 --- a/pkg/gui/controllers/context_lines_controller.go +++ b/pkg/gui/controllers/context_lines_controller.go @@ -71,8 +71,8 @@ func (self *ContextLinesController) Increase() error { return err } - if self.c.AppState.DiffContextSize < math.MaxUint64 { - self.c.AppState.DiffContextSize++ + if self.c.UserConfig().Git.DiffContextSize < math.MaxUint64 { + self.c.UserConfig().Git.DiffContextSize++ } return self.applyChange() } @@ -86,8 +86,8 @@ func (self *ContextLinesController) Decrease() error { return err } - if self.c.AppState.DiffContextSize > 0 { - self.c.AppState.DiffContextSize-- + if self.c.UserConfig().Git.DiffContextSize > 0 { + self.c.UserConfig().Git.DiffContextSize-- } return self.applyChange() } @@ -96,8 +96,7 @@ func (self *ContextLinesController) Decrease() error { } func (self *ContextLinesController) applyChange() error { - self.c.Toast(fmt.Sprintf(self.c.Tr.DiffContextSizeChanged, self.c.AppState.DiffContextSize)) - self.c.SaveAppStateAndLogError() + self.c.Toast(fmt.Sprintf(self.c.Tr.DiffContextSizeChanged, self.c.UserConfig().Git.DiffContextSize)) currentContext := self.currentSidePanel() switch currentContext.GetKey() { diff --git a/pkg/gui/controllers/rename_similarity_threshold_controller.go b/pkg/gui/controllers/rename_similarity_threshold_controller.go index cae0fb80f..98df26127 100644 --- a/pkg/gui/controllers/rename_similarity_threshold_controller.go +++ b/pkg/gui/controllers/rename_similarity_threshold_controller.go @@ -59,10 +59,10 @@ func (self *RenameSimilarityThresholdController) Context() types.Context { } func (self *RenameSimilarityThresholdController) Increase() error { - old_size := self.c.AppState.RenameSimilarityThreshold + old_size := self.c.UserConfig().Git.RenameSimilarityThreshold if self.isShowingRenames() && old_size < 100 { - self.c.AppState.RenameSimilarityThreshold = min(100, old_size+5) + self.c.UserConfig().Git.RenameSimilarityThreshold = min(100, old_size+5) return self.applyChange() } @@ -70,10 +70,10 @@ func (self *RenameSimilarityThresholdController) Increase() error { } func (self *RenameSimilarityThresholdController) Decrease() error { - old_size := self.c.AppState.RenameSimilarityThreshold + old_size := self.c.UserConfig().Git.RenameSimilarityThreshold if self.isShowingRenames() && old_size > 5 { - self.c.AppState.RenameSimilarityThreshold = max(5, old_size-5) + self.c.UserConfig().Git.RenameSimilarityThreshold = max(5, old_size-5) return self.applyChange() } @@ -81,8 +81,7 @@ func (self *RenameSimilarityThresholdController) Decrease() error { } func (self *RenameSimilarityThresholdController) applyChange() error { - self.c.Toast(fmt.Sprintf(self.c.Tr.RenameSimilarityThresholdChanged, self.c.AppState.RenameSimilarityThreshold)) - self.c.SaveAppStateAndLogError() + self.c.Toast(fmt.Sprintf(self.c.Tr.RenameSimilarityThresholdChanged, self.c.UserConfig().Git.RenameSimilarityThreshold)) currentContext := self.currentSidePanel() switch currentContext.GetKey() { diff --git a/pkg/gui/controllers/staging_controller.go b/pkg/gui/controllers/staging_controller.go index d7198bdcb..51c6fafec 100644 --- a/pkg/gui/controllers/staging_controller.go +++ b/pkg/gui/controllers/staging_controller.go @@ -187,7 +187,7 @@ func (self *StagingController) TogglePanel() error { } func (self *StagingController) ToggleStaged() error { - if self.c.AppState.DiffContextSize == 0 { + if self.c.UserConfig().Git.DiffContextSize == 0 { return fmt.Errorf(self.c.Tr.Actions.NotEnoughContextToStage, keybindings.Label(self.c.UserConfig().Keybinding.Universal.IncreaseContextInDiffView)) } @@ -196,7 +196,7 @@ func (self *StagingController) ToggleStaged() error { } func (self *StagingController) DiscardSelection() error { - if self.c.AppState.DiffContextSize == 0 { + if self.c.UserConfig().Git.DiffContextSize == 0 { return fmt.Errorf(self.c.Tr.Actions.NotEnoughContextToDiscard, keybindings.Label(self.c.UserConfig().Keybinding.Universal.IncreaseContextInDiffView)) } diff --git a/schema/config.json b/schema/config.json index 194cb8e9c..9da832b4e 100644 --- a/schema/config.json +++ b/schema/config.json @@ -364,6 +364,18 @@ "description": "If true, git diffs are rendered with the `--ignore-all-space` flag, which ignores whitespace changes. Can be toggled from within Lazygit with `\u003cc-w\u003e`.", "default": false }, + "diffContextSize": { + "type": "integer", + "description": "The number of lines of context to show around each diff hunk. Can be changed from within Lazygit with the `{` and `}` keys.", + "default": 3 + }, + "renameSimilarityThreshold": { + "type": "integer", + "maximum": 100, + "minimum": 0, + "description": "The threshold for considering a file to be renamed, in percent. Can be changed from within Lazygit with the `(` and `)` keys.", + "default": 50 + }, "overrideGpg": { "type": "boolean", "description": "If true, do not spawn a separate process when using GPG", From d79283656d1685c3514889aa71ff6fc7c839dc25 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 7 Jul 2025 15:46:38 +0200 Subject: [PATCH 04/11] Add missing validation tests --- pkg/config/user_config_validation_test.go | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/pkg/config/user_config_validation_test.go b/pkg/config/user_config_validation_test.go index 8440d89b2..f98431713 100644 --- a/pkg/config/user_config_validation_test.go +++ b/pkg/config/user_config_validation_test.go @@ -30,6 +30,32 @@ func TestUserConfigValidate_enums(t *testing.T) { {value: "invalid_value", valid: false}, }, }, + { + name: "Gui.ShowDivergenceFromBaseBranch", + setup: func(config *UserConfig, value string) { + config.Gui.ShowDivergenceFromBaseBranch = value + }, + testCases: []testCase{ + {value: "none", valid: true}, + {value: "onlyArrow", valid: true}, + {value: "arrowAndNumber", valid: true}, + {value: "", valid: false}, + {value: "invalid_value", valid: false}, + }, + }, + { + name: "Git.AutoForwardBranches", + setup: func(config *UserConfig, value string) { + config.Git.AutoForwardBranches = value + }, + testCases: []testCase{ + {value: "none", valid: true}, + {value: "onlyMainBranches", valid: true}, + {value: "allBranches", valid: true}, + {value: "", valid: false}, + {value: "invalid_value", valid: false}, + }, + }, { name: "Keybindings", setup: func(config *UserConfig, value string) { From 703256e92d7eb12d49d92f58ffadda13b4a26c42 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 7 Jul 2025 15:37:05 +0200 Subject: [PATCH 05/11] Move LocalBranchSortOrder and RemoteBranchSortOrder to user config At the same time, we change the defaults for both of them to "date" (they were "recency" and "alphabetical", respectively, before). This is the reason we need to touch so many integration tests. For some of them I decided to adapt the test assertions to the changed sort order; for others, I added a SetupConfig step to set the order back to "recency" so that I don't have to change what the test does (e.g. how many SelectNextItem() calls are needed to get to a certain branch). --- docs/Config.md | 10 +++++++ pkg/commands/git_commands/branch_loader.go | 6 ++--- pkg/commands/git_commands/remote_loader.go | 2 +- pkg/config/app_config.go | 18 +++++-------- pkg/config/user_config.go | 10 +++++++ pkg/config/user_config_validation.go | 8 ++++++ pkg/config/user_config_validation_test.go | 26 +++++++++++++++++++ pkg/gui/controllers/branches_controller.go | 7 +++-- pkg/gui/controllers/helpers/refresh_helper.go | 4 +-- .../controllers/remote_branches_controller.go | 7 +++-- .../tests/branch/checkout_by_name.go | 2 +- pkg/integration/tests/branch/delete.go | 4 ++- .../tests/branch/delete_multiple.go | 3 ++- .../tests/branch/delete_while_filtering.go | 2 +- pkg/integration/tests/branch/rebase.go | 4 ++- .../tests/branch/rebase_abort_on_conflict.go | 4 ++- .../tests/branch/rebase_and_drop.go | 4 ++- .../tests/branch/rebase_cancel_on_conflict.go | 4 ++- .../rebase_conflicts_fix_build_errors.go | 4 ++- .../tests/branch/rebase_from_marked_base.go | 4 ++- .../tests/branch/reset_to_upstream.go | 4 ++- .../tests/branch/sort_local_branches.go | 16 ++++++------ .../tests/branch/sort_remote_branches.go | 16 ++++++------ .../tests/cherry_pick/cherry_pick.go | 4 ++- .../cherry_pick/cherry_pick_conflicts.go | 4 ++- .../cherry_pick/cherry_pick_during_rebase.go | 1 + .../tests/cherry_pick/cherry_pick_merge.go | 4 ++- .../tests/cherry_pick/cherry_pick_range.go | 4 ++- pkg/integration/tests/commit/checkout.go | 4 +-- .../custom_commands/check_for_conflicts.go | 2 ++ .../custom_commands/suggestions_command.go | 4 +-- .../custom_commands/suggestions_preset.go | 4 +-- .../filter_updates_when_model_changes.go | 4 +-- .../tests/filter_and_search/nested_filter.go | 4 +-- schema/config.json | 19 ++++++++++++++ 35 files changed, 161 insertions(+), 66 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 25f9fcbd3..6be09a383 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -399,6 +399,16 @@ git: # displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`) showWholeGraph: false + # How branches are sorted in the local branches view. + # One of: 'date' (default) | 'recency' | 'alphabetical' + # Can be changed from within Lazygit with the Sort Order menu (`s`) in the branches panel. + localBranchSortOrder: date + + # How branches are sorted in the remote branches view. + # One of: 'date' (default) | 'alphabetical' + # Can be changed from within Lazygit with the Sort Order menu (`s`) in the remote branches panel. + remoteBranchSortOrder: date + # When copying commit hashes to the clipboard, truncate them to this # length. Set to 40 to disable truncation. truncateCopiedCommitHashesTo: 12 diff --git a/pkg/commands/git_commands/branch_loader.go b/pkg/commands/git_commands/branch_loader.go index 73127ae63..a4e41b756 100644 --- a/pkg/commands/git_commands/branch_loader.go +++ b/pkg/commands/git_commands/branch_loader.go @@ -74,7 +74,7 @@ func (self *BranchLoader) Load(reflogCommits []*models.Commit, ) ([]*models.Branch, error) { branches := self.obtainBranches() - if self.AppState.LocalBranchSortOrder == "recency" { + if self.UserConfig().Git.LocalBranchSortOrder == "recency" { reflogBranches := self.obtainReflogBranches(reflogCommits) // loop through reflog branches. If there is a match, merge them, then remove it from the branches and keep it in the reflog branches branchesWithRecency := make([]*models.Branch, 0) @@ -254,7 +254,7 @@ func (self *BranchLoader) obtainBranches() []*models.Branch { return nil, false } - storeCommitDateAsRecency := self.AppState.LocalBranchSortOrder != "recency" + storeCommitDateAsRecency := self.UserConfig().Git.LocalBranchSortOrder != "recency" return obtainBranch(split, storeCommitDateAsRecency), true }) } @@ -268,7 +268,7 @@ func (self *BranchLoader) getRawBranches() (string, error) { ) var sortOrder string - switch strings.ToLower(self.AppState.LocalBranchSortOrder) { + switch strings.ToLower(self.UserConfig().Git.LocalBranchSortOrder) { case "recency", "date": sortOrder = "-committerdate" case "alphabetical": diff --git a/pkg/commands/git_commands/remote_loader.go b/pkg/commands/git_commands/remote_loader.go index 1b2e33682..2e632def4 100644 --- a/pkg/commands/git_commands/remote_loader.go +++ b/pkg/commands/git_commands/remote_loader.go @@ -85,7 +85,7 @@ func (self *RemoteLoader) getRemoteBranchesByRemoteName() (map[string][]*models. remoteBranchesByRemoteName := make(map[string][]*models.RemoteBranch) var sortOrder string - switch strings.ToLower(self.AppState.RemoteBranchSortOrder) { + switch strings.ToLower(self.UserConfig().Git.RemoteBranchSortOrder) { case "alphabetical": sortOrder = "refname" case "date": diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index aaaf7adb3..184d8e07a 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -676,9 +676,7 @@ type AppState struct { // For backwards compatibility we keep the old name in yaml files. ShellCommandsHistory []string `yaml:"customcommandshistory"` - HideCommandLog bool - LocalBranchSortOrder string - RemoteBranchSortOrder string + HideCommandLog bool // One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default' // 'topo-order' makes it easier to read the git log graph, but commits may not @@ -692,14 +690,12 @@ type AppState struct { func getDefaultAppState() *AppState { return &AppState{ - LastUpdateCheck: 0, - RecentRepos: []string{}, - StartupPopupVersion: 0, - LastVersion: "", - LocalBranchSortOrder: "recency", - RemoteBranchSortOrder: "alphabetical", - GitLogOrder: "", // should be "topo-order" eventually - GitLogShowGraph: "", // should be "always" eventually + LastUpdateCheck: 0, + RecentRepos: []string{}, + StartupPopupVersion: 0, + LastVersion: "", + GitLogOrder: "", // should be "topo-order" eventually + GitLogShowGraph: "", // should be "always" eventually } } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 39c67bc4b..5d619231e 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -285,6 +285,14 @@ type GitConfig struct { ParseEmoji bool `yaml:"parseEmoji"` // Config for showing the log in the commits view Log LogConfig `yaml:"log"` + // How branches are sorted in the local branches view. + // One of: 'date' (default) | 'recency' | 'alphabetical' + // Can be changed from within Lazygit with the Sort Order menu (`s`) in the branches panel. + LocalBranchSortOrder string `yaml:"localBranchSortOrder" jsonschema:"enum=date,enum=recency,enum=alphabetical"` + // How branches are sorted in the remote branches view. + // One of: 'date' (default) | 'alphabetical' + // Can be changed from within Lazygit with the Sort Order menu (`s`) in the remote branches panel. + RemoteBranchSortOrder string `yaml:"remoteBranchSortOrder" jsonschema:"enum=date,enum=alphabetical"` // When copying commit hashes to the clipboard, truncate them to this // length. Set to 40 to disable truncation. TruncateCopiedCommitHashesTo int `yaml:"truncateCopiedCommitHashesTo"` @@ -805,6 +813,8 @@ func GetDefaultConfig() *UserConfig { ShowGraph: "always", ShowWholeGraph: false, }, + LocalBranchSortOrder: "date", + RemoteBranchSortOrder: "date", SkipHookPrefix: "WIP", MainBranches: []string{"master", "main"}, AutoFetch: true, diff --git a/pkg/config/user_config_validation.go b/pkg/config/user_config_validation.go index f46dfca9a..5d43c4a28 100644 --- a/pkg/config/user_config_validation.go +++ b/pkg/config/user_config_validation.go @@ -23,6 +23,14 @@ func (config *UserConfig) Validate() error { []string{"none", "onlyMainBranches", "allBranches"}); err != nil { return err } + if err := validateEnum("git.localBranchSortOrder", config.Git.LocalBranchSortOrder, + []string{"date", "recency", "alphabetical"}); err != nil { + return err + } + if err := validateEnum("git.remoteBranchSortOrder", config.Git.RemoteBranchSortOrder, + []string{"date", "alphabetical"}); err != nil { + return err + } if err := validateKeybindings(config.Keybinding); err != nil { return err } diff --git a/pkg/config/user_config_validation_test.go b/pkg/config/user_config_validation_test.go index f98431713..67ff16991 100644 --- a/pkg/config/user_config_validation_test.go +++ b/pkg/config/user_config_validation_test.go @@ -56,6 +56,32 @@ func TestUserConfigValidate_enums(t *testing.T) { {value: "invalid_value", valid: false}, }, }, + { + name: "Git.LocalBranchSortOrder", + setup: func(config *UserConfig, value string) { + config.Git.LocalBranchSortOrder = value + }, + testCases: []testCase{ + {value: "date", valid: true}, + {value: "recency", valid: true}, + {value: "alphabetical", valid: true}, + {value: "", valid: false}, + {value: "invalid_value", valid: false}, + }, + }, + { + name: "Git.RemoteBranchSortOrder", + setup: func(config *UserConfig, value string) { + config.Git.RemoteBranchSortOrder = value + }, + testCases: []testCase{ + {value: "date", valid: true}, + {value: "recency", valid: false}, + {value: "alphabetical", valid: true}, + {value: "", valid: false}, + {value: "invalid_value", valid: false}, + }, + }, { name: "Keybindings", setup: func(config *UserConfig, value string) { diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 454216df7..b49a5f6f3 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -674,16 +674,15 @@ func (self *BranchesController) createTag(branch *models.Branch) error { func (self *BranchesController) createSortMenu() error { return self.c.Helpers().Refs.CreateSortOrderMenu([]string{"recency", "alphabetical", "date"}, func(sortOrder string) error { - if self.c.GetAppState().LocalBranchSortOrder != sortOrder { - self.c.GetAppState().LocalBranchSortOrder = sortOrder - self.c.SaveAppStateAndLogError() + if self.c.UserConfig().Git.LocalBranchSortOrder != sortOrder { + self.c.UserConfig().Git.LocalBranchSortOrder = sortOrder self.c.Contexts().Branches.SetSelection(0) self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) return nil } return nil }, - self.c.GetAppState().LocalBranchSortOrder) + self.c.UserConfig().Git.LocalBranchSortOrder) } func (self *BranchesController) createResetMenu(selectedBranch *models.Branch) error { diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index e377cfdf9..2682d8296 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -125,7 +125,7 @@ func (self *RefreshHelper) Refresh(options types.RefreshOptions) { refresh("commits and commit files", self.refreshCommitsAndCommitFiles) includeWorktreesWithBranches = scopeSet.Includes(types.WORKTREES) - if self.c.AppState.LocalBranchSortOrder == "recency" { + if self.c.UserConfig().Git.LocalBranchSortOrder == "recency" { refresh("reflog and branches", func() { self.refreshReflogAndBranches(includeWorktreesWithBranches, options.KeepBranchSelectionIndex) }) } else { refresh("branches", func() { self.refreshBranches(includeWorktreesWithBranches, options.KeepBranchSelectionIndex, true) }) @@ -446,7 +446,7 @@ func (self *RefreshHelper) refreshBranches(refreshWorktrees bool, keepBranchSele defer self.c.Mutexes().RefreshingBranchesMutex.Unlock() reflogCommits := self.c.Model().FilteredReflogCommits - if self.c.Modes().Filtering.Active() && self.c.AppState.LocalBranchSortOrder == "recency" { + if self.c.Modes().Filtering.Active() && self.c.UserConfig().Git.LocalBranchSortOrder == "recency" { // in filter mode we filter our reflog commits to just those containing the path // however we need all the reflog entries to populate the recencies of our branches // which allows us to order them correctly. So if we're filtering we'll just diff --git a/pkg/gui/controllers/remote_branches_controller.go b/pkg/gui/controllers/remote_branches_controller.go index 629bbbaa3..3bb99380a 100644 --- a/pkg/gui/controllers/remote_branches_controller.go +++ b/pkg/gui/controllers/remote_branches_controller.go @@ -146,15 +146,14 @@ func (self *RemoteBranchesController) rebase(selectedBranch *models.RemoteBranch func (self *RemoteBranchesController) createSortMenu() error { return self.c.Helpers().Refs.CreateSortOrderMenu([]string{"alphabetical", "date"}, func(sortOrder string) error { - if self.c.GetAppState().RemoteBranchSortOrder != sortOrder { - self.c.GetAppState().RemoteBranchSortOrder = sortOrder - self.c.SaveAppStateAndLogError() + if self.c.UserConfig().Git.RemoteBranchSortOrder != sortOrder { + self.c.UserConfig().Git.RemoteBranchSortOrder = sortOrder self.c.Contexts().RemoteBranches.SetSelection(0) self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.REMOTES}}) } return nil }, - self.c.GetAppState().RemoteBranchSortOrder) + self.c.UserConfig().Git.RemoteBranchSortOrder) } func (self *RemoteBranchesController) createResetMenu(selectedBranch *models.RemoteBranch) error { diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index 127ea10dd..af06162a7 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -33,8 +33,8 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ }). Lines( MatchesRegexp(`\*.*new-branch`).IsSelected(), - Contains("master"), Contains("@"), + Contains("master"), ) }, }) diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index ae29a679c..5da844622 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -9,7 +9,9 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Try all combination of local and remote branch deletions", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shell. CloneIntoRemote("origin"). diff --git a/pkg/integration/tests/branch/delete_multiple.go b/pkg/integration/tests/branch/delete_multiple.go index a03a822f6..0bba33b9d 100644 --- a/pkg/integration/tests/branch/delete_multiple.go +++ b/pkg/integration/tests/branch/delete_multiple.go @@ -10,7 +10,8 @@ var DeleteMultiple = NewIntegrationTest(NewIntegrationTestArgs{ ExtraCmdArgs: []string{}, Skip: false, SetupConfig: func(config *config.AppConfig) { - config.GetAppState().LocalBranchSortOrder = "alphabetic" + config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical" + config.GetUserConfig().Git.RemoteBranchSortOrder = "alphabetical" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/branch/delete_while_filtering.go b/pkg/integration/tests/branch/delete_while_filtering.go index d967ff40f..2b2039d67 100644 --- a/pkg/integration/tests/branch/delete_while_filtering.go +++ b/pkg/integration/tests/branch/delete_while_filtering.go @@ -12,7 +12,7 @@ var DeleteWhileFiltering = NewIntegrationTest(NewIntegrationTestArgs{ ExtraCmdArgs: []string{}, Skip: false, SetupConfig: func(config *config.AppConfig) { - config.GetAppState().LocalBranchSortOrder = "alphabetic" + config.GetUserConfig().Git.LocalBranchSortOrder = "alphabetical" }, SetupRepo: func(shell *Shell) { shell.EmptyCommit("one") diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 6bc2083c4..3c86ddffc 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -10,7 +10,9 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Rebase onto another branch, deal with the conflicts.", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, diff --git a/pkg/integration/tests/branch/rebase_abort_on_conflict.go b/pkg/integration/tests/branch/rebase_abort_on_conflict.go index 47f59d3d1..79ceba510 100644 --- a/pkg/integration/tests/branch/rebase_abort_on_conflict.go +++ b/pkg/integration/tests/branch/rebase_abort_on_conflict.go @@ -10,7 +10,9 @@ var RebaseAbortOnConflict = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Rebase onto another branch, abort when there are conflicts.", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 896d27068..ff17d6417 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -10,7 +10,9 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Rebase onto another branch, deal with the conflicts. Also mark a commit to be dropped before continuing.", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) // adding a couple additional commits so that we can drop one diff --git a/pkg/integration/tests/branch/rebase_cancel_on_conflict.go b/pkg/integration/tests/branch/rebase_cancel_on_conflict.go index 03923c81d..be69f9753 100644 --- a/pkg/integration/tests/branch/rebase_cancel_on_conflict.go +++ b/pkg/integration/tests/branch/rebase_cancel_on_conflict.go @@ -10,7 +10,9 @@ var RebaseCancelOnConflict = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Rebase onto another branch, cancel when there are conflicts.", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, diff --git a/pkg/integration/tests/branch/rebase_conflicts_fix_build_errors.go b/pkg/integration/tests/branch/rebase_conflicts_fix_build_errors.go index 2ae75dafb..3690f8f2e 100644 --- a/pkg/integration/tests/branch/rebase_conflicts_fix_build_errors.go +++ b/pkg/integration/tests/branch/rebase_conflicts_fix_build_errors.go @@ -10,7 +10,9 @@ var RebaseConflictsFixBuildErrors = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Rebase onto another branch, deal with the conflicts. While continue prompt is showing, fix build errors; get another prompt when continuing.", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, diff --git a/pkg/integration/tests/branch/rebase_from_marked_base.go b/pkg/integration/tests/branch/rebase_from_marked_base.go index c26dce9a3..3dd60184b 100644 --- a/pkg/integration/tests/branch/rebase_from_marked_base.go +++ b/pkg/integration/tests/branch/rebase_from_marked_base.go @@ -9,7 +9,9 @@ var RebaseFromMarkedBase = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Rebase onto another branch from a marked base commit", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shell. NewBranch("base-branch"). diff --git a/pkg/integration/tests/branch/reset_to_upstream.go b/pkg/integration/tests/branch/reset_to_upstream.go index e5503f127..9a5ea498e 100644 --- a/pkg/integration/tests/branch/reset_to_upstream.go +++ b/pkg/integration/tests/branch/reset_to_upstream.go @@ -9,7 +9,9 @@ var ResetToUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Hard reset the current branch to the selected branch upstream", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shell. CloneIntoRemote("origin"). diff --git a/pkg/integration/tests/branch/sort_local_branches.go b/pkg/integration/tests/branch/sort_local_branches.go index ceff654be..9c29e17bf 100644 --- a/pkg/integration/tests/branch/sort_local_branches.go +++ b/pkg/integration/tests/branch/sort_local_branches.go @@ -22,13 +22,13 @@ var SortLocalBranches = NewIntegrationTest(NewIntegrationTestArgs{ Checkout("master") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { - // sorted by recency by default + // sorted by date by default t.Views().Branches(). Focus(). Lines( Contains("master").IsSelected(), - Contains("third"), Contains("second"), + Contains("third"), Contains("first"), ). SelectNextItem() // to test that the selection jumps back to the top when sorting @@ -38,20 +38,20 @@ var SortLocalBranches = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectPopup().Menu().Title(Equals("Sort order")). Lines( - Contains("r (•) Recency").IsSelected(), + Contains("r ( ) Recency").IsSelected(), Contains("a ( ) Alphabetical"), - Contains("d ( ) Date"), + Contains("d (•) Date"), Contains(" Cancel"), ). - Select(Contains("-committerdate")). + Select(Contains("Recency")). Confirm() t.Views().Branches(). IsFocused(). Lines( Contains("master").IsSelected(), - Contains("second"), Contains("third"), + Contains("second"), Contains("first"), ) @@ -60,9 +60,9 @@ var SortLocalBranches = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectPopup().Menu().Title(Equals("Sort order")). Lines( - Contains("r ( ) Recency").IsSelected(), + Contains("r (•) Recency").IsSelected(), Contains("a ( ) Alphabetical"), - Contains("d (•) Date"), + Contains("d ( ) Date"), Contains(" Cancel"), ). Select(Contains("refname")). diff --git a/pkg/integration/tests/branch/sort_remote_branches.go b/pkg/integration/tests/branch/sort_remote_branches.go index 2cbbdb31d..90c787f41 100644 --- a/pkg/integration/tests/branch/sort_remote_branches.go +++ b/pkg/integration/tests/branch/sort_remote_branches.go @@ -27,13 +27,13 @@ var SortRemoteBranches = NewIntegrationTest(NewIntegrationTestArgs{ ). PressEnter() - // sorted alphabetically by default + // sorted by date by default t.Views().RemoteBranches(). IsFocused(). Lines( - Contains("first").IsSelected(), - Contains("second"), + Contains("second").IsSelected(), Contains("third"), + Contains("first"), ). SelectNextItem() // to test that the selection jumps back to the first when sorting @@ -42,19 +42,19 @@ var SortRemoteBranches = NewIntegrationTest(NewIntegrationTestArgs{ t.ExpectPopup().Menu().Title(Equals("Sort order")). Lines( - Contains("a (•) Alphabetical").IsSelected(), - Contains("d ( ) Date"), + Contains("a ( ) Alphabetical").IsSelected(), + Contains("d (•) Date"), Contains(" Cancel"), ). - Select(Contains("-committerdate")). + Select(Contains("Alphabetical")). Confirm() t.Views().RemoteBranches(). IsFocused(). Lines( - Contains("second").IsSelected(), + Contains("first").IsSelected(), + Contains("second"), Contains("third"), - Contains("first"), ) }, }) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick.go b/pkg/integration/tests/cherry_pick/cherry_pick.go index ccdb606f8..a278a5639 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -9,7 +9,9 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Cherry pick commits from the subcommits view, without conflicts", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shell. EmptyCommit("base"). diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index f3d5eca82..b135bfd7f 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -10,7 +10,9 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Cherry pick commits from the subcommits view, with conflicts", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shared.MergeConflictsSetup(shell) }, diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go b/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go index af4e8b9d2..45811fad7 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go @@ -11,6 +11,7 @@ var CherryPickDuringRebase = NewIntegrationTest(NewIntegrationTestArgs{ Skip: false, SetupConfig: func(config *config.AppConfig) { config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_merge.go b/pkg/integration/tests/cherry_pick/cherry_pick_merge.go index 7c68ce8eb..6c883cfa4 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_merge.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_merge.go @@ -9,7 +9,9 @@ var CherryPickMerge = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Cherry pick a merge commit", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shell. EmptyCommit("base"). diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_range.go b/pkg/integration/tests/cherry_pick/cherry_pick_range.go index 329ef1e9c..dfebeae2e 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_range.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_range.go @@ -9,7 +9,9 @@ var CherryPickRange = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Cherry pick range of commits from the subcommits view, without conflicts", ExtraCmdArgs: []string{}, Skip: false, - SetupConfig: func(config *config.AppConfig) {}, + SetupConfig: func(config *config.AppConfig) { + config.GetUserConfig().Git.LocalBranchSortOrder = "recency" + }, SetupRepo: func(shell *Shell) { shell. EmptyCommit("base"). diff --git a/pkg/integration/tests/commit/checkout.go b/pkg/integration/tests/commit/checkout.go index 7815e89de..7f2f4e0d9 100644 --- a/pkg/integration/tests/commit/checkout.go +++ b/pkg/integration/tests/commit/checkout.go @@ -42,8 +42,8 @@ var Checkout = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() t.Views().Branches().Lines( Contains("* (HEAD detached at"), - Contains("branch2"), Contains("branch1"), + Contains("branch2"), Contains("master"), ) @@ -63,8 +63,8 @@ var Checkout = NewIntegrationTest(NewIntegrationTestArgs{ Confirm() t.Views().Branches().Lines( Contains("master"), - Contains("branch2"), Contains("branch1"), + Contains("branch2"), ) }, }) diff --git a/pkg/integration/tests/custom_commands/check_for_conflicts.go b/pkg/integration/tests/custom_commands/check_for_conflicts.go index 25f1d2097..d3376b456 100644 --- a/pkg/integration/tests/custom_commands/check_for_conflicts.go +++ b/pkg/integration/tests/custom_commands/check_for_conflicts.go @@ -24,6 +24,8 @@ var CheckForConflicts = NewIntegrationTest(NewIntegrationTestArgs{ }, }, } + + cfg.GetUserConfig().Git.LocalBranchSortOrder = "recency" }, Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Branches(). diff --git a/pkg/integration/tests/custom_commands/suggestions_command.go b/pkg/integration/tests/custom_commands/suggestions_command.go index 4b6aa0f4e..0710a7698 100644 --- a/pkg/integration/tests/custom_commands/suggestions_command.go +++ b/pkg/integration/tests/custom_commands/suggestions_command.go @@ -43,9 +43,9 @@ var SuggestionsCommand = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Lines( Contains("branch-four").IsSelected(), + Contains("branch-one"), Contains("branch-three"), Contains("branch-two"), - Contains("branch-one"), ). Press("a") @@ -59,8 +59,8 @@ var SuggestionsCommand = NewIntegrationTest(NewIntegrationTestArgs{ Lines( Contains("branch-three"), Contains("branch-four").IsSelected(), - Contains("branch-two"), Contains("branch-one"), + Contains("branch-two"), ) }, }) diff --git a/pkg/integration/tests/custom_commands/suggestions_preset.go b/pkg/integration/tests/custom_commands/suggestions_preset.go index aa599946f..41a16e271 100644 --- a/pkg/integration/tests/custom_commands/suggestions_preset.go +++ b/pkg/integration/tests/custom_commands/suggestions_preset.go @@ -43,9 +43,9 @@ var SuggestionsPreset = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Lines( Contains("branch-four").IsSelected(), + Contains("branch-one"), Contains("branch-three"), Contains("branch-two"), - Contains("branch-one"), ). Press("a") @@ -59,8 +59,8 @@ var SuggestionsPreset = NewIntegrationTest(NewIntegrationTestArgs{ Lines( Contains("branch-three"), Contains("branch-four").IsSelected(), - Contains("branch-two"), Contains("branch-one"), + Contains("branch-two"), ) }, }) diff --git a/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go b/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go index 1907a7159..5def8bfe5 100644 --- a/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go +++ b/pkg/integration/tests/filter_and_search/filter_updates_when_model_changes.go @@ -21,9 +21,9 @@ var FilterUpdatesWhenModelChanges = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Lines( Contains("checked-out-branch").IsSelected(), - Contains("other"), Contains("branch-to-delete"), Contains("master"), + Contains("other"), ). FilterOrSearch("branch"). Lines( @@ -65,9 +65,9 @@ var FilterUpdatesWhenModelChanges = NewIntegrationTest(NewIntegrationTestArgs{ PressEscape(). Lines( Contains("checked-out-branch").IsSelected(), - Contains("other"), Contains("master"), Contains("new-branch"), + Contains("other"), ) }, }) diff --git a/pkg/integration/tests/filter_and_search/nested_filter.go b/pkg/integration/tests/filter_and_search/nested_filter.go index db20dd5b5..b94f8990f 100644 --- a/pkg/integration/tests/filter_and_search/nested_filter.go +++ b/pkg/integration/tests/filter_and_search/nested_filter.go @@ -35,8 +35,8 @@ var NestedFilter = NewIntegrationTest(NewIntegrationTestArgs{ Focus(). Lines( Contains(`branch-bronze`).IsSelected(), - Contains(`branch-silver`), Contains(`branch-gold`), + Contains(`branch-silver`), ). FilterOrSearch("sil"). Lines( @@ -148,8 +148,8 @@ var NestedFilter = NewIntegrationTest(NewIntegrationTestArgs{ }). Lines( Contains(`branch-bronze`), - Contains(`branch-silver`).IsSelected(), Contains(`branch-gold`), + Contains(`branch-silver`).IsSelected(), ) }, }) diff --git a/schema/config.json b/schema/config.json index 9da832b4e..a98076ecb 100644 --- a/schema/config.json +++ b/schema/config.json @@ -416,6 +416,25 @@ "$ref": "#/$defs/LogConfig", "description": "Config for showing the log in the commits view" }, + "localBranchSortOrder": { + "type": "string", + "enum": [ + "date", + "recency", + "alphabetical" + ], + "description": "How branches are sorted in the local branches view.\nOne of: 'date' (default) | 'recency' | 'alphabetical'\nCan be changed from within Lazygit with the Sort Order menu (`s`) in the branches panel.", + "default": "date" + }, + "remoteBranchSortOrder": { + "type": "string", + "enum": [ + "date", + "alphabetical" + ], + "description": "How branches are sorted in the remote branches view.\nOne of: 'date' (default) | 'alphabetical'\nCan be changed from within Lazygit with the Sort Order menu (`s`) in the remote branches panel.", + "default": "date" + }, "truncateCopiedCommitHashesTo": { "type": "integer", "description": "When copying commit hashes to the clipboard, truncate them to this\nlength. Set to 40 to disable truncation.", From 562a2aaa6ba24489cb620d17cd8a88b5001c6f90 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 7 Jul 2025 17:14:55 +0200 Subject: [PATCH 06/11] Un-deprecate UserConfig.Git.Log.Order and ShowGraph And remove them from AppState. --- docs/Config.md | 13 +++++++++++ pkg/commands/git_commands/commit_loader.go | 2 +- .../git_commands/commit_loader_test.go | 4 +--- pkg/config/app_config.go | 22 ------------------- pkg/config/user_config.go | 8 +++---- pkg/gui/context/local_commits_context.go | 2 +- .../controllers/local_commits_controller.go | 10 ++++----- pkg/integration/tests/bisect/basic.go | 2 +- pkg/integration/tests/bisect/choose_terms.go | 2 +- pkg/integration/tests/bisect/skip.go | 2 +- .../tests/branch/rebase_copied_branch.go | 2 +- .../cherry_pick/cherry_pick_during_rebase.go | 2 +- ..._not_show_branch_marker_for_head_commit.go | 2 +- pkg/integration/tests/commit/highlight.go | 2 +- .../tests/filter_by_author/select_author.go | 2 +- .../dont_show_branch_heads_for_todo_items.go | 2 +- ...commit_in_copied_branch_with_update_ref.go | 2 +- .../drop_todo_commit_with_update_ref.go | 2 +- .../edit_last_commit_of_stacked_branch.go | 2 +- .../interactive_rebase_of_copied_branch.go | 2 +- ...e_across_branch_boundary_outside_rebase.go | 2 +- .../quick_start_keep_selection.go | 2 +- .../quick_start_keep_selection_range.go | 2 +- .../reword_last_commit_of_stacked_branch.go | 2 +- .../view_files_of_todo_entries.go | 2 +- ...commit_in_last_commit_of_stacked_branch.go | 2 +- ...how_branch_markers_in_reflog_subcommits.go | 2 +- schema/config.json | 4 ++-- 28 files changed, 46 insertions(+), 59 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index 6be09a383..77a3932ab 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -396,6 +396,19 @@ git: # Config for showing the log in the commits view log: + # One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default' + # 'topo-order' makes it easier to read the git log graph, but commits may not + # appear chronologically. See https://git-scm.com/docs/ + # + # Can be changed from within Lazygit with `Log menu -> Commit sort order` (`` in the commits window by default). + order: topo-order + + # This determines whether the git graph is rendered in the commits panel + # One of 'always' | 'never' | 'when-maximised' + # + # Can be toggled from within lazygit with `Log menu -> Show git graph` (`` in the commits window by default). + showGraph: always + # displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`) showWholeGraph: false diff --git a/pkg/commands/git_commands/commit_loader.go b/pkg/commands/git_commands/commit_loader.go index 4a899379f..7cdac4c33 100644 --- a/pkg/commands/git_commands/commit_loader.go +++ b/pkg/commands/git_commands/commit_loader.go @@ -583,7 +583,7 @@ func (self *CommitLoader) getFirstPushedCommit(refName string) (string, error) { // getLog gets the git log. func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) *oscommands.CmdObj { - gitLogOrder := self.AppState.GitLogOrder + gitLogOrder := self.UserConfig().Git.Log.Order refSpec := opts.RefName if opts.RefToShowDivergenceFrom != "" { diff --git a/pkg/commands/git_commands/commit_loader_test.go b/pkg/commands/git_commands/commit_loader_test.go index fcbc825d9..6f20e7cc6 100644 --- a/pkg/commands/git_commands/commit_loader_test.go +++ b/pkg/commands/git_commands/commit_loader_test.go @@ -9,7 +9,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" - "github.com/jesseduffield/lazygit/pkg/config" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/samber/lo" "github.com/stefanhaller/git-todo-parser/todo" @@ -298,8 +297,7 @@ func TestGetCommits(t *testing.T) { for _, scenario := range scenarios { t.Run(scenario.testName, func(t *testing.T) { common := common.NewDummyCommon() - common.AppState = &config.AppState{} - common.AppState.GitLogOrder = scenario.logOrder + common.UserConfig().Git.Log.Order = scenario.logOrder cmd := oscommands.NewDummyCmdObjBuilder(scenario.runner) builder := &CommitLoader{ diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 184d8e07a..36807a423 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -107,17 +107,6 @@ func NewAppConfig( return nil, err } - // Temporary: the defaults for these are set to empty strings in - // getDefaultAppState so that we can migrate them from userConfig (which is - // now deprecated). Once we remove the user configs, we can remove this code - // and set the proper defaults in getDefaultAppState. - if appState.GitLogOrder == "" { - appState.GitLogOrder = userConfig.Git.Log.Order - } - if appState.GitLogShowGraph == "" { - appState.GitLogShowGraph = userConfig.Git.Log.ShowGraph - } - appConfig := &AppConfig{ name: name, version: version, @@ -677,15 +666,6 @@ type AppState struct { ShellCommandsHistory []string `yaml:"customcommandshistory"` HideCommandLog bool - - // One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default' - // 'topo-order' makes it easier to read the git log graph, but commits may not - // appear chronologically. See https://git-scm.com/docs/ - GitLogOrder string - - // This determines whether the git graph is rendered in the commits panel - // One of 'always' | 'never' | 'when-maximised' - GitLogShowGraph string } func getDefaultAppState() *AppState { @@ -694,8 +674,6 @@ func getDefaultAppState() *AppState { RecentRepos: []string{}, StartupPopupVersion: 0, LastVersion: "", - GitLogOrder: "", // should be "topo-order" eventually - GitLogShowGraph: "", // should be "always" eventually } } diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 5d619231e..5a7838601 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -346,13 +346,13 @@ type LogConfig struct { // 'topo-order' makes it easier to read the git log graph, but commits may not // appear chronologically. See https://git-scm.com/docs/ // - // Deprecated: Configure this with `Log menu -> Commit sort order` ( in the commits window by default). - Order string `yaml:"order" jsonschema:"deprecated,enum=date-order,enum=author-date-order,enum=topo-order,enum=default,deprecated"` + // Can be changed from within Lazygit with `Log menu -> Commit sort order` (`` in the commits window by default). + Order string `yaml:"order" jsonschema:"enum=date-order,enum=author-date-order,enum=topo-order,enum=default"` // This determines whether the git graph is rendered in the commits panel // One of 'always' | 'never' | 'when-maximised' // - // Deprecated: Configure this with `Log menu -> Show git graph` ( in the commits window by default). - ShowGraph string `yaml:"showGraph" jsonschema:"deprecated,enum=always,enum=never,enum=when-maximised"` + // Can be toggled from within lazygit with `Log menu -> Show git graph` (`` in the commits window by default). + ShowGraph string `yaml:"showGraph" jsonschema:"enum=always,enum=never,enum=when-maximised"` // displays the whole git graph by default in the commits view (equivalent to passing the `--all` argument to `git log`) ShowWholeGraph bool `yaml:"showWholeGraph"` } diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index 6a2a20c8d..c43d041d3 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -251,7 +251,7 @@ func shouldShowGraph(c *ContextCommon) bool { return false } - value := c.GetAppState().GitLogShowGraph + value := c.UserConfig().Git.Log.ShowGraph switch value { case "always": diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 0a0a96988..1458756cb 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -1182,11 +1182,10 @@ func (self *LocalCommitsController) handleOpenLogMenu() error { Label: self.c.Tr.ShowGitGraph, OpensMenu: true, OnPress: func() error { - currentValue := self.c.GetAppState().GitLogShowGraph + currentValue := self.c.UserConfig().Git.Log.ShowGraph onPress := func(value string) func() error { return func() error { - self.c.GetAppState().GitLogShowGraph = value - self.c.SaveAppStateAndLogError() + self.c.UserConfig().Git.Log.ShowGraph = value self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits) self.c.PostRefreshUpdate(self.c.Contexts().SubCommits) return nil @@ -1218,11 +1217,10 @@ func (self *LocalCommitsController) handleOpenLogMenu() error { Label: self.c.Tr.SortCommits, OpensMenu: true, OnPress: func() error { - currentValue := self.c.GetAppState().GitLogOrder + currentValue := self.c.UserConfig().Git.Log.Order onPress := func(value string) func() error { return func() error { - self.c.GetAppState().GitLogOrder = value - self.c.SaveAppStateAndLogError() + self.c.UserConfig().Git.Log.Order = value return self.c.WithWaitingStatus(self.c.Tr.LoadingCommits, func(gocui.Task) error { self.c.Refresh( types.RefreshOptions{ diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index c0188a7dc..dbce50969 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -15,7 +15,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ CreateNCommits(10) }, SetupConfig: func(cfg *config.AppConfig) { - cfg.GetAppState().GitLogShowGraph = "never" + cfg.GetUserConfig().Git.Log.ShowGraph = "never" }, Run: func(t *TestDriver, keys config.KeybindingConfig) { markCommitAsBad := func() { diff --git a/pkg/integration/tests/bisect/choose_terms.go b/pkg/integration/tests/bisect/choose_terms.go index 7b9c4740e..51c9246ba 100644 --- a/pkg/integration/tests/bisect/choose_terms.go +++ b/pkg/integration/tests/bisect/choose_terms.go @@ -15,7 +15,7 @@ var ChooseTerms = NewIntegrationTest(NewIntegrationTestArgs{ CreateNCommits(10) }, SetupConfig: func(cfg *config.AppConfig) { - cfg.GetAppState().GitLogShowGraph = "never" + cfg.GetUserConfig().Git.Log.ShowGraph = "never" }, Run: func(t *TestDriver, keys config.KeybindingConfig) { markCommitAsFixed := func() { diff --git a/pkg/integration/tests/bisect/skip.go b/pkg/integration/tests/bisect/skip.go index a8a9616d5..c879cc408 100644 --- a/pkg/integration/tests/bisect/skip.go +++ b/pkg/integration/tests/bisect/skip.go @@ -14,7 +14,7 @@ var Skip = NewIntegrationTest(NewIntegrationTestArgs{ CreateNCommits(10) }, SetupConfig: func(cfg *config.AppConfig) { - cfg.GetAppState().GitLogShowGraph = "never" + cfg.GetUserConfig().Git.Log.ShowGraph = "never" }, Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Commits(). diff --git a/pkg/integration/tests/branch/rebase_copied_branch.go b/pkg/integration/tests/branch/rebase_copied_branch.go index 330feb6c4..0247e65d8 100644 --- a/pkg/integration/tests/branch/rebase_copied_branch.go +++ b/pkg/integration/tests/branch/rebase_copied_branch.go @@ -11,7 +11,7 @@ var RebaseCopiedBranch = NewIntegrationTest(NewIntegrationTestArgs{ Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go b/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go index 45811fad7..a14dbe7c9 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_during_rebase.go @@ -10,7 +10,7 @@ var CherryPickDuringRebase = NewIntegrationTest(NewIntegrationTestArgs{ ExtraCmdArgs: []string{}, Skip: false, SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" config.GetUserConfig().Git.LocalBranchSortOrder = "recency" }, SetupRepo: func(shell *Shell) { diff --git a/pkg/integration/tests/commit/do_not_show_branch_marker_for_head_commit.go b/pkg/integration/tests/commit/do_not_show_branch_marker_for_head_commit.go index 54b988ef4..51f56cef4 100644 --- a/pkg/integration/tests/commit/do_not_show_branch_marker_for_head_commit.go +++ b/pkg/integration/tests/commit/do_not_show_branch_marker_for_head_commit.go @@ -11,7 +11,7 @@ var DoNotShowBranchMarkerForHeadCommit = NewIntegrationTest(NewIntegrationTestAr Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell.EmptyCommit("one") diff --git a/pkg/integration/tests/commit/highlight.go b/pkg/integration/tests/commit/highlight.go index 077a42b9d..eaa77ccf1 100644 --- a/pkg/integration/tests/commit/highlight.go +++ b/pkg/integration/tests/commit/highlight.go @@ -10,7 +10,7 @@ var Highlight = NewIntegrationTest(NewIntegrationTestArgs{ ExtraCmdArgs: []string{}, Skip: false, SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "always" + config.GetUserConfig().Git.Log.ShowGraph = "always" config.GetUserConfig().Gui.AuthorColors = map[string]string{ "CI": "red", } diff --git a/pkg/integration/tests/filter_by_author/select_author.go b/pkg/integration/tests/filter_by_author/select_author.go index b9603aa87..281034c12 100644 --- a/pkg/integration/tests/filter_by_author/select_author.go +++ b/pkg/integration/tests/filter_by_author/select_author.go @@ -10,7 +10,7 @@ var SelectAuthor = NewIntegrationTest(NewIntegrationTestArgs{ ExtraCmdArgs: []string{}, Skip: false, SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { commonSetup(shell) diff --git a/pkg/integration/tests/interactive_rebase/dont_show_branch_heads_for_todo_items.go b/pkg/integration/tests/interactive_rebase/dont_show_branch_heads_for_todo_items.go index b0192c59f..e5b43ee81 100644 --- a/pkg/integration/tests/interactive_rebase/dont_show_branch_heads_for_todo_items.go +++ b/pkg/integration/tests/interactive_rebase/dont_show_branch_heads_for_todo_items.go @@ -11,7 +11,7 @@ var DontShowBranchHeadsForTodoItems = NewIntegrationTest(NewIntegrationTestArgs{ Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/drop_commit_in_copied_branch_with_update_ref.go b/pkg/integration/tests/interactive_rebase/drop_commit_in_copied_branch_with_update_ref.go index 4ad1b0bec..81462296b 100644 --- a/pkg/integration/tests/interactive_rebase/drop_commit_in_copied_branch_with_update_ref.go +++ b/pkg/integration/tests/interactive_rebase/drop_commit_in_copied_branch_with_update_ref.go @@ -11,7 +11,7 @@ var DropCommitInCopiedBranchWithUpdateRef = NewIntegrationTest(NewIntegrationTes Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/drop_todo_commit_with_update_ref.go b/pkg/integration/tests/interactive_rebase/drop_todo_commit_with_update_ref.go index 3dd44baaf..ca481e986 100644 --- a/pkg/integration/tests/interactive_rebase/drop_todo_commit_with_update_ref.go +++ b/pkg/integration/tests/interactive_rebase/drop_todo_commit_with_update_ref.go @@ -12,7 +12,7 @@ var DropTodoCommitWithUpdateRef = NewIntegrationTest(NewIntegrationTestArgs{ GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { config.GetUserConfig().Git.MainBranches = []string{"master"} - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/edit_last_commit_of_stacked_branch.go b/pkg/integration/tests/interactive_rebase/edit_last_commit_of_stacked_branch.go index 71c66799a..528afb7a4 100644 --- a/pkg/integration/tests/interactive_rebase/edit_last_commit_of_stacked_branch.go +++ b/pkg/integration/tests/interactive_rebase/edit_last_commit_of_stacked_branch.go @@ -12,7 +12,7 @@ var EditLastCommitOfStackedBranch = NewIntegrationTest(NewIntegrationTestArgs{ GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { config.GetUserConfig().Git.MainBranches = []string{"master"} - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/interactive_rebase_of_copied_branch.go b/pkg/integration/tests/interactive_rebase/interactive_rebase_of_copied_branch.go index 8f98e999b..73ace9105 100644 --- a/pkg/integration/tests/interactive_rebase/interactive_rebase_of_copied_branch.go +++ b/pkg/integration/tests/interactive_rebase/interactive_rebase_of_copied_branch.go @@ -11,7 +11,7 @@ var InteractiveRebaseOfCopiedBranch = NewIntegrationTest(NewIntegrationTestArgs{ Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/move_across_branch_boundary_outside_rebase.go b/pkg/integration/tests/interactive_rebase/move_across_branch_boundary_outside_rebase.go index d925acffe..0f341d5b5 100644 --- a/pkg/integration/tests/interactive_rebase/move_across_branch_boundary_outside_rebase.go +++ b/pkg/integration/tests/interactive_rebase/move_across_branch_boundary_outside_rebase.go @@ -12,7 +12,7 @@ var MoveAcrossBranchBoundaryOutsideRebase = NewIntegrationTest(NewIntegrationTes GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { config.GetUserConfig().Git.MainBranches = []string{"master"} - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/quick_start_keep_selection.go b/pkg/integration/tests/interactive_rebase/quick_start_keep_selection.go index d57be84b5..55be5ea4a 100644 --- a/pkg/integration/tests/interactive_rebase/quick_start_keep_selection.go +++ b/pkg/integration/tests/interactive_rebase/quick_start_keep_selection.go @@ -12,7 +12,7 @@ var QuickStartKeepSelection = NewIntegrationTest(NewIntegrationTestArgs{ GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { config.GetUserConfig().Git.MainBranches = []string{"master"} - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/quick_start_keep_selection_range.go b/pkg/integration/tests/interactive_rebase/quick_start_keep_selection_range.go index 6b2fe4717..8ff8f1065 100644 --- a/pkg/integration/tests/interactive_rebase/quick_start_keep_selection_range.go +++ b/pkg/integration/tests/interactive_rebase/quick_start_keep_selection_range.go @@ -12,7 +12,7 @@ var QuickStartKeepSelectionRange = NewIntegrationTest(NewIntegrationTestArgs{ GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { config.GetUserConfig().Git.MainBranches = []string{"master"} - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/reword_last_commit_of_stacked_branch.go b/pkg/integration/tests/interactive_rebase/reword_last_commit_of_stacked_branch.go index 58505d359..e9cdc3a1a 100644 --- a/pkg/integration/tests/interactive_rebase/reword_last_commit_of_stacked_branch.go +++ b/pkg/integration/tests/interactive_rebase/reword_last_commit_of_stacked_branch.go @@ -12,7 +12,7 @@ var RewordLastCommitOfStackedBranch = NewIntegrationTest(NewIntegrationTestArgs{ GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { config.GetUserConfig().Git.MainBranches = []string{"master"} - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/interactive_rebase/view_files_of_todo_entries.go b/pkg/integration/tests/interactive_rebase/view_files_of_todo_entries.go index 29d79513e..f52e80703 100644 --- a/pkg/integration/tests/interactive_rebase/view_files_of_todo_entries.go +++ b/pkg/integration/tests/interactive_rebase/view_files_of_todo_entries.go @@ -11,7 +11,7 @@ var ViewFilesOfTodoEntries = NewIntegrationTest(NewIntegrationTestArgs{ Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/patch_building/move_to_new_commit_in_last_commit_of_stacked_branch.go b/pkg/integration/tests/patch_building/move_to_new_commit_in_last_commit_of_stacked_branch.go index ed98657d5..c9fd80d0e 100644 --- a/pkg/integration/tests/patch_building/move_to_new_commit_in_last_commit_of_stacked_branch.go +++ b/pkg/integration/tests/patch_building/move_to_new_commit_in_last_commit_of_stacked_branch.go @@ -11,7 +11,7 @@ var MoveToNewCommitInLastCommitOfStackedBranch = NewIntegrationTest(NewIntegrati Skip: false, GitVersion: AtLeast("2.38.0"), SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell. diff --git a/pkg/integration/tests/reflog/do_not_show_branch_markers_in_reflog_subcommits.go b/pkg/integration/tests/reflog/do_not_show_branch_markers_in_reflog_subcommits.go index 1cac5a7a1..b8a0ea4df 100644 --- a/pkg/integration/tests/reflog/do_not_show_branch_markers_in_reflog_subcommits.go +++ b/pkg/integration/tests/reflog/do_not_show_branch_markers_in_reflog_subcommits.go @@ -10,7 +10,7 @@ var DoNotShowBranchMarkersInReflogSubcommits = NewIntegrationTest(NewIntegration ExtraCmdArgs: []string{}, Skip: false, SetupConfig: func(config *config.AppConfig) { - config.GetAppState().GitLogShowGraph = "never" + config.GetUserConfig().Git.Log.ShowGraph = "never" }, SetupRepo: func(shell *Shell) { shell.NewBranch("branch1") diff --git a/schema/config.json b/schema/config.json index a98076ecb..c070e4ce0 100644 --- a/schema/config.json +++ b/schema/config.json @@ -1532,7 +1532,7 @@ "topo-order", "default" ], - "description": "One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default'\n'topo-order' makes it easier to read the git log graph, but commits may not\nappear chronologically. See https://git-scm.com/docs/\n\nDeprecated: Configure this with `Log menu -\u003e Commit sort order` (\u003cc-l\u003e in the commits window by default).", + "description": "One of: 'date-order' | 'author-date-order' | 'topo-order' | 'default'\n'topo-order' makes it easier to read the git log graph, but commits may not\nappear chronologically. See https://git-scm.com/docs/\n\nCan be changed from within Lazygit with `Log menu -\u003e Commit sort order` (`\u003cc-l\u003e` in the commits window by default).", "default": "topo-order" }, "showGraph": { @@ -1542,7 +1542,7 @@ "never", "when-maximised" ], - "description": "This determines whether the git graph is rendered in the commits panel\nOne of 'always' | 'never' | 'when-maximised'\n\nDeprecated: Configure this with `Log menu -\u003e Show git graph` (\u003cc-l\u003e in the commits window by default).", + "description": "This determines whether the git graph is rendered in the commits panel\nOne of 'always' | 'never' | 'when-maximised'\n\nCan be toggled from within lazygit with `Log menu -\u003e Show git graph` (`\u003cc-l\u003e` in the commits window by default).", "default": "always" }, "showWholeGraph": { From 3575bb98594c4bb1fa5050fc3b8ae10e82b12fa2 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 8 Jul 2025 12:22:16 +0200 Subject: [PATCH 07/11] Add enum validation for Git.Log.Order and Git.Log.ShowGraph --- pkg/config/user_config_validation.go | 8 +++++++ pkg/config/user_config_validation_test.go | 29 +++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/pkg/config/user_config_validation.go b/pkg/config/user_config_validation.go index 5d43c4a28..fc504fe32 100644 --- a/pkg/config/user_config_validation.go +++ b/pkg/config/user_config_validation.go @@ -31,6 +31,14 @@ func (config *UserConfig) Validate() error { []string{"date", "alphabetical"}); err != nil { return err } + if err := validateEnum("git.log.order", config.Git.Log.Order, + []string{"date-order", "author-date-order", "topo-order", "default"}); err != nil { + return err + } + if err := validateEnum("git.log.showGraph", config.Git.Log.ShowGraph, + []string{"always", "never", "when-maximised"}); err != nil { + return err + } if err := validateKeybindings(config.Keybinding); err != nil { return err } diff --git a/pkg/config/user_config_validation_test.go b/pkg/config/user_config_validation_test.go index 67ff16991..fcbfe1139 100644 --- a/pkg/config/user_config_validation_test.go +++ b/pkg/config/user_config_validation_test.go @@ -82,6 +82,35 @@ func TestUserConfigValidate_enums(t *testing.T) { {value: "invalid_value", valid: false}, }, }, + { + name: "Git.Log.Order", + setup: func(config *UserConfig, value string) { + config.Git.Log.Order = value + }, + testCases: []testCase{ + {value: "date-order", valid: true}, + {value: "author-date-order", valid: true}, + {value: "topo-order", valid: true}, + {value: "default", valid: true}, + + {value: "", valid: false}, + {value: "invalid_value", valid: false}, + }, + }, + { + name: "Git.Log.ShowGraph", + setup: func(config *UserConfig, value string) { + config.Git.Log.ShowGraph = value + }, + testCases: []testCase{ + {value: "always", valid: true}, + {value: "never", valid: true}, + {value: "when-maximised", valid: true}, + + {value: "", valid: false}, + {value: "invalid_value", valid: false}, + }, + }, { name: "Keybindings", setup: func(config *UserConfig, value string) { From 0d4f0e827d953dcffe85ca9da28088501ae83057 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 8 Jul 2025 13:19:02 +0200 Subject: [PATCH 08/11] Add breaking changes entry for the changed sort order for branches --- pkg/i18n/english.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index cc3eb4fe6..962015ceb 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -2102,6 +2102,11 @@ git: If, on the other hand, you want this even for feature branches, you can set it to 'allBranches' instead.`, "0.51.0": `- The 'subprocess', 'stream', and 'showOutput' fields of custom commands have been replaced by a single 'output' field. This should be transparent, if you used these in your config file it should have been automatically updated for you. There's one notable change though: the 'stream' field used to mean both that the command's output would be streamed to the command log, and that the command would be run in a pseudo terminal (pty). We converted this to 'output: log', which means that the command's output will be streamed to the command log, but not use a pty, on the assumption that this is what most people wanted. If you do actually want to run a command in a pty, you can change this to 'output: logWithPty' instead.`, + "0.54.0": `- The default sort order for local and remote branches has changed: it used to be 'recency' (based on reflog) for local branches, and 'alphabetical' for remote branches. Both of these have been changed to 'date' (which means committerdate). If you do liked the old defaults better, you can revert to them with the following config: + +git: + localBranchSortOrder: recency + remoteBranchSortOrder: alphabetical`, }, } } From 9650753db6ec0ef8d18611eead5165947b870420 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 8 Jul 2025 15:00:03 +0200 Subject: [PATCH 09/11] Add configuration hints to existing tooltips --- docs/keybindings/Keybindings_en.md | 14 +++++++------- docs/keybindings/Keybindings_ko.md | 14 +++++++------- docs/keybindings/Keybindings_nl.md | 14 +++++++------- docs/keybindings/Keybindings_pl.md | 4 ++-- docs/keybindings/Keybindings_pt.md | 10 +++++----- docs/keybindings/Keybindings_ru.md | 14 +++++++------- docs/keybindings/Keybindings_zh-TW.md | 14 +++++++------- pkg/i18n/english.go | 12 ++++++------ 8 files changed, 48 insertions(+), 48 deletions(-) diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md index 71aa6f9a7..24c0b65f6 100644 --- a/docs/keybindings/Keybindings_en.md +++ b/docs/keybindings/Keybindings_en.md @@ -14,10 +14,10 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. | | `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. | | `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. | -| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | +| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | | `` : `` | Execute shell command | Bring up a prompt where you can enter a shell command to execute. | | `` `` | View custom patch options | | | `` m `` | View merge/rebase options | View options to abort/continue/skip the current merge/rebase. | @@ -30,7 +30,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` q `` | Quit | | | `` `` | Cancel | | -| `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view. | +| `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Undo | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | | `` `` | Redo | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | @@ -65,7 +65,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | Toggle file included in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` `` | Enter file / Toggle directory collapsed | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. | -| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` - `` | Collapse all files | Collapse all directories in the files tree | | `` = `` | Expand all files | Expand all directories in the file tree | | `` 0 `` | Focus main view | | @@ -149,7 +149,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` d `` | Discard | View options for discarding changes to the selected file. | | `` g `` | View upstream reset options | | | `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). | -| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | Toggle file tree view | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` `` | Open external diff tool (git difftool) | | | `` M `` | Open external merge tool | Run `git mergetool`. | | `` f `` | Fetch | Fetch changes from remote. | diff --git a/docs/keybindings/Keybindings_ko.md b/docs/keybindings/Keybindings_ko.md index 57d156c08..655ea308b 100644 --- a/docs/keybindings/Keybindings_ko.md +++ b/docs/keybindings/Keybindings_ko.md @@ -14,10 +14,10 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` @ `` | 명령어 로그 메뉴 열기 | View options for the command log e.g. show/hide the command log and focus the command log. | | `` P `` | 푸시 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. | | `` p `` | 업데이트 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` } `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트의 크기를 늘리기 | Increase the amount of the context shown around changes in the diff view. | -| `` { `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트 크기 줄이기 | Decrease the amount of the context shown around changes in the diff view. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` } `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트의 크기를 늘리기 | Increase the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | +| `` { `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트 크기 줄이기 | Decrease the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | | `` : `` | Execute shell command | Bring up a prompt where you can enter a shell command to execute. | | `` `` | 커스텀 Patch 옵션 보기 | | | `` m `` | View merge/rebase options | View options to abort/continue/skip the current merge/rebase. | @@ -30,7 +30,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` q `` | 종료 | | | `` `` | 취소 | | -| `` `` | 공백문자를 Diff 뷰에서 표시 여부 전환 | Toggle whether or not whitespace changes are shown in the diff view. | +| `` `` | 공백문자를 Diff 뷰에서 표시 여부 전환 | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | 되돌리기 (reflog) (실험적) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | | `` `` | 다시 실행 (reflog) (실험적) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | @@ -331,7 +331,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | Toggle file included in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` a `` | Toggle all files included in patch | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` `` | Enter file to add selected lines to the patch (or toggle directory collapsed) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. | -| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` - `` | Collapse all files | Collapse all directories in the files tree | | `` = `` | Expand all files | Expand all directories in the file tree | | `` 0 `` | Focus main view | | @@ -384,7 +384,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` d `` | View 'discard changes' options | View options for discarding changes to the selected file. | | `` g `` | View upstream reset options | | | `` D `` | 초기화 | View reset options for working tree (e.g. nuking the working tree). | -| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | 파일 트리뷰로 전환 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` `` | Open external diff tool (git difftool) | | | `` M `` | Git mergetool를 열기 | Run `git mergetool`. | | `` f `` | Fetch | Fetch changes from remote. | diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md index 1213301e3..474582d37 100644 --- a/docs/keybindings/Keybindings_nl.md +++ b/docs/keybindings/Keybindings_nl.md @@ -14,10 +14,10 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. | | `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. | | `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. | -| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | +| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | | `` : `` | Execute shell command | Bring up a prompt where you can enter a shell command to execute. | | `` `` | Bekijk aangepaste patch opties | | | `` m `` | Bekijk merge/rebase opties | View options to abort/continue/skip the current merge/rebase. | @@ -30,7 +30,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` q `` | Quit | | | `` `` | Annuleren | | -| `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view. | +| `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Ongedaan maken (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | | `` `` | Redo (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | @@ -75,7 +75,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` d `` | Bekijk 'veranderingen ongedaan maken' opties | View options for discarding changes to the selected file. | | `` g `` | Bekijk upstream reset opties | | | `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). | -| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` `` | Open external diff tool (git difftool) | | | `` M `` | Open external merge tool | Run `git mergetool`. | | `` f `` | Fetch | Fetch changes from remote. | @@ -141,7 +141,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | Toggle bestand inbegrepen in patch | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` a `` | Toggle all files | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` `` | Enter bestand om geselecteerde regels toe te voegen aan de patch | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. | -| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | Toggle bestandsboom weergave | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` - `` | Collapse all files | Collapse all directories in the files tree | | `` = `` | Expand all files | Expand all directories in the file tree | | `` 0 `` | Focus main view | | diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md index 3fbcc39e9..53350645b 100644 --- a/docs/keybindings/Keybindings_pl.md +++ b/docs/keybindings/Keybindings_pl.md @@ -14,8 +14,8 @@ _Legenda: `` oznacza ctrl+b, `` oznacza alt+b, `B` oznacza shift+b_ | `` @ `` | Pokaż opcje dziennika poleceń | Pokaż opcje dla dziennika poleceń, np. pokazywanie/ukrywanie dziennika poleceń i skupienie na dzienniku poleceń. | | `` P `` | Wypchnij | Wypchnij bieżącą gałąź do jej gałęzi nadrzędnej. Jeśli nie skonfigurowano gałęzi nadrzędnej, zostaniesz poproszony o skonfigurowanie gałęzi nadrzędnej. | | `` p `` | Pociągnij | Pociągnij zmiany z zdalnego dla bieżącej gałęzi. Jeśli nie skonfigurowano gałęzi nadrzędnej, zostaniesz poproszony o skonfigurowanie gałęzi nadrzędnej. | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | | `` } `` | Zwiększ rozmiar kontekstu w widoku różnic | Zwiększ ilość kontekstu pokazywanego wokół zmian w widoku różnic. | | `` { `` | Zmniejsz rozmiar kontekstu w widoku różnic | Zmniejsz ilość kontekstu pokazywanego wokół zmian w widoku różnic. | | `` : `` | Execute shell command | Bring up a prompt where you can enter a shell command to execute. | diff --git a/docs/keybindings/Keybindings_pt.md b/docs/keybindings/Keybindings_pt.md index ec435e26a..b5527c602 100644 --- a/docs/keybindings/Keybindings_pt.md +++ b/docs/keybindings/Keybindings_pt.md @@ -14,10 +14,10 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. | | `` P `` | Empurre (Push) | Faça push do branch atual para o seu branch upstream. Se nenhum upstream estiver configurado, você será solicitado a configurar um branch a montante. | | `` p `` | Puxar (Pull) | Puxe alterações do controle remoto para o ramo atual. Se nenhum upstream estiver configurado, será solicitado configurar um ramo a montante. | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. | -| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | +| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | | `` : `` | Executar comando da shell | Traga um prompt onde você pode digitar um comando shell para executar. | | `` `` | Ver opções de patch personalizadas | | | `` m `` | Ver opções de mesclar/rebase | Ver opções para abortar/continuar/pular o merge/rebase atual. | @@ -30,7 +30,7 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_ | `` `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` q `` | Sair | | | `` `` | Cancelar | | -| `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view. | +| `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Desfazer | O reflog será usado para determinar qual comando git para executar para desfazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. | | `` `` | Refazer | O reflog será usado para determinar qual comando git para executar para refazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. | diff --git a/docs/keybindings/Keybindings_ru.md b/docs/keybindings/Keybindings_ru.md index 53d15e13a..7eafc1f5e 100644 --- a/docs/keybindings/Keybindings_ru.md +++ b/docs/keybindings/Keybindings_ru.md @@ -14,10 +14,10 @@ _Связки клавиш_ | `` @ `` | Открыть меню журнала команд | View options for the command log e.g. show/hide the command log and focus the command log. | | `` P `` | Отправить изменения | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. | | `` p `` | Получить и слить изменения | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` } `` | Увеличить размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Increase the amount of the context shown around changes in the diff view. | -| `` { `` | Уменьшите размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Decrease the amount of the context shown around changes in the diff view. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` } `` | Увеличить размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Increase the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | +| `` { `` | Уменьшите размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Decrease the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | | `` : `` | Execute shell command | Bring up a prompt where you can enter a shell command to execute. | | `` `` | Просмотреть пользовательские параметры патча | | | `` m `` | Просмотреть параметры слияния/перебазирования | View options to abort/continue/skip the current merge/rebase. | @@ -30,7 +30,7 @@ _Связки клавиш_ | `` `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` q `` | Выйти | | | `` `` | Отменить | | -| `` `` | Переключить отображение изменении пробелов в просмотрщике сравнении | Toggle whether or not whitespace changes are shown in the diff view. | +| `` `` | Переключить отображение изменении пробелов в просмотрщике сравнении | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Отменить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git запустить, чтобы отменить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. | | `` `` | Повторить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git нужно запустить, чтобы повторить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. | @@ -291,7 +291,7 @@ _Связки клавиш_ | `` `` | Переключить файлы включённые в патч | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` a `` | Переключить все файлы, включённые в патч | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` `` | Введите файл, чтобы добавить выбранные строки в патч (или свернуть каталог переключения) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. | -| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` - `` | Collapse all files | Collapse all directories in the files tree | | `` = `` | Expand all files | Expand all directories in the file tree | | `` 0 `` | Focus main view | | @@ -377,7 +377,7 @@ _Связки клавиш_ | `` d `` | Просмотреть параметры «отмены изменении» | View options for discarding changes to the selected file. | | `` g `` | Просмотреть параметры сброса upstream-ветки | | | `` D `` | Reset | View reset options for working tree (e.g. nuking the working tree). | -| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | Переключить вид дерева файлов | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` `` | Open external diff tool (git difftool) | | | `` M `` | Открыть внешний инструмент слияния (git mergetool) | Run `git mergetool`. | | `` f `` | Получить изменения | Fetch changes from remote. | diff --git a/docs/keybindings/Keybindings_zh-TW.md b/docs/keybindings/Keybindings_zh-TW.md index 1fbe2c966..6c4601cba 100644 --- a/docs/keybindings/Keybindings_zh-TW.md +++ b/docs/keybindings/Keybindings_zh-TW.md @@ -14,10 +14,10 @@ _說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B | `` @ `` | 開啟命令記錄選單 | View options for the command log e.g. show/hide the command log and focus the command log. | | `` P `` | 推送 | 推送到遠端。如果沒有設定遠端,會開啟設定視窗。 | | `` p `` | 拉取 | 從遠端同步當前分支。如果沒有設定遠端,會開啟設定視窗。 | -| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. | -| `` } `` | 增加差異檢視中顯示變更周圍上下文的大小 | Increase the amount of the context shown around changes in the diff view. | -| `` { `` | 減小差異檢視中顯示變更周圍上下文的大小 | Decrease the amount of the context shown around changes in the diff view. | +| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.

The default can be changed in the config file with the key 'git.renameSimilarityThreshold'. | +| `` } `` | 增加差異檢視中顯示變更周圍上下文的大小 | Increase the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | +| `` { `` | 減小差異檢視中顯示變更周圍上下文的大小 | Decrease the amount of the context shown around changes in the diff view.

The default can be changed in the config file with the key 'git.diffContextSize'. | | `` : `` | Execute shell command | Bring up a prompt where you can enter a shell command to execute. | | `` `` | 檢視自訂補丁選項 | | | `` m `` | 查看合併/變基選項 | View options to abort/continue/skip the current merge/rebase. | @@ -30,7 +30,7 @@ _說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B | `` `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` q `` | 結束 | | | `` `` | 取消 | | -| `` `` | 切換是否在差異檢視中顯示空格變更 | Toggle whether or not whitespace changes are shown in the diff view. | +| `` `` | 切換是否在差異檢視中顯示空格變更 | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | 復原 | 將使用 reflog 確任 git 指令以復原。這不包括工作區更改;只考慮提交。 | | `` `` | 取消復原 | 將使用 reflog 確任 git 指令以重作。這不包括工作區更改;只考慮提交。 | @@ -227,7 +227,7 @@ _說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B | `` `` | 切換檔案是否包含在補丁中 | Toggle whether the file is included in the custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` a `` | 切換所有檔案是否包含在補丁中 | Add/remove all commit's files to custom patch. See https://github.com/jesseduffield/lazygit#rebase-magic-custom-patches. | | `` `` | 輸入檔案以將選定的行添加至補丁(或切換目錄折疊) | If a file is selected, enter the file so that you can add/remove individual lines to the custom patch. If a directory is selected, toggle the directory. | -| `` ` `` | 顯示檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | 顯示檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` - `` | Collapse all files | Collapse all directories in the files tree | | `` = `` | Expand all files | Expand all directories in the file tree | | `` 0 `` | Focus main view | | @@ -336,7 +336,7 @@ _說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B | `` d `` | 捨棄 | 檢視選中變動進行捨棄復原 | | `` g `` | 檢視遠端重設選項 | | | `` D `` | 重設 | View reset options for working tree (e.g. nuking the working tree). | -| `` ` `` | 顯示檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory. | +| `` ` `` | 顯示檔案樹狀視圖 | Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.

The default can be changed in the config file with the key 'gui.showFileTree'. | | `` `` | 開啟外部差異工具 (git difftool) | | | `` M `` | 開啟外部合併工具 | 執行 `git mergetool`。 | | `` f `` | 擷取 | 同步遠端異動 | diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 962015ceb..369a7c98d 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -1098,7 +1098,7 @@ func EnglishTranslationSet() *TranslationSet { ToggleStagedAll: "Stage all", ToggleStagedAllTooltip: "Toggle staged/unstaged for all files in working tree.", ToggleTreeView: "Toggle file tree view", - ToggleTreeViewTooltip: "Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.", + ToggleTreeViewTooltip: "Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.\n\nThe default can be changed in the config file with the key 'gui.showFileTree'.", OpenDiffTool: "Open external diff tool (git difftool)", OpenMergeTool: "Open external merge tool", OpenMergeToolTooltip: "Run `git mergetool`.", @@ -1771,17 +1771,17 @@ func EnglishTranslationSet() *TranslationSet { CommandLogHeader: "You can hide/focus this panel by pressing '%s'\n", RandomTip: "Random tip", ToggleWhitespaceInDiffView: "Toggle whitespace", - ToggleWhitespaceInDiffViewTooltip: "Toggle whether or not whitespace changes are shown in the diff view.", + ToggleWhitespaceInDiffViewTooltip: "Toggle whether or not whitespace changes are shown in the diff view.\n\nThe default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'.", IgnoreWhitespaceDiffViewSubTitle: "(ignoring whitespace)", IgnoreWhitespaceNotSupportedHere: "Ignoring whitespace is not supported in this view", IncreaseContextInDiffView: "Increase diff context size", - IncreaseContextInDiffViewTooltip: "Increase the amount of the context shown around changes in the diff view.", + IncreaseContextInDiffViewTooltip: "Increase the amount of the context shown around changes in the diff view.\n\nThe default can be changed in the config file with the key 'git.diffContextSize'.", DecreaseContextInDiffView: "Decrease diff context size", - DecreaseContextInDiffViewTooltip: "Decrease the amount of the context shown around changes in the diff view.", + DecreaseContextInDiffViewTooltip: "Decrease the amount of the context shown around changes in the diff view.\n\nThe default can be changed in the config file with the key 'git.diffContextSize'.", DiffContextSizeChanged: "Changed diff context size to %d", - IncreaseRenameSimilarityThresholdTooltip: "Increase the similarity threshold for a deletion and addition pair to be treated as a rename.", + IncreaseRenameSimilarityThresholdTooltip: "Increase the similarity threshold for a deletion and addition pair to be treated as a rename.\n\nThe default can be changed in the config file with the key 'git.renameSimilarityThreshold'.", IncreaseRenameSimilarityThreshold: "Increase rename similarity threshold", - DecreaseRenameSimilarityThresholdTooltip: "Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.", + DecreaseRenameSimilarityThresholdTooltip: "Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.\n\nThe default can be changed in the config file with the key 'git.renameSimilarityThreshold'.", DecreaseRenameSimilarityThreshold: "Decrease rename similarity threshold", RenameSimilarityThresholdChanged: "Changed rename similarity threshold to %d%%", CreatePullRequestOptions: "View create pull request options", From 6bfcb3d6f0363ed4b0592356bf3b9669330380dd Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 8 Jul 2025 17:20:50 +0200 Subject: [PATCH 10/11] Add tooltips for commit log menu --- pkg/gui/controllers/local_commits_controller.go | 2 ++ pkg/i18n/english.go | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 1458756cb..c4c9fba44 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -1180,6 +1180,7 @@ func (self *LocalCommitsController) handleOpenLogMenu() error { }, { Label: self.c.Tr.ShowGitGraph, + Tooltip: self.c.Tr.ShowGitGraphTooltip, OpensMenu: true, OnPress: func() error { currentValue := self.c.UserConfig().Git.Log.ShowGraph @@ -1215,6 +1216,7 @@ func (self *LocalCommitsController) handleOpenLogMenu() error { }, { Label: self.c.Tr.SortCommits, + Tooltip: self.c.Tr.SortCommitsTooltip, OpensMenu: true, OnPress: func() error { currentValue := self.c.UserConfig().Git.Log.Order diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 369a7c98d..44ed670aa 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -758,12 +758,14 @@ type TranslationSet struct { LogMenuTitle string ToggleShowGitGraphAll string ShowGitGraph string + ShowGitGraphTooltip string SortOrder string SortAlphabetical string SortByDate string SortByRecency string SortBasedOnReflog string SortCommits string + SortCommitsTooltip string CantChangeContextSizeError string OpenCommitInBrowser string ViewBisectOptions string @@ -1803,12 +1805,14 @@ func EnglishTranslationSet() *TranslationSet { LogMenuTitle: "Commit Log Options", ToggleShowGitGraphAll: "Toggle show whole git graph (pass the `--all` flag to `git log`)", ShowGitGraph: "Show git graph", + ShowGitGraphTooltip: "Show or hide the git graph in the commit log.\n\nThe default can be changed in the config file with the key 'git.log.showGraph'.", SortOrder: "Sort order", SortAlphabetical: "Alphabetical", SortByDate: "Date", SortByRecency: "Recency", SortBasedOnReflog: "(based on reflog)", SortCommits: "Commit sort order", + SortCommitsTooltip: "Change the sort order of the commits in the commit log.\n\nThe default can be changed in the config file with the key 'git.log.sortOrder'.", CantChangeContextSizeError: "Cannot change context while in patch building mode because we were too lazy to support it when releasing the feature. If you really want it, please let us know!", OpenCommitInBrowser: "Open commit in browser", ViewBisectOptions: "View bisect options", From df486672533d274c4f0b864d5aee6a17b68f7533 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 8 Jul 2025 17:32:51 +0200 Subject: [PATCH 11/11] Add a prompt for the sort order menus for branches --- pkg/gui/controllers/branches_controller.go | 19 +++++++++++-------- pkg/gui/controllers/helpers/refs_helper.go | 7 ++++--- .../controllers/remote_branches_controller.go | 19 +++++++++++-------- pkg/i18n/english.go | 5 +++++ pkg/integration/components/menu_driver.go | 6 ++++++ .../tests/branch/sort_local_branches.go | 4 ++-- .../tests/branch/sort_remote_branches.go | 2 +- 7 files changed, 40 insertions(+), 22 deletions(-) diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index b49a5f6f3..ef27ba01d 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -673,15 +673,18 @@ func (self *BranchesController) createTag(branch *models.Branch) error { } func (self *BranchesController) createSortMenu() error { - return self.c.Helpers().Refs.CreateSortOrderMenu([]string{"recency", "alphabetical", "date"}, func(sortOrder string) error { - if self.c.UserConfig().Git.LocalBranchSortOrder != sortOrder { - self.c.UserConfig().Git.LocalBranchSortOrder = sortOrder - self.c.Contexts().Branches.SetSelection(0) - self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) + return self.c.Helpers().Refs.CreateSortOrderMenu( + []string{"recency", "alphabetical", "date"}, + self.c.Tr.SortOrderPromptLocalBranches, + func(sortOrder string) error { + if self.c.UserConfig().Git.LocalBranchSortOrder != sortOrder { + self.c.UserConfig().Git.LocalBranchSortOrder = sortOrder + self.c.Contexts().Branches.SetSelection(0) + self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}}) + return nil + } return nil - } - return nil - }, + }, self.c.UserConfig().Git.LocalBranchSortOrder) } diff --git a/pkg/gui/controllers/helpers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go index 68bcbbc33..d5140bb1e 100644 --- a/pkg/gui/controllers/helpers/refs_helper.go +++ b/pkg/gui/controllers/helpers/refs_helper.go @@ -186,7 +186,7 @@ func (self *RefsHelper) ResetToRef(ref string, strength string, envVars []string return nil } -func (self *RefsHelper) CreateSortOrderMenu(sortOptionsOrder []string, onSelected func(sortOrder string) error, currentValue string) error { +func (self *RefsHelper) CreateSortOrderMenu(sortOptionsOrder []string, menuPrompt string, onSelected func(sortOrder string) error, currentValue string) error { type sortMenuOption struct { key types.Key label string @@ -222,8 +222,9 @@ func (self *RefsHelper) CreateSortOrderMenu(sortOptionsOrder []string, onSelecte } }) return self.c.Menu(types.CreateMenuOptions{ - Title: self.c.Tr.SortOrder, - Items: menuItems, + Title: self.c.Tr.SortOrder, + Items: menuItems, + Prompt: menuPrompt, }) } diff --git a/pkg/gui/controllers/remote_branches_controller.go b/pkg/gui/controllers/remote_branches_controller.go index 3bb99380a..3a0350477 100644 --- a/pkg/gui/controllers/remote_branches_controller.go +++ b/pkg/gui/controllers/remote_branches_controller.go @@ -145,14 +145,17 @@ func (self *RemoteBranchesController) rebase(selectedBranch *models.RemoteBranch } func (self *RemoteBranchesController) createSortMenu() error { - return self.c.Helpers().Refs.CreateSortOrderMenu([]string{"alphabetical", "date"}, func(sortOrder string) error { - if self.c.UserConfig().Git.RemoteBranchSortOrder != sortOrder { - self.c.UserConfig().Git.RemoteBranchSortOrder = sortOrder - self.c.Contexts().RemoteBranches.SetSelection(0) - self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.REMOTES}}) - } - return nil - }, + return self.c.Helpers().Refs.CreateSortOrderMenu( + []string{"alphabetical", "date"}, + self.c.Tr.SortOrderPromptRemoteBranches, + func(sortOrder string) error { + if self.c.UserConfig().Git.RemoteBranchSortOrder != sortOrder { + self.c.UserConfig().Git.RemoteBranchSortOrder = sortOrder + self.c.Contexts().RemoteBranches.SetSelection(0) + self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.REMOTES}}) + } + return nil + }, self.c.UserConfig().Git.RemoteBranchSortOrder) } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 44ed670aa..bfac1fc20 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -760,10 +760,13 @@ type TranslationSet struct { ShowGitGraph string ShowGitGraphTooltip string SortOrder string + SortOrderPromptLocalBranches string + SortOrderPromptRemoteBranches string SortAlphabetical string SortByDate string SortByRecency string SortBasedOnReflog string + SortOrderPrompt string SortCommits string SortCommitsTooltip string CantChangeContextSizeError string @@ -1807,6 +1810,8 @@ func EnglishTranslationSet() *TranslationSet { ShowGitGraph: "Show git graph", ShowGitGraphTooltip: "Show or hide the git graph in the commit log.\n\nThe default can be changed in the config file with the key 'git.log.showGraph'.", SortOrder: "Sort order", + SortOrderPromptLocalBranches: "The default sort order for local branches can be set in the config file with the key 'git.localBranchSortOrder'.", + SortOrderPromptRemoteBranches: "The default sort order for remote branches can be set in the config file with the key 'git.remoteBranchSortOrder'.", SortAlphabetical: "Alphabetical", SortByDate: "Date", SortByRecency: "Recency", diff --git a/pkg/integration/components/menu_driver.go b/pkg/integration/components/menu_driver.go index 2f93df82d..eb7392d5a 100644 --- a/pkg/integration/components/menu_driver.go +++ b/pkg/integration/components/menu_driver.go @@ -50,6 +50,12 @@ func (self *MenuDriver) TopLines(matchers ...*TextMatcher) *MenuDriver { return self } +func (self *MenuDriver) ContainsLines(matchers ...*TextMatcher) *MenuDriver { + self.getViewDriver().ContainsLines(matchers...) + + return self +} + func (self *MenuDriver) Filter(text string) *MenuDriver { self.getViewDriver().FilterOrSearch(text) diff --git a/pkg/integration/tests/branch/sort_local_branches.go b/pkg/integration/tests/branch/sort_local_branches.go index 9c29e17bf..fbc5776ba 100644 --- a/pkg/integration/tests/branch/sort_local_branches.go +++ b/pkg/integration/tests/branch/sort_local_branches.go @@ -37,7 +37,7 @@ var SortLocalBranches = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.SortOrder) t.ExpectPopup().Menu().Title(Equals("Sort order")). - Lines( + ContainsLines( Contains("r ( ) Recency").IsSelected(), Contains("a ( ) Alphabetical"), Contains("d (•) Date"), @@ -59,7 +59,7 @@ var SortLocalBranches = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.SortOrder) t.ExpectPopup().Menu().Title(Equals("Sort order")). - Lines( + ContainsLines( Contains("r (•) Recency").IsSelected(), Contains("a ( ) Alphabetical"), Contains("d ( ) Date"), diff --git a/pkg/integration/tests/branch/sort_remote_branches.go b/pkg/integration/tests/branch/sort_remote_branches.go index 90c787f41..7cf78cf15 100644 --- a/pkg/integration/tests/branch/sort_remote_branches.go +++ b/pkg/integration/tests/branch/sort_remote_branches.go @@ -41,7 +41,7 @@ var SortRemoteBranches = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.SortOrder) t.ExpectPopup().Menu().Title(Equals("Sort order")). - Lines( + ContainsLines( Contains("a ( ) Alphabetical").IsSelected(), Contains("d (•) Date"), Contains(" Cancel"),