gh-pr-fix
Fix unresolved PR review comments from Copilot or CodeRabbit
Fix unresolved PR review comments from Copilot or CodeRabbit.
Arguments
$ARGUMENTS should be a GitHub PR URL (e.g., https://github.com/owner/repo/pull/123) or PR number, or empty to use the current branch's PR.
Instructions
-
Determine the PR:
- If $ARGUMENTS is a URL, parse the owner, repo, and PR number
- If $ARGUMENTS is a number, use it with the current repo
- If $ARGUMENTS is empty, get the PR for the current branch:
gh pr view --json number,url - If no PR exists, inform the user and exit
-
Fetch all review comments:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments --paginate -
Filter for unresolved Copilot/CodeRabbit comments:
- Filter comments where
user.loginiscopilot-pull-request-reviewerorcoderabbitai[bot] - Exclude comments that are part of resolved review threads
- Check if comment is in a resolved thread using the
in_reply_to_idfield and thread resolution status - To check resolution status, you may need to fetch review threads:
gh api graphql -f query=' query($owner: String!, $repo: String!, $pr: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $pr) { reviewThreads(first: 100) { nodes { isResolved comments(first: 10) { nodes { id databaseId body author { login } path line } } } } } } } ' -f owner={owner} -f repo={repo} -F pr={pr_number} - Only include threads where
isResolvedisfalse
- Filter comments where
-
If no unresolved comments found:
- Inform the user: "No unresolved comments from Copilot or CodeRabbit found."
- Exit
-
Process each unresolved comment one at a time: For each comment, display:
Comment {N} of {total} ───────────────────────────── File: {path}:{line} From: {author} {comment body} ───────────────────────────── -
Ask user what to do: Use AskUserQuestion with options:
- Fix it - Attempt to fix this issue
- Skip with reply - Skip and reply with a reason
- Skip - Move to the next comment without action
-
If "Fix it" selected: a. Read the relevant file and understand the context around the line mentioned
b. Check git history for context:
- Get the history of the specific file:
git log --oneline -10 -- {file_path} - Look at recent changes to the affected lines:
git log -p -3 -- {file_path} - Search for related commits that might explain the current code:
git log --all --oneline --grep="{function_name or key_term}" - If relevant commits are found, examine them:
git show {commit-hash} - Look for patterns:
- Why was the code written this way originally?
- Were there previous attempts to fix similar issues?
- Is this part of a pattern that exists elsewhere in the codebase?
Display git history findings if relevant:
📜 Git History Context: Recent changes to {file}: - {hash}: {message} - {hash}: {message} Related commits: - {hash}: {message} Context: {brief explanation of why code is structured this way}c. Analyze the comment to understand what change is being requested
d. Search for similar patterns in the codebase if the fix might apply elsewhere:
- Use Grep to find similar code patterns
- Note if other files might need the same fix
e. Implement the fix using the Edit tool
f. Show the diff of your changes:
git diff {file_path}g. Ask user to accept or reject using AskUserQuestion:
- Accept - Stage and commit this fix
- Reject - Discard changes and move to next comment
- Edit - Let me modify the fix before accepting
h. If "Accept" selected:
- Stage the changed file:
git add {file_path} - Use the
commit-msgskill to generate commit message options and create the commit - Reply to the comment explaining what was done:
- If the fix addresses the concern directly: reply "Ok will fix"
- If the reviewer's assumption was incorrect: explain why (e.g., "The assumption that X happens is incorrect because Y. Added a comment to clarify this.")
- Post the reply:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \ -f body="{reply}" \ -F in_reply_to={comment_id}
- Resolve the review thread:
gh api graphql -f query=' mutation($threadId: ID!) { resolveReviewThread(input: {threadId: $threadId}) { thread { isResolved } } } ' -f threadId={thread_node_id}
i. If "Reject" selected:
- Discard changes:
git checkout -- {file_path} - Move to next comment
j. If "Edit" selected:
- Ask user what they want to change
- Apply their requested modifications
- Show the new diff and repeat the accept/reject question
- Get the history of the specific file:
-
If "Skip with reply" selected:
- Ask user for the reason using AskUserQuestion with text input option
- Post a reply to the comment:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \ -f body="{reason}" \ -F in_reply_to={comment_id} - Optionally resolve the thread if the user indicates the issue is not applicable
-
If "Skip" selected:
- Move to the next comment without any action
-
Repeat for all remaining unresolved comments
-
Final summary: After processing all comments, show a summary:
PR Review Comments Summary ══════════════════════════════════════ Total comments processed: {N} - Fixed and committed: {count} - Skipped with reply: {count} - Skipped: {count} Commits created: - {hash}: {title} - {hash}: {title} -
Ask about pushing: If any commits were created:
- Analyze commits for squash candidates:
- Group commits that touch the same file
- Group commits with related themes (e.g., "OAuth2 improvements", "error handling")
- Commits touching completely different files with unrelated purposes are NOT squash candidates
- Present options using AskUserQuestion:
- "Push as-is (Recommended)" - if no good squash candidates exist
- "Squash: {commit1} + {commit2} → '{suggested title}'" - for each squash candidate group
- "Don't push yet"
- If squashing, use interactive rebase to combine, then push
- If push as-is:
git push
- Analyze commits for squash candidates:
Notes
- The command processes comments one at a time to allow careful review
- Each fix creates its own atomic commit for easy tracking and potential reverting
- Bot accounts to look for:
copilot-pull-request-reviewer,coderabbitai[bot] - If a file has multiple comments, they are still processed one at a time
- Always show the full context of the comment before asking for action
- Git history analysis helps understand why code was written a certain way and reveals fix patterns
- If a fix pattern is identified, check if other files might need the same change
Types of Fixes
Not all fixes require changing code behavior. Valid fixes include:
- Code changes: Modifying logic, adding error handling, etc.
- Adding clarifying comments: When the reviewer misunderstands existing behavior, adding a comment to clarify can be the appropriate fix
- Documentation updates: Improving docstrings or inline documentation
Reply Guidelines
When replying to comments after fixing:
- Direct fix: Reply "Ok will fix" when the fix addresses the concern as requested
- Incorrect assumption: If the reviewer's assumption is wrong, explain why (e.g., "The assumption that this contacts the server on every call is incorrect - the implementation uses internal caching. Added a comment to clarify.")
- Keep replies concise but informative