The Perfect Git Workflow for Small Teams (Step-by-Step)
1) Daily workflow (the golden path)
1. Sync development
git switch development
git fetch origin
git pull --rebase origin development
2. Create a feature branch
git switch -c feature/wp-settings-page
3. Commit in small units
git add -A
git commit -m "settings: add basic options page"
4. Stay up to date (rebase onto development, never merge teammates’ branches)
git fetch origin
git rebase origin/development
# resolve → git add -A → git rebase --continue
5. Push & open PR → target development
git push -u origin feature/wp-settings-page
- CI must pass; get review; address comments.
6. Merge with “Squash and merge” (keeps linear history; 1 commit/PR). Delete remote branch after merge.
7. Update local development
git switch development
git pull --rebase origin development
Anti‑pattern to avoid
# ❌ never import a teammate’s feature branch into yours
git merge origin/feature/someone-else
2) Hotfixes (production emergencies)
1. Branch from main
:
git switch main
git pull --rebase origin main
git switch -c hotfix/fix-wp-notice
# make minimal fix, add tests if possible
git commit -m "hotfix: fix wp notice on settings page"
git push -u origin hotfix/fix-wp-notice
2. Open PR hotfix → main. CI + approvals → Squash & merge → tag v1.9.1
.
3. Back‑merge main
into development
(fast‑forward or PR) to keep them aligned:
# on local
git switch development
git pull --rebase origin development
git merge --ff-only origin/main # or open PR main → development
git push
3) Release process (from development → main)
1. Ensure development
is green.
2. Create release branch:
git switch development
git pull --rebase origin development
git switch -c release/1.9.0
3. Bump version, update changelog, run full CI locally if needed.
4. Open PR release/1.9.0 → main. CI + approvals.
5. Squash & merge into main
. Tag the release v1.9.0
.
6. Back‑merge the release changes into development
:
# on local
git switch development
git pull --rebase origin development
git merge --ff-only origin/main # or open PR main → development
git push
- (This guarantees
development
contains the exact released code.)
4) Branch model
main
→ release‑only, always deployable. Protected.development
→ integration branch; all PRs target this. Protected.feature/<ticket-slug>
→ work branches cut fromdevelopment
.hotfix/<slug>
→ emergency fixes cut frommain
.release/<x.y.z>
(optional) → prep window for tagging; merged intomain
, then back intodevelopment
.
Examples
feature/wp-settings-page
feature/login-form-validation
hotfix/fix-php-8.3-warning
release/1.9.0
Set default branch to development
: GitHub → Settings → Branches → Default branch → development.
Add your first comment to this post