Skip to content

Commit 8ed29f2

Browse files
Merge pull request #2390 from seand52/revamp-commit-message
2 parents 826128a + 9adbef4 commit 8ed29f2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1051
-257
lines changed

docs/Config.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ keybinding:
171171
diffingMenu-alt: '<c-e>' # deprecated
172172
copyToClipboard: '<c-o>'
173173
submitEditorText: '<enter>'
174-
appendNewline: '<a-enter>'
175174
extrasMenu: '@'
176175
toggleWhitespaceInDiffView: '<c-w>'
177176
increaseContextInDiffView: '}'

pkg/cheatsheet/generate.go

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,33 +87,34 @@ func writeString(file *os.File, str string) {
8787

8888
func localisedTitle(tr *i18n.TranslationSet, str string) string {
8989
contextTitleMap := map[string]string{
90-
"global": tr.GlobalTitle,
91-
"navigation": tr.NavigationTitle,
92-
"branches": tr.BranchesTitle,
93-
"localBranches": tr.LocalBranchesTitle,
94-
"files": tr.FilesTitle,
95-
"status": tr.StatusTitle,
96-
"submodules": tr.SubmodulesTitle,
97-
"subCommits": tr.SubCommitsTitle,
98-
"remoteBranches": tr.RemoteBranchesTitle,
99-
"remotes": tr.RemotesTitle,
100-
"reflogCommits": tr.ReflogCommitsTitle,
101-
"tags": tr.TagsTitle,
102-
"commitFiles": tr.CommitFilesTitle,
103-
"commitMessage": tr.CommitMessageTitle,
104-
"commits": tr.CommitsTitle,
105-
"confirmation": tr.ConfirmationTitle,
106-
"information": tr.InformationTitle,
107-
"main": tr.NormalTitle,
108-
"patchBuilding": tr.PatchBuildingTitle,
109-
"mergeConflicts": tr.MergingTitle,
110-
"staging": tr.StagingTitle,
111-
"menu": tr.MenuTitle,
112-
"search": tr.SearchTitle,
113-
"secondary": tr.SecondaryTitle,
114-
"stash": tr.StashTitle,
115-
"suggestions": tr.SuggestionsCheatsheetTitle,
116-
"extras": tr.ExtrasTitle,
90+
"global": tr.GlobalTitle,
91+
"navigation": tr.NavigationTitle,
92+
"branches": tr.BranchesTitle,
93+
"localBranches": tr.LocalBranchesTitle,
94+
"files": tr.FilesTitle,
95+
"status": tr.StatusTitle,
96+
"submodules": tr.SubmodulesTitle,
97+
"subCommits": tr.SubCommitsTitle,
98+
"remoteBranches": tr.RemoteBranchesTitle,
99+
"remotes": tr.RemotesTitle,
100+
"reflogCommits": tr.ReflogCommitsTitle,
101+
"tags": tr.TagsTitle,
102+
"commitFiles": tr.CommitFilesTitle,
103+
"commitMessage": tr.CommitMessageTitle,
104+
"commitDescription": tr.CommitDescriptionTitle,
105+
"commits": tr.CommitsTitle,
106+
"confirmation": tr.ConfirmationTitle,
107+
"information": tr.InformationTitle,
108+
"main": tr.NormalTitle,
109+
"patchBuilding": tr.PatchBuildingTitle,
110+
"mergeConflicts": tr.MergingTitle,
111+
"staging": tr.StagingTitle,
112+
"menu": tr.MenuTitle,
113+
"search": tr.SearchTitle,
114+
"secondary": tr.SecondaryTitle,
115+
"stash": tr.StashTitle,
116+
"suggestions": tr.SuggestionsCheatsheetTitle,
117+
"extras": tr.ExtrasTitle,
117118
}
118119

119120
title, ok := contextTitleMap[str]

pkg/commands/git_commands/commit.go

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
99
)
1010

11+
var ErrInvalidCommitIndex = errors.New("invalid commit index")
12+
1113
type CommitCommands struct {
1214
*GitCommon
1315
}
@@ -18,11 +20,6 @@ func NewCommitCommands(gitCommon *GitCommon) *CommitCommands {
1820
}
1921
}
2022

21-
// RewordLastCommit rewords the topmost commit with the given message
22-
func (self *CommitCommands) RewordLastCommit(message string) error {
23-
return self.cmd.New("git commit --allow-empty --amend --only -m " + self.cmd.Quote(message)).Run()
24-
}
25-
2623
// ResetAuthor resets the author of the topmost commit
2724
func (self *CommitCommands) ResetAuthor() error {
2825
return self.cmd.New("git commit --allow-empty --only --no-edit --amend --reset-author").Run()
@@ -45,19 +42,31 @@ func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars [
4542
}
4643

4744
func (self *CommitCommands) CommitCmdObj(message string) oscommands.ICmdObj {
48-
splitMessage := strings.Split(message, "\n")
49-
lineArgs := ""
50-
for _, line := range splitMessage {
51-
lineArgs += fmt.Sprintf(" -m %s", self.cmd.Quote(line))
52-
}
45+
messageArgs := self.commitMessageArgs(message)
5346

5447
skipHookPrefix := self.UserConfig.Git.SkipHookPrefix
5548
noVerifyFlag := ""
5649
if skipHookPrefix != "" && strings.HasPrefix(message, skipHookPrefix) {
5750
noVerifyFlag = " --no-verify"
5851
}
5952

60-
return self.cmd.New(fmt.Sprintf("git commit%s%s%s", noVerifyFlag, self.signoffFlag(), lineArgs))
53+
return self.cmd.New(fmt.Sprintf("git commit%s%s%s", noVerifyFlag, self.signoffFlag(), messageArgs))
54+
}
55+
56+
// RewordLastCommit rewords the topmost commit with the given message
57+
func (self *CommitCommands) RewordLastCommit(message string) error {
58+
messageArgs := self.commitMessageArgs(message)
59+
return self.cmd.New(fmt.Sprintf("git commit --allow-empty --amend --only%s", messageArgs)).Run()
60+
}
61+
62+
func (self *CommitCommands) commitMessageArgs(message string) string {
63+
msg, description, _ := strings.Cut(message, "\n")
64+
descriptionArgs := ""
65+
if description != "" {
66+
descriptionArgs = fmt.Sprintf(" -m %s", self.cmd.Quote(description))
67+
}
68+
69+
return fmt.Sprintf(" -m %s%s", self.cmd.Quote(msg), descriptionArgs)
6170
}
6271

6372
// runs git commit without the -m argument meaning it will invoke the user's editor
@@ -178,3 +187,13 @@ func (self *CommitCommands) RevertMerge(sha string, parentNumber int) error {
178187
func (self *CommitCommands) CreateFixupCommit(sha string) error {
179188
return self.cmd.New(fmt.Sprintf("git commit --fixup=%s", sha)).Run()
180189
}
190+
191+
// a value of 0 means the head commit, 1 is the parent commit, etc
192+
func (self *CommitCommands) GetCommitMessageFromHistory(value int) (string, error) {
193+
hash, _ := self.cmd.New(fmt.Sprintf("git log -1 --skip=%d --pretty=%%H", value)).DontLog().RunWithOutput()
194+
formattedHash := strings.TrimSpace(hash)
195+
if len(formattedHash) == 0 {
196+
return "", ErrInvalidCommitIndex
197+
}
198+
return self.GetCommitMessage(formattedHash)
199+
}

pkg/commands/git_commands/commit_test.go

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,32 @@ import (
99
)
1010

1111
func TestCommitRewordCommit(t *testing.T) {
12-
runner := oscommands.NewFakeRunner(t).
13-
ExpectGitArgs([]string{"commit", "--allow-empty", "--amend", "--only", "-m", "test"}, "", nil)
14-
instance := buildCommitCommands(commonDeps{runner: runner})
12+
type scenario struct {
13+
testName string
14+
runner *oscommands.FakeCmdObjRunner
15+
input string
16+
}
17+
scenarios := []scenario{
18+
{
19+
"Single line reword",
20+
oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"commit", "--allow-empty", "--amend", "--only", "-m", "test"}, "", nil),
21+
"test",
22+
},
23+
{
24+
"Multi line reword",
25+
oscommands.NewFakeRunner(t).ExpectGitArgs([]string{"commit", "--allow-empty", "--amend", "--only", "-m", "test", "-m", "line 2\nline 3"}, "", nil),
26+
"test\nline 2\nline 3",
27+
},
28+
}
29+
for _, s := range scenarios {
30+
s := s
31+
t.Run(s.testName, func(t *testing.T) {
32+
instance := buildCommitCommands(commonDeps{runner: s.runner})
1533

16-
assert.NoError(t, instance.RewordLastCommit("test"))
17-
runner.CheckForMissingCalls()
34+
assert.NoError(t, instance.RewordLastCommit(s.input))
35+
s.runner.CheckForMissingCalls()
36+
})
37+
}
1838
}
1939

2040
func TestCommitResetToCommit(t *testing.T) {
@@ -274,3 +294,40 @@ Merge pull request #1750 from mark2185/fix-issue-template
274294
})
275295
}
276296
}
297+
298+
func TestGetCommitMessageFromHistory(t *testing.T) {
299+
type scenario struct {
300+
testName string
301+
runner *oscommands.FakeCmdObjRunner
302+
test func(string, error)
303+
}
304+
scenarios := []scenario{
305+
{
306+
"Empty message",
307+
oscommands.NewFakeRunner(t).Expect("git log -1 --skip=2 --pretty=%H", "", nil).Expect("git rev-list --format=%B --max-count=1 ", "", nil),
308+
func(output string, err error) {
309+
assert.Error(t, err)
310+
},
311+
},
312+
{
313+
"Default case to retrieve a commit in history",
314+
oscommands.NewFakeRunner(t).Expect("git log -1 --skip=2 --pretty=%H", "sha3 \n", nil).Expect("git rev-list --format=%B --max-count=1 sha3", `commit sha3
315+
use generics to DRY up context code`, nil),
316+
func(output string, err error) {
317+
assert.NoError(t, err)
318+
assert.Equal(t, "use generics to DRY up context code", output)
319+
},
320+
},
321+
}
322+
323+
for _, s := range scenarios {
324+
s := s
325+
t.Run(s.testName, func(t *testing.T) {
326+
instance := buildCommitCommands(commonDeps{runner: s.runner})
327+
328+
output, err := instance.GetCommitMessageFromHistory(2)
329+
330+
s.test(output, err)
331+
})
332+
}
333+
}

pkg/config/user_config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ type KeybindingUniversalConfig struct {
165165
Select string `yaml:"select"`
166166
GoInto string `yaml:"goInto"`
167167
Confirm string `yaml:"confirm"`
168+
ConfirmInEditor string `yaml:"confirmInEditor"`
168169
Remove string `yaml:"remove"`
169170
New string `yaml:"new"`
170171
Edit string `yaml:"edit"`
@@ -193,7 +194,6 @@ type KeybindingUniversalConfig struct {
193194
CopyToClipboard string `yaml:"copyToClipboard"`
194195
OpenRecentRepos string `yaml:"openRecentRepos"`
195196
SubmitEditorText string `yaml:"submitEditorText"`
196-
AppendNewline string `yaml:"appendNewline"`
197197
ExtrasMenu string `yaml:"extrasMenu"`
198198
ToggleWhitespaceInDiffView string `yaml:"toggleWhitespaceInDiffView"`
199199
IncreaseContextInDiffView string `yaml:"increaseContextInDiffView"`
@@ -492,6 +492,7 @@ func GetDefaultConfig() *UserConfig {
492492
Select: "<space>",
493493
GoInto: "<enter>",
494494
Confirm: "<enter>",
495+
ConfirmInEditor: "<a-enter>",
495496
Remove: "d",
496497
New: "n",
497498
Edit: "e",
@@ -520,7 +521,6 @@ func GetDefaultConfig() *UserConfig {
520521
DiffingMenuAlt: "<c-e>",
521522
CopyToClipboard: "<c-o>",
522523
SubmitEditorText: "<enter>",
523-
AppendNewline: "<a-enter>",
524524
ExtrasMenu: "@",
525525
ToggleWhitespaceInDiffView: "<c-w>",
526526
IncreaseContextInDiffView: "}",

pkg/gui/commit_message_panel.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ func (gui *Gui) handleCommitMessageFocused() error {
1515
map[string]string{
1616
"keyBindClose": keybindings.Label(gui.c.UserConfig.Keybinding.Universal.Return),
1717
"keyBindConfirm": keybindings.Label(gui.c.UserConfig.Keybinding.Universal.Confirm),
18-
"keyBindNewLine": keybindings.Label(gui.c.UserConfig.Keybinding.Universal.AppendNewline),
1918
},
2019
)
2120

pkg/gui/confirmation_panel.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,11 @@ func (gui *Gui) getMessageHeight(wrap bool, message string, width int) int {
7878
return lineCount
7979
}
8080

81-
func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, int, int, int) {
82-
panelWidth := gui.getConfirmationPanelWidth()
83-
panelHeight := gui.getMessageHeight(wrap, prompt, panelWidth)
84-
return gui.getConfirmationPanelDimensionsAux(panelWidth, panelHeight)
81+
func (gui *Gui) getPopupPanelDimensionsForContentHeight(panelWidth, contentHeight int) (int, int, int, int) {
82+
return gui.getPopupPanelDimensionsAux(panelWidth, contentHeight)
8583
}
8684

87-
func (gui *Gui) getConfirmationPanelDimensionsForContentHeight(panelWidth, contentHeight int) (int, int, int, int) {
88-
return gui.getConfirmationPanelDimensionsAux(panelWidth, contentHeight)
89-
}
90-
91-
func (gui *Gui) getConfirmationPanelDimensionsAux(panelWidth int, panelHeight int) (int, int, int, int) {
85+
func (gui *Gui) getPopupPanelDimensionsAux(panelWidth int, panelHeight int) (int, int, int, int) {
9286
width, height := gui.g.Size()
9387
if panelHeight > height*3/4 {
9488
panelHeight = height * 3 / 4
@@ -186,7 +180,7 @@ func (gui *Gui) createPopupPanel(ctx context.Context, opts types.CreatePopupPane
186180
}
187181
confirmationView := gui.Views.Confirmation
188182
confirmationView.Editable = opts.Editable
189-
confirmationView.Editor = gocui.EditorFunc(gui.defaultEditor)
183+
confirmationView.Editor = gocui.EditorFunc(gui.promptEditor)
190184

191185
if opts.Editable {
192186
textArea := confirmationView.TextArea

pkg/gui/context.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"github.com/jesseduffield/gocui"
1010
"github.com/jesseduffield/lazygit/pkg/gui/context"
1111
"github.com/jesseduffield/lazygit/pkg/gui/types"
12+
"github.com/samber/lo"
1213
)
1314

1415
// This file is for the management of contexts. There is a context stack such that
@@ -146,6 +147,36 @@ func (gui *Gui) popContext() error {
146147
return gui.activateContext(newContext, types.OnFocusOpts{})
147148
}
148149

150+
func (gui *Gui) removeContexts(contextsToRemove []types.Context) error {
151+
gui.State.ContextManager.Lock()
152+
153+
if len(gui.State.ContextManager.ContextStack) == 1 {
154+
gui.State.ContextManager.Unlock()
155+
return nil
156+
}
157+
158+
rest := lo.Filter(gui.State.ContextManager.ContextStack, func(context types.Context, _ int) bool {
159+
for _, contextToRemove := range contextsToRemove {
160+
if context.GetKey() == contextToRemove.GetKey() {
161+
return false
162+
}
163+
}
164+
return true
165+
})
166+
gui.State.ContextManager.ContextStack = rest
167+
contextToActivate := rest[len(rest)-1]
168+
gui.State.ContextManager.Unlock()
169+
170+
for _, context := range contextsToRemove {
171+
if err := gui.deactivateContext(context, types.OnFocusLostOpts{NewContextKey: contextToActivate.GetKey()}); err != nil {
172+
return err
173+
}
174+
}
175+
176+
// activate the item at the top of the stack
177+
return gui.activateContext(contextToActivate, types.OnFocusOpts{})
178+
}
179+
149180
func (gui *Gui) deactivateContext(c types.Context, opts types.OnFocusLostOpts) error {
150181
view, _ := gui.g.View(c.GetViewName())
151182

0 commit comments

Comments
 (0)