diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2023-05-21 12:31:17 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2023-05-21 13:54:06 +1000 |
commit | 7efe433f1c5a45297d2729e9fddedf41bbe7937c (patch) | |
tree | ad99b699e0b19f4586f8dfb09f80f2ce51cbadc9 | |
parent | 6f535d71c91df96eaa8e29d0b120ba1e281e27d9 (diff) |
Mark commits which changed a file among the last X commitsmark-last-commit-to-change-file
See https://github.com/jesseduffield/lazygit/issues/2653
-rw-r--r-- | docs/Config.md | 2 | ||||
-rw-r--r-- | pkg/commands/git_commands/commit.go | 17 | ||||
-rw-r--r-- | pkg/config/user_config.go | 82 | ||||
-rw-r--r-- | pkg/gui/context/local_commits_context.go | 43 | ||||
-rw-r--r-- | pkg/gui/context/sub_commits_context.go | 15 | ||||
-rw-r--r-- | pkg/gui/controllers/files_controller.go | 11 | ||||
-rw-r--r-- | pkg/gui/gui.go | 10 | ||||
-rw-r--r-- | pkg/gui/presentation/commits.go | 25 | ||||
-rw-r--r-- | pkg/gui/types/common.go | 2 |
9 files changed, 145 insertions, 62 deletions
diff --git a/docs/Config.md b/docs/Config.md index bc860156c..670994c9e 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -65,6 +65,8 @@ gui: splitDiff: 'auto' # one of 'auto' | 'always' skipRewordInEditorWarning: false # for skipping the confirmation before launching the reword editor border: 'single' # one of 'single' | 'double' | 'rounded' | 'hidden' + # For marking recent commits which changed the selected file + experimentalMarkCommitsWhichChangedFile: false git: paging: colorArg: always diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go index bca68c3ac..996ba3c3a 100644 --- a/pkg/commands/git_commands/commit.go +++ b/pkg/commands/git_commands/commit.go @@ -3,6 +3,7 @@ package git_commands import ( "fmt" "strings" + "time" "github.com/go-errors/errors" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" @@ -250,3 +251,19 @@ func (self *CommitCommands) GetCommitMessageFromHistory(value int) (string, erro } return self.GetCommitMessage(formattedHash) } + +// Returns hashes of recent commits which changed the given file +// Note: This does not look for the last X commits to change a file, instead +// it looks among the last X commits and see which of them happened to have changed the file. +// This is more efficient. +func (self *CommitCommands) GetRecentCommitsWhichChangedFile(path string) []string { + t := time.Now() + // Checking last X commits. Funnily this seems to actually consider more than the last + // X, perhaps because of topological sorting. + cmdStr := NewGitCmd("log").Arg("HEAD~50..HEAD", "--pretty=%H", "--", self.cmd.Quote(path)). + ToString() + + hashes, _ := self.cmd.New(cmdStr).DontLog().RunWithOutput() + self.Log.Warn(fmt.Sprintf("GetRecentCommitsWhichChangedFile took %s", time.Since(t))) + return strings.Split(strings.TrimSpace(hashes), "\n") +} diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 9212a2de8..fc530dd5e 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -27,33 +27,34 @@ type RefresherConfig struct { } type GuiConfig struct { - AuthorColors map[string]string `yaml:"authorColors"` - BranchColors map[string]string `yaml:"branchColors"` - ScrollHeight int `yaml:"scrollHeight"` - ScrollPastBottom bool `yaml:"scrollPastBottom"` - MouseEvents bool `yaml:"mouseEvents"` - SkipUnstageLineWarning bool `yaml:"skipUnstageLineWarning"` - SkipStashWarning bool `yaml:"skipStashWarning"` - SidePanelWidth float64 `yaml:"sidePanelWidth"` - ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"` - MainPanelSplitMode string `yaml:"mainPanelSplitMode"` - Language string `yaml:"language"` - TimeFormat string `yaml:"timeFormat"` - Theme ThemeConfig `yaml:"theme"` - CommitLength CommitLengthConfig `yaml:"commitLength"` - SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"` - ShowListFooter bool `yaml:"showListFooter"` - ShowFileTree bool `yaml:"showFileTree"` - ShowRandomTip bool `yaml:"showRandomTip"` - ShowCommandLog bool `yaml:"showCommandLog"` - ShowBottomLine bool `yaml:"showBottomLine"` - ShowIcons bool `yaml:"showIcons"` - ExperimentalShowBranchHeads bool `yaml:"experimentalShowBranchHeads"` - CommandLogSize int `yaml:"commandLogSize"` - SplitDiff string `yaml:"splitDiff"` - SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"` - WindowSize string `yaml:"windowSize"` - Border string `yaml:"border"` + AuthorColors map[string]string `yaml:"authorColors"` + BranchColors map[string]string `yaml:"branchColors"` + ScrollHeight int `yaml:"scrollHeight"` + ScrollPastBottom bool `yaml:"scrollPastBottom"` + MouseEvents bool `yaml:"mouseEvents"` + SkipUnstageLineWarning bool `yaml:"skipUnstageLineWarning"` + SkipStashWarning bool `yaml:"skipStashWarning"` + SidePanelWidth float64 `yaml:"sidePanelWidth"` + ExpandFocusedSidePanel bool `yaml:"expandFocusedSidePanel"` + MainPanelSplitMode string `yaml:"mainPanelSplitMode"` + Language string `yaml:"language"` + TimeFormat string `yaml:"timeFormat"` + Theme ThemeConfig `yaml:"theme"` + CommitLength CommitLengthConfig `yaml:"commitLength"` + SkipNoStagedFilesWarning bool `yaml:"skipNoStagedFilesWarning"` + ShowListFooter bool `yaml:"showListFooter"` + ShowFileTree bool `yaml:"showFileTree"` + ShowRandomTip bool `yaml:"showRandomTip"` + ShowCommandLog bool `yaml:"showCommandLog"` + ShowBottomLine bool `yaml:"showBottomLine"` + ShowIcons bool `yaml:"showIcons"` + ExperimentalShowBranchHeads bool `yaml:"experimentalShowBranchHeads"` + CommandLogSize int `yaml:"commandLogSize"` + SplitDiff string `yaml:"splitDiff"` + SkipRewordInEditorWarning bool `yaml:"skipRewordInEditorWarning"` + WindowSize string `yaml:"windowSize"` + Border string `yaml:"border"` + ExperimentalMarkCommitsWhichChangedFile bool `yaml:"experimentalMarkCommitsWhichChangedFile"` } type ThemeConfig struct { @@ -410,19 +411,20 @@ func GetDefaultConfig() *UserConfig { UnstagedChangesColor: []string{"red"}, DefaultFgColor: []string{"default"}, }, - CommitLength: CommitLengthConfig{Show: true}, - SkipNoStagedFilesWarning: false, - ShowListFooter: true, - ShowCommandLog: true, - ShowBottomLine: true, - ShowFileTree: true, - ShowRandomTip: true, - ShowIcons: false, - ExperimentalShowBranchHeads: false, - CommandLogSize: 8, - SplitDiff: "auto", - SkipRewordInEditorWarning: false, - Border: "single", + CommitLength: CommitLengthConfig{Show: true}, + SkipNoStagedFilesWarning: false, + ShowListFooter: true, + ShowCommandLog: true, + ShowBottomLine: true, + ShowFileTree: true, + ShowRandomTip: true, + ShowIcons: false, + ExperimentalShowBranchHeads: false, + CommandLogSize: 8, + SplitDiff: "auto", + SkipRewordInEditorWarning: false, + Border: "single", + ExperimentalMarkCommitsWhichChangedFile: false, }, Git: GitConfig{ Paging: PagingConfig{ diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index e8ae0b6c5..bdbb81eb2 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -3,6 +3,7 @@ package context import ( "log" + "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "github.com/jesseduffield/lazygit/pkg/gui/presentation" @@ -37,20 +38,14 @@ func NewLocalCommitsContext(c *ContextCommon) *LocalCommitsContext { showYouAreHereLabel := c.Model().WorkingTreeStateAtLastCommitRefresh == enums.REBASE_MODE_REBASING - return presentation.GetCommitListDisplayStrings( - c.Common, + return getCommitsDisplayStrings( + c, c.Model().Commits, - c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL, - c.Modes().CherryPicking.SelectedShaSet(), - c.Modes().Diffing.Ref, - c.UserConfig.Gui.TimeFormat, - c.UserConfig.Git.ParseEmoji, - selectedCommitSha, startIdx, length, - shouldShowGraph(c), - c.Model().BisectInfo, + selectedCommitSha, showYouAreHereLabel, + c.Model().BisectInfo, ) } @@ -159,3 +154,31 @@ func shouldShowGraph(c *ContextCommon) bool { log.Fatalf("Unknown value for git.log.showGraph: %s. Expected one of: 'always', 'never', 'when-maximised'", value) return false } + +func getCommitsDisplayStrings( + c *ContextCommon, + commits []*models.Commit, + startIdx int, + length int, + selectedCommitSha string, + showYouAreHereLabel bool, + bisectInfo *git_commands.BisectInfo, +) [][]string { + return presentation.GetCommitListDisplayStrings( + c.Common, + commits, + c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL, + c.Modes().CherryPicking.SelectedShaSet(), + c.Modes().Diffing.Ref, + c.UserConfig.Gui.TimeFormat, + c.UserConfig.Git.ParseEmoji, + selectedCommitSha, + startIdx, + length, + shouldShowGraph(c), + bisectInfo, + showYouAreHereLabel, + c.State().GetRepoState().GetRecentCommitsWhichChangedFile(), + c.UserConfig.Gui.ExperimentalMarkCommitsWhichChangedFile, + ) +} diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index 16712f982..3c196fefd 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -5,7 +5,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" - "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -40,20 +39,14 @@ func NewSubCommitsContext( selectedCommitSha = selectedCommit.Sha } } - return presentation.GetCommitListDisplayStrings( - c.Common, + return getCommitsDisplayStrings( + c, c.Model().SubCommits, - c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL, - c.Modes().CherryPicking.SelectedShaSet(), - c.Modes().Diffing.Ref, - c.UserConfig.Gui.TimeFormat, - c.UserConfig.Git.ParseEmoji, - selectedCommitSha, startIdx, length, - shouldShowGraph(c), - git_commands.NewNullBisectInfo(), + selectedCommitSha, false, + git_commands.NewNullBisectInfo(), ) } diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index 2876f97fb..b35015cae 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -9,6 +9,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" ) type FilesController struct { @@ -192,6 +193,16 @@ func (self *FilesController) GetOnRenderToMain() func() error { } } + if self.c.UserConfig.Gui.ExperimentalMarkCommitsWhichChangedFile { + go utils.Safe(func() { + recentCommitsWhichChangedFile := self.c.Git().Commit.GetRecentCommitsWhichChangedFile(node.GetPath()) + self.c.OnUIThread(func() error { + self.c.State().GetRepoState().SetRecentCommitsWhichChangedFile(recentCommitsWhichChangedFile) + return self.c.PostRefreshUpdate(self.c.Contexts().LocalCommits) + }) + }) + } + self.c.Helpers().MergeConflicts.ResetMergeState() pair := self.c.MainViewPairs().Normal diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index b429bda27..e1c5b81e8 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -220,6 +220,8 @@ type GuiRepoState struct { ScreenMode types.WindowMaximisation CurrentPopupOpts *types.CreatePopupPanelOpts + + RecentCommitsWhichChangedFile []string } var _ types.IRepoStateAccessor = new(GuiRepoState) @@ -268,6 +270,14 @@ func (self *GuiRepoState) GetSplitMainPanel() bool { return self.SplitMainPanel } +func (self *GuiRepoState) SetRecentCommitsWhichChangedFile(value []string) { + self.RecentCommitsWhichChangedFile = value +} + +func (self *GuiRepoState) GetRecentCommitsWhichChangedFile() []string { + return self.RecentCommitsWhichChangedFile +} + type searchingState struct { view *gocui.View isSearching bool diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index 6b83456b9..0cace9b09 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -16,6 +16,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/kyokomi/emoji/v2" + "github.com/samber/lo" "github.com/sasha-s/go-deadlock" ) @@ -48,6 +49,8 @@ func GetCommitListDisplayStrings( showGraph bool, bisectInfo *git_commands.BisectInfo, showYouAreHereLabel bool, + recentCommitsWhichChangedFile []string, + markRecentFileChanges bool, ) [][]string { mutex.Lock() defer mutex.Unlock() @@ -113,6 +116,8 @@ func GetCommitListDisplayStrings( bisectStatus, bisectInfo, isYouAreHereCommit, + recentCommitsWhichChangedFile, + markRecentFileChanges, )) } return lines @@ -259,6 +264,8 @@ func displayCommit( bisectStatus BisectStatus, bisectInfo *git_commands.BisectInfo, isYouAreHereCommit bool, + recentCommitsWhichChangedFile []string, + markRecentFileChanges bool, ) []string { shaColor := getShaColor(commit, diffName, cherryPickedCommitShaSet, bisectStatus, bisectInfo) bisectString := getBisectStatusText(bisectStatus, bisectInfo) @@ -299,7 +306,23 @@ func displayCommit( cols := make([]string, 0, 7) if icons.IsIconEnabled() { - cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit))) + if markRecentFileChanges && lo.SomeBy(recentCommitsWhichChangedFile, func(sha string) bool { + return utils.ShortSha(sha) == utils.ShortSha(commit.Sha) + }) { + cols = append(cols, style.FgDefault.Sprint(">")) + } else { + cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit))) + } + } else { + if markRecentFileChanges { + if lo.SomeBy(recentCommitsWhichChangedFile, func(sha string) bool { + return utils.ShortSha(sha) == utils.ShortSha(commit.Sha) + }) { + cols = append(cols, style.FgDefault.Sprint(">")) + } else { + cols = append(cols, " ") + } + } } cols = append(cols, shaColor.Sprint(commit.ShortSha())) cols = append(cols, bisectString) diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 3709d3c7b..b2766ada3 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -254,6 +254,8 @@ type IRepoStateAccessor interface { IsSearching() bool SetSplitMainPanel(bool) GetSplitMainPanel() bool + SetRecentCommitsWhichChangedFile([]string) + GetRecentCommitsWhichChangedFile() []string } // startup stages so we don't need to load everything at once |