Skip to content

Commit 59ed18a

Browse files
committed
fix(ship-skill): compare commit content not count, handle WIP before rebase, avoid fixed temp branch name
- Final verify now diffs actual commit subjects between git log and the PR, not just a count — a corrupted branch's inflated count could coincidentally match a later count check - The pre-commit count in step 2 was being compared against the post-commit PR in step 9, which would mismatch even on success; now compares content at the point it's actually available - Recovery flow stashes uncommitted work before rebasing so it isn't blocked by a dirty tree, and checks for an existing tmp branch before reusing the name
1 parent 78c5598 commit 59ed18a

2 files changed

Lines changed: 24 additions & 4 deletions

File tree

.agents/skills/ship/SKILL.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,12 @@ You help ship code by creating commits, pushing to the remote branch, and creati
1212
When the user runs `/ship`:
1313

1414
1. **Check git status** - See what files have changed
15-
2. **Sync check**: `git fetch origin staging && git log --oneline origin/staging..HEAD`. Must list only this session's commit(s) — a worktree/branch can silently be cut from a stale local `staging`, dragging in unrelated commits. If it shows extra commits, fix before pushing: `git rebase origin/staging`; if that hits conflicts on commits you don't recognize, `git rebase --abort` and instead `git checkout -b tmp origin/staging`, `git cherry-pick <your-sha(s)>`, resolve conflicts, then `git branch -f <branch> HEAD && git checkout <branch>` and `git push --force-with-lease`.
15+
2. **Sync check**: `git fetch origin staging && git log --oneline origin/staging..HEAD`. Read the actual commit list, not just how many there are — it must show ONLY commits you can attribute to this session (recognizable subjects/SHAs). A worktree/branch can silently be cut from a stale local `staging`, dragging in unrelated commits; a corrupted branch's inflated commit *count* can coincidentally match a later check even when the *commits* are wrong, so always compare content, never just a number.
16+
- If it shows commits you don't recognize, fix it now, **before** staging/committing any new work (step 7 hasn't run yet):
17+
- If the working tree has uncommitted changes, stash them first — `git stash push -u -m ship-sync-fix` — so the rebase below isn't blocked by dirty state. Restore with `git stash pop` once the branch is fixed.
18+
- Try `git rebase origin/staging` first.
19+
- If that walks through unrelated history and conflicts on commits you don't recognize, `git rebase --abort` and rebuild instead: pick a temp branch name that isn't already in use (`git branch --list ship-sync-tmp`; if it exists, delete it or pick another name), `git checkout -b ship-sync-tmp origin/staging`, `git cherry-pick <your-sha(s)>`, resolve conflicts, then `git branch -f <original-branch> HEAD`, `git checkout <original-branch>`, and delete the temp branch.
20+
- Re-verify with `git log --oneline origin/staging..HEAD` — it should list only commits you recognize.
1621
3. **Generate a commit message** following this format: `type(scope): description`
1722
- Types: `fix`, `feat`, `improvement`, `chore`
1823
- Scope: short identifier (e.g., `undo-redo`, `api`, `ui`)
@@ -27,7 +32,12 @@ When the user runs `/ship`:
2732
- `bun run check:api-validation:strict` to catch boundary contract failures before CI
2833
7. **Stage and commit** the changes with the generated message
2934
8. **Push to origin** using the current branch name
30-
9. **Create a PR** to staging with a description in the user's voice, then confirm `gh pr view <n> --json commits -q '.commits | length'` matches the commit count from step 2 — otherwise redo the sync fix and force-push
35+
9. **Create a PR** to staging with a description in the user's voice, then do a final content check — not a count check — comparing what actually landed:
36+
```bash
37+
git log --oneline origin/staging..HEAD
38+
gh pr view <n> --json commits -q '.commits[].messageHeadline'
39+
```
40+
These two lists must describe the same commits (same subjects, one of which is the commit from step 7). If they don't match, the branch still has a problem — redo step 2's fix and `git push --force-with-lease`.
3141

3242
## Commit Message Format
3343

.cursor/commands/ship.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,12 @@ You help ship code by creating commits, pushing to the remote branch, and creati
77
When the user runs `/ship`:
88

99
1. **Check git status** - See what files have changed
10-
2. **Sync check**: `git fetch origin staging && git log --oneline origin/staging..HEAD`. Must list only this session's commit(s) — a worktree/branch can silently be cut from a stale local `staging`, dragging in unrelated commits. If it shows extra commits, fix before pushing: `git rebase origin/staging`; if that hits conflicts on commits you don't recognize, `git rebase --abort` and instead `git checkout -b tmp origin/staging`, `git cherry-pick <your-sha(s)>`, resolve conflicts, then `git branch -f <branch> HEAD && git checkout <branch>` and `git push --force-with-lease`.
10+
2. **Sync check**: `git fetch origin staging && git log --oneline origin/staging..HEAD`. Read the actual commit list, not just how many there are — it must show ONLY commits you can attribute to this session (recognizable subjects/SHAs). A worktree/branch can silently be cut from a stale local `staging`, dragging in unrelated commits; a corrupted branch's inflated commit *count* can coincidentally match a later check even when the *commits* are wrong, so always compare content, never just a number.
11+
- If it shows commits you don't recognize, fix it now, **before** staging/committing any new work (step 5 hasn't run yet):
12+
- If the working tree has uncommitted changes, stash them first — `git stash push -u -m ship-sync-fix` — so the rebase below isn't blocked by dirty state. Restore with `git stash pop` once the branch is fixed.
13+
- Try `git rebase origin/staging` first.
14+
- If that walks through unrelated history and conflicts on commits you don't recognize, `git rebase --abort` and rebuild instead: pick a temp branch name that isn't already in use (`git branch --list ship-sync-tmp`; if it exists, delete it or pick another name), `git checkout -b ship-sync-tmp origin/staging`, `git cherry-pick <your-sha(s)>`, resolve conflicts, then `git branch -f <original-branch> HEAD`, `git checkout <original-branch>`, and delete the temp branch.
15+
- Re-verify with `git log --oneline origin/staging..HEAD` — it should list only commits you recognize.
1116
3. **Generate a commit message** following this format: `type(scope): description`
1217
- Types: `fix`, `feat`, `improvement`, `chore`
1318
- Scope: short identifier (e.g., `undo-redo`, `api`, `ui`)
@@ -21,7 +26,12 @@ When the user runs `/ship`:
2126

2227
6. **Push to origin** using the current branch name
2328

24-
7. **Create a PR** to staging with a description in the user's voice, then confirm `gh pr view <n> --json commits -q '.commits | length'` matches the commit count from step 2 — otherwise redo the sync fix and force-push
29+
7. **Create a PR** to staging with a description in the user's voice, then do a final content check — not a count check — comparing what actually landed:
30+
```bash
31+
git log --oneline origin/staging..HEAD
32+
gh pr view <n> --json commits -q '.commits[].messageHeadline'
33+
```
34+
These two lists must describe the same commits (same subjects, one of which is the commit from step 5). If they don't match, the branch still has a problem — redo step 2's fix and `git push --force-with-lease`.
2535

2636
## Commit Message Format
2737

0 commit comments

Comments
 (0)