summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-03-18 20:21:49 +0100
committerStefan Haller <stefan@haller-berlin.de>2024-03-22 08:27:45 +0100
commit150cc706981ec6a6e1e4f79f1fbf09cb7af224fd (patch)
treeb94262cc4b79863afb9340b9379ba39371897bfa
parentc92e9d9bdc1c5122a3a1400c63b308a9c6a8253b (diff)
Make it easy to create "amend!" commits
To support this, we turn the confirmation prompt of the "Create fixup commit" command into a menu; creating a fixup commit is the first entry, so that "shift-F, enter" behaves the same as before. But there are additional entries for creating "amend!" commits, either with or without file changes. These make it easy to reword commit messages of existing commits.
-rw-r--r--docs/Fixup_Commits.md13
-rw-r--r--pkg/commands/git_commands/commit.go15
-rw-r--r--pkg/commands/git_commands/commit_test.go51
-rw-r--r--pkg/gui/controllers/local_commits_controller.go83
-rw-r--r--pkg/i18n/chinese.go1
-rw-r--r--pkg/i18n/dutch.go1
-rw-r--r--pkg/i18n/english.go972
-rw-r--r--pkg/i18n/japanese.go1
-rw-r--r--pkg/i18n/korean.go1
-rw-r--r--pkg/i18n/polish.go1
-rw-r--r--pkg/i18n/russian.go1
-rw-r--r--pkg/i18n/traditional_chinese.go1
-rw-r--r--pkg/integration/tests/commit/create_amend_commit.go60
-rw-r--r--pkg/integration/tests/interactive_rebase/squash_fixups_above.go4
-rw-r--r--pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go4
-rw-r--r--pkg/integration/tests/test_list.go1
16 files changed, 706 insertions, 504 deletions
diff --git a/docs/Fixup_Commits.md b/docs/Fixup_Commits.md
index 1d148c546..fde85ee39 100644
--- a/docs/Fixup_Commits.md
+++ b/docs/Fixup_Commits.md
@@ -27,6 +27,19 @@ creates a commit with the appropriate subject line.
Don't confuse this with the lowercase "f" command ("Fixup commit"); that one
squashes the selected commit into its parent, this is not what we want here.
+## Creating amend commits
+
+There's a special type of fixup commit that uses "amend!" instead of "fixup!" in
+the commit message subject; in addition to fixing up the original commit with
+changes it allows you to also (or only) change the commit message of the
+original commit. The menu that appears when pressing shift-F has options for
+both of these; they bring up a commit message panel similar to when you reword a
+commit, but then create the "amend!" commit containing the new message. Note
+that in that panel you only type the new message as you want it to be
+eventually; lazygit then takes care of formatting the "amend!" commit
+appropriately for you (with the subject of your new message moving into the body
+of the "amend!" commit).
+
## Squashing fixup commits
When you're ready to merge the branch and want to squash all these fixup commits
diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go
index 400cd7608..6bf1985e1 100644
--- a/pkg/commands/git_commands/commit.go
+++ b/pkg/commands/git_commands/commit.go
@@ -297,6 +297,21 @@ func (self *CommitCommands) CreateFixupCommit(sha string) error {
return self.cmd.New(cmdArgs).Run()
}
+// CreateAmendCommit creates a commit that changes the commit message of a previous commit
+func (self *CommitCommands) CreateAmendCommit(originalSubject, newSubject, newDescription string, includeFileChanges bool) error {
+ description := newSubject
+ if newDescription != "" {
+ description += "\n\n" + newDescription
+ }
+ cmdArgs := NewGitCmd("commit").
+ Arg("-m", "amend! "+originalSubject).
+ Arg("-m", description).
+ ArgIf(!includeFileChanges, "--only", "--allow-empty").
+ ToArgv()
+
+ return self.cmd.New(cmdArgs).Run()
+}
+
// a value of 0 means the head commit, 1 is the parent commit, etc
func (self *CommitCommands) GetCommitMessageFromHistory(value int) (string, error) {
cmdArgs := NewGitCmd("log").Arg("-1", fmt.Sprintf("--skip=%d", value), "--pretty=%H").
diff --git a/pkg/commands/git_commands/commit_test.go b/pkg/commands/git_commands/commit_test.go
index d6e3397e3..8dc8afa83 100644
--- a/pkg/commands/git_commands/commit_test.go
+++ b/pkg/commands/git_commands/commit_test.go
@@ -180,6 +180,57 @@ func TestCommitCreateFixupCommit(t *testing.T) {
}
}
+func TestCommitCreateAmendCommit(t *testing.T) {
+ type scenario struct {
+ testName string
+ originalSubject string
+ newSubject string
+ newDescription string
+ includeFileChanges bool
+ runner *oscommands.FakeCmdObjRunner
+ }
+
+ scenarios := []scenario{
+ {
+ testName: "subject only",
+ originalSubject: "original subject",
+ newSubject: "new subject",
+ newDescription: "",
+ includeFileChanges: true,
+ runner: oscommands.NewFakeRunner(t).
+ ExpectGitArgs([]string{"commit", "-m", "amend! original subject", "-m", "new subject"}, "", nil),
+ },
+ {
+ testName: "subject and description",
+ originalSubject: "original subject",
+ newSubject: "new subject",
+ newDescription: "new description",
+ includeFileChanges: true,
+ runner: oscommands.NewFakeRunner(t).
+ ExpectGitArgs([]string{"commit", "-m", "amend! original subject", "-m", "new subject\n\nnew description"}, "", nil),
+ },
+ {
+ testName: "without file changes",
+ originalSubject: "original subject",
+ newSubject: "new subject",
+ newDescription: "",
+ includeFileChanges: false,
+ runner: oscommands.NewFakeRunner(t).
+ ExpectGitArgs([]string{"commit", "-m", "amend! original subject", "-m", "new subject", "--only", "--allow-empty"}, "", nil),
+ },
+ }
+
+ for _, s := range scenarios {
+ s := s
+ t.Run(s.testName, func(t *testing.T) {
+ instance := buildCommitCommands(commonDeps{runner: s.runner})
+ err := instance.CreateAmendCommit(s.originalSubject, s.newSubject, s.newDescription, s.includeFileChanges)
+ assert.NoError(t, err)
+ s.runner.CheckForMissingCalls()
+ })
+ }
+}
+
func TestCommitShowCmdObj(t *testing.T) {
type scenario struct {
testName string
diff --git a/pkg/gui/controllers/local_commits_controller.go b/pkg/gui/controllers/local_commits_controller.go
index a4511988e..5c4ce2bd0 100644
--- a/pkg/gui/controllers/local_commits_controller.go
+++ b/pkg/gui/controllers/local_commits_controller.go
@@ -832,30 +832,87 @@ func (self *LocalCommitsController) afterRevertCommit() error {
}
func (self *LocalCommitsController) createFixupCommit(commit *models.Commit) error {
- prompt := utils.ResolvePlaceholderString(
- self.c.Tr.SureCreateFixupCommit,
- map[string]string{
- "commit": commit.Sha,
+ var disabledReasonWhenFilesAreNeeded *types.DisabledReason
+ if len(self.c.Model().Files) == 0 {
+ disabledReasonWhenFilesAreNeeded = &types.DisabledReason{
+ Text: self.c.Tr.NoFilesStagedTitle,
+ ShowErrorInPanel: true,
+ }
+ }
+
+ return self.c.Menu(types.CreateMenuOptions{
+ Title: self.c.Tr.CreateFixupCommit,
+ Items: []*types.MenuItem{
+ {
+ Label: self.c.Tr.FixupMenu_Fixup,
+ Key: 'f',
+ OnPress: func() error {
+ return self.c.Helpers().WorkingTree.WithEnsureCommitableFiles(func() error {
+ self.c.LogAction(self.c.Tr.Actions.CreateFixupCommit)
+ return self.c.WithWaitingStatusSync(self.c.Tr.CreatingFixupCommitStatus, func() error {
+ if err := self.c.Git().Commit.CreateFixupCommit(commit.Sha); err != nil {
+ return self.c.Error(err)
+ }
+
+ self.context().MoveSelectedLine(1)
+ return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC})
+ })
+ })
+ },
+ DisabledReason: disabledReasonWhenFilesAreNeeded,
+ Tooltip: self.c.Tr.FixupMenu_FixupTooltip,
+ },
+ {
+ Label: self.c.Tr.FixupMenu_AmendWithChanges,
+ Key: 'a',
+ OnPress: func() error {
+ return self.c.Helpers().WorkingTree.WithEnsureCommitableFiles(func() error {
+ return self.createAmendCommit(commit, true)
+ })
+ },
+ DisabledReason: disabledReasonWhenFilesAreNeeded,
+ Tooltip: self.c.Tr.FixupMenu_AmendWithChangesTooltip,
+ },
+ {
+ Label: self.c.Tr.FixupMenu_AmendWithoutChanges,
+ Key: 'r',
+ OnPress: func() error { return self.createAmendCommit(commit, false) },
+ Tooltip: self.c.Tr.FixupMenu_AmendWithoutChangesTooltip,
+ },
},
- )
+ })
+}
- return self.c.Confirm(types.ConfirmOpts{
- Title: self.c.Tr.CreateFixupCommit,
- Prompt: prompt,
- HandleConfirm: func() error {
- return self.c.Helpers().WorkingTree.WithEnsureCommitableFiles(func() error {
+func (self *LocalCommitsController) createAmendCommit(commit *models.Commit, includeFileChanges bool) error {
+ commitMessage, err := self.c.Git().Commit.GetCommitMessage(commit.Sha)
+ if err != nil {
+ return self.c.Error(err)
+ }
+ if self.c.UserConfig.Git.Commit.AutoWrapCommitMessage {
+ commitMessage = helpers.TryRemoveHardLineBreaks(commitMessage, self.c.UserConfig.Git.Commit.AutoWrapWidth)
+ }
+ originalSubject, _, _ := strings.Cut(commitMessage, "\n")
+ return self.c.Helpers().Commits.OpenCommitMessagePanel(
+ &helpers.OpenCommitMessagePanelOpts{
+ CommitIndex: self.context().GetSelectedLineIdx(),
+ InitialMessage: commitMessage,
+ SummaryTitle: self.c.Tr.CreateAmendCommit,
+ DescriptionTitle: self.c.Tr.CommitDescriptionTitle,
+ PreserveMessage: false,
+ OnConfirm: func(summary string, description string) error {
self.c.LogAction(self.c.Tr.Actions.CreateFixupCommit)
return self.c.WithWaitingStatusSync(self.c.Tr.CreatingFixupCommitStatus, func() error {
- if err := self.c.Git().Commit.CreateFixupCommit(commit.Sha); err != nil {
+ if err := self.c.Git().Commit.CreateAmendCommit(originalSubject, summary, description, includeFileChanges); err != nil {
return self.c.Error(err)
}
self.context().MoveSelectedLine(1)
return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC})
})
- })
+ },
+ OnSwitchToEditor: nil,
},
- })
+ )
}
func (self *LocalCommitsController) squashFixupCommits() error {
diff --git a/pkg/i18n/chinese.go b/pkg/i18n/chinese.go
index 3d3c14021..5648c922f 100644
--- a/pkg/i18n/chinese.go
+++ b/pkg/i18n/chinese.go
@@ -254,7 +254,6 @@ func chineseTranslationSet() TranslationSet {
CreateFixupCommit: `为此提交创建修正`,
SquashAboveCommitsTooltip: `压缩在所选提交之上的所有“fixup!”提交(自动压缩)`,
CreateFixupCommitTooltip: `创建修正提交`,
- SureCreateFixupCommit: `您确定要对 {{.commit}} 创建修正提交吗?`,
ExecuteCustomCommand: "执行自定义命令",
CustomCommand: "自定义命令:",
CommitChangesWithoutHook: "提交更改而无需预先提交钩子",
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index 73a76c777..99ff50e06 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -217,7 +217,6 @@ func dutchTranslationSet() TranslationSet {
CreateFixupCommit: `Creëer fixup commit`,
SquashAboveCommitsTooltip: `Squash bovenstaande commits`,
CreateFixupCommitTooltip: `Creëer fixup commit`,
- SureCreateFixupCommit: `Weet je zeker dat je een fixup wil maken! commit voor commit {{.commit}}?`,
ExecuteCustomCommand: "Voer aangepaste commando uit",
CustomCommand: "Aangepaste commando:",
CommitChangesWithoutHook: "Commit veranderingen zonder pre-commit hook",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 5c9dce504..bcbf66da8 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -392,6 +392,13 @@ type TranslationSet struct {
FileResetOptionsTooltip string
CreateFixupCommit string
CreateFixupCommitTooltip string
+ CreateAmendCommit string
+ FixupMenu_Fixup string
+ FixupMenu_FixupTooltip string
+ FixupMenu_AmendWithChanges string
+ FixupMenu_AmendWithChangesTooltip string
+ FixupMenu_AmendWithoutChanges string
+ FixupMenu_AmendWithoutChangesTooltip string
SquashAboveCommitsTooltip string
SquashCommitsAboveSelectedTooltip string
SquashCommitsInCurrentBranchTooltip string
@@ -399,7 +406,6 @@ type TranslationSet struct {
SquashCommitsInCurrentBranch string
SquashCommitsAboveSelectedCommit string
CannotSquashCommitsInCurrentBranch string
- SureCreateFixupCommit string
ExecuteCustomCommand string
ExecuteCustomCommandTooltip string
CustomCommand string
@@ -968,485 +974,491 @@ for up-to-date information how to configure your editor.
// exporting this so we can use it in tests
func EnglishTranslationSet() TranslationSet {
return TranslationSet{
- NotEnoughSpace: "Not enough space to render panels",
- DiffTitle: "Diff",
- FilesTitle: "Files",
- BranchesTitle: "Branches",
- CommitsTitle: "Commits",
- StashTitle: "Stash",
- SnakeTitle: "Snake",
- EasterEgg: "Easter egg",
- UnstagedChanges: "Unstaged changes",
- StagedChanges: "Staged changes",
- MainTitle: "Main",
- MergeConfirmTitle: "Merge",
- StagingTitle: "Main panel (staging)",
- MergingTitle: "Main panel (merging)",
- NormalTitle: "Main panel (normal)",
- LogTitle: "Log",
- CommitSummary: "Commit summary",
- CredentialsUsername: "Username",
- CredentialsPassword: "Password",
- CredentialsPassphrase: "Enter passphrase for SSH key",
- CredentialsPIN: "Enter PIN for SSH key",
- PassUnameWrong: "Password, passphrase and/or username wrong",
- Commit: "Commit",
- CommitTooltip: "Commit staged changes.",
- AmendLastCommit: "Amend last commit",
- AmendLastCommitTitle: "Amend last commit",
- SureToAmend: "Are you sure you want to amend last commit? Afterwards, you can change the commit message from the commits panel.",
- NoCommitToAmend: "There's no commit to amend.",
- CommitChangesWithEditor: "Commit changes using git editor",
- FindBaseCommitForFixup: "Find base commit for fixup",
- FindBaseCommitForFixupTooltip: "Find the commit that your current changes are building upon, for the sake of amending/fixing up the commit. This spares you from having to look through your branch's commits one-by-one to see which commit should be amended/fixed up. See docs: <https://github.com/jesseduffield/lazygit/tree/master/docs/Fixup_Commits.md>",
- NoDeletedLinesInDiff: "No deleted lines in diff",
- NoBaseCommitsFound: "No base commits found",
- MultipleBaseCommitsFoundStaged: "Multiple base commits found. (Try staging fewer changes at once)",
- MultipleBaseCommitsFoundUnstaged: "Multiple base commits found. (Try staging some of the changes)",
- BaseCommitIsAlreadyOnMainBranch: "The base commit for this change is already on the main branch",
- BaseCommitIsNotInCurrentView: "Base commit is not in current view",
- HunksWithOnlyAddedLinesWarning: "There are ranges of only added lines in the diff; be careful to check that these belong in the found base commit.\n\nProceed?",
- StatusTitle: "Status",
- Menu: "Menu",
- Execute: "Execute",
- Stage: "Stage",
- StageTooltip: "Toggle staged for selected file.",
- ToggleStagedAll: "Stage all",
- ToggleStagedAllTooltip: "Toggle staged/unstaged for all files in working tree.",
- ToggleTreeView: "Toggle file tree view",
- ToggleTreeViewTooltip: "Toggle file view between flat and tree layout. Flat layout shows all file paths in a single list, tree layout groups files by directory.",
- OpenDiffTool: "Open external diff tool (git difftool)",
- OpenMergeTool: "Open external merge tool",
- OpenMergeToolTooltip: "Run `git mergetool`.",
- Refresh: "Refresh",
- RefreshTooltip: "Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`.",
- Push: "Push",
- PushTooltip: "Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch.",
- Pull: "Pull",
- PullTooltip: "Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch.",
- Scroll: "Scroll",
- MergeConflictsTitle: "Merge conflicts",
- Checkout: "Checkout",
- CheckoutTooltip: "Checkout selected item.",
- CantCheckoutBranchWhilePulling: "You cannot checkout another branch while pulling the current branch",
- TagCheckoutTooltip: "Checkout the selected tag tag as a detached HEAD.",
- RemoteBranchCheckoutTooltip: "Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head.",
- CantPullOrPushSameBranchTwice: "You cannot push or pull a branch while it is already being pushed or pulled",
- FileFilter: "Filter files by status",
- CopyToClipboardMenu: "Copy to clipboard",
- CopyFileName: "File name",
- CopyFilePath: "Path",
- CopyFileDiffTooltip: "If there are staged items, this command considers only them. Otherwise, it considers all the unstaged ones.",
- CopySelectedDiff: "Diff of selected file",
- CopyAllFilesDiff: "Diff of all files",
- NoContentToCopyError: "Nothing to copy",
- FileNameCopiedToast: "File name copied to clipboard",
- FilePathCopiedToast: "File path copied to clipboard",
- FileDiffCopiedToast: "File diff copied to clipboard",
- AllFilesDiffCopiedToast: "All files diff copied to clipboard",
- FilterStagedFiles: "Show only staged files",
- FilterUnstagedFiles: "Show only unstaged files",
- ResetFilter: "Reset filter",
- NoChangedFiles: "No changed files",
- SoftReset: "Soft reset",
- AlreadyCheckedOutBranch: "You have already checked out this branch",
- SureForceCheckout: "Are you sure you want force checkout? You will lose all local changes",
- ForceCheckoutBranch: "Force checkout branch",
- BranchName: "Branch name",
- NewBranchNameBranchOff: "New branch name (branch is off of '{{.branchName}}')",
- CantDeleteCheckOutBranch: "You cannot delete the checked out branch!",
- DeleteBranchTitle: "Delete branch '{{.selectedBranchName}}'?",
- DeleteLocalBranch: "Delete local branch",
- DeleteRemoteBranchOption: "Delete remote branch",
- DeleteRemoteBranchPrompt: "Are you sure you want to delete the remote branch '{{.selectedBranchName}}' from '{{.upstream}}'?",
- ForceDeleteBranchTitle: "Force delete branch",
- ForceDeleteBranchMessage: "'{{.selectedBranchName}}' is not fully merged. Are you sure you want to delete it?",
- RebaseBranch: "Rebase",
- RebaseBranchTooltip: "Rebase the checked-out branch onto the selected branch.",
- CantRebaseOntoSelf: "You cannot rebase a branch onto itself",
- CantMergeBranchIntoItself: "You cannot merge a branch into itself",
- ForceCheckout: "Force checkout",
- ForceCheckoutTooltip: "Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch.",
- CheckoutByName: "Checkout by name",
- CheckoutByNameTooltip: "Checkout by name. In the input box you can enter '-' to switch to the last branch.",
- RemoteBranchCheckoutTitle: "Checkout {{.branchName}}",
- CheckoutTypeNewBranch: "New local branch",
- CheckoutTypeNewBranchTooltip: "Checkout the remote branch as a local branch, tracking the remote branch.",
- CheckoutTypeDetachedHead: "Detached head",
- CheckoutTypeDetachedHeadTooltip: "Checkout the remote branch as a detached head, which can be useful if you just want to test the branch but not work on it yourself. You can still create a local branch from it later.",
- NewBranch: "New branch",
- NewBranchFromStashTooltip: "Create a new branch from the selected stash entry. This works by git checking out the commit that the stash entry was created from, creating a new branch from that commit, then applying the stash entry to the new branch as an additional commit.",
- NoBranchesThisRepo: "No branches for this repo",
- CommitWithoutMessageErr: "You cannot commit without a commit message",
- Close: "Close",
- CloseCancel: "Close/Cancel",
- Confirm: "Confirm",
- Quit: "Quit",
- SquashTooltip: "Squash the selected commit into the commit below it. The selected commit's message will be appended to the commit below it.",
- NoCommitsThisBranch: "No commits for this branch",
- UpdateRefHere: "Update branch '{{.ref}}' here",
- CannotSquashOrFixupFirstCommit: "There's no commit below to squash into",
- Fixup: "Fixup",
- SureFixupThisCommit: "Are you sure you want to 'fixup' the selected commit(s) into the commit below?",
- SureSquashThisCommit: "Are you sure you want to squash the selected commit(s) into the commit below?",
- Squash: "Squash",
- PickCommitTooltip: "Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase.",
- Pick: "Pick",
- CantPickDisabledReason: "Cannot pick a commit when not mid-rebase",
- Edit: "Edit",
- RevertCommit: "Revert commit",
- Revert: "Revert",
- RevertCommitTooltip: "Create a revert commit for the selected commit, which applies the selected commit's changes in reverse.",
- Reword: "Reword",
- CommitRewordTooltip: "Reword the selected commit's message.",
- DropCommit: "Drop",
- DropCommitTooltip: "Drop the selected commit. This will remove the commit from the branch via a rebase. If the commit makes changes that later commits depend on, you may need to resolve merge conflicts.",
- MoveDownCommit: "Move commit down one",
- MoveUpCommit: "Move commit up one",
- CannotMoveAnyFurther: "Cannot move any further",
- EditCommit: "Edit (start interactive rebase)",
- EditCommitTooltip: "Edit the selected commit. Use this to start an interactive rebase from the selected commit. When already mid-rebase, this will mark the selected commit for editing, which means that upon continuing the rebase, the rebase will pause at the selected commit to allow you to make changes.",
- 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",
- ResetAuthor: "Reset author",
- ResetAuthorTooltip: "Reset the commit's author to the currently configured user. This will also renew the author timestamp",
- SetAuthor: "Set author",
- SetAuthorTooltip: "Set the author based on a prompt",
- AddCoAuthor: "Add co-author",
- AmendCommitAttribute: "Amend commit attribute",
- AmendCommitAttributeTooltip: "Set/Reset commit author or set co-author.",
- SetAuthorPromptTitle: "Set author (must look like 'Name <Email>')",
- AddCoAuthorPromptTitle: "Add co-author (must look like 'Name <Email>')",
- AddCoAuthorTooltip: "Add co-author using the Github/Gitlab metadata Co-authored-by.",
- SureResetCommitAuthor: "The author field of this commit will be updated to match the configured user. This also renews the author timestamp. Continue?",
- RewordCommitEditor: "Reword with editor",
- Error: "Error",
- PickHunk: "Pick hunk",
- PickAllHunks: "Pick all hunks",
- Undo: "Undo",
- UndoReflog: "Undo",
- RedoReflog: "Redo",
- UndoTooltip: "The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration.",
- RedoTooltip: "The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration.",
- UndoMergeResolveTooltip: "Undo last merge conflict resolution.",
- DiscardAllTooltip: "Discard both staged and unstaged changes in '{{.path}}'.",
- DiscardUnstagedTooltip: "Discard unstaged changes in '{{.path}}'.",
- Pop: "Pop",
- StashPopTooltip: "Apply the stash entry to your working directory and remove the stash entry.",
- Drop: "Drop",
- StashDropTooltip: "Remove the stash entry from the stash list.",
- Apply: "Apply",
- StashApplyTooltip: "Apply the stash entry to your working directory.",
- NoStashEntries: "No stash entries",
- StashDrop: "Stash drop",
- SureDropStashEntry: "Are you sure you want to drop this stash entry?",
- StashPop: "Stash pop",
- SurePopStashEntry: "Are you sure you want to pop this stash entry?",
- StashApply: "Stash apply",
- SureApplyStashEntry: "Are you sure you want to apply this stash entry?",
- NoTrackedStagedFilesStash: "You have no tracked/staged files to stash",
- NoFilesToStash: "You have no files to stash",
- StashChanges: "Stash changes",
- RenameStash: "Rename stash",
- RenameStashPrompt: "Rename stash: {{.stashName}}",
- OpenConfig: "Open config file",
- EditConfig: "Edit config file",
- ForcePush: "Force push",
- ForcePushPrompt: "Your branch has diverged from the remote branch. Press {{.cancelKey}} to cancel, or {{.confirmKey}} to force push.",
- ForcePushDisabled: "Your branch has diverged from the remote branch and you've disabled force pushing",
- UpdatesRejected: "Updates were rejected. Please fetch and examine the remote changes before pushing again.",
- CheckForUpdate: "Check for update",
- CheckingForUpdates: "Checking for updates...",
- UpdateAvailableTitle: "Update available!",
- UpdateAvailable: "Download and install version {{.newVersion}}?",
- UpdateInProgressWaitingStatus: "Updating",
- UpdateCompletedTitle: "Update completed!",
- UpdateCompleted: "Update has been installed successfully. Restart lazygit for it to take effect.",
- FailedToRetrieveLatestVersionErr: "Failed to retrieve version information",
- OnLatestVersionErr: "You already have the latest version",
- MajorVersionErr: "New version ({{.newVersion}}) has non-backwards compatible changes compared to the current version ({{.currentVersion}})",
- CouldNotFindBinaryErr: "Could not find any binary at {{.url}}",
- UpdateFailedErr: "Update failed: {{.errMessage}}",
- ConfirmQuitDuringUpdateTitle: "Currently updating",
- ConfirmQuitDuringUpdate: "An update is in progress. Are you sure you want to quit?",
- MergeToolTitle: "Merge tool",
- MergeToolPrompt: "Are you sure you want to open `git mergetool`?",
- IntroPopupMessage: englishIntroPopupMessage,
- DeprecatedEditConfigWarning: englishDeprecatedEditConfigWarning,
- GitconfigParseErr: `Gogit failed to parse your gitconfig file due to the presence of unquoted '\' characters. Removing these should fix the issue.`,
- EditFile: `Edit file`,
- EditFileTooltip: "Open file in external editor.",
- OpenFile: `Open file`,
- OpenFileTooltip: "Open file in default application.",
- OpenInEditor: "Open in editor",
- IgnoreFile: `Add to .gitignore`,
- ExcludeFile: `Add to .git/info/exclude`,
- RefreshFiles: `Refresh files`,
- Merge: `Merge`,
- MergeBranchTooltip: "Merge selected branch into currently checked out branch.",
- ConfirmQuit: `Are you sure you want to quit?`,
- SwitchRepo: `Switch to a recent repo`,
- AllBranchesLogGraph: `Show all branch logs`,
- UnsupportedGitService: `Unsupported git service`,
- CreatePullRequest: `Create pull request`,
- CopyPullRequestURL: `Copy pull request URL to clipboard`,
- NoBranchOnRemote: `This branch doesn't exist on remote. You need to push it to remote first.`,
- Fetch: `Fetch`,
- FetchTooltip: "Fetch changes from remote.",
- NoAutomaticGitFetchTitle: `No automatic git fetch`,
- NoAutomaticGitFetchBody: `Lazygit can't use "git fetch" in a private repo; use 'f' in the files panel to run "git fetch" manually`,
- FileEnter: `Stage lines / Collapse directory`,
- FileEnterTooltip: "If the selected item is a file, focus the staging view so you can stage individual hunks/lines. If the selected item is a directory, collapse/expand it.",
- FileStagingRequirements: `Can only stage individual lines for tracked files`,
- StageSelectionTooltip: `Toggle selection staged / unstaged.`,
- DiscardSelection: `Discard`,
- DiscardSelectionTooltip: "When unstaged change is selected, discard the change using `git reset`. When staged change is selected, unstage the change.",
- ToggleRangeSelect: "Toggle range select",
- ToggleSelectHunk: "Select hunk",
- ToggleSelectHunkTooltip: "Toggle hunk selection mode.",
- ToggleSelectionForPatch: `Toggle lines in patch`,
- EditHunk: `Edit hunk`,
- EditHunkTooltip: "Edit selected hunk in external editor.",
- ToggleStagingView: "Switch view",
- ToggleStagingViewTooltip: "Switch to other view (staged/unstaged changes).",
- ReturnToFilesPanel: `Return to files panel`,
- FastForward: `Fast-forward`,
- FastForwardTooltip: "Fast-forward selected branch from its upstream.",
- FastForwarding: "Fast-forwarding",
- FoundConflictsTitle: "Conflicts!",
- ViewConflictsMenuItem: "View conflicts",
- AbortMenuItem: "Abort the %s",
- ViewMergeRebaseOptions: "View merge/rebase options",
- ViewMergeRebaseOptionsTooltip: "View options to abort/continue/skip the current merge/rebase.",
- ViewMergeOptions: "View merge options",
- ViewRebaseOptions: "View rebase options",
- NotMergingOrRebasing: "You are currently neither rebasing nor merging",
- AlreadyRebasing: "Can't perform this action during a rebase",
- RecentRepos: "Recent repositories",
- MergeOptionsTitle: "Merge options",
- RebaseOptionsTitle: "Rebase options",
- CommitSummaryTitle: "Commit summary",
- CommitDescriptionTitle: "Commit description",
- CommitDescriptionSubTitle: "Press {{.togglePanelKeyBinding}} to toggle focus, {{.commitMenuKeybinding}} to open menu",
- LocalBranchesTitle: "Local branches",
- SearchTitle: "Search",
- TagsTitle: "Tags",
- MenuTitle: "Menu",
- CommitMenuTitle: "Commit Menu",
- RemotesTitle: "Remotes",
- RemoteBranchesTitle: "Remote branches",
- PatchBuildingTitle: "Main panel (patch building)",
- InformationTitle: "Information",
- SecondaryTitle: "Secondary",
- ReflogCommitsTitle: "Reflog",
- GlobalTitle: "Global keybindings",
- ConflictsResolved: "All merge conflicts resolved. Continue?",
- Continue: "Continue",
- Keybindings: "Keybindings",
- KeybindingsMenuSectionLocal: "Local",
- KeybindingsMenuSectionGlobal: "Global",
- KeybindingsMenuSectionNavigation: "Navigation",
- RebasingTitle: "Rebase '{{.checkedOutBranch}}' onto '{{.ref}}'",
- RebasingFromBaseCommitTitle: "Rebase '{{.checkedOutBranch}}' from marked base onto '{{.ref}}'",
- SimpleRebase: "Simple rebase",
- InteractiveRebase: "Interactive rebase",
- InteractiveRebaseTooltip: "Begin an interactive rebase with a break at the start, so you can update the TODO commits before continuing.",
- MustSelectTodoCommits: "When rebasing, this action only works on a selection of TODO commits.",
- ConfirmMerge: "Are you sure you want to merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}'?",
- FwdNoUpstream: "Cannot fast-forward a branch with no upstream",
- FwdNoLocalUpstream: "Cannot fast-forward a branch whose remote is not registered locally",
- FwdCommitsToPush: "Cannot fast-forward a branch with commits to push",
- PullRequestNoUpstream: "Cannot open a pull request for a branch with no upstream",
- ErrorOccurred: "An error occurred! Please create an issue at",
- NoRoom: "Not enough room",
- YouAreHere: "YOU ARE HERE",
- YouDied: "YOU DIED!",
- RewordNotSupported: "Rewording commits while interactively rebasing is not currently supported",
- ChangingThisActionIsNotAllowed: "Changing this kind of rebase todo entry is not allowed",
- CherryPickCopy: "Copy (cherry-pick)",
- CherryPickCopyTooltip: "Mark commit as copied. Then, within the local commits view, you can press `{{.paste}}` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `{{.escape}}` to cancel the selection.",
- CherryPickCopyRangeTooltip: "Mark commits as copied from the last copied commit to the selected commit.",
- PasteCommits: "Paste (cherry-pick)",
- SureCher