diff --git a/pkg/commands/commit_list_builder.go b/pkg/commands/commit_list_builder.go index 6506d3f26..dd575e4d5 100644 --- a/pkg/commands/commit_list_builder.go +++ b/pkg/commands/commit_list_builder.go @@ -37,14 +37,14 @@ type CommitListBuilder struct { } // NewCommitListBuilder builds a new commit list builder -func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *OSCommand, tr *i18n.Localizer, cherryPickedCommits []*Commit) (*CommitListBuilder, error) { +func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *OSCommand, tr *i18n.Localizer, cherryPickedCommits []*Commit) *CommitListBuilder { return &CommitListBuilder{ Log: log, GitCommand: gitCommand, OSCommand: osCommand, Tr: tr, CherryPickedCommits: cherryPickedCommits, - }, nil + } } // extractCommitFromLine takes a line from a git log and extracts the sha, message, date, and tag if present @@ -82,33 +82,40 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit { } type GetCommitsOptions struct { - Limit bool - FilterPath string + Limit bool + FilterPath string + IncludeRebaseCommits bool + RefName string // e.g. "HEAD" or "my_branch" } // GetCommits obtains the commits of the current branch -func (c *CommitListBuilder) GetCommits(options GetCommitsOptions) ([]*Commit, error) { +func (c *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*Commit, error) { commits := []*Commit{} var rebasingCommits []*Commit - rebaseMode, err := c.GitCommand.RebaseMode() - if err != nil { - return nil, err - } - if rebaseMode != "" && options.FilterPath == "" { - // here we want to also prepend the commits that we're in the process of rebasing - rebasingCommits, err = c.getRebasingCommits(rebaseMode) + rebaseMode := "" + + if opts.IncludeRebaseCommits { + var err error + rebaseMode, err = c.GitCommand.RebaseMode() if err != nil { return nil, err } - if len(rebasingCommits) > 0 { - commits = append(commits, rebasingCommits...) + if rebaseMode != "" && opts.FilterPath == "" { + // here we want to also prepend the commits that we're in the process of rebasing + rebasingCommits, err = c.getRebasingCommits(rebaseMode) + if err != nil { + return nil, err + } + if len(rebasingCommits) > 0 { + commits = append(commits, rebasingCommits...) + } } } - unpushedCommits := c.getUnpushedCommits() - cmd := c.getLogCmd(options) + unpushedCommits := c.getUnpushedCommits(opts.RefName) + cmd := c.getLogCmd(opts) - err = RunLineOutputCmd(cmd, func(line string) (bool, error) { + err := RunLineOutputCmd(cmd, func(line string) (bool, error) { if strings.Split(line, " ")[0] != "gpg:" { commit := c.extractCommitFromLine(line) _, unpushed := unpushedCommits[commit.ShortSha()] @@ -287,9 +294,9 @@ func (c *CommitListBuilder) getMergeBase() (string, error) { // getUnpushedCommits Returns the sha's of the commits that have not yet been pushed // to the remote branch of the current branch, a map is returned to ease look up -func (c *CommitListBuilder) getUnpushedCommits() map[string]bool { +func (c *CommitListBuilder) getUnpushedCommits(refName string) map[string]bool { pushables := map[string]bool{} - o, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..HEAD --abbrev-commit --abbrev=8") + o, err := c.OSCommand.RunCommandWithOutput("git rev-list %s@{u}..%s --abbrev-commit --abbrev=8", refName, refName) if err != nil { return pushables } @@ -301,16 +308,16 @@ func (c *CommitListBuilder) getUnpushedCommits() map[string]bool { } // getLog gets the git log. -func (c *CommitListBuilder) getLogCmd(options GetCommitsOptions) *exec.Cmd { +func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) *exec.Cmd { limitFlag := "" - if options.Limit { + if opts.Limit { limitFlag = "-300" } filterFlag := "" - if options.FilterPath != "" { - filterFlag = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(options.FilterPath)) + if opts.FilterPath != "" { + filterFlag = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(opts.FilterPath)) } - return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix %s", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20, filterFlag)) + return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log %s --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix %s", opts.RefName, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20, filterFlag)) } diff --git a/pkg/commands/commit_list_builder_test.go b/pkg/commands/commit_list_builder_test.go index 541dfd99c..de49bd6a8 100644 --- a/pkg/commands/commit_list_builder_test.go +++ b/pkg/commands/commit_list_builder_test.go @@ -55,7 +55,7 @@ func TestCommitListBuilderGetUnpushedCommits(t *testing.T) { t.Run(s.testName, func(t *testing.T) { c := NewDummyCommitListBuilder() c.OSCommand.SetCommand(s.command) - s.test(c.getUnpushedCommits()) + s.test(c.getUnpushedCommits("HEAD")) }) } } diff --git a/pkg/commands/file.go b/pkg/commands/file.go index 4a277be22..12f63c9db 100644 --- a/pkg/commands/file.go +++ b/pkg/commands/file.go @@ -36,3 +36,7 @@ func (f *File) Names() []string { func (f *File) Matches(f2 *File) bool { return utils.StringArraysOverlap(f.Names(), f2.Names()) } + +func (f *File) ID() string { + return f.Name +} diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 427f62b71..3663112ee 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -98,12 +98,16 @@ func (gui *Gui) refreshCommits() error { } func (gui *Gui) refreshCommitsWithLimit() error { - builder, err := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr, gui.State.CherryPickedCommits) - if err != nil { - return err - } + builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr, gui.State.CherryPickedCommits) - commits, err := builder.GetCommits(commands.GetCommitsOptions{Limit: gui.State.Panels.Commits.LimitCommits, FilterPath: gui.State.FilterPath}) + commits, err := builder.GetCommits( + commands.GetCommitsOptions{ + Limit: gui.State.Panels.Commits.LimitCommits, + FilterPath: gui.State.FilterPath, + IncludeRebaseCommits: true, + RefName: "HEAD", + }, + ) if err != nil { return err } diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 05f8212ee..9167f8fe7 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -3,6 +3,7 @@ package gui import ( "fmt" + "github.com/davecgh/go-spew/spew" "github.com/jesseduffield/gocui" ) @@ -22,6 +23,7 @@ const ( TAGS_CONTEXT_KEY = "tags" BRANCH_COMMITS_CONTEXT_KEY = "commits" REFLOG_COMMITS_CONTEXT_KEY = "reflogCommits" + SUB_COMMITS_CONTEXT_KEY = "subCommits" COMMIT_FILES_CONTEXT_KEY = "commitFiles" STASH_CONTEXT_KEY = "stash" MAIN_NORMAL_CONTEXT_KEY = "normal" @@ -129,6 +131,7 @@ type ContextTree struct { BranchCommits SimpleContextNode CommitFiles SimpleContextNode ReflogCommits SimpleContextNode + SubCommits SimpleContextNode Stash SimpleContextNode Normal SimpleContextNode Staging SimpleContextNode @@ -160,6 +163,7 @@ func (gui *Gui) allContexts() []Context { gui.Contexts.Staging.Context, gui.Contexts.Merging.Context, gui.Contexts.PatchBuilding.Context, + gui.Contexts.SubCommits.Context, } } @@ -194,6 +198,9 @@ func (gui *Gui) contextTree() ContextTree { ReflogCommits: SimpleContextNode{ Context: gui.reflogCommitsListContext(), }, + SubCommits: SimpleContextNode{ + Context: gui.subCommitsListContext(), + }, Branches: SimpleContextNode{ Context: gui.branchesListContext(), }, @@ -510,6 +517,31 @@ func (gui *Gui) currentContext() Context { return gui.State.ContextStack[len(gui.State.ContextStack)-1] } +func (gui *Gui) currentSideContext() *ListContext { + stack := gui.State.ContextStack + + // on startup the stack can be empty so we'll return an empty string in that case + if len(stack) == 0 { + return nil + } + + // find the first context in the stack with the type of SIDE_CONTEXT + for i := range stack { + context := stack[len(stack)-1-i] + + if context.GetKind() == SIDE_CONTEXT { + gui.Log.Warn(spew.Sdump(context.GetKey())) + return context.(*ListContext) + } + } + + return nil +} + +func (gui *Gui) defaultSideContext() Context { + return gui.Contexts.Files.Context +} + func (gui *Gui) setInitialViewContexts() { // arguably we should only have our ViewContextMap and we should do away with // contexts on views, or vice versa diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 1b6446909..b0249b37a 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -173,6 +173,13 @@ type reflogCommitPanelState struct { listPanelState } +type subCommitPanelState struct { + listPanelState + + // e.g. name of branch whose commits we're looking at + refName string +} + type stashPanelState struct { listPanelState } @@ -199,6 +206,7 @@ type panelStates struct { Tags *tagsPanelState Commits *commitPanelState ReflogCommits *reflogCommitPanelState + SubCommits *subCommitPanelState Stash *stashPanelState Menu *menuPanelState LineByLine *lineByLinePanelState @@ -237,6 +245,7 @@ type guiState struct { // if we're not in filtering mode, CommitFiles and FilteredReflogCommits will be // one and the same ReflogCommits []*commands.Commit + SubCommits []*commands.Commit Remotes []*commands.Remote RemoteBranches []*commands.RemoteBranch Tags []*commands.Tag @@ -289,13 +298,15 @@ func (gui *Gui) resetState() { CherryPickedCommits: make([]*commands.Commit, 0), StashEntries: make([]*commands.StashEntry, 0), Panels: &panelStates{ + // TODO: work out why some of these are -1 and some are 0. Last time I checked there was a good reason but I'm less certain now Files: &filePanelState{listPanelState{SelectedLineIdx: -1}}, Branches: &branchPanelState{listPanelState{SelectedLineIdx: 0}}, Remotes: &remotePanelState{listPanelState{SelectedLineIdx: 0}}, RemoteBranches: &remoteBranchesState{listPanelState{SelectedLineIdx: -1}}, Tags: &tagsPanelState{listPanelState{SelectedLineIdx: -1}}, Commits: &commitPanelState{listPanelState: listPanelState{SelectedLineIdx: -1}, LimitCommits: true}, - ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLineIdx: 0}}, // TODO: might need to make -1 + ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLineIdx: 0}}, + SubCommits: &subCommitPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, refName: ""}, CommitFiles: &commitFilesPanelState{listPanelState: listPanelState{SelectedLineIdx: -1}, refName: ""}, Stash: &stashPanelState{listPanelState{SelectedLineIdx: -1}}, Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil}, diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 96a300c72..76e28fdf5 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -555,6 +555,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleClipboardCopyBranch, Description: gui.Tr.SLocalize("copyBranchNameToClipboard"), }, + { + ViewName: "branches", + Contexts: []string{LOCAL_BRANCHES_CONTEXT_KEY}, + Key: gui.getKey("universal.goInto"), + Handler: gui.wrappedHandler(gui.handleSwitchToSubCommits), + Description: gui.Tr.SLocalize("viewCommits"), + }, { ViewName: "branches", Contexts: []string{TAGS_CONTEXT_KEY}, @@ -590,6 +597,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleCreateResetToTagMenu, Description: gui.Tr.SLocalize("viewResetOptions"), }, + { + ViewName: "branches", + Contexts: []string{TAGS_CONTEXT_KEY}, + Key: gui.getKey("universal.goInto"), + Handler: gui.wrappedHandler(gui.handleSwitchToSubCommits), + Description: gui.Tr.SLocalize("viewCommits"), + }, { ViewName: "branches", Key: gui.getKey("universal.nextTab"), @@ -616,6 +630,13 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleCreateResetToRemoteBranchMenu, Description: gui.Tr.SLocalize("viewResetOptions"), }, + { + ViewName: "branches", + Contexts: []string{REMOTE_BRANCHES_CONTEXT_KEY}, + Key: gui.getKey("universal.goInto"), + Handler: gui.wrappedHandler(gui.handleSwitchToSubCommits), + Description: gui.Tr.SLocalize("viewCommits"), + }, { ViewName: "branches", Contexts: []string{REMOTES_CONTEXT_KEY}, @@ -818,6 +839,27 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleCreateReflogResetMenu, Description: gui.Tr.SLocalize("viewResetOptions"), }, + { + ViewName: "branches", + Contexts: []string{SUB_COMMITS_CONTEXT_KEY}, + Key: gui.getKey("universal.goInto"), + Handler: gui.wrappedHandler(gui.handleViewSubCommitFiles), + Description: gui.Tr.SLocalize("viewCommitFiles"), + }, + { + ViewName: "branches", + Contexts: []string{SUB_COMMITS_CONTEXT_KEY}, + Key: gui.getKey("universal.select"), + Handler: gui.handleCheckoutSubCommit, + Description: gui.Tr.SLocalize("checkoutCommit"), + }, + { + ViewName: "branches", + Contexts: []string{SUB_COMMITS_CONTEXT_KEY}, + Key: gui.getKey("commits.viewResetOptions"), + Handler: gui.wrappedHandler(gui.handleCreateSubCommitResetMenu), + Description: gui.Tr.SLocalize("viewResetOptions"), + }, { ViewName: "stash", Key: gui.getKey("universal.goInto"), diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go index cebda6375..1687a26dd 100644 --- a/pkg/gui/layout.go +++ b/pkg/gui/layout.go @@ -338,7 +338,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { func (gui *Gui) onInitialViewsCreation() error { gui.setInitialViewContexts() - if err := gui.switchContext(gui.Contexts.Files.Context); err != nil { + if err := gui.switchContext(gui.defaultSideContext()); err != nil { return err } diff --git a/pkg/gui/list_context.go b/pkg/gui/list_context.go index ba2b41962..e152affd1 100644 --- a/pkg/gui/list_context.go +++ b/pkg/gui/list_context.go @@ -5,6 +5,14 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/presentation" ) +// TODO: if we don't end up using this, delete it +const ( + CONTAINS_NOTHING = iota + CONTAINS_COMMITS + CONTAINS_FILES + CONTAINS_BRANCHES +) + type ListContext struct { ViewName string ContextKey string @@ -21,12 +29,17 @@ type ListContext struct { Kind int ParentContext Context WindowName string + Contains int } type ListItem interface { ID() string } +func (lc *ListContext) GetContains() int { + return lc.Contains +} + func (lc *ListContext) SetWindowName(windowName string) { lc.WindowName = windowName } @@ -69,7 +82,6 @@ func (lc *ListContext) GetSelectedItem() ListItem { } func (lc *ListContext) GetSelectedItemId() string { - item := lc.GetSelectedItem() if item == nil { @@ -119,6 +131,13 @@ func (lc *ListContext) HandleFocus() error { return nil } + view, err := lc.Gui.g.View(lc.ViewName) + if err != nil { + return nil + } + + view.FocusPoint(0, lc.GetPanelState().GetSelectedLineIdx()) + if lc.Gui.inDiffMode() { return lc.Gui.renderDiff() } @@ -248,6 +267,7 @@ func (gui *Gui) menuListContext() *ListContext { Gui: gui, RendersToMainView: false, Kind: PERSISTENT_POPUP, + Contains: CONTAINS_NOTHING, // no GetDisplayStrings field because we do a custom render on menu creation } @@ -267,6 +287,7 @@ func (gui *Gui) filesListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetFileListDisplayStrings(gui.State.Files, gui.State.Diff.Ref) }, + Contains: CONTAINS_NOTHING, } } @@ -283,6 +304,7 @@ func (gui *Gui) branchesListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Diff.Ref) }, + Contains: CONTAINS_COMMITS, } } @@ -300,6 +322,7 @@ func (gui *Gui) remotesListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetRemoteListDisplayStrings(gui.State.Remotes, gui.State.Diff.Ref) }, + Contains: CONTAINS_BRANCHES, } } @@ -316,6 +339,7 @@ func (gui *Gui) remoteBranchesListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetRemoteBranchListDisplayStrings(gui.State.RemoteBranches, gui.State.Diff.Ref) }, + Contains: CONTAINS_COMMITS, } } @@ -332,6 +356,7 @@ func (gui *Gui) tagsListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetTagListDisplayStrings(gui.State.Tags, gui.State.Diff.Ref) }, + Contains: CONTAINS_COMMITS, } } @@ -349,6 +374,7 @@ func (gui *Gui) branchCommitsListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetCommitListDisplayStrings(gui.State.Commits, gui.State.ScreenMode != SCREEN_NORMAL, gui.cherryPickedCommitShaMap(), gui.State.Diff.Ref) }, + Contains: CONTAINS_FILES, } } @@ -365,6 +391,24 @@ func (gui *Gui) reflogCommitsListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetReflogCommitListDisplayStrings(gui.State.FilteredReflogCommits, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Diff.Ref) }, + Contains: CONTAINS_FILES, + } +} + +func (gui *Gui) subCommitsListContext() *ListContext { + return &ListContext{ + ViewName: "branches", + ContextKey: SUB_COMMITS_CONTEXT_KEY, + GetItemsLength: func() int { return len(gui.State.SubCommits) }, + GetPanelState: func() IListPanelState { return gui.State.Panels.SubCommits }, + OnFocus: gui.handleSubCommitSelect, + Gui: gui, + RendersToMainView: true, + Kind: SIDE_CONTEXT, + GetDisplayStrings: func() [][]string { + return presentation.GetCommitListDisplayStrings(gui.State.SubCommits, gui.State.ScreenMode != SCREEN_NORMAL, gui.cherryPickedCommitShaMap(), gui.State.Diff.Ref) + }, + Contains: CONTAINS_COMMITS, } } @@ -381,6 +425,7 @@ func (gui *Gui) stashListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetStashEntryListDisplayStrings(gui.State.StashEntries, gui.State.Diff.Ref) }, + Contains: CONTAINS_FILES, } } @@ -398,6 +443,7 @@ func (gui *Gui) commitFilesListContext() *ListContext { GetDisplayStrings: func() [][]string { return presentation.GetCommitFileListDisplayStrings(gui.State.CommitFiles, gui.State.Diff.Ref) }, + Contains: CONTAINS_NOTHING, } } @@ -411,6 +457,7 @@ func (gui *Gui) getListContexts() []*ListContext { gui.tagsListContext(), gui.branchCommitsListContext(), gui.reflogCommitsListContext(), + gui.subCommitsListContext(), gui.stashListContext(), gui.commitFilesListContext(), } diff --git a/pkg/gui/sub_commits_panel.go b/pkg/gui/sub_commits_panel.go new file mode 100644 index 000000000..b892364e6 --- /dev/null +++ b/pkg/gui/sub_commits_panel.go @@ -0,0 +1,113 @@ +package gui + +import ( + "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/commands" +) + +// list panel functions + +func (gui *Gui) getSelectedSubCommit() *commands.Commit { + selectedLine := gui.State.Panels.SubCommits.SelectedLineIdx + commits := gui.State.SubCommits + if selectedLine == -1 || len(commits) == 0 { + return nil + } + + return commits[selectedLine] +} + +func (gui *Gui) handleSubCommitSelect() error { + commit := gui.getSelectedSubCommit() + var task updateTask + if commit == nil { + task = gui.createRenderStringTask("No commits") + } else { + cmd := gui.OSCommand.ExecutableFromString( + gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.FilterPath), + ) + + task = gui.createRunPtyTask(cmd) + } + + return gui.refreshMain(refreshMainOpts{ + main: &viewUpdateOpts{ + title: "Commit", + task: task, + }, + }) +} + +func (gui *Gui) handleCheckoutSubCommit(g *gocui.Gui, v *gocui.View) error { + commit := gui.getSelectedSubCommit() + if commit == nil { + return nil + } + + err := gui.ask(askOpts{ + returnToView: gui.getCommitsView(), + returnFocusOnClose: true, + title: gui.Tr.SLocalize("checkoutCommit"), + prompt: gui.Tr.SLocalize("SureCheckoutThisCommit"), + handleConfirm: func() error { + return gui.handleCheckoutRef(commit.Sha, handleCheckoutRefOptions{}) + }, + }) + if err != nil { + return err + } + + gui.State.Panels.SubCommits.SelectedLineIdx = 0 + + return nil +} + +func (gui *Gui) handleCreateSubCommitResetMenu() error { + commit := gui.getSelectedSubCommit() + + return gui.createResetMenu(commit.Sha) +} + +func (gui *Gui) handleViewSubCommitFiles() error { + commit := gui.getSelectedSubCommit() + if commit == nil { + return nil + } + + return gui.switchToCommitFilesContext(commit.Sha, REF_TYPE_OTHER_COMMIT, gui.Contexts.SubCommits.Context, "branches") +} + +func (gui *Gui) switchToSubCommitsContext(refName string) error { + // need to populate my sub commits + builder := commands.NewCommitListBuilder(gui.Log, gui.GitCommand, gui.OSCommand, gui.Tr, gui.State.CherryPickedCommits) + + commits, err := builder.GetCommits( + commands.GetCommitsOptions{ + Limit: gui.State.Panels.Commits.LimitCommits, + FilterPath: gui.State.FilterPath, + IncludeRebaseCommits: false, + RefName: refName, + }, + ) + if err != nil { + return err + } + + gui.State.SubCommits = commits + gui.State.Panels.SubCommits.refName = refName + gui.State.Panels.SubCommits.SelectedLineIdx = 0 + gui.Contexts.SubCommits.Context.SetParentContext(gui.currentSideContext()) + + return gui.switchContext(gui.Contexts.SubCommits.Context) +} + +func (gui *Gui) handleSwitchToSubCommits() error { + currentContext := gui.currentSideContext() + if currentContext == nil { + return nil + } + + gui.Log.Warn(currentContext.GetKey()) + + return gui.switchToSubCommitsContext(currentContext.GetSelectedItemId()) +} diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index fb4356139..7f52790f8 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -1173,6 +1173,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "buildingPatch", Other: "building patch", + }, &i18n.Message{ + ID: "viewCommits", + Other: "view commits", }, ) }