Skip to content

Commit

Permalink
support setting the author of a commit
Browse files Browse the repository at this point in the history
update copy
  • Loading branch information
jesseduffield committed Jun 9, 2022
1 parent 901ab3a commit 9591cc3
Show file tree
Hide file tree
Showing 31 changed files with 141 additions and 14 deletions.
6 changes: 6 additions & 0 deletions pkg/commands/git_commands/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ func (self *CommitCommands) ResetAuthor() error {
return self.cmd.New("git commit --allow-empty --only --no-edit --amend --reset-author").Run()
}

// Sets the commit's author to the supplied value. Value is expected to be of the form 'Name <Email>'
func (self *CommitCommands) SetAuthor(value string) error {
commandStr := fmt.Sprintf("git commit --allow-empty --only --no-edit --amend --author=%s", self.cmd.Quote(value))
return self.cmd.New(commandStr).Run()
}

// ResetToCommit reset to commit
func (self *CommitCommands) ResetToCommit(sha string, strength string, envVars []string) error {
return self.cmd.New(fmt.Sprintf("git reset --%s %s", strength, sha)).
Expand Down
18 changes: 15 additions & 3 deletions pkg/commands/git_commands/rebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,30 @@ func (self *RebaseCommands) RewordCommitInEditor(commits []*models.Commit, index
}

func (self *RebaseCommands) ResetCommitAuthor(commits []*models.Commit, index int) error {
return self.GenericAmend(commits, index, func() error {
return self.commit.ResetAuthor()
})
}

func (self *RebaseCommands) SetCommitAuthor(commits []*models.Commit, index int, value string) error {
return self.GenericAmend(commits, index, func() error {
return self.commit.SetAuthor(value)
})
}

func (self *RebaseCommands) GenericAmend(commits []*models.Commit, index int, f func() error) error {
if index == 0 {
// we've selected the top commit so no rebase is required
return self.commit.ResetAuthor()
return f()
}

err := self.BeginInteractiveRebaseForCommit(commits, index)
if err != nil {
return err
}

// now the selected commit should be our head so we'll amend it with the new author
err = self.commit.ResetAuthor()
// now the selected commit should be our head so we'll amend it
err = f()
if err != nil {
return err
}
Expand Down
9 changes: 9 additions & 0 deletions pkg/gui/controllers/helpers/suggestions_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/jesseduffield/minimal/gitignore"
"github.com/samber/lo"
"gopkg.in/ozeidan/fuzzy-patricia.v3/patricia"
)

Expand Down Expand Up @@ -174,6 +175,14 @@ func (self *SuggestionsHelper) GetRefsSuggestionsFunc() func(string) []*types.Su
return FuzzySearchFunc(refNames)
}

func (self *SuggestionsHelper) GetAuthorsSuggestionsFunc() func(string) []*types.Suggestion {
authors := lo.Uniq(slices.Map(self.model.Commits, func(commit *models.Commit) string {
return fmt.Sprintf("%s <%s>", commit.AuthorName, commit.AuthorEmail)
}))

return FuzzySearchFunc(authors)
}

func FuzzySearchFunc(options []string) func(string) []*types.Suggestion {
return func(input string) []*types.Suggestion {
var matches []string
Expand Down
55 changes: 44 additions & 11 deletions pkg/gui/controllers/local_commits_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
},
{
Key: opts.GetKey(opts.Config.Commits.ResetCommitAuthor),
Handler: self.checkSelected(self.resetAuthor),
Handler: self.checkSelected(self.amendAttribute),
Description: self.c.Tr.LcResetCommitAuthor,
},
{
Expand Down Expand Up @@ -423,17 +423,50 @@ func (self *LocalCommitsController) amendTo(commit *models.Commit) error {
})
}

func (self *LocalCommitsController) resetAuthor(commit *models.Commit) error {
return self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.LcResetCommitAuthor,
Prompt: self.c.Tr.SureResetCommitAuthor,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.ResetCommitAuthor)
if err := self.git.Rebase.ResetCommitAuthor(self.model.Commits, self.context().GetSelectedLineIdx()); err != nil {
return self.c.Error(err)
}
func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error {
return self.c.Menu(types.CreateMenuOptions{
Title: "Amend commit attribute",
Items: []*types.MenuItem{
{
Label: "reset author",
OnPress: self.resetAuthor,
Key: 'a',
Tooltip: "Reset the commit's author to the currently configured user. This will also renew the author timestamp",
},
{
Label: "set author",
OnPress: self.setAuthor,
Key: 'A',
Tooltip: "Set the author based on a prompt",
},
},
})
}

return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
func (self *LocalCommitsController) resetAuthor() error {
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.ResetCommitAuthor)
if err := self.git.Rebase.ResetCommitAuthor(self.model.Commits, self.context().GetSelectedLineIdx()); err != nil {
return self.c.Error(err)
}

return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
})
}

func (self *LocalCommitsController) setAuthor() error {
return self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.SetAuthorPromptTitle,
FindSuggestionsFunc: self.helpers.Suggestions.GetAuthorsSuggestionsFunc(),
HandleConfirm: func(value string) error {
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func() error {
self.c.LogAction(self.c.Tr.Actions.SetCommitAuthor)
if err := self.git.Rebase.SetCommitAuthor(self.model.Commits, self.context().GetSelectedLineIdx(), value); err != nil {
return self.c.Error(err)
}

return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
})
},
})
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/i18n/english.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ type TranslationSet struct {
LcEditCommit string
LcAmendToCommit string
LcResetCommitAuthor string
SetAuthorPromptTitle string
SureResetCommitAuthor string
LcRenameCommitEditor string
NoCommitsThisBranch string
Expand Down Expand Up @@ -537,6 +538,7 @@ type Actions struct {
EditCommit string
AmendCommit string
ResetCommitAuthor string
SetCommitAuthor string
RevertCommit string
CreateFixupCommit string
SquashAllAboveFixupCommits string
Expand Down Expand Up @@ -725,6 +727,7 @@ func EnglishTranslationSet() TranslationSet {
LcEditCommit: "edit commit",
LcAmendToCommit: "amend commit with staged changes",
LcResetCommitAuthor: "reset commit author",
SetAuthorPromptTitle: "Set author (must look like 'Name <Email>')",
SureResetCommitAuthor: "The author field of this commit will be updated to match the configured user. This also renews the author timestamp. Continue?",
LcRenameCommitEditor: "reword commit with editor",
Error: "Error",
Expand Down Expand Up @@ -1142,6 +1145,7 @@ func EnglishTranslationSet() TranslationSet {
EditCommit: "Edit commit",
AmendCommit: "Amend commit",
ResetCommitAuthor: "Reset commit author",
SetCommitAuthor: "Set commit author",
RevertCommit: "Revert commit",
CreateFixupCommit: "Create fixup commit",
SquashAllAboveFixupCommits: "Squash all above fixup commits",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
myfile3
Empty file.
1 change: 1 addition & 0 deletions test/integration/setAuthor/expected/repo/.git_keep/HEAD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/heads/master
10 changes: 10 additions & 0 deletions test/integration/setAuthor/expected/repo/.git_keep/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[user]
email = [email protected]
name = Author2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Unnamed repository; edit this file 'description' to name the repository.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
# *.[oa]
# *~
.DS_Store
4 changes: 4 additions & 0 deletions test/integration/setAuthor/expected/repo/.git_keep/logs/HEAD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0000000000000000000000000000000000000000 2075aeb39a2a66a9607860a65b2a71c517760254 Author1 <[email protected]> 1652008089 +1000 commit (initial): myfile1
2075aeb39a2a66a9607860a65b2a71c517760254 d01c8bb001458d0a7c01193813685c658e0355ac Author1 <[email protected]> 1652008089 +1000 commit: myfile2
d01c8bb001458d0a7c01193813685c658e0355ac 8710ece70b7db9638b9645e93abdbcf210fa4595 Author2 <[email protected]> 1652008089 +1000 commit: myfile3
8710ece70b7db9638b9645e93abdbcf210fa4595 baf3189129ba8878ba9b4107eaaaf3389287259b Author2 <[email protected]> 1652008097 +1000 commit (amend): myfile3
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0000000000000000000000000000000000000000 2075aeb39a2a66a9607860a65b2a71c517760254 Author1 <[email protected]> 1652008089 +1000 commit (initial): myfile1
2075aeb39a2a66a9607860a65b2a71c517760254 d01c8bb001458d0a7c01193813685c658e0355ac Author1 <[email protected]> 1652008089 +1000 commit: myfile2
d01c8bb001458d0a7c01193813685c658e0355ac 8710ece70b7db9638b9645e93abdbcf210fa4595 Author2 <[email protected]> 1652008089 +1000 commit: myfile3
8710ece70b7db9638b9645e93abdbcf210fa4595 baf3189129ba8878ba9b4107eaaaf3389287259b Author2 <[email protected]> 1652008097 +1000 commit (amend): myfile3
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
x��Q
�0D��)�_�ݸ�n��%M6Xh��z{�x�fx0ob-em@"����ČA�q2M�F*I��#/|N�9����l�����\��c�S��ҵ�GT� �����~���+�nF�ȋ5'
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
baf3189129ba8878ba9b4107eaaaf3389287259b
1 change: 1 addition & 0 deletions test/integration/setAuthor/expected/repo/myfile1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test1
1 change: 1 addition & 0 deletions test/integration/setAuthor/expected/repo/myfile2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test2
1 change: 1 addition & 0 deletions test/integration/setAuthor/expected/repo/myfile3
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test3
1 change: 1 addition & 0 deletions test/integration/setAuthor/recording.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"KeyEvents":[{"Timestamp":1118,"Mod":0,"Key":259,"Ch":0},{"Timestamp":1382,"Mod":0,"Key":259,"Ch":0},{"Timestamp":2654,"Mod":0,"Key":256,"Ch":97},{"Timestamp":3632,"Mod":0,"Key":258,"Ch":0},{"Timestamp":4070,"Mod":0,"Key":13,"Ch":13},{"Timestamp":6702,"Mod":0,"Key":9,"Ch":9},{"Timestamp":7486,"Mod":0,"Key":258,"Ch":0},{"Timestamp":7899,"Mod":0,"Key":13,"Ch":13},{"Timestamp":9141,"Mod":0,"Key":256,"Ch":113}],"ResizeEvents":[{"Timestamp":0,"Width":272,"Height":74}]}
24 changes: 24 additions & 0 deletions test/integration/setAuthor/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/sh

set -e

cd $1

git init

git config user.email "[email protected]"
git config user.name "Author1"

echo test1 > myfile1
git add .
git commit -am "myfile1"
echo test2 > myfile2
git add .
git commit -am "myfile2"

git config user.email "[email protected]"
git config user.name "Author2"

echo test3 > myfile3
git add .
git commit -am "myfile3"
4 changes: 4 additions & 0 deletions test/integration/setAuthor/test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"description": "In this test the author of a commit is set to a different name/email.",
"speed": 5
}

0 comments on commit 9591cc3

Please sign in to comment.