diff --git a/pkg/gui/context/commit_files_context.go b/pkg/gui/context/commit_files_context.go index 1d936f015..4e9382481 100644 --- a/pkg/gui/context/commit_files_context.go +++ b/pkg/gui/context/commit_files_context.go @@ -1,6 +1,8 @@ package context import ( + "fmt" + "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/filetree" @@ -75,12 +77,25 @@ func (self *CommitFilesContext) GetDiffTerminals() []string { return []string{self.GetRef().RefName()} } +func (self *CommitFilesContext) GetFromAndToForDiff() (string, string) { + if refs := self.GetRefRange(); refs != nil { + return refs.From.ParentRefName(), refs.To.RefName() + } + ref := self.GetRef() + return ref.ParentRefName(), ref.RefName() +} + func (self *CommitFilesContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition { return nil } -func (self *CommitFilesContext) ReInit(ref types.Ref) { +func (self *CommitFilesContext) ReInit(ref types.Ref, refRange *types.RefRange) { self.SetRef(ref) - self.SetTitleRef(ref.Description()) + self.SetRefRange(refRange) + if refRange != nil { + self.SetTitleRef(fmt.Sprintf("%s-%s", refRange.From.ShortRefName(), refRange.To.ShortRefName())) + } else { + self.SetTitleRef(ref.Description()) + } self.GetView().Title = self.Title() } diff --git a/pkg/gui/context/reflog_commits_context.go b/pkg/gui/context/reflog_commits_context.go index 403e5e91c..db33481e5 100644 --- a/pkg/gui/context/reflog_commits_context.go +++ b/pkg/gui/context/reflog_commits_context.go @@ -71,6 +71,11 @@ func (self *ReflogCommitsContext) GetSelectedRef() types.Ref { return commit } +func (self *ReflogCommitsContext) GetSelectedRefRangeForDiffFiles() *types.RefRange { + // It doesn't make much sense to show a range diff between two reflog entries. + return nil +} + func (self *ReflogCommitsContext) GetCommits() []*models.Commit { return self.getModel() } diff --git a/pkg/gui/context/stash_context.go b/pkg/gui/context/stash_context.go index c8d487688..64c7c9fc9 100644 --- a/pkg/gui/context/stash_context.go +++ b/pkg/gui/context/stash_context.go @@ -61,6 +61,11 @@ func (self *StashContext) GetSelectedRef() types.Ref { return stash } +func (self *StashContext) GetSelectedRefRangeForDiffFiles() *types.RefRange { + // It doesn't make much sense to show a range diff between two stash entries. + return nil +} + func (self *StashContext) GetDiffTerminals() []string { itemId := self.GetSelectedItemId() diff --git a/pkg/gui/controllers/commits_files_controller.go b/pkg/gui/controllers/commits_files_controller.go index 17c92224a..8c4f7cf14 100644 --- a/pkg/gui/controllers/commits_files_controller.go +++ b/pkg/gui/controllers/commits_files_controller.go @@ -136,9 +136,8 @@ func (self *CommitFilesController) GetOnRenderToMain() func() error { return nil } - ref := self.context().GetRef() - to := ref.RefName() - from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) + from, to := self.context().GetFromAndToForDiff() + from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) cmdObj := self.c.Git().WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false) task := types.NewRunPtyTask(cmdObj.GetCmd()) @@ -250,9 +249,8 @@ func (self *CommitFilesController) canEditFiles(nodes []*filetree.CommitFileNode } func (self *CommitFilesController) openDiffTool(node *filetree.CommitFileNode) error { - ref := self.context().GetRef() - to := ref.RefName() - from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) + from, to := self.context().GetFromAndToForDiff() + from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) _, err := self.c.RunSubprocess(self.c.Git().Diff.OpenDiffToolCmdObj( git_commands.DiffToolCmdOptions{ Filepath: node.GetPath(), @@ -340,9 +338,8 @@ func (self *CommitFilesController) startPatchBuilder() error { func (self *CommitFilesController) currentFromToReverseForPatchBuilding() (string, string, bool) { commitFilesContext := self.context() - ref := commitFilesContext.GetRef() - to := ref.RefName() - from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) + from, to := commitFilesContext.GetFromAndToForDiff() + from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) return from, to, reverse } diff --git a/pkg/gui/controllers/helpers/patch_building_helper.go b/pkg/gui/controllers/helpers/patch_building_helper.go index 4c2fc40d0..df6e34216 100644 --- a/pkg/gui/controllers/helpers/patch_building_helper.go +++ b/pkg/gui/controllers/helpers/patch_building_helper.go @@ -73,9 +73,8 @@ func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpt return nil } - ref := self.c.Contexts().CommitFiles.CommitFileTreeViewModel.GetRef() - to := ref.RefName() - from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) + from, to := self.c.Contexts().CommitFiles.GetFromAndToForDiff() + from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) diff, err := self.c.Git().WorkingTree.ShowFileDiff(from, to, reverse, path, true) if err != nil { return err diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index 40a6b0355..c1f187d07 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -285,7 +285,8 @@ func (self *RefreshHelper) refreshCommitsAndCommitFiles() { // For now the awkwardness remains. commit := self.c.Contexts().LocalCommits.GetSelected() if commit != nil && commit.RefName() != "" { - self.c.Contexts().CommitFiles.ReInit(commit) + refRange := self.c.Contexts().LocalCommits.GetSelectedRefRangeForDiffFiles() + self.c.Contexts().CommitFiles.ReInit(commit, refRange) _ = self.refreshCommitFilesContext() } } @@ -386,9 +387,8 @@ func (self *RefreshHelper) RefreshAuthors(commits []*models.Commit) { } func (self *RefreshHelper) refreshCommitFilesContext() error { - ref := self.c.Contexts().CommitFiles.GetRef() - to := ref.RefName() - from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName()) + from, to := self.c.Contexts().CommitFiles.GetFromAndToForDiff() + from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from) files, err := self.c.Git().Loaders.CommitFileLoader.GetFilesInDiff(from, to, reverse) if err != nil { diff --git a/pkg/gui/controllers/switch_to_diff_files_controller.go b/pkg/gui/controllers/switch_to_diff_files_controller.go index 1d0cc48f8..b6cfe94d2 100644 --- a/pkg/gui/controllers/switch_to_diff_files_controller.go +++ b/pkg/gui/controllers/switch_to_diff_files_controller.go @@ -12,6 +12,7 @@ type CanSwitchToDiffFiles interface { types.IListContext CanRebase() bool GetSelectedRef() types.Ref + GetSelectedRefRangeForDiffFiles() *types.RefRange } // Not using our ListControllerTrait because our 'selected' item is not a list item @@ -46,8 +47,8 @@ func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOp bindings := []*types.Binding{ { Key: opts.GetKey(opts.Config.Universal.GoInto), - Handler: self.withItem(self.enter), - GetDisabledReason: self.require(self.singleItemSelected(self.itemRepresentsCommit)), + Handler: self.enter, + GetDisabledReason: self.canEnter, Description: self.c.Tr.ViewItemFiles, }, } @@ -56,10 +57,18 @@ func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOp } func (self *SwitchToDiffFilesController) GetOnClick() func() error { - return self.withItemGraceful(self.enter) + return func() error { + if self.canEnter() == nil { + return self.enter() + } + + return nil + } } -func (self *SwitchToDiffFilesController) enter(ref types.Ref) error { +func (self *SwitchToDiffFilesController) enter() error { + ref := self.context.GetSelectedRef() + refsRange := self.context.GetSelectedRefRangeForDiffFiles() commitFilesContext := self.c.Contexts().CommitFiles canRebase := self.context.CanRebase() @@ -68,10 +77,12 @@ func (self *SwitchToDiffFilesController) enter(ref types.Ref) error { if self.c.Modes().Diffing.Ref != ref.RefName() { canRebase = false } + } else if refsRange != nil { + canRebase = false } } - commitFilesContext.ReInit(ref) + commitFilesContext.ReInit(ref, refsRange) commitFilesContext.SetSelection(0) commitFilesContext.SetCanRebase(canRebase) commitFilesContext.SetParentContext(self.context) @@ -88,7 +99,15 @@ func (self *SwitchToDiffFilesController) enter(ref types.Ref) error { return self.c.Context().Push(commitFilesContext) } -func (self *SwitchToDiffFilesController) itemRepresentsCommit(ref types.Ref) *types.DisabledReason { +func (self *SwitchToDiffFilesController) canEnter() *types.DisabledReason { + refRange := self.context.GetSelectedRefRangeForDiffFiles() + if refRange != nil { + return nil + } + ref := self.context.GetSelectedRef() + if ref == nil { + return &types.DisabledReason{Text: self.c.Tr.NoItemSelected} + } if ref.RefName() == "" { return &types.DisabledReason{Text: self.c.Tr.SelectedItemDoesNotHaveFiles} } diff --git a/pkg/gui/filetree/commit_file_tree_view_model.go b/pkg/gui/filetree/commit_file_tree_view_model.go index 95cb1a140..cbbb2fbcf 100644 --- a/pkg/gui/filetree/commit_file_tree_view_model.go +++ b/pkg/gui/filetree/commit_file_tree_view_model.go @@ -16,6 +16,8 @@ type ICommitFileTreeViewModel interface { GetRef() types.Ref SetRef(types.Ref) + GetRefRange() *types.RefRange // can be nil, in which case GetRef should be used + SetRefRange(*types.RefRange) // should be set to nil when selection is not a range GetCanRebase() bool SetCanRebase(bool) } @@ -25,9 +27,14 @@ type CommitFileTreeViewModel struct { types.IListCursor ICommitFileTree - // this is e.g. the commit for which we're viewing the files + // this is e.g. the commit for which we're viewing the files, if there is no + // range selection, or if the range selection can't be used for some reason ref types.Ref + // this is a commit range for which we're viewing the files. Can be nil, in + // which case ref is used. + refRange *types.RefRange + // we set this to true when you're viewing the files within the checked-out branch's commits. // If you're viewing the files of some random other branch we can't do any rebase stuff. canRebase bool @@ -42,6 +49,7 @@ func NewCommitFileTreeViewModel(getFiles func() []*models.CommitFile, log *logru ICommitFileTree: fileTree, IListCursor: listCursor, ref: nil, + refRange: nil, canRebase: false, } } @@ -54,6 +62,14 @@ func (self *CommitFileTreeViewModel) SetRef(ref types.Ref) { self.ref = ref } +func (self *CommitFileTreeViewModel) GetRefRange() *types.RefRange { + return self.refRange +} + +func (self *CommitFileTreeViewModel) SetRefRange(refsForRange *types.RefRange) { + self.refRange = refsForRange +} + func (self *CommitFileTreeViewModel) GetCanRebase() bool { return self.canRebase }