mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-08-06 22:33:07 +02:00
Allow rewording or dropping commits in filtering mode (#4756)
- **PR Description** Rewording or dropping commits was disabled when filtering commits by path or author. This used to be necessary a long time ago for technical reasons, but these reasons went away with the merge of #2552, so enable them now. Technically we could enable a few more, but I chose not to because some might be surprising or confusing in filtering mode. For example, creating a fixup commit would work (shift-F), but the newly created commit might not show up if it doesn't match the filter. Similarly, pressing `f` to fixup a commit into its parent would work, but that parent commit might not be visible, so users might expect to be fixing up into the next visible commit. Fixes #2554.
This commit is contained in:
@ -55,10 +55,10 @@ func NewLocalCommitsController(
|
|||||||
func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
editCommitKey := opts.Config.Universal.Edit
|
editCommitKey := opts.Config.Universal.Edit
|
||||||
|
|
||||||
outsideFilterModeBindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.SquashDown),
|
Key: opts.GetKey(opts.Config.Commits.SquashDown),
|
||||||
Handler: self.withItemsRange(self.squashDown),
|
Handler: opts.Guards.OutsideFilterMode(self.withItemsRange(self.squashDown)),
|
||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.itemRangeSelected(
|
self.itemRangeSelected(
|
||||||
self.midRebaseCommandEnabled,
|
self.midRebaseCommandEnabled,
|
||||||
@ -71,7 +71,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsFixup),
|
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsFixup),
|
||||||
Handler: self.withItemsRange(self.fixup),
|
Handler: opts.Guards.OutsideFilterMode(self.withItemsRange(self.fixup)),
|
||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.itemRangeSelected(
|
self.itemRangeSelected(
|
||||||
self.midRebaseCommandEnabled,
|
self.midRebaseCommandEnabled,
|
||||||
@ -115,7 +115,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(editCommitKey),
|
Key: opts.GetKey(editCommitKey),
|
||||||
Handler: self.withItemsRange(self.edit),
|
Handler: opts.Guards.OutsideFilterMode(self.withItemsRange(self.edit)),
|
||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.itemRangeSelected(self.midRebaseCommandEnabled),
|
self.itemRangeSelected(self.midRebaseCommandEnabled),
|
||||||
),
|
),
|
||||||
@ -129,7 +129,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
// we're calling it 'quick-start interactive rebase' to differentiate it from
|
// we're calling it 'quick-start interactive rebase' to differentiate it from
|
||||||
// when you manually select the base commit.
|
// when you manually select the base commit.
|
||||||
Key: opts.GetKey(opts.Config.Commits.StartInteractiveRebase),
|
Key: opts.GetKey(opts.Config.Commits.StartInteractiveRebase),
|
||||||
Handler: self.quickStartInteractiveRebase,
|
Handler: opts.Guards.OutsideFilterMode(self.quickStartInteractiveRebase),
|
||||||
GetDisabledReason: self.require(self.notMidRebase(self.c.Tr.AlreadyRebasing), self.canFindCommitForQuickStart),
|
GetDisabledReason: self.require(self.notMidRebase(self.c.Tr.AlreadyRebasing), self.canFindCommitForQuickStart),
|
||||||
Description: self.c.Tr.QuickStartInteractiveRebase,
|
Description: self.c.Tr.QuickStartInteractiveRebase,
|
||||||
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.QuickStartInteractiveRebaseTooltip, map[string]string{
|
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.QuickStartInteractiveRebaseTooltip, map[string]string{
|
||||||
@ -138,7 +138,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.PickCommit),
|
Key: opts.GetKey(opts.Config.Commits.PickCommit),
|
||||||
Handler: self.withItems(self.pick),
|
Handler: opts.Guards.OutsideFilterMode(self.withItems(self.pick)),
|
||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.itemRangeSelected(self.pickEnabled),
|
self.itemRangeSelected(self.pickEnabled),
|
||||||
),
|
),
|
||||||
@ -147,7 +147,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
||||||
Handler: self.withItem(self.createFixupCommit),
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.createFixupCommit)),
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.CreateFixupCommit,
|
Description: self.c.Tr.CreateFixupCommit,
|
||||||
Tooltip: utils.ResolvePlaceholderString(
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
@ -159,7 +159,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.SquashAboveCommits),
|
Key: opts.GetKey(opts.Config.Commits.SquashAboveCommits),
|
||||||
Handler: self.squashFixupCommits,
|
Handler: opts.Guards.OutsideFilterMode(self.squashFixupCommits),
|
||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.notMidRebase(self.c.Tr.AlreadyRebasing),
|
self.notMidRebase(self.c.Tr.AlreadyRebasing),
|
||||||
),
|
),
|
||||||
@ -169,7 +169,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
||||||
Handler: self.withItemsRange(self.moveDown),
|
Handler: opts.Guards.OutsideFilterMode(self.withItemsRange(self.moveDown)),
|
||||||
GetDisabledReason: self.require(self.itemRangeSelected(
|
GetDisabledReason: self.require(self.itemRangeSelected(
|
||||||
self.midRebaseMoveCommandEnabled,
|
self.midRebaseMoveCommandEnabled,
|
||||||
self.canMoveDown,
|
self.canMoveDown,
|
||||||
@ -178,7 +178,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MoveUpCommit),
|
Key: opts.GetKey(opts.Config.Commits.MoveUpCommit),
|
||||||
Handler: self.withItemsRange(self.moveUp),
|
Handler: opts.Guards.OutsideFilterMode(self.withItemsRange(self.moveUp)),
|
||||||
GetDisabledReason: self.require(self.itemRangeSelected(
|
GetDisabledReason: self.require(self.itemRangeSelected(
|
||||||
self.midRebaseMoveCommandEnabled,
|
self.midRebaseMoveCommandEnabled,
|
||||||
self.canMoveUp,
|
self.canMoveUp,
|
||||||
@ -187,25 +187,18 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.PasteCommits),
|
Key: opts.GetKey(opts.Config.Commits.PasteCommits),
|
||||||
Handler: self.paste,
|
Handler: opts.Guards.OutsideFilterMode(self.paste),
|
||||||
GetDisabledReason: self.require(self.canPaste),
|
GetDisabledReason: self.require(self.canPaste),
|
||||||
Description: self.c.Tr.PasteCommits,
|
Description: self.c.Tr.PasteCommits,
|
||||||
DisplayStyle: &style.FgCyan,
|
DisplayStyle: &style.FgCyan,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsBaseForRebase),
|
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsBaseForRebase),
|
||||||
Handler: self.withItem(self.markAsBaseCommit),
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.markAsBaseCommit)),
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.MarkAsBaseCommit,
|
Description: self.c.Tr.MarkAsBaseCommit,
|
||||||
Tooltip: self.c.Tr.MarkAsBaseCommitTooltip,
|
Tooltip: self.c.Tr.MarkAsBaseCommitTooltip,
|
||||||
},
|
},
|
||||||
}
|
|
||||||
|
|
||||||
for _, binding := range outsideFilterModeBindings {
|
|
||||||
binding.Handler = opts.Guards.OutsideFilterMode(binding.Handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
bindings := append(outsideFilterModeBindings, []*types.Binding{
|
|
||||||
// overriding this navigation keybinding because we might need to load
|
// overriding this navigation keybinding because we might need to load
|
||||||
// more commits on demand
|
// more commits on demand
|
||||||
{
|
{
|
||||||
@ -251,7 +244,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
Tooltip: self.c.Tr.OpenLogMenuTooltip,
|
Tooltip: self.c.Tr.OpenLogMenuTooltip,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
}...)
|
}
|
||||||
|
|
||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package filter_by_path
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DropCommitInFilteringMode = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Filter commits by file path, then drop a commit",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {
|
||||||
|
},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
commonSetup(shell)
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
filterByFilterFile(t, keys)
|
||||||
|
|
||||||
|
t.Views().Commits().
|
||||||
|
IsFocused().
|
||||||
|
Lines(
|
||||||
|
Contains(`both files`).IsSelected(),
|
||||||
|
Contains(`only filterFile`),
|
||||||
|
).
|
||||||
|
Press(keys.Universal.Remove).
|
||||||
|
Tap(func() {
|
||||||
|
t.ExpectPopup().Confirmation().
|
||||||
|
Title(Equals("Drop commit")).
|
||||||
|
Content(Equals("Are you sure you want to drop the selected commit(s)?")).
|
||||||
|
Confirm()
|
||||||
|
}).
|
||||||
|
Lines(
|
||||||
|
Contains(`only filterFile`).IsSelected(),
|
||||||
|
).
|
||||||
|
Press(keys.Universal.Return).
|
||||||
|
Lines(
|
||||||
|
Contains(`none of the two`),
|
||||||
|
Contains(`only otherFile`),
|
||||||
|
Contains(`only filterFile`).IsSelected(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -15,26 +15,10 @@ var KeepSameCommitSelectedOnExit = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
commonSetup(shell)
|
commonSetup(shell)
|
||||||
},
|
},
|
||||||
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
t.Views().Commits().
|
filterByFilterFile(t, keys)
|
||||||
Focus().
|
|
||||||
Lines(
|
|
||||||
Contains(`none of the two`).IsSelected(),
|
|
||||||
Contains(`both files`),
|
|
||||||
Contains(`only otherFile`),
|
|
||||||
Contains(`only filterFile`),
|
|
||||||
).Press(keys.Universal.FilteringMenu).
|
|
||||||
Tap(func() {
|
|
||||||
t.ExpectPopup().Menu().
|
|
||||||
Title(Equals("Filtering")).
|
|
||||||
Select(Contains("Enter path to filter by")).
|
|
||||||
Confirm()
|
|
||||||
|
|
||||||
t.ExpectPopup().Prompt().
|
t.Views().Commits().
|
||||||
Title(Equals("Enter path:")).
|
IsFocused().
|
||||||
Type("filterF").
|
|
||||||
SuggestionLines(Equals("filterFile")).
|
|
||||||
ConfirmFirstSuggestion()
|
|
||||||
}).
|
|
||||||
Lines(
|
Lines(
|
||||||
Contains(`both files`).IsSelected(),
|
Contains(`both files`).IsSelected(),
|
||||||
Contains(`only filterFile`),
|
Contains(`only filterFile`),
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package filter_by_path
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var RewordCommitInFilteringMode = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Filter commits by file path, then reword a commit",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {
|
||||||
|
},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
commonSetup(shell)
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
filterByFilterFile(t, keys)
|
||||||
|
|
||||||
|
t.Views().Commits().
|
||||||
|
IsFocused().
|
||||||
|
Lines(
|
||||||
|
Contains(`both files`).IsSelected(),
|
||||||
|
Contains(`only filterFile`),
|
||||||
|
).
|
||||||
|
SelectNextItem().
|
||||||
|
Press(keys.Commits.RenameCommit).
|
||||||
|
Tap(func() {
|
||||||
|
t.ExpectPopup().CommitMessagePanel().
|
||||||
|
Clear().
|
||||||
|
Type("new message").
|
||||||
|
Confirm()
|
||||||
|
}).
|
||||||
|
Lines(
|
||||||
|
Contains(`both files`),
|
||||||
|
Contains(`new message`).IsSelected(),
|
||||||
|
).
|
||||||
|
Press(keys.Universal.Return).
|
||||||
|
Lines(
|
||||||
|
Contains(`none of the two`),
|
||||||
|
Contains(`both files`),
|
||||||
|
Contains(`only otherFile`),
|
||||||
|
Contains(`new message`).IsSelected(),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -1,6 +1,7 @@
|
|||||||
package filter_by_path
|
package filter_by_path
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -17,6 +18,28 @@ func commonSetup(shell *Shell) {
|
|||||||
shell.EmptyCommit("none of the two")
|
shell.EmptyCommit("none of the two")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func filterByFilterFile(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
t.Views().Commits().
|
||||||
|
Focus().
|
||||||
|
Lines(
|
||||||
|
Contains(`none of the two`).IsSelected(),
|
||||||
|
Contains(`both files`),
|
||||||
|
Contains(`only otherFile`),
|
||||||
|
Contains(`only filterFile`),
|
||||||
|
).
|
||||||
|
Press(keys.Universal.FilteringMenu)
|
||||||
|
|
||||||
|
t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Filtering")).
|
||||||
|
Select(Contains("Enter path to filter by")).
|
||||||
|
Confirm()
|
||||||
|
t.ExpectPopup().Prompt().
|
||||||
|
Title(Equals("Enter path:")).
|
||||||
|
Type("filterF").
|
||||||
|
SuggestionLines(Equals("filterFile")).
|
||||||
|
ConfirmFirstSuggestion()
|
||||||
|
}
|
||||||
|
|
||||||
func postFilterTest(t *TestDriver) {
|
func postFilterTest(t *TestDriver) {
|
||||||
t.Views().Information().Content(Contains("Filtering by 'filterFile'"))
|
t.Views().Information().Content(Contains("Filtering by 'filterFile'"))
|
||||||
|
|
||||||
|
@ -233,7 +233,9 @@ var tests = []*components.IntegrationTest{
|
|||||||
filter_by_author.SelectAuthor,
|
filter_by_author.SelectAuthor,
|
||||||
filter_by_author.TypeAuthor,
|
filter_by_author.TypeAuthor,
|
||||||
filter_by_path.CliArg,
|
filter_by_path.CliArg,
|
||||||
|
filter_by_path.DropCommitInFilteringMode,
|
||||||
filter_by_path.KeepSameCommitSelectedOnExit,
|
filter_by_path.KeepSameCommitSelectedOnExit,
|
||||||
|
filter_by_path.RewordCommitInFilteringMode,
|
||||||
filter_by_path.SelectFile,
|
filter_by_path.SelectFile,
|
||||||
filter_by_path.ShowDiffsForRenamedFile,
|
filter_by_path.ShowDiffsForRenamedFile,
|
||||||
filter_by_path.TypeFile,
|
filter_by_path.TypeFile,
|
||||||
|
Reference in New Issue
Block a user