Repository navigation
feat(shell): PR-aware, main-checkout-first git checkout/switch - #47
Merged
Merged
Conversation
With gh installed, a bare `git checkout|switch` (and omz gco/gsw) of #123, a PR URL, or a number that is neither a rev nor a path lands on the PR's exact head commit: stay put if HEAD is already there, else switch to (or cd into the worktree of) a local branch whose tip is that commit, preferring the PR's branch name. Only when no branch carries it does `gh pr checkout` create one, named after the PR's branch unless that name is taken (then pr-<n>, then pr-<n>-<sha>), so a local branch that has moved ahead of the PR is never reused. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A bare `git checkout|switch <branch|pr>` from any worktree now switches the main checkout and cds there, instead of jumping to whichever worktree already has the branch; `-H` does it in the current worktree. A linked worktree holding the branch is detached at the same commit to free it, refused if it has uncommitted changes, and reattached if the switch then fails. Commits, tags, paths and other flags still go straight to git. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`git checkout dev -.` (or `-. dev`) switches the current worktree instead of the main checkout. Unlike a bare `.`, which git reads as a pathspec and would restore files with if the wrapper were not loaded, `-.` is rejected by git itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zsh-utils' completion plugin turns on EXTENDED_GLOB, which makes `#` a glob operator, so `nixpkgs#hello` fails with "no matches found" and `gco #47` with "bad pattern". `disable -p '#'` turns off just that operator, keeping the rest of extended globbing; the `(#i)`-style glob flags go with it. Replaces the commented-out `setopt noglob` attempt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Pass straight to git under Claude Code ($CLAUDECODE): agents' shells snapshot this function and expect plain git in their own worktrees. - Match remote branches exactly (<remote>/<name> for each remote), so a name that only tails a nested remote branch is not sent to the main checkout, where git would read it as a path and restore that file. - Replace `disable -p '#'` with `unsetopt extended_glob`: the former silently broke `##` even in code that sets extendedglob locally. - Ignore untracked files when deciding whether a holder worktree is dirty; detaching at the same commit never touches them. - Checking out the current worktree's own branch stays put instead of detaching it and moving the branch to the main checkout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Error out when the PR's branch name, pr-<n> and pr-<n>-<sha> are all taken, instead of letting gh reuse the last one off the PR's commit. - Count `-.` only before `--` (after it, it is a path) and keep empty arguments when stripping it. - Refuse a PR URL whose owner/repo none of the remotes point at. - Say so when gh returns incomplete PR info instead of failing silently. - Read the main checkout and every branch's worktree from one `git worktree list`: an intercepted checkout now runs 3 extra git processes instead of 5-6, and other git commands take a fast path (~4 us) before any locals are set up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends the zsh
gitwrapper inmodules/shells/zsh/zshrc(also used by omzgco/gsw).What changes
git checkout #123, a PR URL, or a bare number that is neither a rev nor a path lands on the PR's exact head commit. If a local branch's tip is already that commit, it switches to that branch, preferring the one named like the PR's branch. Otherwisegh pr checkoutcreates a new branch named after the PR's branch, orpr-<n>, orpr-<n>-<sha>if those are taken. A local branch that has moved ahead of the PR is never reused.git checkout|switch <branch|pr>from any worktree now switches the main checkout and cds there. Before, it jumped to whichever worktree held the branch.-.for the current worktree.gco dev -.(orgco -. dev) switches the current worktree instead. A bare.was rejected because git reads it as a pathspec, and without the wrappergit checkout dev .would overwrite files. Git rejects-.outright.#stays literal. zsh-utils' completion plugin turns onEXTENDED_GLOBglobally, which madegco #47fail withbad patternandnixpkgs#hellowithno matches found. This turns it back off after plugins load; completion, p10k and fast-syntax-highlighting set it locally.$CLAUDECODE) the wrapper passes straight to git, since agent shells snapshot this function and expect plain git in their own worktrees.git worktree path <branch>is unchanged.Reviewer notes
claude/...branch from elsewhere takes it from that session's worktree if it is clean. Use-.orgit worktree pathwhen you only want to look.gh, originally across 13 cases: a free branch, a branch held by a clean or dirty worktree,-.in both positions, a branch the main repo already has, a failed switch with reattach, a commit, a remote-only branch, PRs with and without-.,git grep -Hpassthrough, and plaingit checkout .. The realgh pr checkout --branchpath has not been run.worktree list, onerev-parse, onefor-each-ref)..nixfiles;zsh -npasses. 22 scratch-repo cases pass, including untracked-only holders, the current worktree's own branch, nested remote branch names,$CLAUDECODE, foreign PR URLs, all fallback names taken,-- -., and incomplete gh output.🤖 Generated with Claude Code