Repository navigation
Conflicting PRs: stop running a background merge to list files; the agent's own merge shows them - #24266
Conflicting PRs: stop running a background merge to list files; the agent's own merge shows them#24266brennanb2025 wants to merge 9 commits into
Conversation
…ting files Conflicting PRs used to trigger a base fetch, merge-base, rev-list and `git merge-tree` on every PR refresh and on the Merge button's preflight, just to show a list of conflicting file names. Those runs piled up on every main move, competed for disk during worktree creation, and wrote unreferenced objects into the user's repository. Orca now takes the conflict yes/no from the hosting provider only: - Checks panel (desktop and mobile) says "GitHub reports conflicts with <base>" (or "GitLab reports conflicts with the target branch") and points the user at merging the base to see the files. - "Resolve conflicts with AI" names the PR's base branch and base repository, fetches from the remote that matches it (forks), lets Git list the conflicted files, and treats a clean merge as a possibly stale report. - The Merge button blocks a conflicting PR immediately, including SSH repos and PRs without a base name. - Mobile now keeps the PR's base branch name when parsing the host reply. Removes the merge-tree --merge-base capability and its doc row; branch cleanup's merge-tree use is left for the follow-up.
…kground-conflict-file-list
…a clean conflict merge stale
…kground-conflict-file-list
…merge, and stop when behind
…tead of refusing to merge
…stead of guessing the cause
Review status: ready for review (head
|
|
There was a problem hiding this comment.
✅ No new issues found. The background practice-merge removal is coherent and the supporting contracts all line up.
Reviewed changes
- Removed the background conflict-file list.
conflict-summary.ts/conflict-summary-cache.tsand their tests are deleted, along with thePRConflictSummarytype, the optionalconflictSummaryfield onPRInfo/HostedReviewInfo/MRInfo, and themerge-tree-merge-baseGit capability (plus its error matcher, docs row, and the now-dead real-Git test slice). Conflict yes/no still comes from the hosting provider. - Merge button answers without local Git.
getPRMergeBlockernow derives its message from GitHub'smergeablealone for local, WSL, and SSH repos; therepoPathparameter and the conflict preflight are gone. - Checks panel shows provider attribution, not a file list.
ConflictingFilesSectionand the old notice are replaced bymerge-conflict-notice.tsx, which names the GitHub base branch (or falls back to "the base branch") and the GitLab target branch. Six newchecksPanel.mergeConflict.*keys are added to all six catalogs; eleven removed. - Resolve-conflicts prompt reworked.
buildResolvePullRequestConflictsPrompttakesbaseRepositoryinstead ofentries, points at the matching remote for fork checkouts, adds a clean-merge rule that printsgit status -sband explicitly forbids pushing, and leaves file discovery togit status. - Mobile parity.
PRConflictingFilesSection→PRMergeConflictsSection,resolveConflictDisplayreturns{title, body}, the reply schema keepsbaseRefName, and the affected goldens were re-recorded.
ℹ️ Carried-forward side effect
The removed background fetch was also the thing that refreshed origin/<base> for every conflicting PR, so ahead/behind counts and compare-base for those PRs now depend on Orca's other fetches. This is intentional and documented in the PR body — noting it only so it is on the record as the one behavior change outside the conflict UI itself.
DeepSeek Flash (free via Pullfrog for OSS) | 𝕏
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (71)
💤 Files with no reviewable changes (16)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review. 📝 WalkthroughWalkthroughThe change removes locally derived conflict summaries from pull-request data and merge handling. Desktop and mobile conflict notices now use provider and base-branch details. Resolution prompts use base-repository information and leave conflict-file discovery to Git. GitHub PR schemas and RPC golden recordings are updated to include Priority: ⬇️ Low Merge Risk: ⚪ Minimal · up to Conflict guidance now uses provider-reported status and available base-branch metadata, leaving file discovery to Git during a local merge. No concrete merge-blocking issue remains; merging is appropriate after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change removes background merge work without weakening the inspected hosting-provider merge checks. No introduced security weakness was demonstrated. Local conflict-resolution execution and compatibility across deployed versions were not fully established. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 35 functions across 34 files. (17 skipped: 17 unsupported.) Full details: Description checkExplanation The description is detailed and covers the change, rationale, testing, visual proof, compatibility, and checklist. However, the required Linked Issue section does not contain an actual issue reference. Resolution Add the actual issue reference in the Linked Issue section, such as
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
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 |
|
Closing. This removed the conflicting-file list to save background work, which loses a feature users rely on. The underlying problem (conflict checks leaving throwaway objects in the repository) is fixed in #22356 with no change to what users see. |

ELI5
When a pull request conflicts with its base branch, Orca used to quietly do a practice merge in the background, over and over, just to print the names of the conflicting files. That was slow, fought with worktree creation for the disk, and left junk files in your repository. Orca now just says what GitHub or GitLab says ("GitHub reports conflicts with main"), and the files appear when you (or the "Resolve conflicts with AI" agent) actually merge the base branch in your worktree.
What Changed
The problem. For every pull request that GitHub reported as conflicting, every PR refresh (and the Merge button's pre-check) ran
git fetch origin <base>,git merge-base,git rev-listandgit merge-treeagainst the local repository. Each new commit on main restarted that work for every conflicting PR. On 2026-09-28 one machine logged 357 of these practice merges in 3.6 hours. They competed for the disk while worktrees were being created, and each one wrote unreferenced Git objects into the user's repository. All of it existed to show a list of conflicting file names that the hosting provider does not supply (GitHub's and GitLab's APIs only say yes/no).The change. Orca no longer computes a conflicting-file list. Whether a pull request conflicts still comes from the hosting provider, exactly as before. The file names come from where Git already shows them: a real merge in the user's own worktree, which Source Control lists with each file's conflict kind.
Checks panel (desktop):
The one-time forced refresh when you open a conflicting PR stays, because a stale "conflicting" now sends you to an agent. Only its "Refreshing conflict details…" text is gone.
"Resolve conflicts with AI" (desktop and mobile):
git status -sb: the conflicts may already be resolved in local commits that were not pushed (for example by an earlier "Resolve with AI" run), or the host's conflict report may be stale. It does not push.Merge button (blocked merge message):
Mobile PR sidebar (GitHub):
The mechanism.
src/main/github/conflict-summary.tsand its cache, and stopped threading the summary through the PR lookup (branch-lookup-derived-data.ts,branch-lookup-resolution.ts,pr-refresh-outcome-assembly.ts).getPRMergeBlockernow returns the generic conflict text straight from GitHub'smergeable, with no local Git, for local, WSL and SSH repos alike.PRConflictSummarytype and the optionalconflictSummaryfield fromPRInfo,HostedReviewInfoandMRInfo(the GitLab one was never filled in).ConflictingFilesSection, the "locally clean" notice and its command box are replaced byMergeConflictNoticeinmerge-conflict-notice.tsx. It reads the GitHub base name from the PR the panel already holds; the shared review mapper is unchanged on purpose, because adding a base name there would switch on a Source Control base-branch repair that is currently off.buildResolvePullRequestConflictsPrompttakes the base repository instead of a file list.baseRefName.merge-tree-merge-baseGit capability, its error matcher, its row indocs/reference/git-compatibility.md, and the part of the real-Git compatibility test that only this feature used.Side effects to know about.
origin/<base>for every conflicting PR. Source Control's ahead/behind counts and compare base now get that ref only from Orca's other fetches and the user's own.Why
The practice merge was the most expensive way to get a nice-to-have: it ran on every refresh of every conflicting PR, restarted on every main move, wrote objects into repositories, and still could not run for SSH repos, older Git, or offline base fetches, where users saw "details are unavailable" anyway. The list was also often wrong for forks, because it merged origin's copy of the base.
The new design has no background Git at all for this feature. Conflict yes/no stays with the provider, which is the source of truth for whether the PR can merge. The file names come from the one place that is always right: an actual merge of the real base in the user's worktree, which the "Resolve conflicts with AI" agent performs and Source Control already displays.
Alternatives considered:
Compatibility with other versions. The host simply stops sending an optional field. An older desktop or mobile client talking to this host sees no list and shows the "Conflict file details are unavailable" notice it already shows for SSH repos. A new client talking to an older host ignores the old field and gets the full new experience (the base name has always been on the PR). The SSH relay protocol is unchanged. Old cached PR entries that still carry the field are never read and are replaced on the next refresh.
Git versions. This removes the feature's dependency on Git 2.38/2.40; nothing new is required of Git.
Where this fits
This PR is step 1 of 2 in the plan to remove background
git merge-treefrom Orca:merge-treecall sites).branch -d, and when Git refuses, asks the provider whether the PR was merged at this exact commit instead of running a local squash proof. That removes the lastmerge-treecall site.After B lands, #22356's scratch-folder quarantine has nothing left to protect; whether to close it then is Brennan's call. This work is part of the wider worktree-create latency plan: #23699 is its step 1, and #23698 is tracked separately.
Differences from the common pattern
Linked Issue
Part of the plan described in "Where this fits" (supersedes the approach in #22356).
Visual Proof
Checks panel on a separate macOS QA machine, in an isolated app profile with no GitHub login. Its PR cache was seeded with a conflicting pull request, and the app keeps showing the cached PR when its refresh fails, so the panel renders from that cache. The live PR card could not be shown, because the test app is never given a GitHub credential.
main"Resolve conflicts with AI" dialog and its prompt preview (After):
Mobile was not run on a device; it is covered by unit tests.
Testing
Typecheck: node, web, mobile, and the mobile test-typecheck ratchet all pass.
Mobile recorded RPC replies (the golden recordings) were re-recorded: the mobile PR reader now keeps the optional
baseRefName, so 14 recordings gain that one key and nothing else (checked by decoding every changed recording).Unit tests: 57 desktop test files (501 passed, 19 skipped: the real-Git compatibility file, which needs a Git binary set in the environment) and 7 mobile test files (121 passed).
Real-Git compatibility contract run locally against Git 2.50.1: 19 passed. CI covers Git 2.25.5, 2.38.1 and 2.49.1.
New tests: a conflicting PR refresh (local and WSL) runs no fetch, merge-base, rev-list or merge-tree; the merge blocker for local, SSH and missing base; the Checks panel copy for GitHub with and without a base and for GitLab, also rendered through the panel; the one-time refresh fires once per PR; the resolve prompt for a fork-shaped base repository, a non-github.com host, GitLab, option-looking branch names, and the clean-merge rule; GitHub reporting "merge state dirty" while mergeability is still unknown still counts as conflicting (its only test lived in a deleted file); the Checks panel hands the PR's base and repository to the prompt; mobile copy, section, prompt, and a mobile reply from an older host that still sends
conflictSummary.Each new test was checked to fail when the old behaviour is put back (old SSH/missing-base skip, notice without the base name,
git fetch origin, no clean-merge rule, prompt without the PR's base, refresh without its once-per-PR guard, the background summary restored, mobile reader droppingbaseRefName).Lint, changed-code quality gate, React Doctor, and localization catalog/extraction/coverage checks pass.
Platforms: unit tests on macOS. Manual QA on a separate macOS machine: the Checks panel notice (both variants, against main's old notice), the Resolve dialog's prompt, and a real agent following the prompt in a fork-shaped clone (origin is a fork with a stale
main, upstream is the base). The agent fetched the base fromupstream, Git listed the conflicted file, it resolved and committed the merge, and it pushed nothing. Run a second time on the already-merged clone, it said the conflicts already looked resolved locally and that pushing would update the PR, rather than blaming the host. Re-run on the final wording with fresh agents in a normal checkout, a fork checkout, and a branch that tracks the base: each merged and resolved, pushed nothing, and on the second run gave a hedged answer withgit status -sbinstead of blaming GitHub.Not verified live: a real GitHub PR card (needs a credential in the test app) and the Merge button's message (the button is disabled while the PR conflicts). Windows, Linux, WSL, SSH and mobile are covered by unit tests only.
I manually tested these changes locally
Automated tests added/updated, or explained why not below
AI Disclosure
Review
Agent skill upstream boundary
docs/reference/agent-skill-sharing-upstream-boundary.mdand copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.Notes
Ensure no issues in: Security, Cross-platoform support (Linux, Windows, Mac), Remote SSH, Mobile, general backwards compatibility, performance
Author: @BrennanKB5
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)