Use non-sticky range diff when entering commit files panel

We make the name of the GetSelectedRefRangeForDiffFiles very specific on purpose
to make it clear that this is only for switching to diff files, so the
implementations can make assumptions about that (unlike GetSelectedRef, which is
used for different purposes and needs to stay more generic).
This commit is contained in:
Stefan Haller 2024-08-23 20:55:37 +02:00
parent a6656e307c
commit ef7d1a8602
8 changed files with 81 additions and 25 deletions

View file

@ -1,6 +1,8 @@
package context package context
import ( import (
"fmt"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/filetree" "github.com/jesseduffield/lazygit/pkg/gui/filetree"
@ -75,12 +77,25 @@ func (self *CommitFilesContext) GetDiffTerminals() []string {
return []string{self.GetRef().RefName()} 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 { func (self *CommitFilesContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition {
return nil return nil
} }
func (self *CommitFilesContext) ReInit(ref types.Ref) { func (self *CommitFilesContext) ReInit(ref types.Ref, refRange *types.RefRange) {
self.SetRef(ref) 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() self.GetView().Title = self.Title()
} }

View file

@ -71,6 +71,11 @@ func (self *ReflogCommitsContext) GetSelectedRef() types.Ref {
return commit 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 { func (self *ReflogCommitsContext) GetCommits() []*models.Commit {
return self.getModel() return self.getModel()
} }

View file

@ -61,6 +61,11 @@ func (self *StashContext) GetSelectedRef() types.Ref {
return stash 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 { func (self *StashContext) GetDiffTerminals() []string {
itemId := self.GetSelectedItemId() itemId := self.GetSelectedItemId()

View file

@ -136,9 +136,8 @@ func (self *CommitFilesController) GetOnRenderToMain() func() error {
return nil return nil
} }
ref := self.context().GetRef() from, to := self.context().GetFromAndToForDiff()
to := ref.RefName() from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from)
from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName())
cmdObj := self.c.Git().WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false) cmdObj := self.c.Git().WorkingTree.ShowFileDiffCmdObj(from, to, reverse, node.GetPath(), false)
task := types.NewRunPtyTask(cmdObj.GetCmd()) task := types.NewRunPtyTask(cmdObj.GetCmd())
@ -250,9 +249,8 @@ func (self *CommitFilesController) canEditFiles(nodes []*filetree.CommitFileNode
} }
func (self *CommitFilesController) openDiffTool(node *filetree.CommitFileNode) error { func (self *CommitFilesController) openDiffTool(node *filetree.CommitFileNode) error {
ref := self.context().GetRef() from, to := self.context().GetFromAndToForDiff()
to := ref.RefName() from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from)
from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName())
_, err := self.c.RunSubprocess(self.c.Git().Diff.OpenDiffToolCmdObj( _, err := self.c.RunSubprocess(self.c.Git().Diff.OpenDiffToolCmdObj(
git_commands.DiffToolCmdOptions{ git_commands.DiffToolCmdOptions{
Filepath: node.GetPath(), Filepath: node.GetPath(),
@ -340,9 +338,8 @@ func (self *CommitFilesController) startPatchBuilder() error {
func (self *CommitFilesController) currentFromToReverseForPatchBuilding() (string, string, bool) { func (self *CommitFilesController) currentFromToReverseForPatchBuilding() (string, string, bool) {
commitFilesContext := self.context() commitFilesContext := self.context()
ref := commitFilesContext.GetRef() from, to := commitFilesContext.GetFromAndToForDiff()
to := ref.RefName() from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from)
from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName())
return from, to, reverse return from, to, reverse
} }

View file

@ -73,9 +73,8 @@ func (self *PatchBuildingHelper) RefreshPatchBuildingPanel(opts types.OnFocusOpt
return nil return nil
} }
ref := self.c.Contexts().CommitFiles.CommitFileTreeViewModel.GetRef() from, to := self.c.Contexts().CommitFiles.GetFromAndToForDiff()
to := ref.RefName() from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from)
from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName())
diff, err := self.c.Git().WorkingTree.ShowFileDiff(from, to, reverse, path, true) diff, err := self.c.Git().WorkingTree.ShowFileDiff(from, to, reverse, path, true)
if err != nil { if err != nil {
return err return err

View file

@ -285,7 +285,8 @@ func (self *RefreshHelper) refreshCommitsAndCommitFiles() {
// For now the awkwardness remains. // For now the awkwardness remains.
commit := self.c.Contexts().LocalCommits.GetSelected() commit := self.c.Contexts().LocalCommits.GetSelected()
if commit != nil && commit.RefName() != "" { 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() _ = self.refreshCommitFilesContext()
} }
} }
@ -386,9 +387,8 @@ func (self *RefreshHelper) RefreshAuthors(commits []*models.Commit) {
} }
func (self *RefreshHelper) refreshCommitFilesContext() error { func (self *RefreshHelper) refreshCommitFilesContext() error {
ref := self.c.Contexts().CommitFiles.GetRef() from, to := self.c.Contexts().CommitFiles.GetFromAndToForDiff()
to := ref.RefName() from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(from)
from, reverse := self.c.Modes().Diffing.GetFromAndReverseArgsForDiff(ref.ParentRefName())
files, err := self.c.Git().Loaders.CommitFileLoader.GetFilesInDiff(from, to, reverse) files, err := self.c.Git().Loaders.CommitFileLoader.GetFilesInDiff(from, to, reverse)
if err != nil { if err != nil {

View file

@ -12,6 +12,7 @@ type CanSwitchToDiffFiles interface {
types.IListContext types.IListContext
CanRebase() bool CanRebase() bool
GetSelectedRef() types.Ref GetSelectedRef() types.Ref
GetSelectedRefRangeForDiffFiles() *types.RefRange
} }
// Not using our ListControllerTrait because our 'selected' item is not a list item // 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{ bindings := []*types.Binding{
{ {
Key: opts.GetKey(opts.Config.Universal.GoInto), Key: opts.GetKey(opts.Config.Universal.GoInto),
Handler: self.withItem(self.enter), Handler: self.enter,
GetDisabledReason: self.require(self.singleItemSelected(self.itemRepresentsCommit)), GetDisabledReason: self.canEnter,
Description: self.c.Tr.ViewItemFiles, Description: self.c.Tr.ViewItemFiles,
}, },
} }
@ -56,10 +57,18 @@ func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOp
} }
func (self *SwitchToDiffFilesController) GetOnClick() func() error { 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 commitFilesContext := self.c.Contexts().CommitFiles
canRebase := self.context.CanRebase() canRebase := self.context.CanRebase()
@ -68,10 +77,12 @@ func (self *SwitchToDiffFilesController) enter(ref types.Ref) error {
if self.c.Modes().Diffing.Ref != ref.RefName() { if self.c.Modes().Diffing.Ref != ref.RefName() {
canRebase = false canRebase = false
} }
} else if refsRange != nil {
canRebase = false
} }
} }
commitFilesContext.ReInit(ref) commitFilesContext.ReInit(ref, refsRange)
commitFilesContext.SetSelection(0) commitFilesContext.SetSelection(0)
commitFilesContext.SetCanRebase(canRebase) commitFilesContext.SetCanRebase(canRebase)
commitFilesContext.SetParentContext(self.context) commitFilesContext.SetParentContext(self.context)
@ -88,7 +99,15 @@ func (self *SwitchToDiffFilesController) enter(ref types.Ref) error {
return self.c.Context().Push(commitFilesContext) 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() == "" { if ref.RefName() == "" {
return &types.DisabledReason{Text: self.c.Tr.SelectedItemDoesNotHaveFiles} return &types.DisabledReason{Text: self.c.Tr.SelectedItemDoesNotHaveFiles}
} }

View file

@ -16,6 +16,8 @@ type ICommitFileTreeViewModel interface {
GetRef() types.Ref GetRef() types.Ref
SetRef(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 GetCanRebase() bool
SetCanRebase(bool) SetCanRebase(bool)
} }
@ -25,9 +27,14 @@ type CommitFileTreeViewModel struct {
types.IListCursor types.IListCursor
ICommitFileTree 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 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. // 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. // If you're viewing the files of some random other branch we can't do any rebase stuff.
canRebase bool canRebase bool
@ -42,6 +49,7 @@ func NewCommitFileTreeViewModel(getFiles func() []*models.CommitFile, log *logru
ICommitFileTree: fileTree, ICommitFileTree: fileTree,
IListCursor: listCursor, IListCursor: listCursor,
ref: nil, ref: nil,
refRange: nil,
canRebase: false, canRebase: false,
} }
} }
@ -54,6 +62,14 @@ func (self *CommitFileTreeViewModel) SetRef(ref types.Ref) {
self.ref = 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 { func (self *CommitFileTreeViewModel) GetCanRebase() bool {
return self.canRebase return self.canRebase
} }