Skip to content

Commit a7ce12f

Browse files
committed
Add co-author to commits
Add addCoAuthor command for commits - Implement the `addCoAuthor` command to add co-authors to commits. - Utilize suggestions helpers to populate author names from the suggestions list. - Added command to gui at `LocalCommitsController`. This commit introduces the `addCoAuthor` command, which allows users to easily add co-authors to their commits. The co-author names are populated from the suggestions list, minimizing the chances of user input errors. The co-authors are added using the Co-authored-by metadata format recognized by GitHub and GitLab.
1 parent cdea5b4 commit a7ce12f

File tree

6 files changed

+127
-0
lines changed

6 files changed

+127
-0
lines changed

pkg/commands/git_commands/commit.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ func (self *CommitCommands) SetAuthor(value string) error {
3838
return self.cmd.New(cmdArgs).Run()
3939
}
4040

41+
// Add a commit's coauthor using Github/Gitlab Co-authored-by metadata. Value is expected to be of the form 'Name <Email>'
42+
func (self *CommitCommands) AddCoAuthor(sha string, value string) error {
43+
message, err := self.GetCommitMessage(sha)
44+
if err != nil {
45+
return err
46+
}
47+
48+
message = message + fmt.Sprintf("\nCo-authored-by: %s", value)
49+
50+
args := []string{"-m", message}
51+
cmdArgs := NewGitCmd("commit").
52+
Arg("--allow-empty", "--amend", "--only").
53+
Arg(args...).
54+
ToArgv()
55+
56+
return self.cmd.New(cmdArgs).Run()
57+
}
58+
4159
// ResetToCommit reset to commit
4260
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
4361
cmdArgs := NewGitCmd("reset").Arg("--"+strength, sha).ToArgv()

pkg/commands/git_commands/rebase.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ func (self *RebaseCommands) SetCommitAuthor(commits []*models.Commit, index int,
7979
})
8080
}
8181

82+
func (self *RebaseCommands) AddCommitCoAuthor(commits []*models.Commit, index int, value string) error {
83+
return self.GenericAmend(commits, index, func() error {
84+
return self.commit.AddCoAuthor(commits[index].Sha, value)
85+
})
86+
}
87+
8288
func (self *RebaseCommands) GenericAmend(commits []*models.Commit, index int, f func() error) error {
8389
if models.IsHeadCommit(commits, index) {
8490
// we've selected the top commit so no rebase is required

pkg/gui/controllers/local_commits_controller.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,12 @@ func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error
575575
Key: 'A',
576576
Tooltip: "Set the author based on a prompt",
577577
},
578+
{
579+
Label: self.c.Tr.AddCoAuthor,
580+
OnPress: self.addCoAuthor,
581+
Key: 'c',
582+
Tooltip: "Add co-author using the Github/Gitlab metadata Co-authored-by",
583+
},
578584
},
579585
})
580586
}
@@ -607,6 +613,22 @@ func (self *LocalCommitsController) setAuthor() error {
607613
})
608614
}
609615

616+
func (self *LocalCommitsController) addCoAuthor() error {
617+
return self.c.Prompt(types.PromptOpts{
618+
Title: self.c.Tr.AddCoAuthorPromptTitle,
619+
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc(),
620+
HandleConfirm: func(value string) error {
621+
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(gocui.Task) error {
622+
self.c.LogAction(self.c.Tr.Actions.AddCommitCoAuthor)
623+
if err := self.c.Git().Rebase.AddCommitCoAuthor(self.c.Model().Commits, self.context().GetSelectedLineIdx(), value); err != nil {
624+
return self.c.Error(err)
625+
}
626+
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
627+
})
628+
},
629+
})
630+
}
631+
610632
func (self *LocalCommitsController) revert(commit *models.Commit) error {
611633
if commit.IsMerge() {
612634
return self.createRevertMergeCommitMenu(commit)

pkg/i18n/english.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,10 @@ type TranslationSet struct {
100100
AmendToCommit string
101101
ResetAuthor string
102102
SetAuthor string
103+
AddCoAuthor string
103104
SetResetCommitAuthor string
104105
SetAuthorPromptTitle string
106+
AddCoAuthorPromptTitle string
105107
SureResetCommitAuthor string
106108
RenameCommitEditor string
107109
NoCommitsThisBranch string
@@ -650,6 +652,7 @@ type Actions struct {
650652
AmendCommit string
651653
ResetCommitAuthor string
652654
SetCommitAuthor string
655+
AddCommitCoAuthor string
653656
RevertCommit string
654657
CreateFixupCommit string
655658
SquashAllAboveFixupCommits string
@@ -862,8 +865,10 @@ func EnglishTranslationSet() TranslationSet {
862865
AmendToCommit: "Amend commit with staged changes",
863866
ResetAuthor: "Reset author",
864867
SetAuthor: "Set author",
868+
AddCoAuthor: "Add co-author",
865869
SetResetCommitAuthor: "Set/Reset commit author",
866870
SetAuthorPromptTitle: "Set author (must look like 'Name <Email>')",
871+
AddCoAuthorPromptTitle: "Add co-author (must look like 'Name <Email>')",
867872
SureResetCommitAuthor: "The author field of this commit will be updated to match the configured user. This also renews the author timestamp. Continue?",
868873
RenameCommitEditor: "Reword commit with editor",
869874
Error: "Error",
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package commit
2+
3+
import (
4+
"github.com/jesseduffield/lazygit/pkg/config"
5+
. "github.com/jesseduffield/lazygit/pkg/integration/components"
6+
)
7+
8+
var AddCoAuthor = NewIntegrationTest(NewIntegrationTestArgs{
9+
Description: "Add co-author on a commit",
10+
ExtraCmdArgs: []string{},
11+
Skip: false,
12+
SetupConfig: func(config *config.AppConfig) {},
13+
SetupRepo: func(shell *Shell) {
14+
shell.NewBranch("original")
15+
16+
shell.SetConfig("user.email", "[email protected]")
17+
shell.SetConfig("user.name", "Bill Smith")
18+
19+
shell.EmptyCommit("one")
20+
21+
shell.NewBranch("other")
22+
23+
shell.SetConfig("user.email", "[email protected]")
24+
shell.SetConfig("user.name", "John Smith")
25+
26+
shell.EmptyCommit("two")
27+
28+
shell.Checkout("original")
29+
},
30+
Run: func(t *TestDriver, keys config.KeybindingConfig) {
31+
t.Views().Commits().
32+
Focus().
33+
Lines(
34+
Contains("BS").Contains("one").IsSelected(),
35+
)
36+
37+
t.Views().Branches().
38+
Focus().
39+
Lines(
40+
Contains("original").IsSelected(),
41+
Contains("other"),
42+
).
43+
NavigateToLine(Contains("other")).
44+
PressEnter()
45+
46+
// ensuring we get these commit authors as suggestions
47+
t.Views().SubCommits().
48+
IsFocused().
49+
Lines(
50+
Contains("JS").Contains("two").IsSelected(),
51+
Contains("BS").Contains("one"),
52+
)
53+
54+
t.Views().Commits().
55+
Focus().
56+
Press(keys.Commits.ResetCommitAuthor).
57+
Tap(func() {
58+
t.ExpectPopup().Menu().
59+
Title(Equals("Amend commit attribute")).
60+
Select(Contains("Add co-author")).
61+
Confirm()
62+
63+
t.ExpectPopup().Prompt().
64+
Title(Contains("Add co-author")).
65+
SuggestionLines(
66+
Contains("Bill Smith"),
67+
Contains("John Smith"),
68+
).
69+
ConfirmSuggestion(Contains("John Smith"))
70+
})
71+
t.Views().Main().ContainsLines(
72+
Contains("Co-authored-by"),
73+
)
74+
},
75+
})

pkg/integration/tests/test_list.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ var tests = []*components.IntegrationTest{
5252
branch.Suggestions,
5353
cherry_pick.CherryPick,
5454
cherry_pick.CherryPickConflicts,
55+
commit.AddCoAuthor,
5556
commit.Amend,
5657
commit.Commit,
5758
commit.CommitMultiline,

0 commit comments

Comments
 (0)