diff --git a/pkg/gui/context/local_commits_context.go b/pkg/gui/context/local_commits_context.go index eecb16107..6d1a72aae 100644 --- a/pkg/gui/context/local_commits_context.go +++ b/pkg/gui/context/local_commits_context.go @@ -128,6 +128,19 @@ func (self *LocalCommitsContext) GetSelectedRef() types.Ref { return commit } +func (self *LocalCommitsContext) GetSelectedRefRangeForDiffFiles() *types.RefRange { + commits, startIdx, endIdx := self.GetSelectedItems() + if commits == nil || startIdx == endIdx { + return nil + } + from := commits[len(commits)-1] + to := commits[0] + if from.IsTODO() || to.IsTODO() { + return nil + } + return &types.RefRange{From: from, To: to} +} + // Returns the commit hash of the selected commit, or an empty string if no // commit is selected func (self *LocalCommitsContext) GetSelectedCommitHash() string { diff --git a/pkg/gui/context/sub_commits_context.go b/pkg/gui/context/sub_commits_context.go index 6adb7a53e..cd19dcae2 100644 --- a/pkg/gui/context/sub_commits_context.go +++ b/pkg/gui/context/sub_commits_context.go @@ -186,6 +186,19 @@ func (self *SubCommitsContext) GetSelectedRef() types.Ref { return commit } +func (self *SubCommitsContext) GetSelectedRefRangeForDiffFiles() *types.RefRange { + commits, startIdx, endIdx := self.GetSelectedItems() + if commits == nil || startIdx == endIdx { + return nil + } + from := commits[len(commits)-1] + to := commits[0] + if from.Divergence != to.Divergence { + return nil + } + return &types.RefRange{From: from, To: to} +} + func (self *SubCommitsContext) GetCommits() []*models.Commit { return self.getModel() } diff --git a/pkg/gui/controllers/helpers/diff_helper.go b/pkg/gui/controllers/helpers/diff_helper.go index 1aad725fc..42cdb99dd 100644 --- a/pkg/gui/controllers/helpers/diff_helper.go +++ b/pkg/gui/controllers/helpers/diff_helper.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" + "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/modes/diffing" "github.com/jesseduffield/lazygit/pkg/gui/style" @@ -49,6 +50,32 @@ func (self *DiffHelper) DiffArgs() []string { return output } +// Returns an update task that can be passed to RenderToMainViews to render a +// diff for the selected commit(s). We need to pass both the selected commit +// and the refRange for a range selection. If the refRange is nil (meaning that +// either there's no range, or it can't be diffed for some reason), then we want +// to fall back to rendering the diff for the single commit. +func (self *DiffHelper) GetUpdateTaskForRenderingCommitsDiff(commit *models.Commit, refRange *types.RefRange) types.UpdateTask { + if refRange != nil { + from, to := refRange.From, refRange.To + args := []string{from.ParentRefName(), to.RefName(), "--stat", "-p"} + if self.c.GetAppState().IgnoreWhitespaceInDiffView { + args = append(args, "--ignore-all-space") + } + args = append(args, "--") + if path := self.c.Modes().Filtering.GetPath(); path != "" { + args = append(args, path) + } + cmdObj := self.c.Git().Diff.DiffCmdObj(args) + task := types.NewRunPtyTask(cmdObj.GetCmd()) + task.Prefix = style.FgYellow.Sprintf("%s %s-%s\n\n", self.c.Tr.ShowingDiffForRange, from.ShortRefName(), to.ShortRefName()) + return task + } + + cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash, self.c.Modes().Filtering.GetPath()) + return types.NewRunPtyTask(cmdObj.GetCmd()) +} + func (self *DiffHelper) ExitDiffMode() error { self.c.Modes().Diffing = diffing.New() return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go index 2d4232f33..f0ca624c1 100644 --- a/pkg/gui/controllers/local_commits_controller.go +++ b/pkg/gui/controllers/local_commits_controller.go @@ -290,8 +290,8 @@ func (self *LocalCommitsController) GetOnRenderToMain() func() error { task = types.NewRenderStringTask( self.c.Tr.ExecCommandHere + "\n\n" + commit.Name) } else { - cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash, self.c.Modes().Filtering.GetPath()) - task = types.NewRunPtyTask(cmdObj.GetCmd()) + refRange := self.context().GetSelectedRefRangeForDiffFiles() + task = self.c.Helpers().Diff.GetUpdateTaskForRenderingCommitsDiff(commit, refRange) } return self.c.RenderToMainViews(types.RefreshMainOpts{ diff --git a/pkg/gui/controllers/sub_commits_controller.go b/pkg/gui/controllers/sub_commits_controller.go index 9ce708272..0f3ca9907 100644 --- a/pkg/gui/controllers/sub_commits_controller.go +++ b/pkg/gui/controllers/sub_commits_controller.go @@ -46,9 +46,8 @@ func (self *SubCommitsController) GetOnRenderToMain() func() error { if commit == nil { task = types.NewRenderStringTask("No commits") } else { - cmdObj := self.c.Git().Commit.ShowCmdObj(commit.Hash, self.c.Modes().Filtering.GetPath()) - - task = types.NewRunPtyTask(cmdObj.GetCmd()) + refRange := self.context().GetSelectedRefRangeForDiffFiles() + task = self.c.Helpers().Diff.GetUpdateTaskForRenderingCommitsDiff(commit, refRange) } return self.c.RenderToMainViews(types.RefreshMainOpts{ diff --git a/pkg/gui/types/ref.go b/pkg/gui/types/ref.go index 4319f12e0..18fc7e998 100644 --- a/pkg/gui/types/ref.go +++ b/pkg/gui/types/ref.go @@ -7,3 +7,8 @@ type Ref interface { ParentRefName() string Description() string } + +type RefRange struct { + From Ref + To Ref +} diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 831cfa27e..b09a14d79 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -581,6 +581,7 @@ type TranslationSet struct { OpenCommandLogMenu string OpenCommandLogMenuTooltip string ShowingGitDiff string + ShowingDiffForRange string CommitDiff string CopyCommitHashToClipboard string CommitHash string @@ -1569,6 +1570,7 @@ func EnglishTranslationSet() *TranslationSet { OpenCommandLogMenu: "View command log options", OpenCommandLogMenuTooltip: "View options for the command log e.g. show/hide the command log and focus the command log.", ShowingGitDiff: "Showing output for:", + ShowingDiffForRange: "Showing diff for range", CommitDiff: "Commit diff", CopyCommitHashToClipboard: "Copy commit hash to clipboard", CommitHash: "Commit hash",