feat: add interactive worktree PR checkout command (gwp)#502
feat: add interactive worktree PR checkout command (gwp)#502
Conversation
Select a PR from fzf, fetch it, and create a worktree in one step. Requires GitHub CLI (gh). Preview shows PR metadata, commits, changed files, and diff. Idempotent — reselecting an existing PR worktree returns its path without re-fetching.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds an interactive PR-to-worktree command (gwp / worktree_pr): core implementation in the main script, shell integrations (zsh/fish), completion updates, and README documentation entries for the new subcommand and options. Changes
Sequence DiagramsequenceDiagram
actor User
participant Shell as Shell (zsh/fish)
participant Main as git-forgit:worktree_pr
participant FZF as FZF (selector)
participant GH as gh (GitHub CLI)
participant Git as Git
User->>Shell: run gwp
Shell->>Main: invoke worktree_pr
Main->>GH: list open PRs / pr view (preview)
GH-->>Main: PR list / details
Main->>FZF: present PRs with preview
FZF->>Main: selected PR
Main->>GH: fetch PR diff/details for preview
GH-->>Main: PR preview
Main->>Git: check for existing worktree / fetch PR head
Git-->>Main: branch fetched / existing worktree path
Main->>Git: create worktree if needed
Git-->>Main: new worktree path
Main-->>Shell: return worktree path
Shell->>User: cd into worktree
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested Reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (2)
bin/git-forgit (2)
1543-1543: Hardcodedoriginremote may not work for all repository configurations.The fetch command assumes the remote is named
origin. While this is the common default, repositories may use different remote names or may have been cloned from a fork.This is acceptable for the initial implementation since
gh prcommands inherently target the repository's default remote. If issues arise, consider dynamically determining the remote:# Example approach (for future consideration): local remote remote=$(gh repo view --json name -q '.name' 2>/dev/null && echo "origin" || git remote | head -1)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@bin/git-forgit` at line 1543, Replace the hardcoded "origin" in the git fetch call by computing a remote variable and using it in the fetch; locate the fetch invocation that uses git fetch origin "pull/${pr_number}/head:${local_branch}" and introduce a REMOTE (or remote) variable determined from gh/git (prefer using gh/CLI to get the repo remote when available, falling back to git remote | head -1), then use "${REMOTE}" in the git fetch to avoid assuming the remote is named origin while keeping existing pr_number and local_branch usage.
1531-1531: Consider escaping special characters in branch name for grep.The branch name
$local_branchis used directly in a grep regex pattern. If the branch name contains regex metacharacters (e.g.,.,*,[), the match could fail or match incorrectly.♻️ Proposed fix using grep -F for literal matching
- if git worktree list --porcelain | grep -q "^branch refs/heads/${local_branch}$"; then + if git worktree list --porcelain | grep -qF "branch refs/heads/${local_branch}"; thenNote: Using
-Ffor fixed-string matching avoids regex interpretation. The^and$anchors are lost, but sincerefs/heads/is a unique prefix and branch names don't contain newlines, false positives are unlikely.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@bin/git-forgit` at line 1531, The grep pattern in the git worktree check uses an unescaped regex with ${local_branch}, which can misbehave for branch names containing regex metacharacters; update the command that contains git worktree list | grep -q "^branch refs/heads/${local_branch}$" to perform a literal, whole-line match (e.g., use grep -q -xF "branch refs/heads/${local_branch}") so the branch name is treated as a fixed string; change the line in the script where the worktree check is performed to use grep -xF with the literal string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@bin/git-forgit`:
- Line 1543: Replace the hardcoded "origin" in the git fetch call by computing a
remote variable and using it in the fetch; locate the fetch invocation that uses
git fetch origin "pull/${pr_number}/head:${local_branch}" and introduce a REMOTE
(or remote) variable determined from gh/git (prefer using gh/CLI to get the repo
remote when available, falling back to git remote | head -1), then use
"${REMOTE}" in the git fetch to avoid assuming the remote is named origin while
keeping existing pr_number and local_branch usage.
- Line 1531: The grep pattern in the git worktree check uses an unescaped regex
with ${local_branch}, which can misbehave for branch names containing regex
metacharacters; update the command that contains git worktree list | grep -q
"^branch refs/heads/${local_branch}$" to perform a literal, whole-line match
(e.g., use grep -q -xF "branch refs/heads/${local_branch}") so the branch name
is treated as a fixed string; change the line in the script where the worktree
check is performed to use grep -xF with the literal string.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: dbb237cc-2143-43f5-94e2-88cb779c96f2
📒 Files selected for processing (6)
README.mdbin/git-forgitcompletions/_git-forgitcompletions/git-forgit.bashconf.d/forgit.plugin.fishforgit.plugin.zsh
Branch names from PRs may contain regex metacharacters (e.g. dots), which would cause the grep pattern match to behave incorrectly.
|
This looks neat, but I personally think that this feature is out of scope for this project. So far, every |
|
Thanks for the thoughtful feedback @sandr01d, and I appreciate you referencing #406 for context. I do think there's an important distinction worth drawing here though. The license generator in #406 had no relationship to git at all — it was purely a project management utility. Regarding the GitHub-specific concern — I understand the principle, but I think we should be pragmatic here. GitHub hosts the vast majority of open-source projects (including forgit itself), and forgit already has a pattern of gracefully integrating with external tools — That said, I'm open to hearing what @cjappl and @carlfriedrich think. If the consensus is that this crosses a line, I'd respect that — but I do believe the git-centrality of this command meaningfully differentiates it from #406. |
|
Thanks for the ping. I am actually more on @sandr01d's side here. While I understand the difference to #406, I still also do see a difference compared to the existing forgit features. Yes, forgit gracefully integrates optional external tools, but up to now it does so to optionally improve the user experience of its features. All of the features also work without any of these external tools. This PR adds an optional external tool to implement a completely new feature. The feature won't work without this tool. That is a difference. To me, indeed, this PR screems "feature creep!!". I definitely see the benefit of it, but I also think that it makes forgit stick less to the unix philosophy. That being said, I am also open to the "let's be pragmatic" argument here. The bigger issue I see here, though: IMO the function does too much. Why does it fetch a PR AND create a worktree (a function we already have in forgit)? The new function obviously duplicates functionality. IMO the better UI here would be to add a (On a side note: that's actually something I already do in my own workflow using navi (which is also fzf-based). See my navi cheat for fetching GitHub PRs for reference, which simply queries the GitHub API via Maybe we can reconsider the design from this perspective, and maybe we find a solution which fits better into forgit's scope while still bringing the benefit @wfxr is looking for. |
|
After reflecting on the discussion, I think you're right that this sits outside forgit's scope. I'll keep it in my own dotfiles for now. Thanks for the thoughtful feedback — it actually helped clarify the boundary nicely. Who knows, maybe one day there'll be a |

Check list
Description
Add
gwpcommand (forgit::worktree::pr/git forgit worktree_pr) that streamlines local PR review workflow:gh pr listin fzf (with title, author, draft status, relative time).wt/pr-<N>/<branch>, andcds into itRequires GitHub CLI (
gh).Configurable via:
FORGIT_WORKTREE_PR_FZF_OPTS— extra fzf optionsFORGIT_WORKTREE_PR_DIR— custom worktree directoryFORGIT_WORKTREE_PR_LIMIT— max PRs to list (default 100)Type of change
Test environment
Summary by CodeRabbit
New Features
gwpcommand lists open PRs with previews (author, creation time, commits, changed files) and automatically creates local worktrees for selected PRs.Documentation
gwpcommand documentation and shell alias configuration.