mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-23 12:18:51 +02:00
Add Squash merge (#3566)
- **PR Description** Hello, This PR add merge --squash. A PR already exist https://github.com/jesseduffield/lazygit/pull/3130, but the author abandoned it, so I remake it. I modified to fit most of the comment made except this one https://github.com/jesseduffield/lazygit/pull/3130/files#r1404808121. I didn't find an existing example and thus didn't know to modify the code to fit it to the new way of doing things. There's still the choice box to commit or not to do as discussed https://github.com/jesseduffield/lazygit/pull/3130#issuecomment-2112324990. I'll do it when I have time, I first need to read the code to see how it really works. Also only english has been made for now.  - **Please check if the PR fulfills these requirements** * [x] Cheatsheets are up-to-date (run `go generate ./...`) * [x] Code has been formatted (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting)) * [x] Tests have been added/updated (see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md) for the integration test guide) * [x] Text is internationalised (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation)) * [x] Docs (specifically `docs/Config.md`) have been updated if necessary * [x] You've read through your own file changes for silly mistakes etc <!-- Be sure to name your PR with an imperative e.g. 'Add worktrees view' see https://github.com/jesseduffield/lazygit/releases/tag/v0.40.0 for examples -->
This commit is contained in:
commit
1285554cb2
@ -283,6 +283,9 @@ git:
|
|||||||
# Extra args passed to `git merge`, e.g. --no-ff
|
# Extra args passed to `git merge`, e.g. --no-ff
|
||||||
args: ""
|
args: ""
|
||||||
|
|
||||||
|
# The commit message to use for a squash merge commit. Can contain "{{selectedRef}}" and "{{currentBranch}}" placeholders.
|
||||||
|
squashMergeMessage: Squash merge {{selectedRef}} into {{currentBranch}}
|
||||||
|
|
||||||
# list of branches that are considered 'main' branches, used when displaying commits
|
# list of branches that are considered 'main' branches, used when displaying commits
|
||||||
mainBranches:
|
mainBranches:
|
||||||
- master
|
- master
|
||||||
|
@ -162,7 +162,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` F `` | Force checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | Force checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | Merge | Merge selected branch into currently checked out branch. |
|
| `` M `` | Merge | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | New tag | |
|
| `` T `` | New tag | |
|
||||||
| `` s `` | Sort order | |
|
| `` s `` | Sort order | |
|
||||||
@ -265,7 +265,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` <c-o> `` | Copy branch name to clipboard | |
|
| `` <c-o> `` | Copy branch name to clipboard | |
|
||||||
| `` <space> `` | Checkout | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | Checkout | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | New branch | |
|
| `` n `` | New branch | |
|
||||||
| `` M `` | Merge | Merge selected branch into currently checked out branch. |
|
| `` M `` | Merge | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||||
|
@ -232,7 +232,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` F `` | Force checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | Force checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | 現在のブランチにマージ | Merge selected branch into currently checked out branch. |
|
| `` M `` | 現在のブランチにマージ | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
| `` f `` | Fast-forward | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | タグを作成 | |
|
| `` T `` | タグを作成 | |
|
||||||
| `` s `` | 並び替え | |
|
| `` s `` | 並び替え | |
|
||||||
@ -329,7 +329,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` <c-o> `` | ブランチ名をクリップボードにコピー | |
|
| `` <c-o> `` | ブランチ名をクリップボードにコピー | |
|
||||||
| `` <space> `` | チェックアウト | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | チェックアウト | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | 新しいブランチを作成 | |
|
| `` n `` | 新しいブランチを作成 | |
|
||||||
| `` M `` | 現在のブランチにマージ | Merge selected branch into currently checked out branch. |
|
| `` M `` | 現在のブランチにマージ | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Rebase | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||||
|
@ -189,7 +189,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
|||||||
| `` F `` | 강제 체크아웃 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | 강제 체크아웃 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | 체크아웃된 브랜치를 이 브랜치에 리베이스 | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | 체크아웃된 브랜치를 이 브랜치에 리베이스 | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | 현재 브랜치에 병합 | Merge selected branch into currently checked out branch. |
|
| `` M `` | 현재 브랜치에 병합 | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | Fast-forward this branch from its upstream | Fast-forward selected branch from its upstream. |
|
| `` f `` | Fast-forward this branch from its upstream | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | 태그를 생성 | |
|
| `` T `` | 태그를 생성 | |
|
||||||
| `` s `` | Sort order | |
|
| `` s `` | Sort order | |
|
||||||
@ -242,7 +242,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
|||||||
| `` <c-o> `` | 브랜치명을 클립보드에 복사 | |
|
| `` <c-o> `` | 브랜치명을 클립보드에 복사 | |
|
||||||
| `` <space> `` | 체크아웃 | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | 체크아웃 | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | 새 브랜치 생성 | |
|
| `` n `` | 새 브랜치 생성 | |
|
||||||
| `` M `` | 현재 브랜치에 병합 | Merge selected branch into currently checked out branch. |
|
| `` M `` | 현재 브랜치에 병합 | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | 체크아웃된 브랜치를 이 브랜치에 리베이스 | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | 체크아웃된 브랜치를 이 브랜치에 리베이스 | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
| `` u `` | Set as upstream | Set the selected remote branch as the upstream of the checked-out branch. |
|
||||||
|
@ -101,7 +101,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
|||||||
| `` F `` | Forceer checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | Forceer checkout | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | Rebase branch | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Rebase branch | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | Merge in met huidige checked out branch | Merge selected branch into currently checked out branch. |
|
| `` M `` | Merge in met huidige checked out branch | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | Fast-forward deze branch vanaf zijn upstream | Fast-forward selected branch from its upstream. |
|
| `` f `` | Fast-forward deze branch vanaf zijn upstream | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | Creëer tag | |
|
| `` T `` | Creëer tag | |
|
||||||
| `` s `` | Sort order | |
|
| `` s `` | Sort order | |
|
||||||
@ -243,7 +243,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` <c-o> `` | Kopieer branch name naar klembord | |
|
| `` <c-o> `` | Kopieer branch name naar klembord | |
|
||||||
| `` <space> `` | Uitchecken | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | Uitchecken | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | Nieuwe branch | |
|
| `` n `` | Nieuwe branch | |
|
||||||
| `` M `` | Merge in met huidige checked out branch | Merge selected branch into currently checked out branch. |
|
| `` M `` | Merge in met huidige checked out branch | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | Rebase branch | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Rebase branch | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | Stel in als upstream van uitgecheckte branch |
|
| `` u `` | Set as upstream | Stel in als upstream van uitgecheckte branch |
|
||||||
|
@ -189,7 +189,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` F `` | Принудительное переключение | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | Принудительное переключение | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | Перебазировать переключённую ветку на эту ветку | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Перебазировать переключённую ветку на эту ветку | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | Слияние с текущей переключённой веткой | Merge selected branch into currently checked out branch. |
|
| `` M `` | Слияние с текущей переключённой веткой | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | Перемотать эту ветку вперёд из её upstream-ветки | Fast-forward selected branch from its upstream. |
|
| `` f `` | Перемотать эту ветку вперёд из её upstream-ветки | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | Создать тег | |
|
| `` T `` | Создать тег | |
|
||||||
| `` s `` | Порядок сортировки | |
|
| `` s `` | Порядок сортировки | |
|
||||||
@ -299,7 +299,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` <c-o> `` | Скопировать название ветки в буфер обмена | |
|
| `` <c-o> `` | Скопировать название ветки в буфер обмена | |
|
||||||
| `` <space> `` | Переключить | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | Переключить | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | Новая ветка | |
|
| `` n `` | Новая ветка | |
|
||||||
| `` M `` | Слияние с текущей переключённой веткой | Merge selected branch into currently checked out branch. |
|
| `` M `` | Слияние с текущей переключённой веткой | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | Перебазировать переключённую ветку на эту ветку | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | Перебазировать переключённую ветку на эту ветку | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | Установить как upstream-ветку переключённую ветку |
|
| `` u `` | Set as upstream | Установить как upstream-ветку переключённую ветку |
|
||||||
|
@ -91,7 +91,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
|
|||||||
| `` F `` | 强制检出 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | 强制检出 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | 将已检出的分支变基到该分支 | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | 将已检出的分支变基到该分支 | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | 合并到当前检出的分支 | Merge selected branch into currently checked out branch. |
|
| `` M `` | 合并到当前检出的分支 | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | 从上游快进此分支 | Fast-forward selected branch from its upstream. |
|
| `` f `` | 从上游快进此分支 | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | 创建标签 | |
|
| `` T `` | 创建标签 | |
|
||||||
| `` s `` | Sort order | |
|
| `` s `` | Sort order | |
|
||||||
@ -342,7 +342,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` <c-o> `` | 将分支名称复制到剪贴板 | |
|
| `` <c-o> `` | 将分支名称复制到剪贴板 | |
|
||||||
| `` <space> `` | 检出 | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | 检出 | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | 新分支 | |
|
| `` n `` | 新分支 | |
|
||||||
| `` M `` | 合并到当前检出的分支 | Merge selected branch into currently checked out branch. |
|
| `` M `` | 合并到当前检出的分支 | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | 将已检出的分支变基到该分支 | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | 将已检出的分支变基到该分支 | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | 设置为检出分支的上游 |
|
| `` u `` | Set as upstream | 设置为检出分支的上游 |
|
||||||
|
@ -264,7 +264,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` F `` | 強制檢出 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
| `` F `` | 強制檢出 | Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch. |
|
||||||
| `` d `` | Delete | View delete options for local/remote branch. |
|
| `` d `` | Delete | View delete options for local/remote branch. |
|
||||||
| `` r `` | 將已檢出的分支變基至此分支 | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | 將已檢出的分支變基至此分支 | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` M `` | 合併到當前檢出的分支 | Merge selected branch into currently checked out branch. |
|
| `` M `` | 合併到當前檢出的分支 | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` f `` | 從上游快進此分支 | Fast-forward selected branch from its upstream. |
|
| `` f `` | 從上游快進此分支 | Fast-forward selected branch from its upstream. |
|
||||||
| `` T `` | 建立標籤 | |
|
| `` T `` | 建立標籤 | |
|
||||||
| `` s `` | Sort order | |
|
| `` s `` | Sort order | |
|
||||||
@ -353,7 +353,7 @@ If you would instead like to start an interactive rebase from the selected commi
|
|||||||
| `` <c-o> `` | 複製分支名稱到剪貼簿 | |
|
| `` <c-o> `` | 複製分支名稱到剪貼簿 | |
|
||||||
| `` <space> `` | 檢出 | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
| `` <space> `` | 檢出 | Checkout a new local branch based on the selected remote branch, or the remote branch as a detached head. |
|
||||||
| `` n `` | 新分支 | |
|
| `` n `` | 新分支 | |
|
||||||
| `` M `` | 合併到當前檢出的分支 | Merge selected branch into currently checked out branch. |
|
| `` M `` | 合併到當前檢出的分支 | View options for merging the selected item into the current branch (regular merge, squash merge) |
|
||||||
| `` r `` | 將已檢出的分支變基至此分支 | Rebase the checked-out branch onto the selected branch. |
|
| `` r `` | 將已檢出的分支變基至此分支 | Rebase the checked-out branch onto the selected branch. |
|
||||||
| `` d `` | Delete | Delete the remote branch from the remote. |
|
| `` d `` | Delete | Delete the remote branch from the remote. |
|
||||||
| `` u `` | Set as upstream | 將此分支設為當前分支之上游 |
|
| `` u `` | Set as upstream | 將此分支設為當前分支之上游 |
|
||||||
|
@ -216,13 +216,18 @@ func (self *BranchCommands) Rename(oldName string, newName string) error {
|
|||||||
|
|
||||||
type MergeOpts struct {
|
type MergeOpts struct {
|
||||||
FastForwardOnly bool
|
FastForwardOnly bool
|
||||||
|
Squash bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
|
func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
|
||||||
|
if opts.Squash && opts.FastForwardOnly {
|
||||||
|
panic("Squash and FastForwardOnly can't both be true")
|
||||||
|
}
|
||||||
cmdArgs := NewGitCmd("merge").
|
cmdArgs := NewGitCmd("merge").
|
||||||
Arg("--no-edit").
|
Arg("--no-edit").
|
||||||
Arg(strings.Fields(self.UserConfig.Git.Merging.Args)...).
|
Arg(strings.Fields(self.UserConfig.Git.Merging.Args)...).
|
||||||
ArgIf(opts.FastForwardOnly, "--ff-only").
|
ArgIf(opts.FastForwardOnly, "--ff-only").
|
||||||
|
ArgIf(opts.Squash, "--squash", "--ff").
|
||||||
Arg(branchName).
|
Arg(branchName).
|
||||||
ToArgv()
|
ToArgv()
|
||||||
|
|
||||||
|
@ -285,6 +285,8 @@ type MergingConfig struct {
|
|||||||
ManualCommit bool `yaml:"manualCommit"`
|
ManualCommit bool `yaml:"manualCommit"`
|
||||||
// Extra args passed to `git merge`, e.g. --no-ff
|
// Extra args passed to `git merge`, e.g. --no-ff
|
||||||
Args string `yaml:"args" jsonschema:"example=--no-ff"`
|
Args string `yaml:"args" jsonschema:"example=--no-ff"`
|
||||||
|
// The commit message to use for a squash merge commit. Can contain "{{selectedRef}}" and "{{currentBranch}}" placeholders.
|
||||||
|
SquashMergeMessage string `yaml:"squashMergeMessage"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LogConfig struct {
|
type LogConfig struct {
|
||||||
@ -732,6 +734,7 @@ func GetDefaultConfig() *UserConfig {
|
|||||||
Merging: MergingConfig{
|
Merging: MergingConfig{
|
||||||
ManualCommit: false,
|
ManualCommit: false,
|
||||||
Args: "",
|
Args: "",
|
||||||
|
SquashMergeMessage: "Squash merge {{selectedRef}} into {{currentBranch}}",
|
||||||
},
|
},
|
||||||
Log: LogConfig{
|
Log: LogConfig{
|
||||||
Order: "topo-order",
|
Order: "topo-order",
|
||||||
|
@ -111,10 +111,11 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
||||||
Handler: opts.Guards.OutsideFilterMode(self.merge),
|
Handler: opts.Guards.OutsideFilterMode(self.merge),
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected(self.notMergingIntoYourself)),
|
||||||
Description: self.c.Tr.Merge,
|
Description: self.c.Tr.Merge,
|
||||||
Tooltip: self.c.Tr.MergeBranchTooltip,
|
Tooltip: self.c.Tr.MergeBranchTooltip,
|
||||||
DisplayOnScreen: true,
|
DisplayOnScreen: true,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
||||||
@ -826,3 +827,14 @@ func (self *BranchesController) branchIsReal(branch *models.Branch) *types.Disab
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *BranchesController) notMergingIntoYourself(branch *models.Branch) *types.DisabledReason {
|
||||||
|
selectedBranchName := branch.Name
|
||||||
|
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef().Name
|
||||||
|
|
||||||
|
if checkedOutBranch == selectedBranchName {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.CantMergeBranchIntoItself}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -369,23 +369,82 @@ func (self *MergeAndRebaseHelper) MergeRefIntoCheckedOutBranch(refName string) e
|
|||||||
if checkedOutBranchName == refName {
|
if checkedOutBranchName == refName {
|
||||||
return errors.New(self.c.Tr.CantMergeBranchIntoItself)
|
return errors.New(self.c.Tr.CantMergeBranchIntoItself)
|
||||||
}
|
}
|
||||||
prompt := utils.ResolvePlaceholderString(
|
|
||||||
self.c.Tr.ConfirmMerge,
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
|
Title: self.c.Tr.Merge,
|
||||||
|
Items: []*types.MenuItem{
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.RegularMerge,
|
||||||
|
OnPress: self.RegularMerge(refName),
|
||||||
|
Key: 'm',
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.RegularMergeTooltip,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
"checkedOutBranch": checkedOutBranchName,
|
"checkedOutBranch": checkedOutBranchName,
|
||||||
"selectedBranch": refName,
|
"selectedBranch": refName,
|
||||||
},
|
},
|
||||||
)
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.SquashMergeUncommittedTitle,
|
||||||
|
OnPress: self.SquashMergeUncommitted(refName),
|
||||||
|
Key: 's',
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.SquashMergeUncommitted,
|
||||||
|
map[string]string{
|
||||||
|
"selectedBranch": refName,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Label: self.c.Tr.SquashMergeCommittedTitle,
|
||||||
|
OnPress: self.SquashMergeCommitted(refName, checkedOutBranchName),
|
||||||
|
Key: 'S',
|
||||||
|
Tooltip: utils.ResolvePlaceholderString(
|
||||||
|
self.c.Tr.SquashMergeCommitted,
|
||||||
|
map[string]string{
|
||||||
|
"checkedOutBranch": checkedOutBranchName,
|
||||||
|
"selectedBranch": refName,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return self.c.Confirm(types.ConfirmOpts{
|
func (self *MergeAndRebaseHelper) RegularMerge(refName string) func() error {
|
||||||
Title: self.c.Tr.MergeConfirmTitle,
|
return func() error {
|
||||||
Prompt: prompt,
|
|
||||||
HandleConfirm: func() error {
|
|
||||||
self.c.LogAction(self.c.Tr.Actions.Merge)
|
self.c.LogAction(self.c.Tr.Actions.Merge)
|
||||||
err := self.c.Git().Branch.Merge(refName, git_commands.MergeOpts{})
|
err := self.c.Git().Branch.Merge(refName, git_commands.MergeOpts{})
|
||||||
return self.CheckMergeOrRebase(err)
|
return self.CheckMergeOrRebase(err)
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *MergeAndRebaseHelper) SquashMergeUncommitted(refName string) func() error {
|
||||||
|
return func() error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.SquashMerge)
|
||||||
|
err := self.c.Git().Branch.Merge(refName, git_commands.MergeOpts{Squash: true})
|
||||||
|
return self.CheckMergeOrRebase(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *MergeAndRebaseHelper) SquashMergeCommitted(refName, checkedOutBranchName string) func() error {
|
||||||
|
return func() error {
|
||||||
|
self.c.LogAction(self.c.Tr.Actions.SquashMerge)
|
||||||
|
err := self.c.Git().Branch.Merge(refName, git_commands.MergeOpts{Squash: true})
|
||||||
|
if err = self.CheckMergeOrRebase(err); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
message := utils.ResolvePlaceholderString(self.c.UserConfig.Git.Merging.SquashMergeMessage, map[string]string{
|
||||||
|
"selectedRef": refName,
|
||||||
|
"currentBranch": checkedOutBranchName,
|
||||||
})
|
})
|
||||||
|
err = self.c.Git().Commit.CommitCmdObj(message, "").Run()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MergeAndRebaseHelper) ResetMarkedBaseCommit() error {
|
func (self *MergeAndRebaseHelper) ResetMarkedBaseCommit() error {
|
||||||
|
@ -24,7 +24,11 @@ type TranslationSet struct {
|
|||||||
MainTitle string
|
MainTitle string
|
||||||
StagingTitle string
|
StagingTitle string
|
||||||
MergingTitle string
|
MergingTitle string
|
||||||
MergeConfirmTitle string
|
SquashMergeUncommittedTitle string
|
||||||
|
SquashMergeCommittedTitle string
|
||||||
|
SquashMergeUncommitted string
|
||||||
|
SquashMergeCommitted string
|
||||||
|
RegularMergeTooltip string
|
||||||
NormalTitle string
|
NormalTitle string
|
||||||
LogTitle string
|
LogTitle string
|
||||||
CommitSummary string
|
CommitSummary string
|
||||||
@ -133,6 +137,7 @@ type TranslationSet struct {
|
|||||||
SureFixupThisCommit string
|
SureFixupThisCommit string
|
||||||
SureSquashThisCommit string
|
SureSquashThisCommit string
|
||||||
Squash string
|
Squash string
|
||||||
|
SquashMerge string
|
||||||
PickCommitTooltip string
|
PickCommitTooltip string
|
||||||
Pick string
|
Pick string
|
||||||
CantPickDisabledReason string
|
CantPickDisabledReason string
|
||||||
@ -229,6 +234,7 @@ type TranslationSet struct {
|
|||||||
ExcludeFile string
|
ExcludeFile string
|
||||||
RefreshFiles string
|
RefreshFiles string
|
||||||
Merge string
|
Merge string
|
||||||
|
RegularMerge string
|
||||||
MergeBranchTooltip string
|
MergeBranchTooltip string
|
||||||
ConfirmQuit string
|
ConfirmQuit string
|
||||||
SwitchRepo string
|
SwitchRepo string
|
||||||
@ -296,7 +302,6 @@ type TranslationSet struct {
|
|||||||
InteractiveRebaseTooltip string
|
InteractiveRebaseTooltip string
|
||||||
RebaseOntoBaseBranchTooltip string
|
RebaseOntoBaseBranchTooltip string
|
||||||
MustSelectTodoCommits string
|
MustSelectTodoCommits string
|
||||||
ConfirmMerge string
|
|
||||||
FwdNoUpstream string
|
FwdNoUpstream string
|
||||||
FwdNoLocalUpstream string
|
FwdNoLocalUpstream string
|
||||||
FwdCommitsToPush string
|
FwdCommitsToPush string
|
||||||
@ -841,6 +846,7 @@ type Actions struct {
|
|||||||
DeleteLocalBranch string
|
DeleteLocalBranch string
|
||||||
DeleteBranch string
|
DeleteBranch string
|
||||||
Merge string
|
Merge string
|
||||||
|
SquashMerge string
|
||||||
RebaseBranch string
|
RebaseBranch string
|
||||||
RenameBranch string
|
RenameBranch string
|
||||||
CreateBranch string
|
CreateBranch string
|
||||||
@ -993,7 +999,8 @@ func EnglishTranslationSet() *TranslationSet {
|
|||||||
UnstagedChanges: "Unstaged changes",
|
UnstagedChanges: "Unstaged changes",
|
||||||
StagedChanges: "Staged changes",
|
StagedChanges: "Staged changes",
|
||||||
MainTitle: "Main",
|
MainTitle: "Main",
|
||||||
MergeConfirmTitle: "Merge",
|
SquashMergeUncommittedTitle: "Squash merge and leave uncommitted",
|
||||||
|
SquashMergeCommittedTitle: "Squash merge and commit",
|
||||||
StagingTitle: "Main panel (staging)",
|
StagingTitle: "Main panel (staging)",
|
||||||
MergingTitle: "Main panel (merging)",
|
MergingTitle: "Main panel (merging)",
|
||||||
NormalTitle: "Main panel (normal)",
|
NormalTitle: "Main panel (normal)",
|
||||||
@ -1105,6 +1112,7 @@ func EnglishTranslationSet() *TranslationSet {
|
|||||||
SureFixupThisCommit: "Are you sure you want to 'fixup' the selected commit(s) into the commit below?",
|
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?",
|
SureSquashThisCommit: "Are you sure you want to squash the selected commit(s) into the commit below?",
|
||||||
Squash: "Squash",
|
Squash: "Squash",
|
||||||
|
SquashMerge: "Squash Merge",
|
||||||
PickCommitTooltip: "Mark the selected commit to be picked (when mid-rebase). This means that the commit will be retained upon continuing the rebase.",
|
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",
|
Pick: "Pick",
|
||||||
CantPickDisabledReason: "Cannot pick a commit when not mid-rebase",
|
CantPickDisabledReason: "Cannot pick a commit when not mid-rebase",
|
||||||
@ -1200,7 +1208,8 @@ func EnglishTranslationSet() *TranslationSet {
|
|||||||
ExcludeFile: `Add to .git/info/exclude`,
|
ExcludeFile: `Add to .git/info/exclude`,
|
||||||
RefreshFiles: `Refresh files`,
|
RefreshFiles: `Refresh files`,
|
||||||
Merge: `Merge`,
|
Merge: `Merge`,
|
||||||
MergeBranchTooltip: "Merge selected branch into currently checked out branch.",
|
RegularMerge: "Regular merge",
|
||||||
|
MergeBranchTooltip: "View options for merging the selected item into the current branch (regular merge, squash merge)",
|
||||||
ConfirmQuit: `Are you sure you want to quit?`,
|
ConfirmQuit: `Are you sure you want to quit?`,
|
||||||
SwitchRepo: `Switch to a recent repo`,
|
SwitchRepo: `Switch to a recent repo`,
|
||||||
AllBranchesLogGraph: `Show all branch logs`,
|
AllBranchesLogGraph: `Show all branch logs`,
|
||||||
@ -1271,7 +1280,9 @@ func EnglishTranslationSet() *TranslationSet {
|
|||||||
InteractiveRebaseTooltip: "Begin an interactive rebase with a break at the start, so you can update the TODO commits before continuing.",
|
InteractiveRebaseTooltip: "Begin an interactive rebase with a break at the start, so you can update the TODO commits before continuing.",
|
||||||
RebaseOntoBaseBranchTooltip: "Rebase the checked out branch onto its base branch (i.e. the closest main branch).",
|
RebaseOntoBaseBranchTooltip: "Rebase the checked out branch onto its base branch (i.e. the closest main branch).",
|
||||||
MustSelectTodoCommits: "When rebasing, this action only works on a selection of TODO commits.",
|
MustSelectTodoCommits: "When rebasing, this action only works on a selection of TODO commits.",
|
||||||
ConfirmMerge: "Are you sure you want to merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}'?",
|
SquashMergeUncommitted: "Squash merge '{{.selectedBranch}}' into the working tree.",
|
||||||
|
SquashMergeCommitted: "Squash merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}' as a single commit.",
|
||||||
|
RegularMergeTooltip: "Merge '{{.selectedBranch}}' into '{{.checkedOutBranch}}'.",
|
||||||
FwdNoUpstream: "Cannot fast-forward a branch with no upstream",
|
FwdNoUpstream: "Cannot fast-forward a branch with no upstream",
|
||||||
FwdNoLocalUpstream: "Cannot fast-forward a branch whose remote is not registered locally",
|
FwdNoLocalUpstream: "Cannot fast-forward a branch whose remote is not registered locally",
|
||||||
FwdCommitsToPush: "Cannot fast-forward a branch with commits to push",
|
FwdCommitsToPush: "Cannot fast-forward a branch with commits to push",
|
||||||
@ -1770,6 +1781,7 @@ func EnglishTranslationSet() *TranslationSet {
|
|||||||
DeleteLocalBranch: "Delete local branch",
|
DeleteLocalBranch: "Delete local branch",
|
||||||
DeleteBranch: "Delete branch",
|
DeleteBranch: "Delete branch",
|
||||||
Merge: "Merge",
|
Merge: "Merge",
|
||||||
|
SquashMerge: "Squash merge",
|
||||||
RebaseBranch: "Rebase branch",
|
RebaseBranch: "Rebase branch",
|
||||||
RenameBranch: "Rename branch",
|
RenameBranch: "Rename branch",
|
||||||
CreateBranch: "Create branch",
|
CreateBranch: "Create branch",
|
||||||
|
64
pkg/integration/tests/branch/squash_merge.go
Normal file
64
pkg/integration/tests/branch/squash_merge.go
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package branch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
)
|
||||||
|
|
||||||
|
var SquashMerge = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "Squash merge a branch both with and without committing",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.NewBranch("original-branch").
|
||||||
|
EmptyCommit("one").
|
||||||
|
NewBranch("change-worktree-branch").
|
||||||
|
CreateFileAndAdd("work", "content").
|
||||||
|
Commit("work").
|
||||||
|
Checkout("original-branch").
|
||||||
|
NewBranch("change-commit-branch").
|
||||||
|
CreateFileAndAdd("file", "content").
|
||||||
|
Commit("file").
|
||||||
|
Checkout("original-branch")
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
t.Views().Commits().TopLines(
|
||||||
|
Contains("one"),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Views().Branches().
|
||||||
|
Focus().
|
||||||
|
Lines(
|
||||||
|
Contains("original-branch").IsSelected(),
|
||||||
|
Contains("change-commit-branch"),
|
||||||
|
Contains("change-worktree-branch"),
|
||||||
|
).
|
||||||
|
SelectNextItem().
|
||||||
|
Press(keys.Branches.MergeIntoCurrentBranch)
|
||||||
|
|
||||||
|
t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Merge")).
|
||||||
|
Select(Contains("Squash merge and commit")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.Views().Commits().TopLines(
|
||||||
|
Contains("Squash merge change-commit-branch into original-branch"),
|
||||||
|
Contains("one"),
|
||||||
|
)
|
||||||
|
|
||||||
|
t.Views().Branches().
|
||||||
|
Focus().
|
||||||
|
NavigateToLine(Contains("change-worktree-branch")).
|
||||||
|
Press(keys.Branches.MergeIntoCurrentBranch)
|
||||||
|
|
||||||
|
t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Merge")).
|
||||||
|
Select(Contains("Squash merge and leave uncommitted")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.Views().Files().Focus().Lines(
|
||||||
|
Contains("work"),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
@ -61,6 +61,7 @@ var tests = []*components.IntegrationTest{
|
|||||||
branch.ShowDivergenceFromUpstream,
|
branch.ShowDivergenceFromUpstream,
|
||||||
branch.SortLocalBranches,
|
branch.SortLocalBranches,
|
||||||
branch.SortRemoteBranches,
|
branch.SortRemoteBranches,
|
||||||
|
branch.SquashMerge,
|
||||||
branch.Suggestions,
|
branch.Suggestions,
|
||||||
branch.UnsetUpstream,
|
branch.UnsetUpstream,
|
||||||
cherry_pick.CherryPick,
|
cherry_pick.CherryPick,
|
||||||
|
@ -101,9 +101,9 @@ var ModeSpecificKeybindingSuggestions = NewIntegrationTest(NewIntegrationTestArg
|
|||||||
NavigateToLine(Contains("second-change-branch")).
|
NavigateToLine(Contains("second-change-branch")).
|
||||||
Press(keys.Branches.MergeIntoCurrentBranch).
|
Press(keys.Branches.MergeIntoCurrentBranch).
|
||||||
Tap(func() {
|
Tap(func() {
|
||||||
t.ExpectPopup().Confirmation().
|
t.ExpectPopup().Menu().
|
||||||
Title(Equals("Merge")).
|
Title(Equals("Merge")).
|
||||||
Content(Contains("Are you sure you want to merge")).
|
Select(Contains("Regular merge")).
|
||||||
Confirm()
|
Confirm()
|
||||||
|
|
||||||
t.Common().AcknowledgeConflicts()
|
t.Common().AcknowledgeConflicts()
|
||||||
|
@ -530,6 +530,11 @@
|
|||||||
"examples": [
|
"examples": [
|
||||||
"--no-ff"
|
"--no-ff"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"squashMergeMessage": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "The commit message to use for a squash merge commit. Can contain \"{{selectedRef}}\" and \"{{currentBranch}}\" placeholders.",
|
||||||
|
"default": "Squash merge {{selectedRef}} into {{currentBranch}}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user