mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-12 04:45:47 +02:00
Add Co-Author support to new commits (#3097)
- Adds Co-Author support to commit menu (`<C-o>` by default) - `e` Opens up the commit message in your editor - `c` Lets you add a co author to your commit - Cleans up and amend commit attribute menu related code
This commit is contained in:
commit
d12ceeb1ec
16 changed files with 278 additions and 37 deletions
|
@ -254,6 +254,7 @@ keybinding:
|
||||||
moveDownCommit: '<c-j>' # move commit down one
|
moveDownCommit: '<c-j>' # move commit down one
|
||||||
moveUpCommit: '<c-k>' # move commit up one
|
moveUpCommit: '<c-k>' # move commit up one
|
||||||
amendToCommit: 'A'
|
amendToCommit: 'A'
|
||||||
|
amendAttributeMenu: 'a'
|
||||||
pickCommit: 'p' # pick commit (when mid-rebase)
|
pickCommit: 'p' # pick commit (when mid-rebase)
|
||||||
revertCommit: 't'
|
revertCommit: 't'
|
||||||
cherryPickCopy: 'C'
|
cherryPickCopy: 'C'
|
||||||
|
@ -276,6 +277,12 @@ keybinding:
|
||||||
init: 'i'
|
init: 'i'
|
||||||
update: 'u'
|
update: 'u'
|
||||||
bulkMenu: 'b'
|
bulkMenu: 'b'
|
||||||
|
commitMessage:
|
||||||
|
commitMenu: '<c-o>'
|
||||||
|
amendAttribute:
|
||||||
|
addCoAuthor: 'c'
|
||||||
|
resetAuthor: 'a'
|
||||||
|
setAuthor: 'A'
|
||||||
```
|
```
|
||||||
|
|
||||||
## Platform Defaults
|
## Platform Defaults
|
||||||
|
|
|
@ -39,13 +39,13 @@ func (self *CommitCommands) SetAuthor(value string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a commit's coauthor using Github/Gitlab Co-authored-by metadata. Value is expected to be of the form 'Name <Email>'
|
// Add a commit's coauthor using Github/Gitlab Co-authored-by metadata. Value is expected to be of the form 'Name <Email>'
|
||||||
func (self *CommitCommands) AddCoAuthor(sha string, value string) error {
|
func (self *CommitCommands) AddCoAuthor(sha string, author string) error {
|
||||||
message, err := self.GetCommitMessage(sha)
|
message, err := self.GetCommitMessage(sha)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
message = message + fmt.Sprintf("\nCo-authored-by: %s", value)
|
message = AddCoAuthorToMessage(message, author)
|
||||||
|
|
||||||
cmdArgs := NewGitCmd("commit").
|
cmdArgs := NewGitCmd("commit").
|
||||||
Arg("--allow-empty", "--amend", "--only", "-m", message).
|
Arg("--allow-empty", "--amend", "--only", "-m", message).
|
||||||
|
@ -54,6 +54,25 @@ func (self *CommitCommands) AddCoAuthor(sha string, value string) error {
|
||||||
return self.cmd.New(cmdArgs).Run()
|
return self.cmd.New(cmdArgs).Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AddCoAuthorToMessage(message string, author string) string {
|
||||||
|
subject, body, _ := strings.Cut(message, "\n")
|
||||||
|
|
||||||
|
return strings.TrimSpace(subject) + "\n\n" + AddCoAuthorToDescription(strings.TrimSpace(body), author)
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddCoAuthorToDescription(description string, author string) string {
|
||||||
|
if description != "" {
|
||||||
|
lines := strings.Split(description, "\n")
|
||||||
|
if strings.HasPrefix(lines[len(lines)-1], "Co-authored-by:") {
|
||||||
|
description += "\n"
|
||||||
|
} else {
|
||||||
|
description += "\n\n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return description + fmt.Sprintf("Co-authored-by: %s", author)
|
||||||
|
}
|
||||||
|
|
||||||
// ResetToCommit reset to commit
|
// ResetToCommit reset to commit
|
||||||
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
|
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
|
||||||
cmdArgs := NewGitCmd("reset").Arg("--"+strength, sha).ToArgv()
|
cmdArgs := NewGitCmd("reset").Arg("--"+strength, sha).ToArgv()
|
||||||
|
|
|
@ -333,3 +333,70 @@ func TestGetCommitMessageFromHistory(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddCoAuthorToMessage(t *testing.T) {
|
||||||
|
scenarios := []struct {
|
||||||
|
name string
|
||||||
|
message string
|
||||||
|
expectedResult string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// This never happens, I think it isn't possible to create a commit
|
||||||
|
// with an empty message. Just including it for completeness.
|
||||||
|
name: "Empty message",
|
||||||
|
message: "",
|
||||||
|
expectedResult: "\n\nCo-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Just a subject, no body",
|
||||||
|
message: "Subject",
|
||||||
|
expectedResult: "Subject\n\nCo-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Subject and body",
|
||||||
|
message: "Subject\n\nBody",
|
||||||
|
expectedResult: "Subject\n\nBody\n\nCo-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Body already ending with a Co-authored-by line",
|
||||||
|
message: "Subject\n\nBody\n\nCo-authored-by: Jane Smith <jane@smith.com>",
|
||||||
|
expectedResult: "Subject\n\nBody\n\nCo-authored-by: Jane Smith <jane@smith.com>\nCo-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, s := range scenarios {
|
||||||
|
t.Run(s.name, func(t *testing.T) {
|
||||||
|
result := AddCoAuthorToMessage(s.message, "John Doe <john@doe.com>")
|
||||||
|
assert.Equal(t, s.expectedResult, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddCoAuthorToDescription(t *testing.T) {
|
||||||
|
scenarios := []struct {
|
||||||
|
name string
|
||||||
|
description string
|
||||||
|
expectedResult string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Empty description",
|
||||||
|
description: "",
|
||||||
|
expectedResult: "Co-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Non-empty description",
|
||||||
|
description: "Body",
|
||||||
|
expectedResult: "Body\n\nCo-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Description already ending with a Co-authored-by line",
|
||||||
|
description: "Body\n\nCo-authored-by: Jane Smith <jane@smith.com>",
|
||||||
|
expectedResult: "Body\n\nCo-authored-by: Jane Smith <jane@smith.com>\nCo-authored-by: John Doe <john@doe.com>",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, s := range scenarios {
|
||||||
|
t.Run(s.name, func(t *testing.T) {
|
||||||
|
result := AddCoAuthorToDescription(s.description, "John Doe <john@doe.com>")
|
||||||
|
assert.Equal(t, s.expectedResult, result)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -281,17 +281,18 @@ type UpdateConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeybindingConfig struct {
|
type KeybindingConfig struct {
|
||||||
Universal KeybindingUniversalConfig `yaml:"universal"`
|
Universal KeybindingUniversalConfig `yaml:"universal"`
|
||||||
Status KeybindingStatusConfig `yaml:"status"`
|
Status KeybindingStatusConfig `yaml:"status"`
|
||||||
Files KeybindingFilesConfig `yaml:"files"`
|
Files KeybindingFilesConfig `yaml:"files"`
|
||||||
Branches KeybindingBranchesConfig `yaml:"branches"`
|
Branches KeybindingBranchesConfig `yaml:"branches"`
|
||||||
Worktrees KeybindingWorktreesConfig `yaml:"worktrees"`
|
Worktrees KeybindingWorktreesConfig `yaml:"worktrees"`
|
||||||
Commits KeybindingCommitsConfig `yaml:"commits"`
|
Commits KeybindingCommitsConfig `yaml:"commits"`
|
||||||
Stash KeybindingStashConfig `yaml:"stash"`
|
AmendAttribute KeybindingAmendAttributeConfig `yaml:"amendAttribute"`
|
||||||
CommitFiles KeybindingCommitFilesConfig `yaml:"commitFiles"`
|
Stash KeybindingStashConfig `yaml:"stash"`
|
||||||
Main KeybindingMainConfig `yaml:"main"`
|
CommitFiles KeybindingCommitFilesConfig `yaml:"commitFiles"`
|
||||||
Submodules KeybindingSubmodulesConfig `yaml:"submodules"`
|
Main KeybindingMainConfig `yaml:"main"`
|
||||||
CommitMessage KeybindingCommitMessageConfig `yaml:"commitMessage"`
|
Submodules KeybindingSubmodulesConfig `yaml:"submodules"`
|
||||||
|
CommitMessage KeybindingCommitMessageConfig `yaml:"commitMessage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// damn looks like we have some inconsistencies here with -alt and -alt1
|
// damn looks like we have some inconsistencies here with -alt and -alt1
|
||||||
|
@ -440,6 +441,12 @@ type KeybindingCommitsConfig struct {
|
||||||
StartInteractiveRebase string `yaml:"startInteractiveRebase"`
|
StartInteractiveRebase string `yaml:"startInteractiveRebase"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type KeybindingAmendAttributeConfig struct {
|
||||||
|
ResetAuthor string `yaml:"resetAuthor"`
|
||||||
|
SetAuthor string `yaml:"setAuthor"`
|
||||||
|
AddCoAuthor string `yaml:"addCoAuthor"`
|
||||||
|
}
|
||||||
|
|
||||||
type KeybindingStashConfig struct {
|
type KeybindingStashConfig struct {
|
||||||
PopStash string `yaml:"popStash"`
|
PopStash string `yaml:"popStash"`
|
||||||
RenameStash string `yaml:"renameStash"`
|
RenameStash string `yaml:"renameStash"`
|
||||||
|
@ -462,7 +469,7 @@ type KeybindingSubmodulesConfig struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeybindingCommitMessageConfig struct {
|
type KeybindingCommitMessageConfig struct {
|
||||||
SwitchToEditor string `yaml:"switchToEditor"`
|
CommitMenu string `yaml:"commitMenu"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// OSConfig contains config on the level of the os
|
// OSConfig contains config on the level of the os
|
||||||
|
@ -836,6 +843,11 @@ func GetDefaultConfig() *UserConfig {
|
||||||
ViewBisectOptions: "b",
|
ViewBisectOptions: "b",
|
||||||
StartInteractiveRebase: "i",
|
StartInteractiveRebase: "i",
|
||||||
},
|
},
|
||||||
|
AmendAttribute: KeybindingAmendAttributeConfig{
|
||||||
|
ResetAuthor: "a",
|
||||||
|
SetAuthor: "A",
|
||||||
|
AddCoAuthor: "c",
|
||||||
|
},
|
||||||
Stash: KeybindingStashConfig{
|
Stash: KeybindingStashConfig{
|
||||||
PopStash: "g",
|
PopStash: "g",
|
||||||
RenameStash: "r",
|
RenameStash: "r",
|
||||||
|
@ -854,7 +866,7 @@ func GetDefaultConfig() *UserConfig {
|
||||||
BulkMenu: "b",
|
BulkMenu: "b",
|
||||||
},
|
},
|
||||||
CommitMessage: KeybindingCommitMessageConfig{
|
CommitMessage: KeybindingCommitMessageConfig{
|
||||||
SwitchToEditor: "<c-o>",
|
CommitMenu: "<c-o>",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
OS: OSConfig{},
|
OS: OSConfig{},
|
||||||
|
|
|
@ -115,8 +115,8 @@ func (self *CommitMessageContext) SetPanelState(
|
||||||
subtitleTemplate := lo.Ternary(onSwitchToEditor != nil, self.c.Tr.CommitDescriptionSubTitle, self.c.Tr.CommitDescriptionSubTitleNoSwitch)
|
subtitleTemplate := lo.Ternary(onSwitchToEditor != nil, self.c.Tr.CommitDescriptionSubTitle, self.c.Tr.CommitDescriptionSubTitleNoSwitch)
|
||||||
self.c.Views().CommitDescription.Subtitle = utils.ResolvePlaceholderString(subtitleTemplate,
|
self.c.Views().CommitDescription.Subtitle = utils.ResolvePlaceholderString(subtitleTemplate,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"togglePanelKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.Universal.TogglePanel),
|
"togglePanelKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.Universal.TogglePanel),
|
||||||
"switchToEditorKeyBinding": keybindings.Label(self.c.UserConfig.Keybinding.CommitMessage.SwitchToEditor),
|
"commitMenuKeybinding": keybindings.Label(self.c.UserConfig.Keybinding.CommitMessage.CommitMenu),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,8 +36,8 @@ func (self *CommitDescriptionController) GetKeybindings(opts types.KeybindingsOp
|
||||||
Handler: self.confirm,
|
Handler: self.confirm,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.CommitMessage.SwitchToEditor),
|
Key: opts.GetKey(opts.Config.CommitMessage.CommitMenu),
|
||||||
Handler: self.switchToEditor,
|
Handler: self.openCommitMenu,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ func (self *CommitDescriptionController) confirm() error {
|
||||||
return self.c.Helpers().Commits.HandleCommitConfirm()
|
return self.c.Helpers().Commits.HandleCommitConfirm()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitDescriptionController) switchToEditor() error {
|
func (self *CommitDescriptionController) openCommitMenu() error {
|
||||||
return self.c.Helpers().Commits.SwitchToEditor()
|
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
|
||||||
|
return self.c.Helpers().Commits.OpenCommitMenu(authorSuggestion)
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,8 @@ func (self *CommitMessageController) GetKeybindings(opts types.KeybindingsOpts)
|
||||||
Handler: self.switchToCommitDescription,
|
Handler: self.switchToCommitDescription,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.CommitMessage.SwitchToEditor),
|
Key: opts.GetKey(opts.Config.CommitMessage.CommitMenu),
|
||||||
Handler: self.switchToEditor,
|
Handler: self.openCommitMenu,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +89,6 @@ func (self *CommitMessageController) switchToCommitDescription() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitMessageController) switchToEditor() error {
|
|
||||||
return self.c.Helpers().Commits.SwitchToEditor()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *CommitMessageController) handleCommitIndexChange(value int) error {
|
func (self *CommitMessageController) handleCommitIndexChange(value int) error {
|
||||||
currentIndex := self.context().GetSelectedIndex()
|
currentIndex := self.context().GetSelectedIndex()
|
||||||
newIndex := currentIndex + value
|
newIndex := currentIndex + value
|
||||||
|
@ -134,3 +130,8 @@ func (self *CommitMessageController) confirm() error {
|
||||||
func (self *CommitMessageController) close() error {
|
func (self *CommitMessageController) close() error {
|
||||||
return self.c.Helpers().Commits.CloseCommitMessagePanel()
|
return self.c.Helpers().Commits.CloseCommitMessagePanel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *CommitMessageController) openCommitMenu() error {
|
||||||
|
authorSuggestion := self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc()
|
||||||
|
return self.c.Helpers().Commits.OpenCommitMenu(authorSuggestion)
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
@ -215,3 +216,39 @@ func (self *CommitsHelper) commitMessageContexts() []types.Context {
|
||||||
self.c.Contexts().CommitMessage,
|
self.c.Contexts().CommitMessage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *CommitsHelper) OpenCommitMenu(suggestionFunc func(string) []*types.Suggestion) error {
|
||||||
|
menuItems := []*types.MenuItem{
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.OpenInEditor,
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.SwitchToEditor()
|
||||||
|
},
|
||||||
|
Key: 'e',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.AddCoAuthor,
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.addCoAuthor(suggestionFunc)
|
||||||
|
},
|
||||||
|
Key: 'c',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
|
Title: self.c.Tr.CommitMenuTitle,
|
||||||
|
Items: menuItems,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *CommitsHelper) addCoAuthor(suggestionFunc func(string) []*types.Suggestion) error {
|
||||||
|
return self.c.Prompt(types.PromptOpts{
|
||||||
|
Title: self.c.Tr.AddCoAuthorPromptTitle,
|
||||||
|
FindSuggestionsFunc: suggestionFunc,
|
||||||
|
HandleConfirm: func(value string) error {
|
||||||
|
commitDescription := self.getCommitDescription()
|
||||||
|
commitDescription = git_commands.AddCoAuthorToDescription(commitDescription, value)
|
||||||
|
self.setCommitDescription(commitDescription)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -673,25 +673,26 @@ func (self *LocalCommitsController) canAmend(commit *models.Commit) *types.Disab
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error {
|
func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error {
|
||||||
|
opts := self.c.KeybindingsOpts()
|
||||||
return self.c.Menu(types.CreateMenuOptions{
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
Title: "Amend commit attribute",
|
Title: "Amend commit attribute",
|
||||||
Items: []*types.MenuItem{
|
Items: []*types.MenuItem{
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.ResetAuthor,
|
Label: self.c.Tr.ResetAuthor,
|
||||||
OnPress: self.resetAuthor,
|
OnPress: self.resetAuthor,
|
||||||
Key: 'a',
|
Key: opts.GetKey(opts.Config.AmendAttribute.ResetAuthor),
|
||||||
Tooltip: "Reset the commit's author to the currently configured user. This will also renew the author timestamp",
|
Tooltip: self.c.Tr.ResetAuthorTooltip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.SetAuthor,
|
Label: self.c.Tr.SetAuthor,
|
||||||
OnPress: self.setAuthor,
|
OnPress: self.setAuthor,
|
||||||
Key: 'A',
|
Key: opts.GetKey(opts.Config.AmendAttribute.SetAuthor),
|
||||||
Tooltip: "Set the author based on a prompt",
|
Tooltip: self.c.Tr.SetAuthorTooltip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.AddCoAuthor,
|
Label: self.c.Tr.AddCoAuthor,
|
||||||
OnPress: self.addCoAuthor,
|
OnPress: self.addCoAuthor,
|
||||||
Key: 'c',
|
Key: opts.GetKey(opts.Config.AmendAttribute.AddCoAuthor),
|
||||||
Tooltip: self.c.Tr.AddCoAuthorTooltip,
|
Tooltip: self.c.Tr.AddCoAuthorTooltip,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -147,7 +147,9 @@ type TranslationSet struct {
|
||||||
AmendCommitTooltip string
|
AmendCommitTooltip string
|
||||||
Amend string
|
Amend string
|
||||||
ResetAuthor string
|
ResetAuthor string
|
||||||
|
ResetAuthorTooltip string
|
||||||
SetAuthor string
|
SetAuthor string
|
||||||
|
SetAuthorTooltip string
|
||||||
AddCoAuthor string
|
AddCoAuthor string
|
||||||
AmendCommitAttribute string
|
AmendCommitAttribute string
|
||||||
AmendCommitAttributeTooltip string
|
AmendCommitAttributeTooltip string
|
||||||
|
@ -270,6 +272,7 @@ type TranslationSet struct {
|
||||||
SearchTitle string
|
SearchTitle string
|
||||||
TagsTitle string
|
TagsTitle string
|
||||||
MenuTitle string
|
MenuTitle string
|
||||||
|
CommitMenuTitle string
|
||||||
RemotesTitle string
|
RemotesTitle string
|
||||||
RemoteBranchesTitle string
|
RemoteBranchesTitle string
|
||||||
PatchBuildingTitle string
|
PatchBuildingTitle string
|
||||||
|
@ -1093,7 +1096,9 @@ func EnglishTranslationSet() TranslationSet {
|
||||||
AmendCommitTooltip: "Amend commit with staged changes. If the selected commit is the HEAD commit, this will perform `git commit --amend`. Otherwise the commit will be amended via a rebase.",
|
AmendCommitTooltip: "Amend commit with staged changes. If the selected commit is the HEAD commit, this will perform `git commit --amend`. Otherwise the commit will be amended via a rebase.",
|
||||||
Amend: "Amend",
|
Amend: "Amend",
|
||||||
ResetAuthor: "Reset author",
|
ResetAuthor: "Reset author",
|
||||||
|
ResetAuthorTooltip: "Reset the commit's author to the currently configured user. This will also renew the author timestamp",
|
||||||
SetAuthor: "Set author",
|
SetAuthor: "Set author",
|
||||||
|
SetAuthorTooltip: "Set the author based on a prompt",
|
||||||
AddCoAuthor: "Add co-author",
|
AddCoAuthor: "Add co-author",
|
||||||
AmendCommitAttribute: "Amend commit attribute",
|
AmendCommitAttribute: "Amend commit attribute",
|
||||||
AmendCommitAttributeTooltip: "Set/Reset commit author or set co-author.",
|
AmendCommitAttributeTooltip: "Set/Reset commit author or set co-author.",
|
||||||
|
@ -1209,12 +1214,13 @@ func EnglishTranslationSet() TranslationSet {
|
||||||
RebaseOptionsTitle: "Rebase options",
|
RebaseOptionsTitle: "Rebase options",
|
||||||
CommitSummaryTitle: "Commit summary",
|
CommitSummaryTitle: "Commit summary",
|
||||||
CommitDescriptionTitle: "Commit description",
|
CommitDescriptionTitle: "Commit description",
|
||||||
CommitDescriptionSubTitle: "Press {{.togglePanelKeyBinding}} to toggle focus, {{.switchToEditorKeyBinding}} to switch to editor",
|
CommitDescriptionSubTitle: "Press {{.togglePanelKeyBinding}} to toggle focus, {{.commitMenuKeybinding}} to open menu",
|
||||||
CommitDescriptionSubTitleNoSwitch: "Press {{.togglePanelKeyBinding}} to toggle focus",
|
CommitDescriptionSubTitleNoSwitch: "Press {{.togglePanelKeyBinding}} to toggle focus",
|
||||||
LocalBranchesTitle: "Local branches",
|
LocalBranchesTitle: "Local branches",
|
||||||
SearchTitle: "Search",
|
SearchTitle: "Search",
|
||||||
TagsTitle: "Tags",
|
TagsTitle: "Tags",
|
||||||
MenuTitle: "Menu",
|
MenuTitle: "Menu",
|
||||||
|
CommitMenuTitle: "Commit Menu",
|
||||||
RemotesTitle: "Remotes",
|
RemotesTitle: "Remotes",
|
||||||
RemoteBranchesTitle: "Remote branches",
|
RemoteBranchesTitle: "Remote branches",
|
||||||
PatchBuildingTitle: "Main panel (patch building)",
|
PatchBuildingTitle: "Main panel (patch building)",
|
||||||
|
|
|
@ -41,6 +41,17 @@ func (self *CommitDescriptionPanelDriver) GoToBeginning() *CommitDescriptionPane
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *CommitDescriptionPanelDriver) AddCoAuthor(author string) *CommitDescriptionPanelDriver {
|
||||||
|
self.t.press(self.t.keys.CommitMessage.CommitMenu)
|
||||||
|
self.t.ExpectPopup().Menu().Title(Equals("Commit Menu")).
|
||||||
|
Select(Contains("Add co-author")).
|
||||||
|
Confirm()
|
||||||
|
self.t.ExpectPopup().Prompt().Title(Contains("Add co-author")).
|
||||||
|
Type(author).
|
||||||
|
Confirm()
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
func (self *CommitDescriptionPanelDriver) Title(expected *TextMatcher) *CommitDescriptionPanelDriver {
|
func (self *CommitDescriptionPanelDriver) Title(expected *TextMatcher) *CommitDescriptionPanelDriver {
|
||||||
self.getViewDriver().Title(expected)
|
self.getViewDriver().Title(expected)
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,10 @@ func (self *CommitMessagePanelDriver) Cancel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitMessagePanelDriver) SwitchToEditor() {
|
func (self *CommitMessagePanelDriver) SwitchToEditor() {
|
||||||
self.getViewDriver().Press(self.t.keys.CommitMessage.SwitchToEditor)
|
self.OpenCommitMenu()
|
||||||
|
self.t.ExpectPopup().Menu().Title(Equals("Commit Menu")).
|
||||||
|
Select(Contains("Open in editor")).
|
||||||
|
Confirm()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitMessagePanelDriver) SelectPreviousMessage() *CommitMessagePanelDriver {
|
func (self *CommitMessagePanelDriver) SelectPreviousMessage() *CommitMessagePanelDriver {
|
||||||
|
@ -81,3 +84,8 @@ func (self *CommitMessagePanelDriver) SelectNextMessage() *CommitMessagePanelDri
|
||||||
self.getViewDriver().SelectNextItem()
|
self.getViewDriver().SelectNextItem()
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *CommitMessagePanelDriver) OpenCommitMenu() *CommitMessagePanelDriver {
|
||||||
|
self.t.press(self.t.keys.CommitMessage.CommitMenu)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
|
@ -33,8 +33,9 @@ var AddCoAuthor = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Views().Main().ContainsLines(
|
t.Views().Main().ContainsLines(
|
||||||
Contains("initial commit"),
|
Equals(" initial commit"),
|
||||||
Contains("Co-authored-by: John Smith <jsmith@gmail.com>"),
|
Equals(" "),
|
||||||
|
Equals(" Co-authored-by: John Smith <jsmith@gmail.com>"),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package commit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var AddCoAuthorWhileCommitting = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Add co-author while typing the commit message",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {
|
||||||
|
},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.CreateFile("file", "file content")
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
t.Views().Files().
|
||||||
|
IsFocused().
|
||||||
|
PressPrimaryAction(). // stage file
|
||||||
|
Press(keys.Files.CommitChanges)
|
||||||
|
|
||||||
|
t.ExpectPopup().CommitMessagePanel().
|
||||||
|
Type("Subject").
|
||||||
|
SwitchToDescription().
|
||||||
|
Type("Here's my message.").
|
||||||
|
AddCoAuthor("John Doe <john@doe.com>").
|
||||||
|
Content(Equals("Here's my message.\n\nCo-authored-by: John Doe <john@doe.com>")).
|
||||||
|
AddCoAuthor("Jane Smith <jane@smith.com>").
|
||||||
|
// Second co-author doesn't add a blank line:
|
||||||
|
Content(Equals("Here's my message.\n\nCo-authored-by: John Doe <john@doe.com>\nCo-authored-by: Jane Smith <jane@smith.com>")).
|
||||||
|
SwitchToSummary().
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.Views().Commits().
|
||||||
|
Lines(
|
||||||
|
Contains("Subject"),
|
||||||
|
).
|
||||||
|
Focus().
|
||||||
|
Tap(func() {
|
||||||
|
t.Views().Main().ContainsLines(
|
||||||
|
Equals(" Subject"),
|
||||||
|
Equals(" "),
|
||||||
|
Equals(" Here's my message."),
|
||||||
|
Equals(" "),
|
||||||
|
Equals(" Co-authored-by: John Doe <john@doe.com>"),
|
||||||
|
Equals(" Co-authored-by: Jane Smith <jane@smith.com>"),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
|
@ -64,6 +64,7 @@ var tests = []*components.IntegrationTest{
|
||||||
cherry_pick.CherryPickDuringRebase,
|
cherry_pick.CherryPickDuringRebase,
|
||||||
cherry_pick.CherryPickRange,
|
cherry_pick.CherryPickRange,
|
||||||
commit.AddCoAuthor,
|
commit.AddCoAuthor,
|
||||||
|
commit.AddCoAuthorWhileCommitting,
|
||||||
commit.Amend,
|
commit.Amend,
|
||||||
commit.AutoWrapMessage,
|
commit.AutoWrapMessage,
|
||||||
commit.Commit,
|
commit.Commit,
|
||||||
|
|
|
@ -1163,6 +1163,24 @@
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"type": "object"
|
"type": "object"
|
||||||
},
|
},
|
||||||
|
"amendAttribute": {
|
||||||
|
"properties": {
|
||||||
|
"resetAuthor": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "a"
|
||||||
|
},
|
||||||
|
"setAuthor": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "A"
|
||||||
|
},
|
||||||
|
"addCoAuthor": {
|
||||||
|
"type": "string",
|
||||||
|
"default": "c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"stash": {
|
"stash": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"popStash": {
|
"popStash": {
|
||||||
|
@ -1225,7 +1243,7 @@
|
||||||
},
|
},
|
||||||
"commitMessage": {
|
"commitMessage": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"switchToEditor": {
|
"commitMenu": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "\u003cc-o\u003e"
|
"default": "\u003cc-o\u003e"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue