Based on: GitHub Flow + Conventional Commits + Squash Merge + Semantic Versioning
- One permanent branch:
main - All work in short-lived branches
- PRs are mandatory for all changes — no direct push to
main - Clean, linear history via Squash and Merge
- Branches deleted after merge
- Releases tagged from
main
| Prefix | Purpose | Commit Type |
|---|---|---|
feature/ |
New functionality | feat |
bugfix/ |
Fixing non-critical bugs | fix |
hotfix/ |
Critical production fixes | fix |
chore/ |
Maintenance (deps, config, cleanup) | chore |
docs/ |
Documentation updates | docs |
refactor/ |
Code restructuring, no behavior change | refactor |
test/ |
Adding or updating tests | test |
ci/ |
CI/CD pipeline changes | ci |
perf/ |
Performance improvements | perf |
build/ |
Build system changes | build |
security/ |
Security-related fixes | security |
release/ |
Release stabilization (temporary, optional) | — |
Note: Branch prefixes (
feature/,bugfix/) and commit types (feat,fix) are separate conventions.feature/is the standard branch prefix in GitHub Flow;featis the corresponding Conventional Commits type. Some teams preferfeat/for consistency — either is valid as long as the team is consistent.
feature branch → push → PR → review → squash merge → main → delete branch
Before the team starts, configure these on GitHub:
- ✔ Branch Protection Rule on
main(block direct push) - ✔ Required Reviewers (minimum 1 approval before merge)
- ✔ Required CI checks must pass before merge
- ✔ Auto-delete branches after merge
- ✔ PR Template (
.github/PULL_REQUEST_TEMPLATE.md) - ✔ CODEOWNERS (
.github/CODEOWNERS) for automatic reviewer assignment
- Create branch from
main:
git checkout main && git pull
git checkout -b feature/login- Commit with Conventional Commits format:
git commit -m "feat: add login system"- Push branch:
git push -u origin feature/login-
Open PR on GitHub
- Use Draft PR for work-in-progress
- Mark Ready for Review when complete
-
Code review + CI checks pass
-
Squash and Merge into
main -
Branch auto-deleted
For critical production bugs that cannot wait for the normal PR cycle.
main → hotfix/* → PR → squash merge → main → tag
- Branch directly from
main:
git checkout main && git pull
git checkout -b hotfix/fix-critical-crash-
Apply the fix
-
Open PR to
main(expedited review — minimum 1 reviewer) -
Squash and Merge
-
Tag immediately on
main:
git tag v1.4.3
git push origin v1.4.3Most modern teams release directly from main using tags.
Release branches are optional — use them only when stabilization requires multiple coordinated fixes.
feature PR → squash merge → main → tag → release
git tag v1.2.0
git push origin v1.2.0main → release/v1.2.0 → final fixes → merge back to main → tag → delete
- Create release branch from
main:
git checkout -b release/v1.2.0-
Apply only bugfixes — no new features
-
Merge back into
main:
git checkout main
git merge release/v1.2.0
git push- Tag on
main:
git tag v1.2.0
git push origin v1.2.0- Delete release branch:
git branch -d release/v1.2.0
git push origin --delete release/v1.2.0
release/*is temporary. It exists only for stabilization, then it is deleted.
type(scope): description
Or without scope:
type: description
- ✔ lowercase
- ✔ imperative mood (
add,fix,update) - ✔ no period at end
- ❌ no uppercase types
- ❌ no full sentences
| Type | Meaning |
|---|---|
feat |
New feature |
fix |
Bug fix |
chore |
Maintenance tasks |
refactor |
Code restructuring |
docs |
Documentation changes |
test |
Tests addition/update |
ci |
CI/CD changes |
perf |
Performance improvements |
build |
Build system changes |
security |
Security fixes |
feat: add login system
fix: handle null response (#123)
chore: update dependencies
refactor: simplify auth flow
docs: update API documentation
feat(auth): add oauth login
fix(api): handle timeout error (#87)
feat!: redesign authentication API
BREAKING CHANGE: token format has changed from JWT to opaque token
MAJOR.MINOR.PATCH
| Change Type | Version Update | Example |
|---|---|---|
fix |
PATCH | 1.4.2 → 1.4.3 |
feat |
MINOR | 1.4.2 → 1.5.0 |
| Breaking change | MAJOR | 1.4.2 → 2.0.0 |
git tag v1.2.0
git push origin v1.2.0Reference: keepachangelog.com
## [1.2.0] - 2026-06-12
### Added
- login system via OAuth
### Fixed
- crash on startup with empty config (#102)
### Security
- patched XSS vulnerability in input fieldsfeature branch
→ PR (review + CI)
→ squash merge → main
→ tag (vX.Y.Z)
→ delete branch
→ release
| Practice | Recommendation |
|---|---|
| Branching model | GitHub Flow (one permanent branch: main) |
| Merge strategy | Squash and Merge |
| Commit format | Conventional Commits |
| Versioning | Semantic Versioning (SemVer) |
| Changelog | Keep a Changelog |
| Release | Tag from main (release branch optional) |
| Branch protection | Required on main |
| PR review | Minimum 1 required reviewer |