1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-06 22:33:07 +02:00

Add new command "Checkout previous branch" (#4728)

## **PR Description**
I added a new feature to checkout to the last branch.
I think it would be convenient to be able to checkout to the last branch
with just one key stroke(`-`) in some cases, such as when switching
between multiple branches during code review.

Off course, I know that you can same thing by entering `"-"` to the text
input of "Checkout by name" or using custom command but I think `git
checkout -` is occasional use case. So I feel this feature can be a part
of default features.

Another advantage of this feature is that you can checkout to the last
branch regardless of cursor position.
Being able to switch branches without worrying about cursor position
reduces stress I think.
This commit is contained in:
Stefan Haller
2025-07-12 18:20:11 +02:00
committed by GitHub
16 changed files with 86 additions and 6 deletions

View File

@ -627,6 +627,7 @@ keybinding:
copyPullRequestURL: <c-y> copyPullRequestURL: <c-y>
checkoutBranchByName: c checkoutBranchByName: c
forceCheckoutBranch: F forceCheckoutBranch: F
checkoutPreviousBranch: '-'
rebaseBranch: r rebaseBranch: r
renameBranch: R renameBranch: R
mergeIntoCurrentBranch: M mergeIntoCurrentBranch: M

View File

@ -170,7 +170,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` o `` | Create pull request | | | `` o `` | Create pull request | |
| `` O `` | View create pull request options | | | `` O `` | View create pull request options | |
| `` <c-y> `` | Copy pull request URL to clipboard | | | `` <c-y> `` | Copy pull request URL to clipboard | |
| `` c `` | Checkout by name | Checkout by name. In the input box you can enter '-' to switch to the last branch. | | `` c `` | Checkout by name | Checkout by name. In the input box you can enter '-' to switch to the previous branch. |
| `` - `` | Checkout previous branch | |
| `` 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. |

View File

@ -367,6 +367,7 @@ _凡例:`<c-b>` はctrl+b、`<a-b>` はalt+b、`B` はshift+bを意味
| `` O `` | プルリクエスト作成オプションを表示 | | | `` O `` | プルリクエスト作成オプションを表示 | |
| `` <c-y> `` | プルリクエストURLをクリップボードにコピー | | | `` <c-y> `` | プルリクエストURLをクリップボードにコピー | |
| `` c `` | 名前でチェックアウト | 名前でチェックアウトします。入力ボックスに「-」を入力すると、最後のブランチをチェックアウトすることができます。 | | `` c `` | 名前でチェックアウト | 名前でチェックアウトします。入力ボックスに「-」を入力すると、最後のブランチをチェックアウトすることができます。 |
| `` - `` | Checkout previous branch | |
| `` F `` | 強制チェックアウト | 選択したブランチを強制的にチェックアウトします。これにより、選択したブランチをチェックアウトする前にワーキングディレクトリ内のすべてのローカル変更が破棄されます。 | | `` F `` | 強制チェックアウト | 選択したブランチを強制的にチェックアウトします。これにより、選択したブランチをチェックアウトする前にワーキングディレクトリ内のすべてのローカル変更が破棄されます。 |
| `` d `` | 削除 | ローカル/リモートブランチの削除オプションを表示します。 | | `` d `` | 削除 | ローカル/リモートブランチの削除オプションを表示します。 |
| `` r `` | リベース | チェックアウトしたブランチを選択したブランチ上にリベースします。 | | `` r `` | リベース | チェックアウトしたブランチを選択したブランチ上にリベースします。 |

View File

@ -206,7 +206,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` o `` | 풀 리퀘스트 생성 | | | `` o `` | 풀 리퀘스트 생성 | |
| `` O `` | 풀 리퀘스트 생성 옵션 | | | `` O `` | 풀 리퀘스트 생성 옵션 | |
| `` <c-y> `` | 풀 리퀘스트 URL을 클립보드에 복사 | | | `` <c-y> `` | 풀 리퀘스트 URL을 클립보드에 복사 | |
| `` c `` | 이름으로 체크아웃 | Checkout by name. In the input box you can enter '-' to switch to the last branch. | | `` c `` | 이름으로 체크아웃 | Checkout by name. In the input box you can enter '-' to switch to the previous branch. |
| `` - `` | Checkout previous branch | |
| `` 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 `` | 삭제 | View delete options for local/remote branch. | | `` d `` | 삭제 | 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. |

View File

@ -103,7 +103,8 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` o `` | Maak een pull-request | | | `` o `` | Maak een pull-request | |
| `` O `` | Bekijk opties voor pull-aanvraag | | | `` O `` | Bekijk opties voor pull-aanvraag | |
| `` <c-y> `` | Kopieer de URL van het pull-verzoek naar het klembord | | | `` <c-y> `` | Kopieer de URL van het pull-verzoek naar het klembord | |
| `` c `` | Uitchecken bij naam | Checkout by name. In the input box you can enter '-' to switch to the last branch. | | `` c `` | Uitchecken bij naam | Checkout by name. In the input box you can enter '-' to switch to the previous branch. |
| `` - `` | Checkout previous branch | |
| `` 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. |

View File

@ -137,6 +137,7 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
| `` O `` | Zobacz opcje tworzenia pull requesta | | | `` O `` | Zobacz opcje tworzenia pull requesta | |
| `` <c-y> `` | Kopiuj adres URL żądania ściągnięcia do schowka | | | `` <c-y> `` | Kopiuj adres URL żądania ściągnięcia do schowka | |
| `` c `` | Przełącz według nazwy | Przełącz według nazwy. W polu wprowadzania możesz wpisać '-' aby przełączyć się na ostatnią gałąź. | | `` c `` | Przełącz według nazwy | Przełącz według nazwy. W polu wprowadzania możesz wpisać '-' aby przełączyć się na ostatnią gałąź. |
| `` - `` | Checkout previous branch | |
| `` F `` | Wymuś przełączenie | Wymuś przełączenie wybranej gałęzi. To spowoduje odrzucenie wszystkich lokalnych zmian w drzewie roboczym przed przełączeniem na wybraną gałąź. | | `` F `` | Wymuś przełączenie | Wymuś przełączenie wybranej gałęzi. To spowoduje odrzucenie wszystkich lokalnych zmian w drzewie roboczym przed przełączeniem na wybraną gałąź. |
| `` d `` | Usuń | Wyświetl opcje usuwania lokalnej/odległej gałęzi. | | `` d `` | Usuń | Wyświetl opcje usuwania lokalnej/odległej gałęzi. |
| `` r `` | Przebazuj | Przebazuj przełączoną gałąź na wybraną gałąź. | | `` r `` | Przebazuj | Przebazuj przełączoną gałąź na wybraną gałąź. |

View File

@ -97,6 +97,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` O `` | View create pull request options | | | `` O `` | View create pull request options | |
| `` <c-y> `` | Copiar URL do pull request para área de transferência | | | `` <c-y> `` | Copiar URL do pull request para área de transferência | |
| `` c `` | Checar por nome | Checar por nome. Na caixa de entrada você pode inserir '-' para trocar para a última branch | | `` c `` | Checar por nome | Checar por nome. Na caixa de entrada você pode inserir '-' para trocar para a última branch |
| `` - `` | Checkout previous branch | |
| `` F `` | Forçar checagem | Forçar checagem da branch selecionada. Isso irá descartar todas as mudanças no seu diretório de trabalho antes cheque a branch selecionada | | `` F `` | Forçar checagem | Forçar checagem da branch selecionada. Isso irá descartar todas as mudanças no seu diretório de trabalho antes cheque a branch selecionada |
| `` d `` | Apagar | Ver opções de exclusão para a branch local/remoto. | | `` d `` | Apagar | Ver opções de exclusão para a branch local/remoto. |
| `` r `` | Refazer | Refazer a branch checada na branch selecionada | | `` r `` | Refazer | Refazer a branch checada na branch selecionada |

View File

@ -204,7 +204,8 @@ _Связки клавиш_
| `` o `` | Создать запрос на принятие изменений | | | `` o `` | Создать запрос на принятие изменений | |
| `` O `` | Создать параметры запроса принятие изменений | | | `` O `` | Создать параметры запроса принятие изменений | |
| `` <c-y> `` | Скопировать URL запроса на принятие изменений в буфер обмена | | | `` <c-y> `` | Скопировать URL запроса на принятие изменений в буфер обмена | |
| `` c `` | Переключить по названию | Checkout by name. In the input box you can enter '-' to switch to the last branch. | | `` c `` | Переключить по названию | Checkout by name. In the input box you can enter '-' to switch to the previous branch. |
| `` - `` | Checkout previous branch | |
| `` 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. |

View File

@ -228,6 +228,7 @@ _图例:`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` O `` | 创建拉取请求选项 | | | `` O `` | 创建拉取请求选项 | |
| `` <c-y> `` | 复制拉取请求 URL 到剪贴板 | | | `` <c-y> `` | 复制拉取请求 URL 到剪贴板 | |
| `` c `` | 按名称检出 | 按名称检出。在输入框中,您可以输入'-' 来切换到最后一个分支。 | | `` c `` | 按名称检出 | 按名称检出。在输入框中,您可以输入'-' 来切换到最后一个分支。 |
| `` - `` | Checkout previous branch | |
| `` F `` | 强制检出 | 强制检出所选分支。这将在检出所选分支之前放弃工作目录中的所有本地更改。 | | `` F `` | 强制检出 | 强制检出所选分支。这将在检出所选分支之前放弃工作目录中的所有本地更改。 |
| `` d `` | 删除 | 查看本地/远程分支的删除选项 | | `` d `` | 删除 | 查看本地/远程分支的删除选项 |
| `` r `` | 变基 | 将检出的分支变基到所选的分支上。 | | `` r `` | 变基 | 将检出的分支变基到所选的分支上。 |

View File

@ -279,7 +279,8 @@ _說明:`<c-b>` 表示 Ctrl+B、`<a-b>` 表示 Alt+B,`B`表示 Shift+B
| `` o `` | 建立拉取請求 | | | `` o `` | 建立拉取請求 | |
| `` O `` | 建立拉取請求選項 | | | `` O `` | 建立拉取請求選項 | |
| `` <c-y> `` | 複製拉取請求的 URL 到剪貼板 | | | `` <c-y> `` | 複製拉取請求的 URL 到剪貼板 | |
| `` c `` | 根據名稱檢出 | Checkout by name. In the input box you can enter '-' to switch to the last branch. | | `` c `` | 根據名稱檢出 | Checkout by name. In the input box you can enter '-' to switch to the previous branch. |
| `` - `` | Checkout previous branch | |
| `` 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 `` | 刪除 | View delete options for local/remote branch. | | `` d `` | 刪除 | 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. |

View File

@ -497,6 +497,7 @@ type KeybindingBranchesConfig struct {
CopyPullRequestURL string `yaml:"copyPullRequestURL"` CopyPullRequestURL string `yaml:"copyPullRequestURL"`
CheckoutBranchByName string `yaml:"checkoutBranchByName"` CheckoutBranchByName string `yaml:"checkoutBranchByName"`
ForceCheckoutBranch string `yaml:"forceCheckoutBranch"` ForceCheckoutBranch string `yaml:"forceCheckoutBranch"`
CheckoutPreviousBranch string `yaml:"checkoutPreviousBranch"`
RebaseBranch string `yaml:"rebaseBranch"` RebaseBranch string `yaml:"rebaseBranch"`
RenameBranch string `yaml:"renameBranch"` RenameBranch string `yaml:"renameBranch"`
MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"` MergeIntoCurrentBranch string `yaml:"mergeIntoCurrentBranch"`
@ -957,6 +958,7 @@ func GetDefaultConfig() *UserConfig {
ViewPullRequestOptions: "O", ViewPullRequestOptions: "O",
CheckoutBranchByName: "c", CheckoutBranchByName: "c",
ForceCheckoutBranch: "F", ForceCheckoutBranch: "F",
CheckoutPreviousBranch: "-",
RebaseBranch: "r", RebaseBranch: "r",
RenameBranch: "R", RenameBranch: "R",
MergeIntoCurrentBranch: "M", MergeIntoCurrentBranch: "M",

View File

@ -89,6 +89,11 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
Description: self.c.Tr.CheckoutByName, Description: self.c.Tr.CheckoutByName,
Tooltip: self.c.Tr.CheckoutByNameTooltip, Tooltip: self.c.Tr.CheckoutByNameTooltip,
}, },
{
Key: opts.GetKey(opts.Config.Branches.CheckoutPreviousBranch),
Handler: self.checkoutPreviousBranch,
Description: self.c.Tr.CheckoutPreviousBranch,
},
{ {
Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch), Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch),
Handler: self.forceCheckout, Handler: self.forceCheckout,
@ -483,6 +488,11 @@ func (self *BranchesController) forceCheckout() error {
return nil return nil
} }
func (self *BranchesController) checkoutPreviousBranch() error {
self.c.LogAction(self.c.Tr.Actions.CheckoutBranch)
return self.c.Helpers().Refs.CheckoutRef("-", types.CheckoutRefOptions{})
}
func (self *BranchesController) checkoutByName() error { func (self *BranchesController) checkoutByName() error {
self.c.Prompt(types.PromptOpts{ self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.BranchName + ":", Title: self.c.Tr.BranchName + ":",

View File

@ -139,6 +139,7 @@ type TranslationSet struct {
ForceCheckoutTooltip string ForceCheckoutTooltip string
CheckoutByName string CheckoutByName string
CheckoutByNameTooltip string CheckoutByNameTooltip string
CheckoutPreviousBranch string
RemoteBranchCheckoutTitle string RemoteBranchCheckoutTitle string
RemoteBranchCheckoutPrompt string RemoteBranchCheckoutPrompt string
CheckoutTypeNewBranch string CheckoutTypeNewBranch string
@ -1181,7 +1182,8 @@ func EnglishTranslationSet() *TranslationSet {
ForceCheckout: "Force checkout", ForceCheckout: "Force checkout",
ForceCheckoutTooltip: "Force checkout selected branch. This will discard all local changes in your working directory before checking out the selected branch.", 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", CheckoutByName: "Checkout by name",
CheckoutByNameTooltip: "Checkout by name. In the input box you can enter '-' to switch to the last branch.", CheckoutByNameTooltip: "Checkout by name. In the input box you can enter '-' to switch to the previous branch.",
CheckoutPreviousBranch: "Checkout previous branch",
RemoteBranchCheckoutTitle: "Checkout {{.branchName}}", RemoteBranchCheckoutTitle: "Checkout {{.branchName}}",
RemoteBranchCheckoutPrompt: "How would you like to check out this branch?", RemoteBranchCheckoutPrompt: "How would you like to check out this branch?",
CheckoutTypeNewBranch: "New local branch", CheckoutTypeNewBranch: "New local branch",

View File

@ -0,0 +1,51 @@
package branch
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var CheckoutPreviousBranch = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Checkout to the previous branch using the checkout previous branch functionality",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {
shell.
CreateNCommits(3).
NewBranch("previous-branch").
EmptyCommit("previous commit").
Checkout("master").
EmptyCommit("master commit")
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Branches().
Focus().
Lines(
Contains("master").IsSelected(),
Contains("previous-branch"),
)
// Press the checkout previous branch key (should checkout previous-branch)
t.Views().Branches().
Press(keys.Branches.CheckoutPreviousBranch).
Lines(
Contains("previous-branch").IsSelected(),
Contains("master"),
)
// Verify we're on previous-branch
t.Git().CurrentBranchName("previous-branch")
// Press again to go back to master
t.Views().Branches().
Press(keys.Branches.CheckoutPreviousBranch).
Lines(
Contains("master").IsSelected(),
Contains("previous-branch"),
)
// Verify we're back on master
t.Git().CurrentBranchName("master")
},
})

View File

@ -40,6 +40,7 @@ var tests = []*components.IntegrationTest{
bisect.Skip, bisect.Skip,
branch.CheckoutAutostash, branch.CheckoutAutostash,
branch.CheckoutByName, branch.CheckoutByName,
branch.CheckoutPreviousBranch,
branch.CreateTag, branch.CreateTag,
branch.Delete, branch.Delete,
branch.DeleteMultiple, branch.DeleteMultiple,

View File

@ -836,6 +836,10 @@
"type": "string", "type": "string",
"default": "F" "default": "F"
}, },
"checkoutPreviousBranch": {
"type": "string",
"default": "-"
},
"rebaseBranch": { "rebaseBranch": {
"type": "string", "type": "string",
"default": "r" "default": "r"