git-flow · git:20260715.5769a40 · 2026-07-15 · sha256 abee82a46e403d6c
git-flow git:20260715.5769a40A
Immutable. This exact content is served forever at /api/v1/blob/abee82a46e403d6c.
--- name: git-flow description: Use when committing, branching, opening PRs, or deciding merge strategy. Covers GitHub Flow (default), trunk-based, branch naming conventions, squash vs rebase, branch lifecycle, and protected branch enforcement. user-invocable: false related-skills: commit-optimization, post-commit, commit-detection --- # Git Flow Best Practices (2026) ## Workflow Choice | Strategy | When | Verdict | |----------|------|---------| | **Trunk-based** (direct main) | Solo dev, prototypes, strong CI | OK if you have automated tests | | **GitHub Flow** (feature branch → PR → merge → delete) | Teams, OSS, code review | ✅ Default | | **Git Flow** (develop/release/hotfix) | Heavy release cycles | ❌ Outdated for most projects | **fuse-commit-pro default: GitHub Flow.** ## Branch Naming Convention Format: `<type>/<scope-or-summary>` (kebab-case). | Type | Use | Example | |------|-----|---------| | `feat/` | New feature | `feat/seo`, `feat/oauth-google` | | `fix/` | Bug fix | `fix/sniper-loop`, `fix/csv-parser` | | `chore/` | Maintenance, deps | `chore/bump-deps`, `chore/rename-files` | | `docs/` | Documentation | `docs/api-reference` | | `refactor/` | Refactoring (no behavior change) | `refactor/extract-utils` | | `perf/` | Performance | `perf/db-indexes` | | `test/` | Tests only | `test/auth-coverage` | | `ci/` | CI/CD config | `ci/github-actions-cache` | | `build/` | Build system | `build/vite-config` | | `style/` | Formatting | `style/prettier-pass` | **Rules**: - kebab-case only (no underscores, no spaces, no caps) - < 50 chars total - No personal prefix (`bruno/...`) — collaborators don't know who you are 6 months later - No issue number alone (`fix/123`) — meaningless once issue closed ## Protected Branches `main`, `master`, `develop`, `production` → **never commit directly**. `fuse-commit-pro:commit` enforces this in Step 0: - Detects current branch - If protected → blocks + proposes auto-named feature branch from commit type/scope - Exceptions: solo prototype (no remote), explicit `--no-branch-check`, or post-commit version bump ## Branch Lifecycle ``` 1. git checkout -b feat/<scope> # create 2. work + commit # multiple commits OK 3. git push -u origin feat/<scope> # push with upstream 4. gh pr create # open PR 5. (review + CI) 6. gh pr merge --merge --delete-branch # merge + cleanup ``` **Keep branches short-lived** (< 3 days ideally). Long-lived branches accumulate conflicts and lose context. ## Merge Strategy | Strategy | When | Result | |----------|------|--------| | **Merge commit** | fuse-commit-pro default | Branch commits (incl. the bump commit) land on `main` intact, no rewrite | | **Rebase merge** | Small atomic commits worth preserving, no merge commit wanted | Linear history, individual commits kept | | **Squash merge** | *not used here*: the release tag points at the bump commit, squash would orphan it | 1 commit per feature, but incompatible with fuse-commit-pro's post-merge tagging | **fuse-commit-pro recommendation**: real merge commit via `gh pr merge --merge --delete-branch` (see `commands/commit.md` Step 7). ## CI Gate Before Merge **Cardinal rule: never merge before CI checks are resolved; never assume "zero CI" without verifying.** Determine which of the three cases applies from what actually exists on the PR — never from assumption: - **Checks exist + native auto-merge available** → let GitHub merge once required checks pass: ```bash gh pr merge <pr> --auto --merge --delete-branch ``` - **Checks exist, no auto-merge** → watch checks, then merge — **never pipe** `gh pr checks` (e.g. `| tail`): a pipe swallows the exit code and lets a merge proceed after failing CI. Chain with `&&` so the merge only runs if checks passed: ```bash gh pr checks <pr> --watch && gh pr merge <pr> --merge --delete-branch ``` - **Repo has zero CI checks (verified, not assumed)** → immediate merge is allowed: ```bash gh pr merge <pr> --merge --delete-branch ``` Merge is always `--merge` (real merge commit) — **never `--squash`**, it would orphan the release tag's target (see Tagging timing below). **Tagging timing**: never push the tag before the merge is validated — CI could still fail or branch protection could still block the merge, and a tag pushed early would point at a commit that never lands on `main`. Tag `vX.Y.Z` on `main` AFTER the merge completes, then push the tag (`fuse-commit-pro:commit` does this automatically in Step 8 — see also `commands/commit.md` Step 8 and `post-commit/references/tag-timing.md`). ## After Merge - Delete branch automatically (`--delete-branch` flag or GitHub auto-delete setting) - Pull main: `git checkout main && git pull --ff-only origin main` - Delete local: `git branch -d feat/<scope>` (automatic if `--delete-branch` used remotely) ## Pull Request Template ```markdown ## Summary <1-3 bullet points of what changed> ## Changes <list of major files/components touched> ## Test plan - [ ] Manual test on X - [ ] CI green - [ ] Sniper validation clean ## Breaking changes None / <description with migration path> ``` ## Anti-Patterns - ❌ **Long-lived feature branches** (> 1 week) — rebase early or split - ❌ **Commits on main "to save time"** — bypasses review, breaks CI gates - ❌ **Force push to main** — never. Forbidden in fuse-commit-pro. - ❌ **Branch named `wip`, `temp`, `test123`** — meaningless, can't be found later - ❌ **PR without description** — reviewers can't context-switch - ❌ **Merging your own PR without review** (when working in a team) - ❌ **Stale branches** (no commits > 30 days) — delete or close ## Solo Dev Mode If you're alone on a repo with no PR review: - Still use feature branches (rollback safety net) - Self-PR is fine for sanity check (you'll see the diff fresh) - Or commit-then-push on main with strong CI as safety - `fuse-commit-pro:commit` detects no-remote case and skips Step 7