mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Add a log menu option to filter the commit graph by refs
Sometimes you want the graph limited to a handful of branches or tags rather than just the checked-out branch or the entire --all graph. Add a "Filter graph by refs" entry to the log menu that prompts for space-separated ref names and passes them to git log as extra starting points alongside the current ref.
This commit is contained in:
parent
d8b07ee4f5
commit
f13d7b0d2e
|
|
@ -64,6 +64,10 @@ type GetCommitsOptions struct {
|
|||
RefForPushedStatus models.Ref // the ref to use for determining pushed/unpushed status
|
||||
// determines if we show the whole git graph i.e. pass the '--all' flag
|
||||
All bool
|
||||
// If non-empty, these refs are added to the log command as additional
|
||||
// starting points, so the graph shows them alongside RefName. Takes
|
||||
// precedence over All.
|
||||
FilterRefs []string
|
||||
// If non-empty, show divergence from this ref (left-right log)
|
||||
RefToShowDivergenceFrom string
|
||||
MainBranches *MainBranches
|
||||
|
|
@ -588,8 +592,9 @@ func (self *CommitLoader) getLogCmd(opts GetCommitsOptions) *oscommands.CmdObj {
|
|||
|
||||
cmdArgs := NewGitCmd("log").
|
||||
Arg(refSpec).
|
||||
Arg(opts.FilterRefs...).
|
||||
ArgIf(gitLogOrder != "default", "--"+gitLogOrder).
|
||||
ArgIf(opts.All, "--all").
|
||||
ArgIf(opts.All && len(opts.FilterRefs) == 0, "--all").
|
||||
Arg("--oneline").
|
||||
Arg(prettyFormat).
|
||||
Arg("--abbrev=40").
|
||||
|
|
|
|||
|
|
@ -149,6 +149,10 @@ type LocalCommitsViewModel struct {
|
|||
|
||||
// If this is true we'll use git log --all when fetching the commits.
|
||||
showWholeGitGraph bool
|
||||
|
||||
// If non-empty, the git graph is restricted to these refs (plus HEAD)
|
||||
// instead of showing just the current branch or the whole graph.
|
||||
filterRefs []string
|
||||
}
|
||||
|
||||
func NewLocalCommitsViewModel(getModel func() []*models.Commit, c *ContextCommon) *LocalCommitsViewModel {
|
||||
|
|
@ -243,6 +247,14 @@ func (self *LocalCommitsViewModel) GetShowWholeGitGraph() bool {
|
|||
return self.showWholeGitGraph
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) SetFilterRefs(refs []string) {
|
||||
self.filterRefs = refs
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) GetFilterRefs() []string {
|
||||
return self.filterRefs
|
||||
}
|
||||
|
||||
func (self *LocalCommitsViewModel) GetCommits() []*models.Commit {
|
||||
return self.getModel()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -707,6 +707,7 @@ type capturedCommitState struct {
|
|||
selectionRange *localCommitSelectionRange
|
||||
limitCommits bool
|
||||
showWholeGitGraph bool
|
||||
filterRefs []string
|
||||
filterPath string
|
||||
filterAuthor string
|
||||
mainBranches *git_commands.MainBranches
|
||||
|
|
@ -729,6 +730,7 @@ func (self *RefreshHelper) captureCommitsState(commitSelection types.CommitSelec
|
|||
selectionRange: selectionRange,
|
||||
limitCommits: self.c.Contexts().LocalCommits.GetLimitCommits(),
|
||||
showWholeGitGraph: self.c.Contexts().LocalCommits.GetShowWholeGitGraph(),
|
||||
filterRefs: self.c.Contexts().LocalCommits.GetFilterRefs(),
|
||||
filterPath: self.c.Modes().Filtering.GetPath(),
|
||||
filterAuthor: self.c.Modes().Filtering.GetAuthor(),
|
||||
mainBranches: self.c.Model().MainBranches,
|
||||
|
|
@ -805,6 +807,7 @@ func (self *RefreshHelper) refreshCommitsWithLimit(captured capturedCommitState,
|
|||
RefName: refName,
|
||||
RefForPushedStatus: checkedOutRef,
|
||||
All: captured.showWholeGitGraph,
|
||||
FilterRefs: captured.filterRefs,
|
||||
MainBranches: captured.mainBranches,
|
||||
HashPool: captured.hashPool,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -233,6 +233,40 @@ func (self *SuggestionsHelper) GetRefsSuggestionsFunc() func(string) []*types.Su
|
|||
return FilterFunc(refNames, self.c.UserConfig().Gui.UseFuzzySearch())
|
||||
}
|
||||
|
||||
// GetMultiRefsSuggestionsFunc is like GetRefsSuggestionsFunc, but for prompts
|
||||
// accepting multiple space-separated refs: suggestions fuzzily match the last
|
||||
// (possibly partial) ref in the input, and accepting a suggestion completes
|
||||
// that ref while keeping the ones already typed.
|
||||
func (self *SuggestionsHelper) GetMultiRefsSuggestionsFunc() func(string) []*types.Suggestion {
|
||||
remoteBranchNames := self.getRemoteBranchNames("/")
|
||||
localBranchNames := self.getBranchNames()
|
||||
tagNames := self.getTagNames()
|
||||
additionalRefNames := []string{"HEAD", "FETCH_HEAD", "MERGE_HEAD", "ORIG_HEAD"}
|
||||
|
||||
refNames := append(append(append(remoteBranchNames, localBranchNames...), tagNames...), additionalRefNames...)
|
||||
|
||||
return func(input string) []*types.Suggestion {
|
||||
prefix := ""
|
||||
lastToken := input
|
||||
if idx := strings.LastIndex(input, " "); idx != -1 {
|
||||
prefix = input[:idx+1]
|
||||
lastToken = input[idx+1:]
|
||||
}
|
||||
|
||||
matches := refNames
|
||||
if lastToken != "" {
|
||||
matches = utils.FilterStrings(lastToken, refNames, true)
|
||||
}
|
||||
|
||||
return lo.Map(matches, func(match string, _ int) *types.Suggestion {
|
||||
return &types.Suggestion{
|
||||
Value: prefix + match,
|
||||
Label: match,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SuggestionsHelper) GetAuthorsSuggestionsFunc() func(string) []*types.Suggestion {
|
||||
authors := lo.Map(lo.Values(self.c.Model().Authors), func(author *models.Author, _ int) string {
|
||||
return author.Combined()
|
||||
|
|
|
|||
|
|
@ -1270,6 +1270,28 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
|
|||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
Label: self.c.Tr.FilterGraphByRefs,
|
||||
Tooltip: self.c.Tr.FilterGraphByRefsTooltip,
|
||||
OnPress: func() error {
|
||||
self.c.Prompt(types.PromptOpts{
|
||||
Title: self.c.Tr.FilterGraphByRefsPrompt,
|
||||
InitialContent: strings.Join(self.context().GetFilterRefs(), " "),
|
||||
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetMultiRefsSuggestionsFunc(),
|
||||
AllowEmptyInput: true,
|
||||
HandleConfirm: func(response string) error {
|
||||
self.context().SetFilterRefs(strings.Fields(response))
|
||||
return self.c.WithWaitingStatus(self.c.Tr.LoadingCommits, func(gocui.Task) error {
|
||||
self.c.Refresh(
|
||||
types.RefreshOptions{Scope: []types.RefreshableView{types.COMMITS}},
|
||||
)
|
||||
return nil
|
||||
})
|
||||
},
|
||||
})
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Label: self.c.Tr.ShowGitGraph,
|
||||
Tooltip: self.c.Tr.ShowGitGraphTooltip,
|
||||
|
|
|
|||
|
|
@ -821,6 +821,9 @@ type TranslationSet struct {
|
|||
SortOrderPrompt string
|
||||
SortCommits string
|
||||
SortCommitsTooltip string
|
||||
FilterGraphByRefs string
|
||||
FilterGraphByRefsTooltip string
|
||||
FilterGraphByRefsPrompt string
|
||||
CantChangeContextSizeError string
|
||||
CantChangeRenameThresholdError string
|
||||
OpenCommitInBrowser string
|
||||
|
|
@ -1967,6 +1970,9 @@ func EnglishTranslationSet() *TranslationSet {
|
|||
SortBasedOnReflog: "(based on reflog)",
|
||||
SortCommits: "Commit sort order",
|
||||
SortCommitsTooltip: "Change the sort order of the commits in the commit log.\n\nThe default can be changed in the config file with the key 'git.log.sortOrder'.",
|
||||
FilterGraphByRefs: "Filter graph by refs",
|
||||
FilterGraphByRefsTooltip: "Restrict the git graph in the commits panel to the given refs (branches, tags, remote branches) in addition to the current branch. Leave empty to reset.",
|
||||
FilterGraphByRefsPrompt: "Refs to show in the graph (space-separated, empty to reset):",
|
||||
CantChangeContextSizeError: "Cannot change context while in patch building mode because we were too lazy to support it when releasing the feature. If you really want it, please let us know!",
|
||||
CantChangeRenameThresholdError: "Cannot change the rename similarity threshold while in patch building mode, because the custom patch can't cope with a rename turning into a delete and add underneath it.",
|
||||
OpenCommitInBrowser: "Open commit in browser",
|
||||
|
|
|
|||
Loading…
Reference in a new issue