| name | sync-worktree |
| description | Safely transfer changes from a linked git worktree into the parent checkout by committing dirty worktree changes, squashing the worktree delta to one commit, rebasing that intent onto the parent's latest commit, re-running tests in both locations, and landing the final commit in the parent. Use when Codex is asked to sync, transfer, land, port, or move worktree changes back to the parent repository or main checkout. |
Sync Worktree
Overview
Use this skill when the current checkout is a linked git worktree and the goal is to land its changes into the parent checkout without carrying over stale history or blindly replaying conflicts.
Prefer preserving the intent of the worktree changes over preserving the exact patch. If the parent has changed enough that the worktree edits would become unrecognizable, stop and report that instead of forcing the sync through.
Workflow
- Verify the current checkout is a linked worktree, not the primary checkout.
- Identify the parent checkout and capture its starting
HEAD.
- Refuse to continue if the parent checkout has any uncommitted changes.
- If the worktree has no uncommitted changes and is zero commits ahead of the parent main branch, fast-forward the worktree to the parent's latest commit and stop early.
- Commit any dirty changes in the worktree.
- Collapse the worktree delta so it is exactly one commit ahead of the parent starting
HEAD.
- Run the same relevant green test command in both the parent and the worktree.
- Rebase the single worktree commit onto the parent's latest commit, resolving conflicts by porting intent rather than replaying the old diff mechanically.
- Re-run the worktree tests.
- Re-check the parent
HEAD. If it changed since the rebase base was chosen, restart the workflow from the beginning.
- Transfer the rebased worktree commit into the parent checkout.
- Report success with the parent commit SHA, the worktree commit SHA, and a short summary of what changed.
Step Details
1. Verify the checkout shape
Confirm all of the following before changing anything:
git rev-parse --is-inside-work-tree returns true.
git rev-parse --git-dir differs from git rev-parse --git-common-dir.
git worktree list --porcelain shows more than one worktree.
If those checks do not hold, stop and explain that this is not a linked-worktree sync.
2. Identify the parent checkout
Use git worktree list --porcelain to find the primary checkout. Prefer the non-current worktree on the repository's main integration branch when that is obvious. If multiple candidates exist and none is clearly the parent, stop and ask the user which checkout should receive the changes.
Capture:
- Parent path
- Parent starting
HEAD
- Worktree starting
HEAD
Create a temporary safety ref in the worktree before rewriting history, for example a branch or tag pointing at the original worktree HEAD.
3. Verify the parent is clean
Run git status --short in the parent checkout.
If the parent has any uncommitted changes, stop. Do not stash, reset, or clean the parent automatically.
4. Exit early when the worktree has nothing to land
Before creating or rewriting commits, compare the clean worktree against the parent main branch.
If both of the following are true:
git status --short in the worktree is empty
- The worktree is zero commits ahead of the parent main branch
then fast-forward the worktree to the parent's latest commit and stop early with a success report that no landing work was needed.
Use an explicit ahead/behind check such as git rev-list --left-right --count <parent-main>...HEAD to verify the worktree is not ahead. This early exit is only for the zero-ahead case. If the worktree is ahead, behind-only relative to some branch other than parent main, or dirty, continue with the normal workflow.
5. Commit dirty worktree changes
Run git status --short in the worktree.
If the worktree is dirty:
- Stage only the intended worktree changes.
- Create a normal commit with a focused message.
If the worktree is already clean, continue.
6. Squash the worktree delta to one commit
The target shape is:
- The worktree may still be behind the parent by zero or more commits.
- The worktree must be exactly one commit ahead of the parent starting
HEAD.
Preserve a safety ref first, then rewrite the worktree history so all worktree-only commits become one commit. Any equivalent approach is acceptable as long as the final result is one worktree commit containing the intended delta.
After rewriting, verify the relationship explicitly with git rev-list --left-right --count <parent-start>...HEAD.
7. Verify tests in both places
Find the relevant local test command from repository docs, scripts, CI config, or recent commands. Prefer the smallest command that credibly covers the worktree change.
Run that command:
- In the parent checkout before landing anything
- In the worktree before the rebase
If either test run fails, stop and report the failure.
8. Rebase onto the parent's latest commit
Refresh the parent's current HEAD and rebase the single worktree commit onto it.
Record the exact parent HEAD used as the rebase base.
During conflicts:
- Treat the old worktree diff as evidence of intent, not as a patch that must survive unchanged.
- Read the parent-side changes carefully.
- Rewrite the worktree files as needed so the resulting code expresses the same intended behavior on top of the newer parent state.
- Drop redundant pieces when the parent already implements them.
Stop instead of forcing the rebase if:
- The parent has diverged so much that the worktree change would no longer be recognizable.
- You cannot explain the resulting change as the same user intent on top of newer code.
9. Verify the worktree again
Run the same relevant test command in the rebased worktree.
If tests fail, fix the rebased result if the fix is still clearly part of the same intent. Otherwise stop and report the blocker.
10. Guard against parent movement
Check the parent HEAD again immediately before transfer.
If it differs from the HEAD used as the rebase base, restart from the beginning. Do not cherry-pick onto a moving parent and hope it still matches.
11. Transfer the commit to the parent
Use the rebased worktree commit as the source of truth and apply it to the parent checkout, typically with git cherry-pick <worktree-commit>.
After transfer:
- Verify the parent is now clean except for the new commit.
- Record the new parent commit SHA.
12. Report
Summarize:
- Parent path
- Parent starting and ending SHAs
- Worktree starting and ending SHAs
- Test commands run and whether they passed
- Whether any conflicts required rewriting or dropping redundant changes
Safety Rules
- Never proceed with a dirty parent checkout.
- Never discard worktree history without first creating a safety ref.
- Never treat conflict resolution as a purely textual merge when the parent changed materially.
- Never land a result you cannot still describe as the same change in intent.
- If the parent advances while syncing, restart.