From e585accd3727029ef3a8190e69d9fe64721f73d8 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Thu, 2 Oct 2025 18:28:17 +0200 Subject: [PATCH] Give better feedback when checking out the previous branch Previously, the feedback you got when pressing "-" was just a "Checking out..." status in the bottom line. This was both easy to miss if you are used to looking for an inline status in the branches panel, and it didn't provide information about which branch was being checked out, which can be annoying in very large repos where checking out takes a while, and you only see at the end if you are now on the right branch. Improve this by trying to figure out which branch was the previously checked out one, and then checking it out normally so that you get an inline status next to it (as if you had pressed space on it). There are cases where this fails, e.g. when the previously checked out ref was a detached head, in which case we fall back to the previous behavior. --- pkg/commands/git_commands/branch.go | 16 ++++++++++++++++ pkg/gui/controllers/branches_controller.go | 2 +- pkg/gui/controllers/helpers/refs_helper.go | 9 +++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/pkg/commands/git_commands/branch.go b/pkg/commands/git_commands/branch.go index f4c491d63..76b5727c7 100644 --- a/pkg/commands/git_commands/branch.go +++ b/pkg/commands/git_commands/branch.go @@ -116,6 +116,22 @@ func (self *BranchCommands) CurrentBranchName() (string, error) { return strings.TrimSpace(output), nil } +// Gets the full ref name of the previously checked out branch. Can return an empty string (but no +// error) e.g. when the previously checked out thing was a detached head. +func (self *BranchCommands) PreviousRef() (string, error) { + cmdArgs := NewGitCmd("rev-parse"). + Arg("--symbolic-full-name"). + Arg("@{-1}"). + ToArgv() + + output, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput() + if err != nil { + return "", err + } + + return strings.TrimSpace(output), nil +} + // LocalDelete delete branch locally func (self *BranchCommands) LocalDelete(branches []string, force bool) error { cmdArgs := NewGitCmd("branch"). diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index ed2b01509..1fdc75652 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -490,7 +490,7 @@ func (self *BranchesController) forceCheckout() error { func (self *BranchesController) checkoutPreviousBranch() error { self.c.LogAction(self.c.Tr.Actions.CheckoutBranch) - return self.c.Helpers().Refs.CheckoutRef("-", types.CheckoutRefOptions{}) + return self.c.Helpers().Refs.CheckoutPreviousRef() } func (self *BranchesController) checkoutByName() error { diff --git a/pkg/gui/controllers/helpers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go index d5140bb1e..cfb9d3bab 100644 --- a/pkg/gui/controllers/helpers/refs_helper.go +++ b/pkg/gui/controllers/helpers/refs_helper.go @@ -163,6 +163,15 @@ func (self *RefsHelper) CheckoutRemoteBranch(fullBranchName string, localBranchN }) } +func (self *RefsHelper) CheckoutPreviousRef() error { + previousRef, err := self.c.Git().Branch.PreviousRef() + if err == nil && strings.HasPrefix(previousRef, "refs/heads/") { + return self.CheckoutRef(strings.TrimPrefix(previousRef, "refs/heads/"), types.CheckoutRefOptions{}) + } + + return self.CheckoutRef("-", types.CheckoutRefOptions{}) +} + func (self *RefsHelper) GetCheckedOutRef() *models.Branch { if len(self.c.Model().Branches) == 0 { return nil