Git Conventions

SkillCommunication

Esposter git workflow conventions — commit message format, safety rules, branch hygiene, and syncing `main` back into `develop` with the `pnpm-lock.yaml` conflict that merge always brings. Apply when running git operations, merging a branch, resolving a lockfile conflict, or advising on source control workflows.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Git Conventions skill

What this skill tells your AI

The instructions your AI receives, as published by esposter/esposter in .agents/skills/git/SKILL.md and read by ahel’s review.

Commit Message Format

Conventional-commits format and the type list are in ~/.claude/rules/git-workflow.md.

Commit attribution is enabled — commits carry the Co-Authored-By trailer, because includeCoAuthoredBy is unset and defaults on. Expect it; don't strip it, and don't add it by hand either.

Multi-line Commit Messages — Tool-Specific Syntax

The Bash tool is POSIX sh, NOT PowerShell. Never use PowerShell here-string syntax (@'...'@) in the Bash tool — it is taken literally and leaves stray @ lines in the commit message. Pick the form matching the tool:

  • Bash tool → heredoc piped to -F -:

    git commit -F - <<'EOF'
    fix: short subject
    
    Body line.
    EOF
    
  • PowerShell tool → single-quoted here-string with @' / '@ at column 0:

    git commit -m @'
    fix: short subject
    
    Body line.
    '@
    

After committing, verify with git log -1 --format='%B' before pushing.

Safety Rules

  • Never git add -A without reading git status first. The tree can already be dirty with someone else's work — a leftover snapshot refresh, an unfinished edit — and -A sweeps it into your commit, where it ships under a message that does not describe it. Stage the paths you touched, or check the status and confirm every extra file belongs. If one already landed in the commit, git reset --soft HEAD~1 then git restore --staged <paths> puts it back in the working tree with its content intact.
  • Never use git stash — a failed/forgotten pop loses in-progress changes. To inspect prior committed state, use git show HEAD:path/to/file or git diff HEAD. To set work aside, make a WIP commit.
  • Never push into a running CodeRabbit review — if the branch has an open PR, check the review state first; pushing mid-review cancels it, burns a rate-limit slot, and loses the in-progress findings for good (CodeRabbit won't re-review commits it has already seen). The command, the states that mean "running", and the four gates that decide the push are the coderabbit skill's — a second copy of that table here is how one of them goes stale.

Pushing

Batch commits and push once per coherent chunk of work. Several pushes in quick succession each retrigger review, so the later ones reliably land mid-review — the exact case the rule above exists to prevent.

Branch Hygiene

Work is committed straight to develop; there are no per-chunk feature branches. Review happens on one long-lived developmain PR, which re-reviews incrementally on every push — the pipeline and its file budget are the coderabbit skill's. A feature branch here would only add a merge that buys nothing, since nothing gates entry to develop.

  • develop is the working branch; main takes releases from it.
  • Cut a branch only when the work genuinely cannot land incrementally (a spike, or an edit to main itself — use git worktree for that rather than checking it out over work in progress), and delete it after merging.

Syncing main Into develop

main takes commits develop never saw — a Renovate PR merged straight into it, a hotfix — so develop goes behind and the open developmain PR starts showing a diff nobody wrote. Fetch and merge main in; never rebase develop, whose commits are already pushed and already reviewed.

git fetch origin
git merge origin/main --no-edit

The conflict is pnpm-lock.yaml, every time, because both sides regenerated it (below). pnpm-workspace.yaml is authored and usually auto-merges — read the merged catalog anyway rather than trusting that, since a clean auto-merge proves only that the two sides touched different lines, never that the surviving version is the higher one.

The merge commit itself is not a review window: it carries whatever main already held, and the review that matters already ran on the PR those commits came from.

pnpm-lock.yaml Conflicts — Always Regenerate, Never Hand-Resolve

The lockfile is machine state, like snapshot.json. Never hand-merge it, and never reason about which side to keep — a resolved-by-hand lock silently disagrees with the merged pnpm-workspace.yaml catalog. Resolve pnpm-workspace.yaml first, since that one is authored and merges normally: keep the higher version on every conflicting catalog entry. Then throw the lock away and let pnpm rebuild it:

rm pnpm-lock.yaml
pnpm i                  # from the repo root
git add pnpm-lock.yaml

This is the whole procedure, on every merge, in either direction. It is safe because pnpm i rebuilds the lock from the already-installed node_modules tree rather than re-resolving each caret to the newest release it allows — so existing pins survive verbatim, including majors the other branch has never seen. It is fast for the same reason: under a second, not a reinstall.

Already up to date is the normal report, and a rebuilt lock that comes back byte-identical to the one you deleted is the expected outcome, not a skipped step — it means the merged catalog was already fully resolved. A merge that resolves byte-identical to develop is likewise correct: it means main brought no catalog entry develop lacked. The merge commit is still made, since it records the ancestry that keeps the developmain PR diff clean, and it simply carries a zero-content diff.

Escalate to pnpm refresh:lockfile only when pnpm i cannot reconcile the tree — that one deletes every node_modules as well, kills running node processes, and reinstalls from scratch (minutes, and it takes down any dev server or vitest watcher).

Verify On develop

The local check suite runs once per coherent chunk, on develop, before pushing it — not per commit:

  1. Commit as the work lands; commits are free and nothing is triggered by them.
  2. Verify the finished chunk with the check suite (see the package-scripts skill).
  3. Push the chunk, which starts the review. Fix forward on develop.

Rationale: a per-commit check run is re-invalidated by the next commit in the same chunk, and the pushed state is the only state a reviewer ever sees.

Signals

GitHub stars
23
Forks
3
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
git-esposter
Source
github.com/esposter/esposter