[pull] trunk from cli:trunk - #205
Merged
Merged
Conversation
Support checking out a pull request into a new git worktree via `gh pr checkout <pr> --worktree <path>`. Re-running against the same path fast-forwards the existing worktree (idempotent, matching plain checkout), and checking out a branch already present in another worktree fails with a clear message. Adds a git.Client.Worktrees() helper that parses `git worktree list --porcelain`. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
When --worktree is combined with --recurse-submodules, the submodule sync/update commands ran in the main worktree instead of the newly created one, leaving the worktree's submodules uninitialized. Prefix the submodule commands with -C <path> (applied as cmd.Dir, mirroring the fetch handling) so they operate on the correct worktree. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The missing-remote existing-worktree path used checkout -B <branch> FETCH_HEAD, which unconditionally reset the branch and could discard local commits even without --force. Switch to existence-aware logic that mirrors the non-worktree paths: when the branch exists, check it out and sync with merge --ff-only (or reset --hard under --force); only create the branch from FETCH_HEAD when it does not exist yet. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The existing-remote worktree-reuse path assumed the target branch already existed and ran checkout <branch>, which failed when a new --branch name was supplied for an already-existing worktree (e.g. repointing a review worktree at a different PR). Create the branch tracking the remote when it does not exist yet, mirroring the new-worktree path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use slices.Concat instead of append(prefix, ...) when building the worktree-scoped submodule commands so the shared prefix slice can never alias between the two commands. Add a unit test on authenticatedCommand asserting the leading -C <path> is applied as cmd.Dir and stripped from the args, which the CommandStubber-based tests cannot observe. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add the coverage gaps surfaced by review: re-running --detach against an existing worktree (the per-worktree FETCH_HEAD path), a cmd.Dir assertion for the worktree-local fetch shape (the real fork/detach production combo, not just submodule), and a symlink-resolving isWorktreeAtPath unit test so worktree reuse keeps working when git reports a canonical path but the user passes a symlinked one. Drop the custom-branch new-worktree case, which duplicated the new-branch path already covered by the existing-worktree custom-branch case. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Restore the non-fast-forward // TODO breadcrumb in syncBranchCmds - Early-return the non-worktree case in detachCmds to reduce nesting - Reject a --worktree target that is a leaf symlink or non-directory via ensureWorktreePathSafe, with unit coverage Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Replace isWorktreeAtPath path-matching with git rev-parse --show-prefix --git-common-dir, letting git resolve symlinks, "..", case, and trailing slashes; delete resolvePath/EvalSymlinks - Reject a --worktree target that resolves to the current worktree, which would otherwise silently switch the current tree's branch and print a nonsensical "cd ." hint Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
isCurrentWorktree resolves the target with filepath.Abs, which yields a drive-letter path on Windows (e.g. D:\path\to\wt). Match the -C target via a wildcard so the show-toplevel stub matches on all platforms. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Collapse the separate worktree-detection helpers (isWorktreeAtPath, isCurrentWorktree, worktreeToplevel, worktreeInfoAtPath, repoCommonDir) into a single resolveWorktreeTarget call made once in checkoutRun. It runs two rev-parse queries (current + target) instead of the previous four and hands the command builders a plain reuseWorktree bool, so they no longer depend on the git client for detection and stay pure. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Streamline comments in the worktree checkout path to only the non-obvious rationale, and rename the worktreeTarget fields to isCurrentWorktree and isExistingWorktree so they read clearly without explanation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Match the surrounding codebase, which rarely documents unexported helpers: remove the godoc on worktreeCheckoutCmds and tighten syncBranchCmds, keeping comments only where the rationale is non-obvious. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
resolveWorktreeTarget deliberately proceeds with default flags when a rev-parse fails, which the nilerr linter flagged as returning a nil error after a non-nil one. Have revParseFacts report success via an ok bool instead so the best-effort fallthrough is explicit and lint-clean. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reword the --worktree rejection to avoid the "current worktree" jargon, which is confusing for users who don't think of their main checkout as a worktree. Point at "the repository you're already in" instead. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Reject --worktree paths that point inside a different repository or nest inside an existing worktree with clear messages, instead of deferring to git (which silently creates a nested worktree or emits a generic error). Fold all rejection cases into resolveWorktreeTarget, which now returns (reuseWorktree bool, error), removing the worktreeTarget struct and simplifying the checkoutRun guard. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Cover checking out a PR into a new git worktree, reusing an existing worktree, detached checkouts, checkouts of fork PRs whose head repo is not a configured remote, and force syncing across diverging branches. Each scenario also asserts the main working copy's branch is untouched. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e4cb568-27f3-4c7e-a344-859e2c2d69b0
Signed-off-by: Babak K. Shandiz <babakks@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e4cb568-27f3-4c7e-a344-859e2c2d69b0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e4cb568-27f3-4c7e-a344-859e2c2d69b0
git worktree add treats a path that starts with a hyphen as an option, so a --worktree value like -foo failed with an unknown-switch error. Pass a -- end-of-options separator before the path in every worktree add invocation so the value is always parsed positionally. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e4cb568-27f3-4c7e-a344-859e2c2d69b0
The checkoutRun test stubs hardcoded `git -C /path/to/wt rev-parse`, but the command runs after filepath.Abs, which yields `D:\path\to\wt` on Windows and left the stub unmatched (panic: no exec stub). Use a separator-agnostic `.+path.to.wt` pattern so the stub matches the absolute path on every platform while still asserting the -C directory. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Add --worktree flag to gh pr checkout
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )