summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorStefan Haller <stefan@haller-berlin.de>2024-06-01 08:15:35 +0200
committerGitHub <noreply@github.com>2024-06-01 08:15:35 +0200
commitc5baa5da3ad84e7892d6720e54a95460d2f85ebd (patch)
treeeff53fd6a2cc9582e0c85c00a861949982ea01a5 /pkg
parentab797fe986e1fd3acedefde4ef286cddc5046b49 (diff)
parent3284d69886250576b0b1799a0e691fd7bfaba655 (diff)
Fix pushing to branch when upstream not stored locally (#3619)
- **PR Description** This fixes three different problems; two were recent regressions, one has never worked. 1. For branches whose remote is not stored locally, don't ask to force push right away. Try a normal push first. This broke with #3528. 2. For branches whose remote is not stored locally (but only for those), if the server rejects the update, ask to force push. This broke with #3387. 3. When force-pushing a branch whose remote is not stored locally, use `--force` instead of `--force-with-lease`; otherwise the push would always fail with a "stale info" error. This has never worked. Fixes #3588.
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/git_commands/sync.go4
-rw-r--r--pkg/commands/git_commands/sync_test.go22
-rw-r--r--pkg/commands/models/branch.go2
-rw-r--r--pkg/gui/controllers/sync_controller.go34
-rw-r--r--pkg/i18n/chinese.go635
-rw-r--r--pkg/i18n/english.go2
-rw-r--r--pkg/i18n/korean.go529
-rw-r--r--pkg/i18n/polish.go1
-rw-r--r--pkg/i18n/russian.go767
-rw-r--r--pkg/i18n/traditional_chinese.go767
-rw-r--r--pkg/integration/tests/sync/force_push_remote_branch_not_stored_locally.go81
-rw-r--r--pkg/integration/tests/test_list.go1
12 files changed, 1485 insertions, 1360 deletions
diff --git a/pkg/commands/git_commands/sync.go b/pkg/commands/git_commands/sync.go
index 4ab1f336b..1c93fc260 100644
--- a/pkg/commands/git_commands/sync.go
+++ b/pkg/commands/git_commands/sync.go
@@ -19,6 +19,7 @@ func NewSyncCommands(gitCommon *GitCommon) *SyncCommands {
// Push pushes to a branch
type PushOpts struct {
Force bool
+ ForceWithLease bool
UpstreamRemote string
UpstreamBranch string
SetUpstream bool
@@ -30,7 +31,8 @@ func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (oscommands
}
cmdArgs := NewGitCmd("push").
- ArgIf(opts.Force, "--force-with-lease").
+ ArgIf(opts.Force, "--force").
+ ArgIf(opts.ForceWithLease, "--force-with-lease").
ArgIf(opts.SetUpstream, "--set-upstream").
ArgIf(opts.UpstreamRemote != "", opts.UpstreamRemote).
ArgIf(opts.UpstreamBranch != "", opts.UpstreamBranch).
diff --git a/pkg/commands/git_commands/sync_test.go b/pkg/commands/git_commands/sync_test.go
index f5f281e14..6ff8da840 100644
--- a/pkg/commands/git_commands/sync_test.go
+++ b/pkg/commands/git_commands/sync_test.go
@@ -18,24 +18,32 @@ func TestSyncPush(t *testing.T) {
scenarios := []scenario{
{
testName: "Push with force disabled",
- opts: PushOpts{Force: false},
+ opts: PushOpts{ForceWithLease: false},
test: func(cmdObj oscommands.ICmdObj, err error) {
assert.Equal(t, cmdObj.Args(), []string{"git", "push"})
assert.NoError(t, err)
},
},
{
+ testName: "Push with force-with-lease enabled",
+ opts: PushOpts{ForceWithLease: true},
+ test: func(cmdObj oscommands.ICmdObj, err error) {
+ assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--force-with-lease"})
+ assert.NoError(t, err)
+ },
+ },
+ {
testName: "Push with force enabled",
opts: PushOpts{Force: true},
test: func(cmdObj oscommands.ICmdObj, err error) {
- assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--force-with-lease"})
+ assert.Equal(t, cmdObj.Args(), []string{"git", "push", "--force"})
assert.NoError(t, err)
},
},
{
testName: "Push with force disabled, upstream supplied",
opts: PushOpts{
- Force: false,
+ ForceWithLease: false,
UpstreamRemote: "origin",
UpstreamBranch: "master",
},
@@ -47,7 +55,7 @@ func TestSyncPush(t *testing.T) {
{
testName: "Push with force disabled, setting upstream",
opts: PushOpts{
- Force: false,
+ ForceWithLease: false,
UpstreamRemote: "origin",
UpstreamBranch: "master",
SetUpstream: true,
@@ -58,9 +66,9 @@ func TestSyncPush(t *testing.T) {
},
},
{
- testName: "Push with force enabled, setting upstream",
+ testName: "Push with force-with-lease enabled, setting upstream",
opts: PushOpts{
- Force: true,
+ ForceWithLease: true,
UpstreamRemote: "origin",
UpstreamBranch: "master",
SetUpstream: true,
@@ -73,7 +81,7 @@ func TestSyncPush(t *testing.T) {
{
testName: "Push with remote branch but no origin",
opts: PushOpts{
- Force: true,
+ ForceWithLease: true,
UpstreamRemote: "",
UpstreamBranch: "master",
SetUpstream: true,
diff --git a/pkg/commands/models/branch.go b/pkg/commands/models/branch.go
index 25d806fca..5a34ba5e8 100644
--- a/pkg/commands/models/branch.go
+++ b/pkg/commands/models/branch.go
@@ -104,7 +104,7 @@ func (b *Branch) IsBehindForPull() bool {
}
func (b *Branch) IsBehindForPush() bool {
- return b.BehindForPush != "" && b.BehindForPush != "0"
+ return b.RemoteBranchStoredLocally() && b.BehindForPush != "0"
}
// for when we're in a detached head state
diff --git a/pkg/gui/controllers/sync_controller.go b/pkg/gui/controllers/sync_controller.go
index 7d7ca9eed..8c7334031 100644
--- a/pkg/gui/controllers/sync_controller.go
+++ b/pkg/gui/controllers/sync_controller.go
@@ -89,7 +89,7 @@ func (self *SyncController) branchCheckedOut(f func(*models.Branch) error) func(
func (self *SyncController) push(currentBranch *models.Branch) error {
// if we are behind our upstream branch we'll ask if the user wants to force push
if currentBranch.IsTrackingRemote() {
- opts := pushOpts{}
+ opts := pushOpts{remoteBranchStoredLocally: currentBranch.RemoteBranchStoredLocally()}
if currentBranch.IsBehindForPush() {
return self.requestToForcePush(currentBranch, opts)
} else {
@@ -180,9 +180,16 @@ func (self *SyncController) pullWithLock(task gocui.Task, opts PullFilesOptions)
type pushOpts struct {
force bool
+ forceWithLease bool
upstreamRemote string
upstreamBranch string
setUpstream bool
+
+ // If this is false, we can't tell ahead of time whether a force-push will
+ // be necessary, so we start with a normal push and offer to force-push if
+ // the server rejected. If this is true, we don't offer to force-push if the
+ // server rejected, but rather ask the user to fetch.
+ remoteBranchStoredLocally bool
}
func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts) error {
@@ -192,13 +199,32 @@ func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts)
task,
git_commands.PushOpts{
Force: opts.force,
+ ForceWithLease: opts.forceWithLease,
UpstreamRemote: opts.upstreamRemote,
UpstreamBranch: opts.upstreamBranch,
SetUpstream: opts.setUpstream,
})
if err != nil {
- if strings.Contains(err.Error(), "Updates were rejected") {
- return errors.New(self.c.Tr.UpdatesRejected)
+ if !opts.force && !opts.forceWithLease && strings.Contains(err.Error(), "Updates were rejected") {
+ if opts.remoteBranchStoredLocally {
+ return errors.New(self.c.Tr.UpdatesRejected)
+ }
+
+ forcePushDisabled := self.c.UserConfig.Git.DisableForcePushing
+ if forcePushDisabled {
+ return errors.New(self.c.Tr.UpdatesRejectedAndForcePushDisabled)
+ }
+ _ = self.c.Confirm(types.ConfirmOpts{
+ Title: self.c.Tr.ForcePush,
+ Prompt: self.forcePushPrompt(),
+ HandleConfirm: func() error {
+ newOpts := opts
+ newOpts.force = true
+
+ return self.pushAux(currentBranch, newOpts)
+ },
+ })
+ return nil
}
return err
}
@@ -216,7 +242,7 @@ func (self *SyncController) requestToForcePush(currentBranch *models.Branch, opt
Title: self.c.Tr.ForcePush,
Prompt: self.forcePushPrompt(),
HandleConfirm: func() error {
- opts.force = true
+ opts.forceWithLease = true
return self.pushAux(currentBranch, opts)
},
})
diff --git a/pkg/i18n/chinese.go b/pkg/i18n/chinese.go
index 002143b28..f8ec9720c 100644
--- a/pkg/i18n/chinese.go
+++ b/pkg/i18n/chinese.go
@@ -35,323 +35,324 @@ const chineseIntroPopupMessage = `
// exporting this so we can use it in tests
func chineseTranslationSet() TranslationSet {
return TranslationSet{
- NotEnoughSpace: "没有足够的空间来渲染面板",
- DiffTitle: "差异",
- FilesTitle: "文件",
- BranchesTitle: "分支",
- CommitsTitle: "提交",
- StashTitle: "贮藏",
- UnstagedChanges: `未暂存更改`,
- StagedChanges: `已暂存更改`,
- MainTitle: "主要",
- StagingTitle: "正在暂存",
- MergingTitle: "正在合并",
- NormalTitle: "正常",
- CommitSummary: "提交信息",
- CredentialsUsername: "用户名",
- CredentialsPassword: "密码",
- CredentialsPassphrase: "输入 SSH 密钥的密码",
- PassUnameWrong: "密码 和/或 用户名错误",
- Commit: "提交更改",
- AmendLastCommit: "修补最后一次提交",
- AmendLastCommitTitle: "修补最后一次提交",
- SureToAmend: "您确定要修补上一次提交吗?之后您可以从提交面板更改提交消息。",
- NoCommitToAmend: "没有需要提交的修补。",
- CommitChangesWithEditor: "提交更改(使用编辑器编辑提交信息)",
- StatusTitle: "状态",
- Menu: "菜单",
- Execute: "执行",
- Stage: "切换暂存状态",
- ToggleStagedAll: "切换所有文件的暂存状态",
- ToggleTreeView: "切换文件树视图",
- OpenMergeTool: "打开外部合并工具 (git mergetool)",
- Refresh: "刷新",
- Push: "推送",
- Pull: "拉取",
- Scroll: "滚动",
- MergeConflictsTitle: "合并冲突",
- Checkout: "检出",
- NoChangedFiles: "没有更改过文件",
- SoftReset: "软重置",
- AlreadyCheckedOutBranch: "您已经检出至此分支",
- SureForceCheckout: "您确定要强制检出吗?您将丢失所有本地更改",
- ForceCheckoutBranch: "强制检出分支",
- BranchName: "分支名称",
- NewBranchNameBranchOff: "新分支名称(基于 {{.branchName}})",
- CantDeleteCheckOutBranch: "您不能删除已检出的分支!",
- ForceDeleteBranchMessage: "{{.selectedBranchName}} 还没有被完全合并。您确定要删除它吗?",
- RebaseBranch: "将已检出的分支变基到该分支",
- CantRebaseOntoSelf: "您不能将分支变基到其自身",
- CantMergeBranchIntoItself: "您不能将分支合并到其自身",
- ForceCheckout: "强制检出",
- CheckoutByName: "按名称检出",
- NewBranch: "新分支",
- NoBranchesThisRepo: "此仓库中没有分支",
- CommitWithoutMessageErr: "您必须编写提交消息才能进行提交",
- CloseCancel: "关闭",
- Confirm: "确认",
- Close: "关闭",
- Quit: "退出",
- NoCommitsThisBranch: "该分支没有提交",
- CannotSquashOrFixupFirstCommit: "There's no commit below to squash into",
- Fixup: "修正(fixup)",
- SureFixupThisCommit: "您确定要“修正”此提交吗?它将合并到下面的提交中",
- SureSquashThisCommit: "您确定要将这个提交压缩到下面的提交中吗?",
- Squash: "压缩",
- PickCommitTooltip: "选择提交(变基过程中)",
- RevertCommit: "还原提交",
- Reword: "改写提交",
- DropCommit: "删除提交",
- MoveDownCommit: "下移提交",
- MoveUpCommit: "上移提交",
- EditCommitTooltip: "编辑提交",
- AmendCommitTooltip: "用已暂存的更改来修补提交",
- RewordCommitEditor: "使用编辑器重命名提交",
- Error: "错误",
- PickHunk: "选中区块",
- PickAllHunks: "选中所有区块",
- Undo: "撤销",
- UndoReflog: "(通过 reflog)撤销「实验功能」",
- RedoReflog: "(通过 reflog)重做「实验功能」",
- Pop: "应用并删除",
- Drop: "删除",
- Apply: "应用",
- NoStashEntries: "没有贮藏条目",
- StashDrop: "删除贮藏",
- SureDropStashEntry: "您确定要删除此贮藏条目吗?",
- StashPop: "应用并删除贮藏",
- SurePopStashEntry: "您确定要应用并删除此贮藏条目吗?",
- StashApply: "应用贮藏",
- SureApplyStashEntry: "您确定要应用此贮藏条目?",
- NoTrackedStagedFilesStash: "没有可以贮藏的已跟踪/暂存文件",
- StashChanges: "贮藏更改",
- RenameStash: "Rename stash",
- RenameStashPrompt: "Rename stash: {{.stashName}}",
- OpenConfig: "打开配置文件",
- EditConfig: "编辑配置文件",
- ForcePush: "强制推送",
- ForcePushPrompt: "您的分支已与远程分支不同。按‘esc’取消,或‘enter’强制推送.",
- ForcePushDisabled: "您的分支已与远程分支不同, 并且您已经禁用了强行推送",
- CheckForUpdate: "检查更新",
- CheckingForUpdates: "正在检查更新…",
- OnLatestVersionErr: "已是最新版本",
- MajorVersionErr: "新版本 ({{.newVersion}}) 与当前版本 ({{.currentVersion}}) 相比,具有非向后兼容的更改",
- CouldNotFindBinaryErr: "在 {{.url}} 处找不到任何二进制文件",
- MergeToolTitle: "合并工具",
- MergeToolPrompt: "确定要打开 `git mergetool` 吗?",
- IntroPopupMessage: chineseIntroPopupMessage,
- GitconfigParseErr: `由于存在未加引号的'\'字符,因此 Gogit 无法解析您的 gitconfig 文件。删除它们应该可以解决问题。`,
- EditFile: `编辑文件`,
- OpenFile: `打开文件`,
- IgnoreFile: `添加到 .gitignore`,
- RefreshFiles: `刷新文件`,
- Merge: `合并到当前检出的分支`,
- ConfirmQuit: `您确定要退出吗?`,
- SwitchRepo: `切换到最近的仓库`,
- AllBranchesLogGraph: `显示所有分支的日志`,
- UnsupportedGitService: `不支持的 git 服务`,
- CreatePullRequest: `创建抓取请求`,
- CopyPullRequestURL: `将抓取请求 URL 复制到剪贴板`,
- NoBranchOnRemote: `该分支在远程上不存在. 您需要先将其推送到远程.`,
- Fetch: `抓取`,
- NoAutomaticGitFetchTitle: `无法自动进行 "git fetch"`,
- NoAutomaticGitFetchBody: `Lazygit 不能在私人仓库中使用 "git fetch"; 请在文件面板中使用 'f' 手动运行 "git fetch"`,
- FileEnter: `暂存单个 块/行 用于文件, 或 折叠/展开 目录`,
- FileStagingRequirements: `只能暂存跟踪文件的单独行`,
- StageSelectionTooltip: `切换行暂存状态`,
- DiscardSelection: `取消变更 (git reset)`,
- ToggleRangeSelect: `切换拖动选择`,
- ToggleSelectHunk: `切换选择区块`,
- ToggleSelectionForPatch: `添加/移除 行到补丁`,
- ToggleStagingView: `切换到其他面板`,
- ReturnToFilesPanel: `返回文件面板`,
- FastForward: `从上游快进此分支`,
- FastForwarding: "抓取并快进",
- FoundConflictsTitle: "自动合并失败",
- ViewMergeRebaseOptions: "查看 合并/变基 选项",
- NotMergingOrRebasing: "您目前既不进行变基也不进行合并",
- RecentRepos: "最近的仓库",
- MergeOptionsTitle: "合并选项",
- RebaseOptionsTitle: "变基选项",
- CommitSummaryTitle: "提交讯息",
- LocalBranchesTitle: "分支页面",
- SearchTitle: "搜索",
- TagsTitle: "标签页面",
- MenuTitle: "菜单",
- RemotesTitle: "远程页面",
- RemoteBranchesTitle: "远程分支",
- PatchBuildingTitle: "构建补丁中",
- InformationTitle: "信息",
- SecondaryTitle: "次要",
- ReflogCommitsTitle: "Reflog 页面",
- GlobalTitle: "全局键绑定",
- ConflictsResolved: "已解决所有冲突。是否继续?",
- ConfirmMerge: "您确定要将分支 {{.selectedBranch}} 合并到 {{.checkedOutBranch}} 吗?",
- FwdNoUpstream: "此分支没有上游,无法快进",
- FwdNoLocalUpstream: "此分支的远程未在本地注册,无法快进",
- FwdCommitsToPush: "此分支带有尚未推送的提交,无法快进",
- ErrorOccurred: "发生错误!请在以下位置创建 issue",
- NoRoom: "空间不足",
- YouAreHere: "您在这里",
- RewordNotSupported: "当前不支持交互式重新基准化时的重新措词提交",
- CherryPickCopy: "复制提交(拣选)",
- PasteCommits: "粘贴提交(拣选)",
- SureCherryPick: "您确定要将选中的提交进行拣选到这个分支吗?",
- CherryPick: "拣选 (Cherry-Pick)",
- Donate: "捐助",
- AskQuestion: "提问咨询",
- PrevLine: "选择上一行",
- NextLine: "选择下一行",
- PrevHunk: "选择上一个区块",
- NextHunk: "选择下一个区块",
- PrevConflict: "选择上一个冲突",
- NextConflict: "选择下一个冲突",
- SelectPrevHunk: "选择顶部块",
- SelectNextHunk: "选择底部块",
- ScrollDown: "向下滚动",
- ScrollUp: "向上滚动",
- ScrollUpMainWindow: "向上滚动主面板",
- ScrollDownMainWindow: "向下滚动主面板",
- AmendCommitTitle: "修改提交",
- AmendCommitPrompt: "您确定要使用暂存文件来修改此提交吗?",
- DropCommitTitle: "删除提交",
- DropCommitPrompt: "您确定要删除此提交吗?",
- PullingStatus: "正在拉取",
- PushingStatus: "正在推送",
- FetchingStatus: "正在抓取",
- SquashingStatus: "正在压缩",
- FixingStatus: "正在修正",
- DeletingStatus: "正在删除",
- MovingStatus: "正在移动",
- RebasingStatus: "正在变基",
- AmendingStatus: "正在修改",
- CherryPickingStatus: "正在拣选",
- UndoingStatus: "正在撤销",
- RedoingStatus: "正在重做",
- CheckingOutStatus: "长子检出",
- CommittingStatus: "正在提交",
- CommitFiles: "提交文件",
- ViewItemFiles: "查看提交的文件",
- CommitFilesTitle: "提交文件",
- CheckoutCommitFileTooltip: "检出文件",
- DiscardOldFileChangeTooltip: "放弃对此文件的提交更改",
- DiscardFileChangesTitle: "放弃文件更改",
- DiscardFileChangesPrompt: "您确定要舍弃此提交对该文件的更改吗?如果此文件是在此提交中创建的,它将被删除",
- DisabledForGPG: "该功能不适用于使用 GPG 的用户",
- CreateRepo: "当前目录不在 git 仓库中。是否在此目录创建一个新的 git 仓库?(y/n): ",
- AutoStashTitle: "自动存储?",
- AutoStashPrompt: "您必须隐藏并弹出更改以使更改生效。自动执行?(enter/esc)",
- StashPrefix: "自动隐藏更改 ",
- Discard: "查看'放弃更改'选项",
- Cancel: "取消",
- DiscardAllChanges: "放弃所有更改",
- DiscardUnstagedChanges: "放弃未暂存的变更",
- DiscardAllChangesToAllFiles: "清空工作区",
- DiscardAnyUnstagedChanges: "丢弃未暂存的变更",
- DiscardUntrackedFiles: "丢弃未跟踪的文件",
- HardReset: "硬重置",
- ViewResetOptions: `查看重置选项`,
- CreateFixupCommit: `为此提交创建修正`,
- SquashAboveCommitsTooltip: `压缩在所选提交之上的所有“fixup!”提交(自动压缩)`,
- CreateFixupCommitTooltip: `创建修正提交`,
- ExecuteCustomCommand: "执行自定义命令",
- CustomCommand: "自定义命令:",
- CommitChangesWithoutHook: "提交更改而无需预先提交钩子",
- SkipHookPrefixNotConfigured: "您尚未配置用于跳过钩子的提交消息前缀。请在您的配置中设置 `git.skipHookPrefix ='WIP'`",
- ResetTo: `重置为`,
- PressEnterToReturn: "按下 Enter 键返回 lazygit",
- ViewStashOptions: "查看贮藏选项",
- StashAllChanges: "将所有更改加入贮藏",
- StashAllChangesKeepIndex: "将已暂存的更改加入贮藏",
- StashOptions: "贮藏选项",
- NotARepository: "错误:必须在 git 仓库中运行",
- Jump: "跳到面板",
- ScrollLeftRight: "左右滚动",
- ScrollLeft: "向左滚动",
- ScrollRight: "向右滚动",
- DiscardPatch: "丢弃补丁",
- DiscardPatchConfirm: "您一次只能通过一个提交或贮藏条目构建补丁。需要放弃当前补丁吗?",
- CantPatchWhileRebasingError: "处于合并或变基状态时,您无法构建修补程序或运行修补程序命令",
- ToggleAddToPatch: "补丁中包含的切换文件",
- ViewPatchOptions: "查看自定义补丁选项",
- PatchOptionsTitle: "补丁选项",
- NoPatchError: "尚未创建补丁。你可以在提交中的文件上按下“空格”或使用“回车”添加其中的特定行以开始构建补丁",
- EnterCommitFile: "输入文件以将所选行添加到补丁中(或切换目录折叠)",
- ExitCustomPatchBuilder: `退出逐行模式`,
- EnterUpstream: `以这种格式输入上游:'<远程仓库> <分支名称>'`,
- InvalidUpstream: "上游格式无效,格式应当为:'<remote> <branchname>'",
- ReturnToRemotesList: `返回远程仓库列表`,
- NewRemote: `添加新的远程仓库`,
- NewRemoteName: `新远程仓库名称:`,
- NewRemoteUrl: `新远程仓库 URL:`,
- EditRemoteName: `输入远程仓库 {{.remoteName}} 的新名称:`,
- EditRemoteUrl: `输入远程仓库 {{.remoteName}} 的新 URL:`,
- RemoveRemote: `删除远程`,
- RemoveRemotePrompt: "您确定要删除远程仓库吗?",
- DeleteRemoteBranch: "删除远程分支",
- DeleteRemoteBranchMessage: "您确定要删除远程分支吗?",
- SetUpstream: "设置为检出分支的上游",
- SetAsUpstreamTooltip: "设置为检出分支的上游",
- SetUpstreamTitle: "设置上游分支",
- SetUpstreamMessage: "您确定要将 {{.checkedOut}} 的上游分支设置为 {{.selected}} 吗?",
- EditRemoteTooltip: "编辑远程仓库",
- TagCommit: "标签提交",
- TagMenuTitle: "创建标签",
- TagNameTitle: "标签名称",
- TagMessageTitle: "标签消息",
- AnnotatedTag: "附注标签",
- LightweightTag: "轻量标签",
- PushTagTitle: "将 {{.tagName}} 推送到远程仓库:",
- PushTag: "推送标签",
- NewTag: "创建标签",
- FetchRemoteTooltip: "抓取远程仓库",
- FetchingRemoteStatus: "抓取远程仓库中",
- CheckoutCommit: "检出提交",
- SureCheckoutThisCommit: "您确定要检出此提交吗?",
- GitFlowOptions: "显示 git-flow 选项",
- NotAGitFlowBranch: "这似乎不是 git flow 分支",
- NewGitFlowBranchPrompt: "新的 {{.branchType}} 名称:",
- IgnoreTracked: "忽略跟踪文件",
- IgnoreTrackedPrompt: "您确定要忽略已跟踪的文件吗?",
- ViewResetToUpstreamOptions: "查看上游重置选项",
- NextScreenMode: "下一屏模式(正常/半屏/全屏)",
- PrevScreenMode: "上一屏模式",
- StartSearch: "开始搜索",
- Panel: "面板",
- Keybindings: "按键绑定",
- RenameBranch: "重命名分支",
- NewBranchNamePrompt: "输入分支的新名称",
- RenameBranchWarning: "该分支正在跟踪远程仓库。此操作将仅会重命名本地分支名称,而不会重命名远程分支的名称。确定继续?",
- OpenKeybindingsMenu: "打开菜单",
- ResetCherryPick: "重置已拣选(复制)的提交",
- NextTab: "下一个标签",
- PrevTab: "上一个标签",
- CantUndoWhileRebasing: "进行基础调整时无法撤消",
- CantRedoWhileRebasing: "变基时无法重做",
- MustStashWarning: "将补丁拉出到索引中需要存储和取消存储所做的更改。如果出现问题,您将可以从存储中访问文件。继续?",
- MustStashTitle: "必须保存进度",
- ConfirmationTitle: "确认面板",
- PrevPage: "上一页",
- NextPage: "下一页",
- GotoTop: "滚动到顶部",
- GotoBottom: "滚动到底部",
- FilteringBy: "过滤依据",
- ResetInParentheses: "(重置)",
- OpenFilteringMenu: "查看按路径过滤选项",
- FilterBy: "过滤",
- ExitFilterMode: "停止按路径过滤",
- FilterPathOption: "输入要过滤的路径",
- EnterFileName: "输入路径:",
- FilteringMenuTitle: "正在过滤",
- MustExitFilterModeTitle: "命令不可用",
- MustExitFilterModePrompt: "命令在过滤模式下不可用。退出过滤模式?",
- Diff: "差异",
- EnterRefToDiff: "输入 ref 以 diff",
- EnterRefName: "输入 ref:",
- ExitDiffMode: "退出差异模式",
- DiffingMenuTitle: "正在 diff",
- SwapDiff: "反向 diff",
- ViewDiffingOptions: "打开 diff 菜单",
+ NotEnoughSpace: "没有足够的空间来渲染面板",
+ DiffTitle: "差异",
+ FilesTitle: "文件",
+ BranchesTitle: "分支",
+ CommitsTitle: "提交",
+ StashTitle: "贮藏",
+ UnstagedChanges: `未暂存更改`,
+ StagedChanges: `已暂存更改`,
+ MainTitle: "主要",
+ StagingTitle: "正在暂存",
+ MergingTitle: "正在合并",
+ NormalTitle: "正常",
+ CommitSummary: "提交信息",
+ CredentialsUsername: "用户名",
+ CredentialsPassword: "密码",
+ CredentialsPassphrase: "输入 SSH 密钥的密码",
+ PassUnameWrong: "密码 和/或 用户名错误",
+ Commit: "提交更改",
+ AmendLastCommit: "修补最后一次提交",
+ AmendLastCommitTitle: "修补最后一次提交",
+ SureToAmend: "您确定要修补上一次提交吗?之后您可以从提交面板更改提交消息。",
+ NoCommitToAmend: "没有需要提交的修补。",
+ CommitChangesWithEditor: "提交更改(使用编辑器编辑提交信息)",
+ StatusTitle: "状态",
+ Menu: "菜单",
+ Execute: "执行",
+ Stage: "切换暂存状态",
+ ToggleStagedAll: "切换所有文件的暂存状态",
+ ToggleTreeView: "切换文件树视图",
+ OpenMergeTool: "打开外部合并工具 (git mergetool)",
+ Refresh: "刷新",
+ Push: "推送",
+ Pull: "拉取",
+ Scroll: "滚动",
+ MergeConflictsTitle: "合并冲突",
+ Checkout: "检出",
+ NoChangedFiles: "没有更改过文件",
+ SoftReset: "软重置",
+ AlreadyCheckedOutBranch: "您已经检出至此分支",
+ SureForceCheckout: "您确定要强制检出吗?您将丢失所有本地更改",
+ ForceCheckoutBranch: "强制检出分支",
+ BranchName: "分支名称",
+ NewBranchNameBranchOff: "新分支名称(基于 {{.branchName}})",
+ CantDeleteCheckOutBranch: "您不能删除已检出的分支!",
+ ForceDeleteBranchMessage: "{{.selectedBranchName}} 还没有被完全合并。您确定要删除它吗?",
+ RebaseBranch: "将已检出的分支变基到该分支",
+ CantRebaseOntoSelf: "您不能将分支变基到其自身",
+ CantMergeBranchIntoItself: "您不能将分支合并到其自身",
+ ForceCheckout: "强制检出",
+ CheckoutByName: "按名称检出",
+ NewBranch: "新分支",
+ NoBranchesThisRepo: "此仓库中没有分支",
+ CommitWithoutMessageErr: "您必须编写提交消息才能进行提交",
+ CloseCancel: "关闭",
+ Confirm: "确认",
+ Close: "关闭",
+ Quit: "退出",
+ NoCommitsThisBranch: "该分支没有提交",
+ CannotSquashOrFixupFirstCommit: "There's no commit below to squash into",
+ Fixup: "修正(fixup)",
+ SureFixupThisCommit: "您确定要“修正”此提交吗?它将合并到下面的提交中",
+ SureSquashThisCommit: "您确定要将这个提交压缩到下面的提交中吗?",
+ Squash: "压缩",
+ PickCommitTooltip: "选择提交(变基过程中)",
+ RevertCommit: "还原提交",
+ Reword: "改写提交",
+ DropCommit: "删除提交",
+ MoveDownCommit: "下移提交",
+ MoveUpCommit: "上移提交",
+ EditCommitTooltip: "编辑提交",
+ AmendCommitTooltip: "用已暂存的更改来修补提交",
+ RewordCommitEditor: "使用编辑器重命名提交",
+ Error: "错误",
+ PickHunk: "选中区块",
+ PickAllHunks: "选中所有区块",
+ Undo: "撤销",
+ UndoReflog: "(通过 reflog)撤销「实验功能」",
+ RedoReflog: "(通过 reflog)重做「实验功能」",
+ Pop: "应用并删除",
+ Drop: "删除",
+ Apply: "应用",
+ NoStashEntries: "没有贮藏条目",
+ StashDrop: "删除贮藏",
+ SureDropStashEntry: "您确定要删除此贮藏条目吗?",
+ StashPop: "应用并删除贮藏",
+ SurePopStashEntry: "您确定要应用并删除此贮藏条目吗?",
+ StashApply: "应用贮藏",
+ SureApplyStashEntry: "您确定要应用此贮藏条目?",
+ NoTrackedStagedFilesStash: "没有可以贮藏的已跟踪/暂存文件",
+ StashChanges: "贮藏更改",
+ RenameStash: "Rename stash",
+ RenameStashPrompt: "Rename stash: {{.stashName}}",
+ OpenConfig: