diff --git a/skills/rebasing-with-git/SKILL.md b/skills/rebasing-with-git/SKILL.md index b694c359e355d7adc1afafca3683b51d9497ad39..c37784b9748921bf3fd1b97f697ffd17efb67161 100644 --- a/skills/rebasing-with-git/SKILL.md +++ b/skills/rebasing-with-git/SKILL.md @@ -8,7 +8,7 @@ metadata: ## General principles -- **Non-interactive rebases**: prefix with `GIT_EDITOR=true`. For interactive rebases that edit the todo, also set `GIT_SEQUENCE_EDITOR` (see [drop-and-repick](#step-5-rebase-with-drops)). +- **Non-interactive rebases**: prefix with `GIT_EDITOR=true`. For interactive rebases that edit the todo, also set `GIT_SEQUENCE_EDITOR` (see [drop-and-repick](#step-5-rebase-with-drops-and-break)). - **Never push** unless the user explicitly says to. If they say "force push", use `--force-with-lease`. Do not suggest pushing. When work is complete, stop. - **Dirty worktree**: if uncommitted changes exist when a rebase is requested, ask the user how to proceed before doing anything. - **In-progress rebase**: if `.git/rebase-merge` or `.git/rebase-apply` exists (or the worktree-local equivalents under `.git/worktrees//`), read the state—conflicts, staged changes, progress through the todo—and offer to continue or abort based on what you find. @@ -50,7 +50,7 @@ git remote show | grep 'HEAD branch' | sed 's/.*: //' ## Handling conflicts -1. **Stop immediately.** Do not resolve without user confirmation. +1. **Stop immediately.** Do not resolve without user confirmation. **Never skip a commit.** If a commit seems too complex to resolve, present what you see and ask the user—they may know the exact resolution. 2. Run `git status` and examine every conflicting file thoroughly. 3. Present to the user: - What the local changes are doing and why they were made @@ -60,6 +60,17 @@ git remote show | grep 'HEAD branch' | sed 's/.*: //' 4. **Wait for the user to confirm or direct** a resolution. 5. After resolving: `git add` the resolved files, then `GIT_EDITOR=true git rebase --continue`. +### Bulk mechanical changes (import renames, formatting, etc.) + +Large-scale rename or formatting commits often produce massive conflict diffs that obscure the actual change. The typical resolution pattern is: + +1. Check out HEAD's version of the affected files: `git checkout HEAD -- ` +2. Re-apply the mechanical transformation (e.g. `fd -x sd '' ''`) +3. Run the project's formatter +4. `git add` and continue + +**Do not attempt to hand-resolve hundreds of conflicting hunks.** Recognize when a commit is mechanical in nature, describe it to the user, and ask how they want to re-apply the transformation. + ## Fork rebase: feature branches The user will already be in the correct worktree or have the branch checked out. Rebase only the current branch. @@ -123,19 +134,32 @@ Preserve the order the feature-branch commits originally appeared in the persona **Wait for explicit confirmation before proceeding.** -### Step 5: Rebase with drops +### Step 5: Rebase with drops and break -Build a sed command to change `pick` to `drop` for each identified commit. Use short hashes from `git log --oneline`; these match the abbreviation the rebase todo uses. +The rebase todo must be structured as: **drop → break → pick**. The drops remove stale feature-branch commits, the break pauses the rebase so fresh cherry-picks can be inserted, and the remaining picks replay personal-only commits on top. + +Build a sed command that: +1. Changes `pick` to `drop` for each identified commit +2. Inserts a `break` line after the last `drop`, before the first remaining `pick` + +Use short hashes from `git log --oneline`; these match the abbreviation the rebase todo uses. ```sh GIT_EDITOR=true \ -GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick /drop /' -e 's/^pick /drop /'" \ +GIT_SEQUENCE_EDITOR="sed -i \ + -e 's/^pick /drop /' \ + -e 's/^pick /drop /' \ + -e '/^drop /a break'" \ git rebase -i upstream/ ``` -If personal-only commits conflict during this rebase, handle per [Handling conflicts](#handling-conflicts). +Where `` is the last commit being dropped (use `/a break` to append after it). If drops are non-contiguous in the todo, insert the break after the last one. + +The rebase will process the drops, then pause at the `break`. If personal-only commits conflict during the rebase (before or after the break), handle per [Handling conflicts](#handling-conflicts). -### Step 6: Re-pick from feature branches +### Step 6: Re-pick from feature branches (during break) + +The rebase is paused. Cherry-pick feature branches back in now, before the personal-only commits are replayed. For each feature branch, in the order confirmed in step 4: @@ -163,7 +187,17 @@ For each feature branch, in the order confirmed in step 4: 5. Run format/lint/typecheck after completing each feature branch's re-pick. -### Step 7: Final verification +### Step 7: Continue the rebase + +After all feature branches are re-picked: + +```sh +GIT_EDITOR=true git rebase --continue +``` + +This replays the personal-only commits on top of the freshly cherry-picked feature work. Handle conflicts per [Handling conflicts](#handling-conflicts). + +### Step 8: Final verification 1. Review the log: ```sh