From 4992cb375a425c82ced689566d9dc0f8b4058e4b Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Wed, 29 Apr 2026 09:02:23 +0200 Subject: [PATCH 1/3] docs(agents): warn about reversed --ours/--theirs in rebase During rebase, `--ours` refers to the upstream target (not the branch being rebased), which is the opposite of merge. Using `git checkout --ours ` to "keep our work" during a rebase conflict silently takes the upstream version, makes the replayed commit empty, and rebase drops it without error. Adds: - A warning block with merge vs rebase semantics, the safe pattern (`--theirs` to keep your work during rebase), a verification step (`git log --oneline ..HEAD`), and reflog recovery. - An incident-log row for the 2026-04-29 near-miss on the cpan-reports refresh PR. --- AGENTS.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index d0b84401d..809fe2094 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -60,6 +60,55 @@ ╚══════════════════════════════════════════════════════════════════════════════╝ ``` +## ⚠️⚠️⚠️ REBASE: `--ours` AND `--theirs` ARE REVERSED ⚠️⚠️⚠️ + +``` +╔══════════════════════════════════════════════════════════════════════════════╗ +║ ║ +║ During `git rebase`, the meaning of --ours / --theirs is FLIPPED ║ +║ compared to `git merge`. This trips up agents and silently drops work. ║ +║ ║ +║ During MERGE: ║ +║ --ours = the branch you are ON (your work) ║ +║ --theirs = the branch being merged in ║ +║ ║ +║ During REBASE: ║ +║ --ours = the UPSTREAM target (e.g. master) ← NOT your work! ║ +║ --theirs = the commit being replayed (your work) ║ +║ ║ +║ Why: rebase replays your commits onto upstream, so from rebase's POV ║ +║ "ours" is the new base it is building on top of. ║ +║ ║ +║ FAILURE MODE: running `git checkout --ours ` during a rebase ║ +║ conflict takes the upstream version, makes your replayed commit empty, ║ +║ and rebase silently DROPS the now-empty commit. Your work disappears ║ +║ from the branch with no error message. ║ +║ ║ +║ SAFE PATTERN when you want to KEEP your branch's version of a file ║ +║ during a rebase conflict: ║ +║ ║ +║ git checkout --theirs ← takes YOUR work during rebase ║ +║ git add ║ +║ git rebase --continue ║ +║ ║ +║ ALWAYS verify after `--continue`: ║ +║ ║ +║ git log --oneline ..HEAD ║ +║ ║ +║ If the output is empty, your commit was dropped — recover from reflog: ║ +║ ║ +║ git reflog | head -20 ║ +║ git reset --hard ║ +║ ║ +║ If unsure which side is which, abort and inspect both versions first: ║ +║ ║ +║ git show :2: > /tmp/ours.txt # "ours" side of the conflict ║ +║ git show :3: > /tmp/theirs.txt # "theirs" side of the conflict ║ +║ diff /tmp/ours.txt /tmp/theirs.txt ║ +║ ║ +╚══════════════════════════════════════════════════════════════════════════════╝ +``` + ## ⚠️⚠️⚠️ CRITICAL WARNING: NEVER USE `git stash` ⚠️⚠️⚠️ ``` @@ -83,6 +132,7 @@ | Date | What was lost | Root cause | |------------|------------------------------------------------|---------------------------------------------------| | 2026-04-28 | ~600 cpan-tester module results (4736 → 4139) | Agent ran `git checkout dev/cpan-reports/` on an unstaged refresh; concurrent `cpan_random_tester.pl` instances also race on `.dat` files (separate bug). | +| 2026-04-29 | cpan-reports refresh commit (briefly, on a feature branch — recovered from reflog) | Agent resolved a rebase conflict with `git checkout --ours` thinking it would keep the branch's version. During rebase, `--ours` means UPSTREAM, so the upstream files were taken, the replayed commit became empty, and rebase silently dropped it. Recovery: `git reset --hard ` from `git reflog`, then re-rebase using `--theirs`. | When you cause a new incident, append a row here in the same commit that fixes it. Future agents need to see that these warnings are real. From ef92ba68c41afe276e012755e4759d455a205418 Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Wed, 29 Apr 2026 09:03:59 +0200 Subject: [PATCH 2/3] docs(agents): cite git-rebase(1) on swapped --ours/--theirs Add the official quote from git-rebase(1) and a link to the docs so future agents (and humans) can confirm this isn't folklore. --- AGENTS.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 809fe2094..438130483 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -77,7 +77,11 @@ ║ --theirs = the commit being replayed (your work) ║ ║ ║ ║ Why: rebase replays your commits onto upstream, so from rebase's POV ║ -║ "ours" is the new base it is building on top of. ║ +║ "ours" is the new base it is building on top of. From git-rebase(1): ║ +║ "the side reported as ours is the so-far rebased series, starting ║ +║ with , and theirs is the working branch. In other words, ║ +║ the sides are swapped." ║ +║ https://git-scm.com/docs/git-rebase (search for "sides are swapped") ║ ║ ║ ║ FAILURE MODE: running `git checkout --ours ` during a rebase ║ ║ conflict takes the upstream version, makes your replayed commit empty, ║ From 90ee1c06b07e7caf9a012fe6ef153b3395c452fb Mon Sep 17 00:00:00 2001 From: Flavio Soibelmann Glock Date: Wed, 29 Apr 2026 09:05:35 +0200 Subject: [PATCH 3/3] docs(agents): note GitHub auto-closes PR when force-push equals base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a broken rebase drops your commit and you force-push the branch to a SHA that equals master's HEAD, GitHub auto-CLOSES the PR. Pushing the corrected SHA back does NOT reopen it — `gh pr reopen ` is required. Add a verification step to check `gh pr view --json state,files` after any force-push. This actually happened on PR #601 during the cpan-reports refresh. --- AGENTS.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index 438130483..1efbd758e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -104,6 +104,16 @@ ║ git reflog | head -20 ║ ║ git reset --hard ║ ║ ║ +║ GITHUB SIDE-EFFECT: if you ever force-push the branch to a SHA that ║ +║ equals the base branch's HEAD (which happens if rebase silently drops ║ +║ your commit), GitHub will auto-CLOSE the PR. A subsequent force-push ║ +║ back to the correct SHA does NOT auto-reopen it. You have to run: ║ +║ ║ +║ gh pr reopen ║ +║ ║ +║ So: after any force-push, check `gh pr view --json state,files` to ║ +║ make sure the PR is still OPEN and shows the expected files. ║ +║ ║ ║ If unsure which side is which, abort and inspect both versions first: ║ ║ ║ ║ git show :2: > /tmp/ours.txt # "ours" side of the conflict ║