Git Workflow
Intro
Use typed branch names, Conventional Commits, and PR descriptions
that explain the why. Squash-merge feature branches for a clean
history. Keep commits atomic and never force-push to shared
branches.
Overview
Branch naming
Format: <type>/<issue>-<short-description>
Types: feat/, fix/, refactor/, docs/, chore/
Examples:
feat/42-add-user-auth
fix/17-null-pointer-crash
refactor/89-extract-payment-service
Commit messages
Follow Conventional Commits:
- Format:
<type>: <description> — lowercase, imperative
mood, no trailing period
- Types:
feat, fix, refactor, docs, test, chore,
ci
- Body: explain WHY, not WHAT (the diff shows what)
- Footer:
fixes #N or refs #N for issue links
PR descriptions
- Title: same format as commit messages, under 70 characters
- Body: Summary (what and why), test plan, breaking changes
- Link related issues
Merge strategy
- Squash merge for feature branches — keeps mainline history
clean
- Merge commit for long-lived branches — preserves context
across the merge
- Rebase to keep a feature branch up to date before opening
the PR
Gotchas
Agent-specific failure modes — provider-neutral pause-and-self-check items:
- Mega-commits ("various fixes", 40 files changed). A commit that mixes unrelated changes is impossible to review, impossible to revert selectively, and tells a lie in its message. Each commit should represent one logical change that can stand alone.
- Force-pushing to shared branches. Force-pushing to
main or any branch others have checked out rewrites history they depend on, causing diverged local states that are painful to recover. Never force-push to a shared branch.
- Branches that live for months. Long-lived branches diverge from main, accumulate merge conflicts, and eventually require heroic merge efforts. Rebase weekly or split long-running work into shorter-lived feature branches.
- PRs with no description. "See commits" is not a description. The PR description is for the reviewer — it explains what changed, why it changed, and how to verify it. Write it before requesting review.
- Conventional Commit type misuse. Using
fix: for features or feat: for refactors corrupts any automation that generates changelogs or determines version bumps from commit types. Match the type to the nature of the change.
- Squash-merging a long-lived integration branch. Squash-merge is for feature branches with noisy "wip" commits. A long-lived branch with meaningful commit history should be merge-committed so the history is preserved for future investigation.
- Committing unrelated changes in the same PR to "save time". Reviewers are slower on unrelated changes combined in one PR; rollback becomes more expensive if one change needs reverting. Split unrelated changes into separate PRs.
Full reference
General rules
- Commit early and often on feature branches; squash at merge time.
- Never force-push to shared branches (
main, develop, release
branches).
- Keep commits atomic — one logical change per commit. A commit
that touches three unrelated concerns is three commits.
- A commit message body wraps at 72 columns; the subject line at
50 if you can.
Worked example
User: "What should I name this branch for adding search?"
Suggest feat/30-add-search-functionality if there's an issue
#30; otherwise feat/add-search-functionality. Match the
existing repo's convention if it differs.
Anti-patterns
- Mega-commits — "various fixes" with 40 files changed.
Impossible to review or revert.
- Force-push to main — destroys other contributors' work.
- Commit messages like "wip", "fix", "stuff" — every commit
should be reviewable on its own.
- PRs with no description — the PR description is for the
reviewer, not the author. "See commits" is not a description.
- Branches that live for months — long-lived branches
diverge from main and become merge nightmares. Rebase weekly
or split the work.
When to break the rules
Solo-on-a-private-branch force-pushes are fine. Trivial typo
fixes don't need a long body. Use judgment, but the defaults
above are right for almost every team setting.
1---2name: git-workflow3description: Git workflow conventions — branch naming, conventional commits, PR descriptions, and merge strategy. Use when deciding on a branch name, writing a commit message or PR description, or choosing a merge strategy.4---56# Git Workflow78## Intro910Use typed branch names, Conventional Commits, and PR descriptions11that explain the why. Squash-merge feature branches for a clean12history. Keep commits atomic and never force-push to shared13branches.1415## Overview1617### Branch naming1819Format: `<type>/<issue>-<short-description>`2021Types: `feat/`, `fix/`, `refactor/`, `docs/`, `chore/`2223Examples:2425- `feat/42-add-user-auth`26- `fix/17-null-pointer-crash`27- `refactor/89-extract-payment-service`2829### Commit messages3031Follow Conventional Commits:3233- **Format:** `<type>: <description>` — lowercase, imperative34 mood, no trailing period35- **Types:** `feat`, `fix`, `refactor`, `docs`, `test`, `chore`,36 `ci`37- **Body:** explain WHY, not WHAT (the diff shows what)38- **Footer:** `fixes #N` or `refs #N` for issue links3940### PR descriptions4142- **Title:** same format as commit messages, under 70 characters43- **Body:** Summary (what and why), test plan, breaking changes44- Link related issues4546### Merge strategy4748- **Squash merge** for feature branches — keeps mainline history49 clean50- **Merge commit** for long-lived branches — preserves context51 across the merge52- **Rebase** to keep a feature branch up to date before opening53 the PR5455## Gotchas5657Agent-specific failure modes — provider-neutral pause-and-self-check items:5859- **Mega-commits ("various fixes", 40 files changed).** A commit that mixes unrelated changes is impossible to review, impossible to revert selectively, and tells a lie in its message. Each commit should represent one logical change that can stand alone.60- **Force-pushing to shared branches.** Force-pushing to `main` or any branch others have checked out rewrites history they depend on, causing diverged local states that are painful to recover. Never force-push to a shared branch.61- **Branches that live for months.** Long-lived branches diverge from main, accumulate merge conflicts, and eventually require heroic merge efforts. Rebase weekly or split long-running work into shorter-lived feature branches.62- **PRs with no description.** "See commits" is not a description. The PR description is for the reviewer — it explains what changed, why it changed, and how to verify it. Write it before requesting review.63- **Conventional Commit type misuse.** Using `fix:` for features or `feat:` for refactors corrupts any automation that generates changelogs or determines version bumps from commit types. Match the type to the nature of the change.64- **Squash-merging a long-lived integration branch.** Squash-merge is for feature branches with noisy "wip" commits. A long-lived branch with meaningful commit history should be merge-committed so the history is preserved for future investigation.65- **Committing unrelated changes in the same PR to "save time".** Reviewers are slower on unrelated changes combined in one PR; rollback becomes more expensive if one change needs reverting. Split unrelated changes into separate PRs.6667## Full reference6869### General rules7071- Commit early and often on feature branches; squash at merge time.72- Never force-push to shared branches (`main`, `develop`, release73 branches).74- Keep commits atomic — one logical change per commit. A commit75 that touches three unrelated concerns is three commits.76- A commit message body wraps at 72 columns; the subject line at77 50 if you can.7879### Worked example8081User: "What should I name this branch for adding search?"8283Suggest `feat/30-add-search-functionality` if there's an issue84#30; otherwise `feat/add-search-functionality`. Match the85existing repo's convention if it differs.8687### Anti-patterns8889- **Mega-commits** — "various fixes" with 40 files changed.90 Impossible to review or revert.91- **Force-push to main** — destroys other contributors' work.92- **Commit messages like "wip", "fix", "stuff"** — every commit93 should be reviewable on its own.94- **PRs with no description** — the PR description is for the95 reviewer, not the author. "See commits" is not a description.96- **Branches that live for months** — long-lived branches97 diverge from main and become merge nightmares. Rebase weekly98 or split the work.99100### When to break the rules101102Solo-on-a-private-branch force-pushes are fine. Trivial typo103fixes don't need a long body. Use judgment, but the defaults104above are right for almost every team setting.