Name and create a task branch from fresh origin/main, and rotate a task-owned worktree to a new branch after its PR merges. Use when asked for a fresh branch, when /ship needs a branch for detached work, and after a merge.
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Creating or switching branches never needs permission. In a checkout other
sessions are using, branch in a new worktree instead of switching that
checkout's branch under them. Platform-assigned Builder.io and Fusion branches
stay where they are. Never move a branch that another worktree has checked out
(git worktree list --porcelain), and never stash, reset, or force anything.
<login>/changes-N, for example steve8708/changes-545.
login=$(gh api user --jq .login)
git fetch origin --quiet || { echo "fetch failed: not branching from a stale origin/main" >&2; exit 1; }
last=$(git for-each-ref --format='%(refname:short)' refs/heads refs/remotes/origin \
| sed -nE "s#^(origin/)?$login/changes-([0-9]{2,6})\$#\2#p" | sort -n | tail -1)
branch="$login/changes-$(( ${last:-49} + 1 ))"Only your own prefixed branches count, and six digits at most, which skips legacy and timestamp-named branches.
Look at what would come along first:
git status --short --untracked-files=all
git log --oneline origin/main..HEADThen pick the base. The git switch commands below are for a checkout only
this task uses; in a checkout other sessions are using, create the branch in a
new worktree instead (git worktree add -b "$branch" <path> <base>).
main's history; check with
gh pr view <number> --json state): git switch -c "$branch" origin/main.git switch -c "$branch" to keep them at HEAD.Never branch from a local main, which can be stale. If the branch is for an
existing PR update, base it on that PR's freshly fetched live head instead of
origin/main (see babysit-pr for the push target). Don't push the new branch
until it has changes to ship.
Rotate only when the PR merged, the tree is clean, and nothing is unpushed.
git fetch origin --quiet || { echo "fetch failed: keeping this branch" >&2; exit 1; }
git merge-base --is-ancestor <mergeCommit.oid> origin/main
git status --porcelain --untracked-files=all -- ':/' ':(top,exclude)learnings.md' ':(top,exclude)bridge/**' ':(top,exclude)data/**'
git log --oneline <ship_merge_head_oid>..HEADmergeCommit.oid comes from gh pr view <number> --json mergeCommit. If it
isn't in origin/main yet, wait a few seconds and fetch again.ship_merge_head_oid is the head /ship saved before merging. The git log
must print nothing, which means no commits landed after the merged head.
Also confirm the PR's final head is the one that merged:
gh pr view <number> --json headRefOid --jq .headRefOid must print
ship_merge_head_oid. This works even when the source branch was deleted
or lives on a fork. If the command fails, keep the branch.git cat-file -e "<ship_merge_head_oid>^{commit}" and
git merge-base --is-ancestor <ship_merge_head_oid> HEAD must both succeed
first, which proves this checkout holds the merged head. If
the saved OID is missing or invalid, an empty git log proves nothing, so
keep the branch.When it's all clear, compute $branch as above and run
git switch -c "$branch" origin/main. Always use origin/main here, never the
HEAD-keeping branch from "Create": a squash merge leaves the source commits
off main's history, so HEAD would carry already-merged work. In a shared
checkout, don't rotate; leave its branch as it is.
BuilderIO/agent-native
a0356c6
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.