[PATCH b4 21/27] review-tui: only put back a branch b4 checked out itself

Christian Brauner <[email protected]> Fri, 31 Jul 2026 11:21:20 +0200
Newsgroups org.kernel.linux.tools
Message-ID <20260731-work-b4-editor-branch-guard-v1-21-de68a7c8e4cb@kernel.org>
The branch to restore is read once when the TUI starts and checked back
out when it exits, whether or not b4 is what moved HEAD in between. A
review session can sit open for hours, suspended into an editor or a
shell, and the worktree it runs in is shared with the user's other
terminals. Switch branches in one of those, come back and quit the TUI,
and b4 helpfully checks out the branch you left hours ago.

Make both places that restore check first. run_tracking_tui() only
undoes a checkout that landed on a review branch, since that is the only
kind either app makes. ReviewApp only undoes its own if HEAD is still on
the review branch it put there.

Signed-off-by: Christian Brauner (Amutable) <[email protected]>
---
 src/b4/review_tui/_entry.py      | 10 +++++++++-
 src/b4/review_tui/_review_app.py |  7 +++++++
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/src/b4/review_tui/_entry.py b/src/b4/review_tui/_entry.py
index ece97da..6dc71a4 100644
--- a/src/b4/review_tui/_entry.py
+++ b/src/b4/review_tui/_entry.py
@@ -174,9 +174,17 @@ def run_tracking_tui(
         # This covers two cases:
         # - ReviewApp checked out the review branch (shell suspend/agent)
         # - TrackingApp checked out a new series via create_review_branch
+        # Both land on a review branch, and that is the only case we may undo.
+        # Anything else means the user moved HEAD themselves -- possibly hours
+        # ago, from another terminal sharing this worktree -- and the branch
+        # recorded when we started is stale, not something to check back out.
         if original_branch:
             current = b4.git_get_current_branch(topdir)
-            if current and current != original_branch:
+            if (
+                current
+                and current != original_branch
+                and current.startswith(b4.review.REVIEW_BRANCH_PREFIX)
+            ):
                 logger.info(
                     'Checking out %s and starting tracking UI...', original_branch
                 )
diff --git a/src/b4/review_tui/_review_app.py b/src/b4/review_tui/_review_app.py
index 778a8f6..0982f55 100644
--- a/src/b4/review_tui/_review_app.py
+++ b/src/b4/review_tui/_review_app.py
@@ -2164,6 +2164,13 @@ class ReviewApp(LoreNodeShutdownMixin, CheckRunnerMixin, App[None]):
         """Switch back to the original branch after shell/agent use."""
         if not self.branch_checked_out or not self._original_branch:
             return
+        # Only undo our own checkout. If HEAD is no longer on the review
+        # branch we left it on, something else moved it -- the shell we just
+        # suspended into, or another terminal in the same worktree -- and it
+        # is not ours to move back.
+        if b4.git_get_current_branch(self._topdir) != self._branch:
+            self.branch_checked_out = False
+            return
         ecode, _out = b4.git_run_command(
             self._topdir, ['checkout', self._original_branch], logstderr=True
         )

-- 
2.53.0