agentsclimarketplace

Git ref

Skill memorysaver/agentic-engineering-patterns/skills/agentic-development-workflow/git-ref

Canonical AEP git reference: base resolution, worktree lifecycle, naming, task commits, PRs, recovery. Use when a git convention is needed.From its SKILL.md

Install
npx -y skills add memorysaver/agentic-engineering-patterns --skill git-ref

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 17 stars17 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

14.3 KB, as published. Nobody here has run it

Git + Worktree Reference (AEP)

/aep-launch, /aep-build, and /aep-wrap operate on a plain git repository plus git worktree for parallel agent isolation. There is no separate VCS, no colocated mode, no special wrapper — when these skills say "commit", they mean git commit. This skill is the canonical home for AEP's git conventions: every other skill resolves $BASE, creates/removes worktrees, and opens PRs by pointing here, never by re-inlining these blocks.

AEP migrated from Jujutsu to pure git in 2026-04 (agent training data, universal tooling); rationale in docs/decisions/migrate-from-jj-to-git.md.


Integration Branch

Every AEP git operation targets the integration branch — the branch feature worktrees are created from, rebased onto, PR'd into, merged into, and where control-plane commits (/aep-dispatch, /aep-design, the /aep-wrap archive) land. Throughout this skill and the bash blocks in /aep-launch, /aep-build, /aep-wrap, and the product-context skills, this branch is referred to as $BASE.

AEP auto-detects one of two modes — no configuration required for the common cases:

ModeConditionIntegration ($BASE)Production
single-branch (default)no develop branchmainmain (same branch)
two-branchdevelop existsdevelop (staging)main (promote-only)

A project grows from single- to two-branch mode simply by creating a develop branch — no reconfiguration. In two-branch mode AEP never touches the production branch (main): promotion from integration to production (develop → main) is the user's concern, exactly like deployment, which is already outside AEP's scope.

Resolving $BASE

Every git-touching skill resolves the integration branch at the top of its first bash block:

# Resolve AEP integration branch ($BASE): override → auto-detect develop → main
BASE=$(git config --get aep.integration-branch 2>/dev/null || true)
if [ -z "$BASE" ]; then
  if git show-ref --verify --quiet refs/heads/develop \
     || git show-ref --verify --quiet refs/remotes/origin/develop; then
    BASE=develop
  else
    BASE=main
  fi
fi

Resolution order:

  1. Explicit override — git config --get aep.integration-branch. This is an override only, for a non-standard integration branch name (e.g. staging, integration). You do not set it for the standard main/develop cases — those are auto-detected. /aep-onboard reports the detected mode and only writes this key when you use a non-standard name (git config aep.integration-branch <name>; unset with git config --unset aep.integration-branch).
  2. Auto-detect — develop if it exists locally or on origin.
  3. Default — main (single-branch mode).

Because the standard cases are auto-detected (not pinned), a project grows from single- to two-branch mode with no reconfiguration: create develop and every skill resolves $BASE to it on the next run. (If you had pinned aep.integration-branch=main, that override would win and suppress the upgrade — which is why setup does not pin the default.)

git config --get aep.integration-branch is repo-local and shared across all worktrees via the common .git/config, so $BASE resolves identically in the main session and inside any .feature-workspaces/<name> worktree.


Worktree Lifecycle

Create

# Resolve $BASE first — see "Resolving $BASE" above
mkdir -p .feature-workspaces
git worktree add -b feat/<name> .feature-workspaces/<name> "$BASE"
  • Path is always under .feature-workspaces/<name> (kept gitignored).
  • Branch is always feat/<name> — corresponding to the OpenSpec change name or story id.
  • Base is always the integration branch $BASE.

The worktree shares .git/objects with the main repo, so creating it is fast and history is not duplicated. Only the working tree files are duplicated on disk.

Inspect

git worktree list                            # all worktrees, branches, paths
git -C .feature-workspaces/<name> status     # status inside a specific worktree
git -C .feature-workspaces/<name> log --oneline "$BASE"..HEAD   # commits unique to the feature branch

Remove (/aep-wrap step 6)

git worktree remove .feature-workspaces/<name>
git branch -d feat/<name>

If git branch -d warns the branch isn't fully merged (likely because the PR was squash-merged so commit SHAs differ), force with git branch -D feat/<name> after confirming via gh pr view <number> --json state that the PR is MERGED.

Recover from a corrupt worktree directory

If .feature-workspaces/<name>/ was deleted manually:

git worktree prune                           # forget the orphaned registration
git branch -D feat/<name>                    # delete the orphan branch (if needed)

If .git/worktrees/<name>/ still references a missing path (e.g. you moved the parent directory):

git worktree repair .feature-workspaces/<name>

Branch Naming

BranchPatternCreated by
Feature workfeat/<short-name>/aep-launch (one per story)
Migration / chorechore/<short-name>manually, when applicable
Hotfix off mainfix/<short-name>manually
Migration projectmigration/<topic>manually

Rules:

  • Use kebab-case after the slash. No spaces, no underscores.
  • Keep names short (≤ 30 chars) — they appear in tab labels, signal files, and PR titles.
  • Reuse a deleted branch name once its worktree is fully removed (git worktree prune clears the dangling refs).

The One-Commit-per-Task Pattern (Phase 4 of /aep-build)

This is the largest AEP-specific convention.

What

tasks.md lists N tasks. The feature branch ends up with N commits — one per task — in the same order. Conventional-commit format. Workspace agents implement linearly, committing after each task, so the commit count matches the task count:

# Implement task 1
# ... edit files ...
git add -A
git commit -m "feat(auth): extract auth service"

# Implement task 2
# ... edit files ...
git add -A
git commit -m "feat(auth): add token refresh flow"

# ... etc.

After each commit, record the short SHA in .dev-workflow/feature-verification.json against the matching task entry's commit_sha field.

Why this shape

  • The PR's commit list reads like a table of contents matching tasks.md.
  • Each commit is a self-contained unit that the evaluator (in Phase 5) and reviewers (in Phase 11) can git show <sha> independently.
  • We squash-merge at PR-merge time, so per-commit hygiene only matters for review readability — the integration branch's history stays clean automatically.
  • It removes any need to rewrite history mid-stream, which is where agents most often go off the rails.

What to do when something goes wrong

SituationAction
Forgot a file in the just-committed taskgit add <file> && git commit --amend --no-edit (only safe before the next task's commit)
Realized the previous task is broken, several commits agoAdd a new commit: fix(<scope>): correct <issue from task N> — the history stays append-only
Review feedback or eval-loop FAILAdd a follow-up commit: fix(<scope>): address review on <topic>
Need to update against new origin/$BASEgit fetch origin && git rebase origin/"$BASE" && git push --force-with-lease origin feat/<name>
Conflicts during rebaseResolve in working tree, git add <files> && git rebase --continue. If hopelessly tangled, git rebase --abort and surface to the orchestrator via signal file.

Never use git push --force (without --force-with-lease). The lease variant fails safely when someone else has pushed since your last fetch.


Publishing & PR Conventions

Push the feature branch

# First push (after Phase 9 cleanup):
git push -u origin feat/<name>

# Subsequent pushes (review fixes, rebases):
git push origin feat/<name>
# or after a rebase:
git push --force-with-lease origin feat/<name>

Open the PR — always set base explicitly

# $BASE is the integration branch — resolve it first (see "Integration Branch" above)
gh pr create --base "$BASE" --title "<title>" --body "<body>"

The --base "$BASE" flag is mandatory. Without it, gh infers the base from local branch state and can target the wrong branch (especially when a dispatch commit looked like a recent base). PRs targeting the wrong base merge into a non-integration branch, and the code never lands on the integration branch even after a successful merge. In two-branch mode this is doubly important — an inferred base could be production main, which AEP must never merge feature work into directly.

Merge the PR

gh pr merge <number> --squash --delete-branch

We always squash-merge. The feature branch's per-task commits collapse into one commit on the integration branch ($BASE), which keeps its log readable while preserving the per-task review trail in the PR's "Commits" tab.


Control-Plane Commits (on the integration branch)

/aep-design, /aep-dispatch, /aep-envision, /aep-map, /aep-calibrate, /aep-validate, /aep-reflect, and the /aep-wrap archive step all commit directly to the integration branch ($BASE). The pattern is identical:

# Resolve $BASE first — see "Resolving $BASE" above
git pull --ff-only origin "$BASE"       # fail-fast if the integration branch has diverged
git add <specific-files>                # never -A on the integration branch; be explicit
git commit -m "<conventional message>"
git push origin "$BASE"

The --ff-only is intentional — it refuses a non-fast-forward pull, which means concurrent pushes get caught instead of silently merged. If the pull fails because someone else pushed first, fetch, rebase your work, and try again.


Recovery

Lost a commit (committed to wrong branch, or amend'd away)

git reflog                              # find the orphaned commit's SHA
git cherry-pick <sha>                   # bring it onto the current branch
# or
git reset --hard <sha>                  # if you want to rewind to that point

Lost an entire branch (deleted with -D)

git reflog                              # the deleted branch's tip is in here
git branch <name> <sha>                 # recreate the branch at that tip

Lost work in a worktree directory you removed

If you ran rm -rf .feature-workspaces/<name> without committing first, the work is gone — git worktree only tracks committed history. .dev-workflow/ files (signals, lessons, progress) are also gone since they're gitignored. Use git worktree remove instead of rm -rf next time; it refuses if the worktree has uncommitted changes.

OpenSpec files missing after rebase

If the dispatch commit's OpenSpec files disappeared during a rebase or merge:

git log --oneline -n 30                 # find the dispatch commit SHA
git restore --source=<sha> -- openspec/

This restores openspec/ to the state of the dispatch commit without touching anything else.


Disk Budget

Each worktree adds approximately one full working-tree copy on disk. .git/objects is shared across all worktrees, so commit history isn't duplicated. For a typical AEP repo (~100 MB working tree, multi-GB .git/objects after years of history), three concurrent agents adds ~300 MB on top of one shared .git/.

Monitor with:

du -sh .feature-workspaces/             # working-tree footprint
du -sh .git/objects                     # shared history

If disk pressure hits before agents finish, prefer pausing new /aep-launch invocations over forcibly removing in-flight worktrees.


Cheat Sheet

You want to…Run
Create a feature worktreegit worktree add -b feat/<n> .feature-workspaces/<n> "$BASE"
List all worktreesgit worktree list
See feature-branch commitsgit log --oneline "$BASE"..HEAD
Sync against latest $BASEgit fetch origin && git rebase origin/"$BASE"
Push after rebasegit push --force-with-lease origin feat/<n>
Open PRgh pr create --base "$BASE"
Merge PRgh pr merge <#> --squash --delete-branch
Remove worktree post-mergegit worktree remove .feature-workspaces/<n> && git branch -d feat/<n>
Recover deleted commitgit reflog then git cherry-pick <sha>
Restore lost openspec/ filesgit restore --source=<sha> -- openspec/

Keep looking

Skills are one crate of 627,801. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.