mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 20:36:03 +02:00
Add option to copy commit body (#4274)
I based this off of the existing `CommitMessage` option in the copy commit attributes menu.
This commit is contained in:
commit
a7bfeca9c0
8 changed files with 166 additions and 45 deletions
|
@ -122,7 +122,24 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *BasicCommitsController) getCommitMessageBody(hash string) string {
|
||||||
|
commitMessageBody, err := self.c.Git().Commit.GetCommitMessage(hash)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
_, body := self.c.Helpers().Commits.SplitCommitMessageAndDescription(commitMessageBody)
|
||||||
|
return body
|
||||||
|
}
|
||||||
|
|
||||||
func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) error {
|
func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) error {
|
||||||
|
commitMessageBody := self.getCommitMessageBody(commit.Hash)
|
||||||
|
var commitMessageBodyDisabled *types.DisabledReason
|
||||||
|
if commitMessageBody == "" {
|
||||||
|
commitMessageBodyDisabled = &types.DisabledReason{
|
||||||
|
Text: self.c.Tr.CommitHasNoMessageBody,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
items := []*types.MenuItem{
|
items := []*types.MenuItem{
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.CommitHash,
|
Label: self.c.Tr.CommitHash,
|
||||||
|
@ -144,6 +161,14 @@ func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) e
|
||||||
},
|
},
|
||||||
Key: 'm',
|
Key: 'm',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.CommitMessageBody,
|
||||||
|
DisabledReason: commitMessageBodyDisabled,
|
||||||
|
OnPress: func() error {
|
||||||
|
return self.copyCommitMessageBodyToClipboard(commitMessageBody)
|
||||||
|
},
|
||||||
|
Key: 'b',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.CommitURL,
|
Label: self.c.Tr.CommitURL,
|
||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
|
@ -259,6 +284,16 @@ func (self *BasicCommitsController) copyCommitMessageToClipboard(commit *models.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *BasicCommitsController) copyCommitMessageBodyToClipboard(commitMessageBody string) error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.CopyCommitMessageBodyToClipboard)
|
||||||
|
if err := self.c.OS().CopyToClipboard(commitMessageBody); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
self.c.Toast(self.c.Tr.CommitMessageBodyCopiedToClipboard)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (self *BasicCommitsController) copyCommitSubjectToClipboard(commit *models.Commit) error {
|
func (self *BasicCommitsController) copyCommitSubjectToClipboard(commit *models.Commit) error {
|
||||||
message, err := self.c.Git().Commit.GetCommitSubject(commit.Hash)
|
message, err := self.c.Git().Commit.GetCommitSubject(commit.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -621,6 +621,7 @@ type TranslationSet struct {
|
||||||
PasteCommitMessageFromClipboard string
|
PasteCommitMessageFromClipboard string
|
||||||
SurePasteCommitMessage string
|
SurePasteCommitMessage string
|
||||||
CommitMessage string
|
CommitMessage string
|
||||||
|
CommitMessageBody string
|
||||||
CommitSubject string
|
CommitSubject string
|
||||||
CommitAuthor string
|
CommitAuthor string
|
||||||
CommitTags string
|
CommitTags string
|
||||||
|
@ -685,10 +686,12 @@ type TranslationSet struct {
|
||||||
CommitDiffCopiedToClipboard string
|
CommitDiffCopiedToClipboard string
|
||||||
CommitURLCopiedToClipboard string
|
CommitURLCopiedToClipboard string
|
||||||
CommitMessageCopiedToClipboard string
|
CommitMessageCopiedToClipboard string
|
||||||
|
CommitMessageBodyCopiedToClipboard string
|
||||||
CommitSubjectCopiedToClipboard string
|
CommitSubjectCopiedToClipboard string
|
||||||
CommitAuthorCopiedToClipboard string
|
CommitAuthorCopiedToClipboard string
|
||||||
CommitTagsCopiedToClipboard string
|
CommitTagsCopiedToClipboard string
|
||||||
CommitHasNoTags string
|
CommitHasNoTags string
|
||||||
|
CommitHasNoMessageBody string
|
||||||
PatchCopiedToClipboard string
|
PatchCopiedToClipboard string
|
||||||
CopiedToClipboard string
|
CopiedToClipboard string
|
||||||
ErrCannotEditDirectory string
|
ErrCannotEditDirectory string
|
||||||
|
@ -914,6 +917,7 @@ type Actions struct {
|
||||||
MoveCommitUp string
|
MoveCommitUp string
|
||||||
MoveCommitDown string
|
MoveCommitDown string
|
||||||
CopyCommitMessageToClipboard string
|
CopyCommitMessageToClipboard string
|
||||||
|
CopyCommitMessageBodyToClipboard string
|
||||||
CopyCommitSubjectToClipboard string
|
CopyCommitSubjectToClipboard string
|
||||||
CopyCommitDiffToClipboard string
|
CopyCommitDiffToClipboard string
|
||||||
CopyCommitHashToClipboard string
|
CopyCommitHashToClipboard string
|
||||||
|
@ -1653,7 +1657,8 @@ func EnglishTranslationSet() *TranslationSet {
|
||||||
CopyCommitMessageToClipboard: "Copy commit message to clipboard",
|
CopyCommitMessageToClipboard: "Copy commit message to clipboard",
|
||||||
PasteCommitMessageFromClipboard: "Paste commit message from clipboard",
|
PasteCommitMessageFromClipboard: "Paste commit message from clipboard",
|
||||||
SurePasteCommitMessage: "Pasting will overwrite the current commit message, continue?",
|
SurePasteCommitMessage: "Pasting will overwrite the current commit message, continue?",
|
||||||
CommitMessage: "Commit message",
|
CommitMessage: "Commit message (subject and body)",
|
||||||
|
CommitMessageBody: "Commit message body",
|
||||||
CommitSubject: "Commit subject",
|
CommitSubject: "Commit subject",
|
||||||
CommitAuthor: "Commit author",
|
CommitAuthor: "Commit author",
|
||||||
CommitTags: "Commit tags",
|
CommitTags: "Commit tags",
|
||||||
|
@ -1717,10 +1722,12 @@ func EnglishTranslationSet() *TranslationSet {
|
||||||
CommitDiffCopiedToClipboard: "Commit diff copied to clipboard",
|
CommitDiffCopiedToClipboard: "Commit diff copied to clipboard",
|
||||||
CommitURLCopiedToClipboard: "Commit URL copied to clipboard",
|
CommitURLCopiedToClipboard: "Commit URL copied to clipboard",
|
||||||
CommitMessageCopiedToClipboard: "Commit message copied to clipboard",
|
CommitMessageCopiedToClipboard: "Commit message copied to clipboard",
|
||||||
|
CommitMessageBodyCopiedToClipboard: "Commit message body copied to clipboard",
|
||||||
CommitSubjectCopiedToClipboard: "Commit subject copied to clipboard",
|
CommitSubjectCopiedToClipboard: "Commit subject copied to clipboard",
|
||||||
CommitAuthorCopiedToClipboard: "Commit author copied to clipboard",
|
CommitAuthorCopiedToClipboard: "Commit author copied to clipboard",
|
||||||
CommitTagsCopiedToClipboard: "Commit tags copied to clipboard",
|
CommitTagsCopiedToClipboard: "Commit tags copied to clipboard",
|
||||||
CommitHasNoTags: "Commit has no tags",
|
CommitHasNoTags: "Commit has no tags",
|
||||||
|
CommitHasNoMessageBody: "Commit has no message body",
|
||||||
PatchCopiedToClipboard: "Patch copied to clipboard",
|
PatchCopiedToClipboard: "Patch copied to clipboard",
|
||||||
CopiedToClipboard: "copied to clipboard",
|
CopiedToClipboard: "copied to clipboard",
|
||||||
ErrCannotEditDirectory: "Cannot edit directories: you can only edit individual files",
|
ErrCannotEditDirectory: "Cannot edit directories: you can only edit individual files",
|
||||||
|
@ -1873,48 +1880,49 @@ func EnglishTranslationSet() *TranslationSet {
|
||||||
|
|
||||||
Actions: Actions{
|
Actions: Actions{
|
||||||
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
||||||
CheckoutCommit: "Checkout commit",
|
CheckoutCommit: "Checkout commit",
|
||||||
CheckoutBranchAtCommit: "Checkout branch '%s'",
|
CheckoutBranchAtCommit: "Checkout branch '%s'",
|
||||||
CheckoutCommitAsDetachedHead: "Checkout commit %s as detached head",
|
CheckoutCommitAsDetachedHead: "Checkout commit %s as detached head",
|
||||||
CheckoutTag: "Checkout tag",
|
CheckoutTag: "Checkout tag",
|
||||||
CheckoutBranch: "Checkout branch",
|
CheckoutBranch: "Checkout branch",
|
||||||
ForceCheckoutBranch: "Force checkout branch",
|
ForceCheckoutBranch: "Force checkout branch",
|
||||||
CheckoutBranchOrCommit: "Checkout branch or commit",
|
CheckoutBranchOrCommit: "Checkout branch or commit",
|
||||||
DeleteLocalBranch: "Delete local branch",
|
DeleteLocalBranch: "Delete local branch",
|
||||||
Merge: "Merge",
|
Merge: "Merge",
|
||||||
SquashMerge: "Squash merge",
|
SquashMerge: "Squash merge",
|
||||||
RebaseBranch: "Rebase branch",
|
RebaseBranch: "Rebase branch",
|
||||||
RenameBranch: "Rename branch",
|
RenameBranch: "Rename branch",
|
||||||
CreateBranch: "Create branch",
|
CreateBranch: "Create branch",
|
||||||
CherryPick: "(Cherry-pick) paste commits",
|
CherryPick: "(Cherry-pick) paste commits",
|
||||||
CheckoutFile: "Checkout file",
|
CheckoutFile: "Checkout file",
|
||||||
DiscardOldFileChange: "Discard old file change",
|
DiscardOldFileChange: "Discard old file change",
|
||||||
SquashCommitDown: "Squash commit down",
|
SquashCommitDown: "Squash commit down",
|
||||||
FixupCommit: "Fixup commit",
|
FixupCommit: "Fixup commit",
|
||||||
RewordCommit: "Reword commit",
|
RewordCommit: "Reword commit",
|
||||||
DropCommit: "Drop commit",
|
DropCommit: "Drop commit",
|
||||||
EditCommit: "Edit commit",
|
EditCommit: "Edit commit",
|
||||||
AmendCommit: "Amend commit",
|
AmendCommit: "Amend commit",
|
||||||
ResetCommitAuthor: "Reset commit author",
|
ResetCommitAuthor: "Reset commit author",
|
||||||
SetCommitAuthor: "Set commit author",
|
SetCommitAuthor: "Set commit author",
|
||||||
AddCommitCoAuthor: "Add commit co-author",
|
AddCommitCoAuthor: "Add commit co-author",
|
||||||
RevertCommit: "Revert commit",
|
RevertCommit: "Revert commit",
|
||||||
CreateFixupCommit: "Create fixup commit",
|
CreateFixupCommit: "Create fixup commit",
|
||||||
SquashAllAboveFixupCommits: "Squash all above fixup commits",
|
SquashAllAboveFixupCommits: "Squash all above fixup commits",
|
||||||
CreateLightweightTag: "Create lightweight tag",
|
CreateLightweightTag: "Create lightweight tag",
|
||||||
CreateAnnotatedTag: "Create annotated tag",
|
CreateAnnotatedTag: "Create annotated tag",
|
||||||
CopyCommitMessageToClipboard: "Copy commit message to clipboard",
|
CopyCommitMessageToClipboard: "Copy commit message to clipboard",
|
||||||
CopyCommitSubjectToClipboard: "Copy commit subject to clipboard",
|
CopyCommitMessageBodyToClipboard: "Copy commit message body to clipboard",
|
||||||
CopyCommitTagsToClipboard: "Copy commit tags to clipboard",
|
CopyCommitSubjectToClipboard: "Copy commit subject to clipboard",
|
||||||
CopyCommitDiffToClipboard: "Copy commit diff to clipboard",
|
CopyCommitTagsToClipboard: "Copy commit tags to clipboard",
|
||||||
CopyCommitHashToClipboard: "Copy full commit hash to clipboard",
|
CopyCommitDiffToClipboard: "Copy commit diff to clipboard",
|
||||||
CopyCommitURLToClipboard: "Copy commit URL to clipboard",
|
CopyCommitHashToClipboard: "Copy full commit hash to clipboard",
|
||||||
CopyCommitAuthorToClipboard: "Copy commit author to clipboard",
|
CopyCommitURLToClipboard: "Copy commit URL to clipboard",
|
||||||
CopyCommitAttributeToClipboard: "Copy to clipboard",
|
CopyCommitAuthorToClipboard: "Copy commit author to clipboard",
|
||||||
CopyPatchToClipboard: "Copy patch to clipboard",
|
CopyCommitAttributeToClipboard: "Copy to clipboard",
|
||||||
MoveCommitUp: "Move commit up",
|
CopyPatchToClipboard: "Copy patch to clipboard",
|
||||||
MoveCommitDown: "Move commit down",
|
MoveCommitUp: "Move commit up",
|
||||||
CustomCommand: "Custom command",
|
MoveCommitDown: "Move commit down",
|
||||||
|
CustomCommand: "Custom command",
|
||||||
|
|
||||||
// TODO: remove
|
// TODO: remove
|
||||||
DiscardAllChangesInDirectory: "Discard all changes in directory",
|
DiscardAllChangesInDirectory: "Discard all changes in directory",
|
||||||
|
|
|
@ -174,6 +174,10 @@ func (self *Shell) EmptyCommit(message string) *Shell {
|
||||||
return self.RunCommand([]string{"git", "commit", "--allow-empty", "-m", message})
|
return self.RunCommand([]string{"git", "commit", "--allow-empty", "-m", message})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Shell) EmptyCommitWithBody(subject string, body string) *Shell {
|
||||||
|
return self.RunCommand([]string{"git", "commit", "--allow-empty", "-m", subject, "-m", body})
|
||||||
|
}
|
||||||
|
|
||||||
func (self *Shell) EmptyCommitDaysAgo(message string, daysAgo int) *Shell {
|
func (self *Shell) EmptyCommitDaysAgo(message string, daysAgo int) *Shell {
|
||||||
return self.RunCommand([]string{"git", "commit", "--allow-empty", "--date", fmt.Sprintf("%d days ago", daysAgo), "-m", message})
|
return self.RunCommand([]string{"git", "commit", "--allow-empty", "--date", fmt.Sprintf("%d days ago", daysAgo), "-m", message})
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package commit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
// We're emulating the clipboard by writing to a file called clipboard
|
||||||
|
|
||||||
|
var CopyMessageBodyToClipboard = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Copy a commit message body to the clipboard",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {
|
||||||
|
config.GetUserConfig().OS.CopyToClipboardCmd = "printf '%s' {{text}} > clipboard"
|
||||||
|
},
|
||||||
|
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.EmptyCommitWithBody("My Subject", "My awesome commit message body")
|
||||||
|
},
|
||||||
|
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
t.Views().Commits().
|
||||||
|
Focus().
|
||||||
|
Lines(
|
||||||
|
Contains("My Subject").IsSelected(),
|
||||||
|
).
|
||||||
|
Press(keys.Commits.CopyCommitAttributeToClipboard)
|
||||||
|
|
||||||
|
t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Copy to clipboard")).
|
||||||
|
Select(Contains("Commit message body")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.ExpectToast(Equals("Commit message body copied to clipboard"))
|
||||||
|
|
||||||
|
t.FileSystem().FileContent("clipboard", Equals("My awesome commit message body"))
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,33 @@
|
||||||
|
package commit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var DisableCopyCommitMessageBody = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Disables copy commit message body when there is no body",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.EmptyCommit("commit")
|
||||||
|
},
|
||||||
|
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
t.Views().Commits().
|
||||||
|
Focus().
|
||||||
|
Lines(
|
||||||
|
Contains("commit").IsSelected(),
|
||||||
|
).
|
||||||
|
Press(keys.Commits.CopyCommitAttributeToClipboard)
|
||||||
|
|
||||||
|
t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Copy to clipboard")).
|
||||||
|
Select(Contains("Commit message body")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.ExpectToast(Equals("Disabled: Commit has no message body"))
|
||||||
|
},
|
||||||
|
})
|
|
@ -26,7 +26,7 @@ var PasteCommitMessage = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
Press(keys.Commits.CopyCommitAttributeToClipboard)
|
Press(keys.Commits.CopyCommitAttributeToClipboard)
|
||||||
|
|
||||||
t.ExpectPopup().Menu().Title(Equals("Copy to clipboard")).
|
t.ExpectPopup().Menu().Title(Equals("Copy to clipboard")).
|
||||||
Select(Contains("Commit message")).Confirm()
|
Select(Contains("Commit message (subject and body)")).Confirm()
|
||||||
|
|
||||||
t.ExpectToast(Equals("Commit message copied to clipboard"))
|
t.ExpectToast(Equals("Commit message copied to clipboard"))
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ var PasteCommitMessageOverExisting = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
Press(keys.Commits.CopyCommitAttributeToClipboard)
|
Press(keys.Commits.CopyCommitAttributeToClipboard)
|
||||||
|
|
||||||
t.ExpectPopup().Menu().Title(Equals("Copy to clipboard")).
|
t.ExpectPopup().Menu().Title(Equals("Copy to clipboard")).
|
||||||
Select(Contains("Commit message")).Confirm()
|
Select(Contains("Commit message (subject and body)")).Confirm()
|
||||||
|
|
||||||
t.ExpectToast(Equals("Commit message copied to clipboard"))
|
t.ExpectToast(Equals("Commit message copied to clipboard"))
|
||||||
|
|
||||||
|
|
|
@ -97,10 +97,12 @@ var tests = []*components.IntegrationTest{
|
||||||
commit.CommitWithNonMatchingBranchName,
|
commit.CommitWithNonMatchingBranchName,
|
||||||
commit.CommitWithPrefix,
|
commit.CommitWithPrefix,
|
||||||
commit.CopyAuthorToClipboard,
|
commit.CopyAuthorToClipboard,
|
||||||
|
commit.CopyMessageBodyToClipboard,
|
||||||
commit.CopyTagToClipboard,
|
commit.CopyTagToClipboard,
|
||||||
commit.CreateAmendCommit,
|
commit.CreateAmendCommit,
|
||||||
commit.CreateFixupCommitInBranchStack,
|
commit.CreateFixupCommitInBranchStack,
|
||||||
commit.CreateTag,
|
commit.CreateTag,
|
||||||
|
commit.DisableCopyCommitMessageBody,
|
||||||
commit.DiscardOldFileChanges,
|
commit.DiscardOldFileChanges,
|
||||||
commit.FindBaseCommitForFixup,
|
commit.FindBaseCommitForFixup,
|
||||||
commit.FindBaseCommitForFixupDisregardMainBranch,
|
commit.FindBaseCommitForFixupDisregardMainBranch,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue