diff --git a/skills/rebase/SKILL.md b/skills/rebase/SKILL.md index 46d1f63..f43a4b3 100644 --- a/skills/rebase/SKILL.md +++ b/skills/rebase/SKILL.md @@ -67,36 +67,92 @@ If they match, the branch is already up-to-date. Inform the user and stop. git rebase origin/ ``` -### On success +### Clean rebase (no conflicts) -Report how many commits ahead of the base branch: +Report success briefly: + +- How many commits were replayed (`git rev-list --count origin/..HEAD`) +- The branch is now up to date with `origin/` +- If the branch was previously pushed, mention that a force-push (`git push --force-with-lease`) will be needed to update the remote — but do NOT push automatically + +If changes were stashed in Step 1, restore them with `git stash pop`. If stash pop fails due to conflicts, inform the user and suggest `git stash show` to review the stashed changes. + +## Step 4: Handling conflicts + +When `git rebase` stops with conflicts: + +### 4a. Identify conflicted files ```bash -git rev-list --count origin/..HEAD +git diff --name-only --diff-filter=U ``` -### On conflict +### 4b. Resolve each conflicted file + +Read the full file content and locate conflict markers (`<<<<<<<`, `=======`, `>>>>>>>`). For each conflict chunk, decide: + +**Auto-resolve** (the right answer is clear): -Abort the rebase: +- Both sides added imports or list items — combine both sets, deduplicate, maintain sort order +- Generated files (`.g.dart`, `.freezed.dart`, `.gen.dart`, lock files) — take the current branch version; note that regeneration is needed after rebase completes +- Formatting / whitespace-only diffs — accept either side +- One side added new code, the other didn't touch that region — take the addition +- One side modified code the other side deleted — prefer the modification, but mention it in the summary so the user can verify the deletion wasn't intentional + +**Stop and ask the user** (the right answer requires judgment): + +- Both sides changed the same function or logic block differently +- Business logic where correctness depends on product intent +- Anything you aren't confident about + +When in doubt, ask. Losing someone's work is far worse than pausing to check. + +After resolving all conflicts in a file, write the clean version and stage it: ```bash -git rebase --abort +git add ``` -If changes were stashed in Step 1, restore them with `git stash pop`. +### 4c. Continue the rebase -Inform the user that the rebase had conflicts and suggest resolving manually: +```bash +git rebase --continue +``` + +Multi-commit rebases may produce conflicts at multiple steps. Repeat 4a-4c for each. + +### 4d. After all conflicts are resolved, report + +- Every conflict that was resolved, with a one-line explanation of what you chose +- Any files flagged for regeneration +- Suggest running the project's build/test/format/analyze commands to verify correctness +- If the branch was previously pushed, mention that a force-push (`git push --force-with-lease`) will be needed — but do NOT push automatically + +If changes were stashed in Step 1, restore them with `git stash pop`. If `stash pop` fails due to conflicts, inform the user and suggest `git stash show` to review the stashed changes. + +## Step 5: Recovery + +If the rebase enters a bad state or a conflict is too ambiguous to resolve safely: -> Automatic rebase failed due to conflicts. To resolve manually, run: `git rebase origin/` +```bash +git rebase --abort +``` + +This restores the branch to its exact pre-rebase state — nothing is lost. Explain what went wrong so the user can decide how to proceed. + +If changes were stashed in Step 1, restore them with `git stash pop`. ## Gotchas -- If the branch has already been pushed to a remote, rebasing rewrites history. The user will need to force-push (`git push --force-with-lease`) after a successful rebase — warn them. -- `git stash pop` can itself cause conflicts if stashed changes overlap with rebased commits. If stash pop fails, inform the user and suggest `git stash show` to review the stashed changes. - Detached HEAD state (`HEAD` instead of a branch name) means the user is not on any branch. Inform them and stop — do not attempt to rebase. - If the base branch does not exist locally but does on the remote, `git fetch` in Step 2 will create the remote tracking ref. The rebase uses `origin/`, not the local branch. -## Important +## Rules -- This skill only manages git state. Do not modify project files. +- Never force-push unless the user explicitly asks. +- Never squash, reorder, or edit commits during the rebase — just replay them. +- Never proceed on a dirty working tree without the user's consent. +- Prefer keeping both sides' changes when combining — err on the side of inclusion. +- After resolving conflicts, always recommend running build, test, format, and analyze to verify. +- This skill only manages git state. Do not modify project files outside of conflict resolution. - If changes were stashed, always restore them — even if the rebase fails.