agentleFS
nesnilnehcnesnilnehc/ai-cortex/skills/integrate-branches/SKILL.md

integrate-branches

Skill8 starsChanged 2 months agoMITView on GitHub

From the main repo on the main branch, scan all linked worktrees and local branches, let the user multi-select, then merge --no-ff + push them sequentially and clean up succeeded worktrees together.

  • Deletes or force-pushes
  • Commits and pushes

The file

Show its rules and text

We split this skill into the rules it gives an agent

24 rules. About 0 are common, 11 are distinctive, and 13 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Acceptance test: after the skill finishes, git log --oneline <main-branch> holds one merge commit per successful branch.

    line 29
  2. Distinctive:

    Verify the invocation context (main repository root + main branch)

    line 37
  3. Very specific:

    Run pull → --no-ff merge → push in turn for each selected branch

    line 43
  4. Distinctive:

    After each failure, ask the user: continue with the remaining entries, or abort

    line 44
  5. Very specific:

    Commit uncommitted changes (use commit-work inside each worktree first)

    line 52
  6. Distinctive:

    Create or manage pull requests

    line 55
  7. Distinctive:

    A branch hits a merge conflict: stop that one, and ask whether to continue with the rest

    line 63
  8. Distinctive:

    A branch's push is rejected: stop that one, and ask whether to continue with the rest

    line 64
  9. Distinctive:

    If git rev-parse --git-dir differs from git rev-parse --git-common-dir (that is, CWD is inside a linked worktree) → stop:

    line 91
  10. Distinctive:

    If the current branch is not the detected main branch (step 2) → stop:

    line 94
  11. Very specific:

    If the user's request already names the branches or says all, use that selection.

    line 145
  12. Very specific:

    If E.type == branch: it has no working tree of its own — skip the dirty check and treat it as clean.

    line 161
  13. Very specific:

    If <dirty-list> is not empty, report every dirty entry together before any merge starts:

    line 165
  14. Very specific:

    When entry E fails:

    line 198
  15. Very specific:

    Only for the entries in <succeeded-list> where E.type == worktree:

    line 222
  16. Distinctive:

    Run these in order. If one removal fails (the path no longer exists, say), record the error and move on to the next.

    line 228
  17. Very specific:

    Use -d only — never -D. If -d fails, report the error and stop deleting that branch.

    line 249
  18. Very specific:

    Single-worktree delivery: use deliver-feature from inside the worktree

    line 308
  19. Very specific:

    Commit pending changes: use commit-work inside each worktree first

    line 309
  20. Distinctive:

    rebase / squash: use git rebase directly, before invoking this skill

    line 310
  21. Distinctive:

    Create a PR: use the platform's own PR tooling.

    line 311
  22. Very specific:

    Code review: use review-diff before committing.

    line 312
  23. Distinctive:

    If this skill behaves wrongly:

    line 358
  24. Very specific:

    A failed worktree was deleted: stop; only type: worktree entries in <succeeded-list> may be removed

    line 362

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Skill: Integrate Branches

Purpose

Wrap up feature branches in bulk from the main repository: scan every active linked worktree plus the local branches that have no worktree, let the user pick which ones land, check each working tree is clean, merge + push them one after another, then clean up every successfully merged worktree in one pass. It removes the cd into each directory followed by a manual delivery.


Core Objective

Primary goal: on the main repository's main branch, merge the branches the user selected (from a worktree or standalone) into main, push to origin, and clean up the worktrees that succeeded — leaving the repository in a known clean state.

Success criteria (all must be satisfied):

  1. ✅ Invocation context verified: CWD is the main repository root (not inside a linked worktree), and the current branch is the main branch
  2. ✅ All candidates discovered: both git worktree list --porcelain and git branch are parsed; the non-main entries are presented to the user as one list with type markers
  3. ✅ Pre-flight finished before any merge: every selected worktree entry was checked for a clean working tree; every dirty entry is reported together in one block
  4. ✅ Sequential merge + push: each selected clean branch is merged with --no-ff and pushed in turn; the status of each is recorded (succeeded / failed)
  5. ✅ Cleanup in one pass: every succeeded worktree entry is removed together; branch-only entries skip the worktree removal; failed entries get no cleanup at all
  6. ✅ Summary report emitted: the merge / push / cleanup / branch-deletion status of every branch is covered

Acceptance test: after the skill finishes, git log --oneline <main-branch> holds one merge commit per successful branch; git worktree list holds only the main repository plus the failed or skipped worktree entries; git ls-remote origin <main-branch> matches the local state.


Scope Boundaries

This skill does:

  • Verify the invocation context (main repository root + main branch)
  • Determine the main branch (auto-detected; the user is asked only when it cannot be determined)
  • Scan linked worktrees (git worktree list --porcelain) and local branches with no worktree (git branch)
  • Deduplicate: a branch already covered by a worktree entry is not shown twice
  • Let the user multi-select the branches to merge (all, or a subset by index)
  • Pre-flight the working tree: worktree entries through git -C <path> status --porcelain; branch-only entries skip the dirty check (they have no working tree of their own)
  • Run pull → --no-ff merge → push in turn for each selected branch
  • After each failure, ask the user: continue with the remaining entries, or abort
  • Clean up every successfully merged worktree entry in one pass (git worktree remove)
  • Optional feature-branch deletion (user-confirmed, -d only)
  • A per-branch summary report

This skill does not do:

  • Single-worktree delivery (use deliver-feature from inside the worktree)
  • Commit uncommitted changes (use commit-work inside each worktree first)
  • Rebase or squash before merging
  • Resolve merge conflicts (on a conflict it stops and reports to the user)
  • Create or manage pull requests
  • Force-push to any branch
  • Parallel merge execution (execution is always sequential)

Handoff points:

  • → deliver-feature: the user is inside a single worktree and wants to deliver only that branch, without a cd back to the main repository
  • Stop and prompt the user: invoked inside a linked worktree, or invoked on a non-main branch of the main repository
  • A branch hits a merge conflict: stop that one, and ask whether to continue with the rest
  • A branch's push is rejected: stop that one, and ask whether to continue with the rest

Use Cases

  • A developer has 2–4 feature branches (some in worktrees, some standalone) ready to land on main in one go
  • End-of-sprint wrap-up in bulk: merge, push, and clean up every finished feature branch from the main repository
  • A CI or automation run produced several parallel worktrees plus a handful of topic branches, and the results are now being consolidated

Behavior

Workflow (Checklist)

Step 1 — verify the invocation context

git rev-parse --git-dir              # main repo: <root>/.git ; linked worktree: <main-root>/.git/worktrees/<name>
git rev-parse --git-common-dir       # same value in both contexts: <main-root>/.git
git rev-parse --abbrev-ref HEAD      # current branch
git rev-parse --show-toplevel        # current repository root

For a linked worktree git-dir != git-common-dir; in the main repository the two are equal.

  • If git rev-parse --git-dir differs from git rev-parse --git-common-dir (that is, CWD is inside a linked worktree) → stop:

    "This skill must run from the main repository root, not from inside a worktree. Current location: <cwd>. To deliver the current worktree's branch, use deliver-feature."

  • If the current branch is not the detected main branch (step 2) → stop:

    "The current branch is <current-branch>, not <main-branch>. Switch to the main branch first: git checkout <main-branch>."

Record <main-repo> (= git rev-parse --show-toplevel). CWD stays there for every step that follows.

Step 2 — determine the main branch

git remote show origin | grep 'HEAD branch'
  • The result is unambiguous (such as HEAD branch: main) → use it directly.
  • The command fails or returns nothing → look for origin/main in git branch -r, then origin/master.
  • Still undetermined → ask the user:

    "The main branch could not be determined automatically. Enter the main branch name (main, master, develop, and so on):"

Record <main-branch>.

Step 3 — scan and present the selectable branches

# Source 1: linked worktrees
git worktree list --porcelain

# Source 2: all local branches
git branch --format='%(refname:short)'

Parse the porcelain output. The first worktree record is the main repository itself — skip it. Record each of the others as a type: worktree candidate.

Exclude from the git branch output:

  • <main-branch> itself
  • Branches already covered by a worktree entry (deduplicated by branch name)

Record the remaining branches as type: branch candidates (with no associated worktree path).

Build one list of {path, branch, type} tuples. Skip detached entries and mark them unavailable.

  • No candidates → stop:

    "No active linked worktree or local branch was found; there is nothing to integrate."

Present the list with an index, a type marker, the path where applicable, the branch name, and a hint about recent activity:

Available branches to integrate:
  [1]  worktree  /repos/myapp-auth      feat/user-auth      (last commit: 2 days ago)
  [2]  worktree  /repos/myapp-api       feat/api-v2         (last commit: 5 days ago)
  [3]  branch    —                      feat/dashboard      (last commit: 14 days ago — STALE)

If the user's request already names the branches or says all, use that selection. Otherwise ask:

"Select the branches to integrate. Enter the indexes (comma-separated) or all:"

Record <selected-list>.

Step 4 — pre-flight: check every selected entry

For each entry E in <selected-list>:

  • If E.type == worktree:

    git -C <E.path> status --porcelain
  • If E.type == branch: it has no working tree of its own — skip the dirty check and treat it as clean.

Collect the results into <clean-list> and <dirty-list> respectively.

If <dirty-list> is not empty, report every dirty entry together before any merge starts:

Pre-flight check — dirty worktrees (will be skipped):
  /repos/myapp-api  (feat/api-v2)    — 3 uncommitted file(s)

Ask:

"The worktrees above hold uncommitted changes. Continue merging the remaining clean entries, or stop everything? [continue / halt]"

  • halt → stop; run no merges.
  • continue → carry on with <clean-list> only. If <clean-list> is empty → stop and report "nothing to act on".

Nothing is stashed automatically under any circumstances.

Step 5 — bulk merge + push (sequential)

For each entry E in <clean-list>:

# stay current across a multi-branch run
git pull origin <main-branch>

# --no-ff merge
git merge --no-ff <E.branch> -m "Merge branch '<E.branch>' into <main-branch>"

# push
git push origin <main-branch>

CWD stays at <main-repo> throughout.

When entry E fails:

  • Merge conflict:

    "Merging <E.branch> into <main-branch> hit a conflict. Resolve the conflict in <main-repo>, finish the merge by hand, then push and remove the worktree where applicable."

  • Push rejected (not a fast-forward):

    "The push after merging <E.branch> was rejected. Run git reset --hard HEAD~1 in <main-repo> to undo the merge, then pull, merge again, and push."

In both cases mark E as failed and ask:

"Continue with the remaining branches, or abort everything left? [continue / abort]"

  • abort → stop; process none of the remaining entries.
  • continue → mark E as failed and move on to the next one.

Record the result of each one: succeeded or failed.

Step 6 — cleanup in one pass (worktree entries only)

Once all merges are done, confirm CWD is still <main-repo>:

pwd   # must equal <main-repo>

Only for the entries in <succeeded-list> where E.type == worktree:

git worktree remove <E.path>

Run these in order. If one removal fails (the path no longer exists, say), record the error and move on to the next.

type: branch entries have no worktree path — this step skips them entirely. The worktree of a failed entry is never removed.

Step 7 — offer the local branch deletion option

For every entry in <succeeded-list>, present the branch list together:

"The successful entries are cleaned up. Delete the local feature branches below? Enter the indexes, all, or none:"

[1]  feat/user-auth  (was worktree)
[2]  feat/dashboard  (was branch)

Once each one is confirmed, run:

git branch -d <E.branch>

Use -d only — never -D. If -d fails, report the error and stop deleting that branch.

Step 8 — summary report

integrate-branches summary
──────────────────────────────────────────────────────────────────────────
Type      Branch            Merge          Push   Cleanup  Branch-Del
worktree  feat/user-auth    ✓              ✓      ✓        deleted
worktree  feat/api-v2       ✗(conflict)    —      —        —
branch    feat/dashboard    ✓              ✓      —        deleted
──────────────────────────────────────────────────────────────────────────
Main repo: /repos/myapp · Main branch: main · Remote: origin

Status codes: ✓ succeeded · ✗(reason) failed · skipped(dirty) pre-flight failed · — not applicable

The Cleanup column of a type: branch entry is always — (there is no worktree to remove).


Input & Output

Input Requirements

InputRequiredNote
Main repo + main branch contextYesCWD must be the main repository root, and the current branch must equal the main branch
Active candidatesYesAt least one linked worktree or local branch exists, other than main
Branch selectionUser inputall, or comma-separated indexes from the presented list
Clean working treePer worktree entryA dirty worktree is reported up front and skipped; branch-only entries always pass pre-flight
Main branch nameAuto / askDetected from the remote; the user is asked when it cannot be determined
Network accessYespull and push to origin need the network

Output Contract

ElementNote
Merge commitsEach successful branch produces one --no-ff merge commit on <main-branch>
Remote pushOne push per successful branch, updating origin/<main-branch>
Worktree removalEvery successful type: worktree entry is removed from git worktree list
Branch deletionOptional, run after user confirmation; git branch -d only
Batch summary reportA per-branch table: type / branch / merge / push / cleanup / branch-deletion status

Restrictions

Hard Boundaries

  • Never force-push (--force, --force-with-lease) to any branch
  • Never remove a worktree after its merge or push failed
  • Never stash automatically — uncommitted changes are reported up front and that worktree is skipped
  • Never use git branch -D — -d only (the safe delete)
  • Never start a merge before pre-flight has finished for every selected entry
  • Never continue from inside a linked worktree, or on a non-main branch of the main repository — stop and give the matching prompt

Skill Boundaries

  • Single-worktree delivery: use deliver-feature from inside the worktree
  • Commit pending changes: use commit-work inside each worktree first
  • rebase / squash: use git rebase directly, before invoking this skill
  • Create a PR: use the platform's own PR tooling; this skill merges straight into main
  • Code review: use review-diff before committing; this skill does no code review

Anti-Patterns

Invocation Context

✅ Run from the main repository root, on the main branch ❌ Do not run from inside a linked worktree — that is deliver-feature's job; once the worktree is deleted the CWD goes stale and every command after it fails

Pre-Flight Order

✅ Run the dirty check across every selected worktree entry before any merge starts ❌ Do not check an entry only just before its own merge — a dirty worktree then surfaces after some merges are already committed

Merge Method

✅ git merge --no-ff keeps the branch history ❌ Do not use git merge --squash or a fast-forward — the history is lost

Push Safety

✅ Standard git push origin <main-branch> ❌ Never use --force or --force-with-lease on main

Cleanup Order

✅ Remove a worktree only after both the merge and the push succeeded ❌ Do not remove between the merge and the push — if the push fails the branch becomes unreachable

Branch Deletion

✅ git branch -d (safe), with user confirmation ❌ Never use git branch -D (force) — it can delete unmerged commits


Examples

Consult worked examples for mixed worktrees, dirty trees, or wrong invocation context.


AI Refactor Instruction

If this skill behaves wrongly:

  1. It carried on in the wrong context: go back to step 1 and add the git-dir vs git-common-dir comparison and the branch-equality check
  2. Pre-flight was skipped or deferred: go back to step 4 and make sure pre-flight completes for every selected entry before any merge
  3. A failed worktree was deleted: stop; only type: worktree entries in <succeeded-list> may be removed
  4. worktree remove ran on a branch-only entry: a branch-only entry has no worktree path — step 6 skips it entirely
  5. A force-push was attempted: replace it with a standard push; if that fails, stop and report
  6. pull was skipped before a merge: rerun from the pull step
  7. A worktree branch showed up twice: the deduplication in step 3 must exclude branches already in the worktree list from the git branch output

Self-Check

  • Invocation context verified: git rev-parse --git-dir equals git rev-parse --git-common-dir, and the current branch equals <main-branch>
  • Main branch confirmed: auto-detected or explicitly given by the user, never assumed
  • Both sources scanned: git worktree list --porcelain and git branch are both parsed, and the non-main entries are presented
  • Deduplication done: a branch held in a worktree does not show up again in the branch list
  • User selection recorded: all or the index subset was captured before any pre-flight
  • Pre-flight for every worktree entry finished before any merge: git -C <path> status --porcelain ran for each selected worktree entry
  • Branch-only entries skipped the dirty check: they have no working tree to check
  • Dirty worktrees reported together: every dirty entry was listed before the continue/halt prompt
  • pull ran before every merge: git pull origin <main-branch> ran immediately before each git merge --no-ff
  • Merged with --no-ff: git merge --no-ff confirmed, with no fast-forward and no squash
  • succeeded marked only after the push succeeded: an entry joins <succeeded-list> only after git push returns 0
  • Cleanup in one pass touched only successful worktree entries: git worktree remove was never called on a failed, skipped, or type: branch entry
  • CWD confirmed before cleanup: pwd equals <main-repo> before any git worktree remove
  • Branch deletion used -d: no -D flag in any branch-deletion command; the user confirmed each branch
  • Summary report emitted: the status code of every branch is filled in correctly
  • No force-push used: --force and --force-with-lease show up in no command

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.