docs: add pr fixup conflict guidance (#1642)
This commit is contained in:
@@ -30,7 +30,7 @@ The first thing you do — before fetching PR state, before reading logs, before
|
||||
|
||||
Create these tasks immediately (use your task/todo tracking tool if available):
|
||||
|
||||
1. **Gather PR state** — Use `pr-poller` when available; otherwise gather compact CI + bot review state via `scripts/pr-state`
|
||||
1. **Gather PR state** — Use `pr-poller` when available; otherwise gather compact CI + bot review state via `scripts/pr-state`; always check PR mergeability and local conflict state
|
||||
2. **Fix failing CI checks** — Read failing run logs (via `scripts/run-quiet gh-run -- gh run view ...`), fix issues, run E2E tests locally if needed
|
||||
3. **Triage review comments** — Classify each comment as valid, already addressed, nitpick, or wrong
|
||||
4. **Address each comment** — Fix or reply with reasoning, resolve threads
|
||||
@@ -54,12 +54,18 @@ If available, invoke the `pr-poller` subagent with the PR number (or let it reso
|
||||
- Counts unresolved review threads and bot issue comments
|
||||
- Returns a structured report between `=== pr-poller report ===` and `=== end ===` markers
|
||||
|
||||
### Merge-conflict gate
|
||||
|
||||
Always check for merge conflicts during task 1 before acting on any clean-poller shortcut. A PR can be blocked by conflicts before any check fails.
|
||||
|
||||
Inspect GitHub's `mergeable` / `mergeStateStatus` fields and the local index (`git ls-files -u`) before fixing CI or review comments. If GitHub reports file-level conflicts, the local index is unmerged, or conflict markers exist in tracked source files, load `references/merge-conflicts.md` and resolve the conflicts first. Do not start a new merge/rebase while the index is already unmerged, and do not discard unrelated user changes to make conflict resolution easier.
|
||||
|
||||
**Parse the report.** The fields you care about:
|
||||
|
||||
- `ci_failed` — list of `{name, run_id, conclusion, url}`. Empty list ⇒ CI is green.
|
||||
- `ci_pending` — anything still running when the 20-min cap hit. Decide whether to re-invoke `pr-poller` after a short delay, or proceed with what you have and re-check at step 6.
|
||||
- `bots.<name>` — `done` / `rate_limited` / `pending` / `timeout`. Anything in `done` or `rate_limited` has had its chance; treat the rest as missing data, not a blocker.
|
||||
- `unresolved_review_threads` and `issue_comments_from_bots` — drive steps 3-4. If both are 0 and `ci_failed` is empty, skip to step 5 (still run verify + push if you have fixes from earlier).
|
||||
- `unresolved_review_threads` and `issue_comments_from_bots` — drive steps 3-4. If both are 0, `ci_failed` is empty, and the merge-conflict gate is clean, skip to step 5 (still run verify + push if you have fixes from earlier).
|
||||
|
||||
**E2E CI outlasts the poller.** The pr-poller caps at ~20 minutes. Standard E2E shards plus container shards often run longer. GitHub can expand E2E matrix jobs late, and the shard matrix may appear only after the build job finishes; if pending checks briefly drop near zero and then jump when E2E shards appear, keep treating that as normal pending CI unless a shard reports failure. If the report shows `ci_pending` with only E2E/lint jobs and `ci_failed` is empty, re-invoke pr-poller once those jobs finish — do not spin a manual `gh pr checks` loop in the parent. If the cap hits with E2E still pending, report "CI in progress" to the user instead of blocking, and include the exact pending shard names from `ci_pending`.
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
# Merge Conflicts
|
||||
|
||||
Use this when the PR fixup flow finds GitHub file-level conflicts, an unmerged local index, or conflict markers in tracked files.
|
||||
|
||||
## Detect
|
||||
|
||||
Inspect GitHub's mergeability state:
|
||||
|
||||
```bash
|
||||
gh pr view <PR> --json number,url,baseRefName,headRefName,mergeable,mergeStateStatus
|
||||
```
|
||||
|
||||
Treat `mergeable:"CONFLICTING"` or `mergeStateStatus:"DIRTY"` as an actionable merge-conflict blocker. Treat `mergeable:"UNKNOWN"` as inconclusive: wait one short cadence and query again before deciding. States such as `BEHIND`, `BLOCKED`, `UNSTABLE`, or `HAS_HOOKS` may require an update or more CI/review work, but they are not by themselves proof of file-level conflicts.
|
||||
|
||||
Inspect the local worktree:
|
||||
|
||||
```bash
|
||||
git status --short
|
||||
git ls-files -u
|
||||
git grep -n -E '^(<<<<<<<|>>>>>>>)'
|
||||
```
|
||||
|
||||
If `git ls-files -u` prints entries, or conflict markers are present in tracked source files, resolve those conflicts before fixing CI or review comments. `git grep` scans only tracked files, and intentionally checks only the unambiguous start/end markers so Markdown setext headings do not create false positives. Do not start a new merge/rebase while the index is already unmerged.
|
||||
|
||||
## Resolve
|
||||
|
||||
### When GitHub reports conflicts and the local index is clean
|
||||
|
||||
1. Fetch the latest base branch:
|
||||
```bash
|
||||
git fetch origin <baseRefName>
|
||||
```
|
||||
2. Prefer merging `origin/<baseRefName>` into the PR branch for conflict-fixup work:
|
||||
```bash
|
||||
git merge --no-edit origin/<baseRefName>
|
||||
```
|
||||
Use `git rebase origin/<baseRefName>` only when the branch already uses a rebase-style history or the user asks for it. If a rebase is used and succeeds, the push later may need `git push --force-with-lease`.
|
||||
3. If conflicts appear, inspect each conflicted file, preserve the intended behavior from both sides, remove all conflict markers, and stage only the resolved files.
|
||||
4. Confirm the conflict is gone before continuing:
|
||||
```bash
|
||||
git ls-files -u
|
||||
git grep -n -E '^(<<<<<<<|>>>>>>>)'
|
||||
git diff --check
|
||||
git diff --cached --check
|
||||
```
|
||||
|
||||
### When the local index is already unmerged
|
||||
|
||||
If `git ls-files -u` shows entries, a previous merge or rebase was left incomplete. Do not start another merge. Instead:
|
||||
|
||||
1. Inspect each conflicted file:
|
||||
```bash
|
||||
git diff --diff-filter=U
|
||||
```
|
||||
2. Resolve conflict markers manually, preserving the intended behavior from both sides.
|
||||
3. Stage each resolved file:
|
||||
```bash
|
||||
git add <file>
|
||||
```
|
||||
4. Confirm the conflict is gone before continuing:
|
||||
```bash
|
||||
git ls-files -u
|
||||
git grep -n -E '^(<<<<<<<|>>>>>>>)'
|
||||
git diff --check
|
||||
git diff --cached --check
|
||||
```
|
||||
5. Complete the interrupted operation:
|
||||
```bash
|
||||
git commit
|
||||
# or, if mid-rebase:
|
||||
git rebase --continue
|
||||
```
|
||||
|
||||
Do not discard unrelated user changes to make a merge/rebase easier. If unrelated dirty files block the conflict-resolution attempt, stop and ask before stashing, committing, or reverting them.
|
||||
Reference in New Issue
Block a user