|$ curl https://forge-ai.dev/api/markdown?path=docs/git/workflow
$cat docs/git-workflows.md
updated Recently·30 min read·published

Git Workflows

GitIntermediate🎯Free Tools
Introduction

A Git workflow is a recipe or guideline for how to use Git effectively. The right workflow depends on your team size, release cadence, and deployment strategy. Choosing poorly can slow development; choosing well enables rapid, safe shipping.

This guide covers the five most popular workflows, their trade-offs, and when each is appropriate — from solo development to large distributed teams.

Gitflow Workflow

Gitflow uses long-lived main and develop branches, with feature, release, and hotfix branches. It excels at scheduled releases with versioned software.

gitflow.sh
Bash
1# Gitflow setup
2git flow init -d
3
4# Feature development
5git flow feature start user-authentication
6# ... work on feature ...
7git flow feature finish user-authentication
8
9# Release preparation
10git flow release start 2.0.0
11# ... bump version, update changelog ...
12git flow release finish 2.0.0
13
14# Hotfix for production bugs
15git flow hotfix start critical-fix
16# ... fix the bug ...
17git flow hotfix finish critical-fix
18
19# Branch structure:
20# main — production-ready code
21# develop — integration branch
22# feature/* — new features (branch from develop)
23# release/* — release preparation (branch from develop)
24# hotfix/* — production fixes (branch from main)

best practice

Use Gitflow when your team does scheduled releases (mobile apps, desktop software, versioned APIs). For continuous deployment, prefer GitHub Flow or trunk-based development.
GitHub Flow

GitHub Flow is a lightweight, branch-based workflow. Every change goes through: create a branch, make changes, open a PR, get reviewed, deploy to staging, merge to main. Simple and effective for continuous deployment.

github-flow.sh
Bash
1# GitHub Flow — simplified
2# 1. Create a descriptive branch
3git checkout main && git pull
4git checkout -b feature/add-dark-mode
5
6# 2. Make changes and commit
7git add -A
8git commit -m "feat: add dark mode toggle"
9
10# 3. Push and create PR
11git push -u origin feature/add-dark-mode
12# Open PR on GitHub
13
14# 4. After review and CI passes, merge (squash)
15# 5. Deploy main automatically
16
17# Naming conventions:
18# feature/description — new features
19# fix/description — bug fixes
20# docs/description — documentation
21# refactor/description — code refactoring
22# chore/description — maintenance tasks

info

GitHub Flow is ideal for web applications with continuous deployment. The key rule: main is always deployable. If CI passes and review is approved, merge immediately.
GitLab Flow

GitLab Flow sits between Gitflow and GitHub Flow. It uses environment branches (staging, production) with downstream merging, giving you more control than GitHub Flow while staying simpler than Gitflow.

gitlab-flow.sh
Bash
1# GitLab Flow — environment branches
2# Feature branches merge into pre-production first
3git checkout -b feature/new-api
4# ... work ...
5# Merge: feature -> pre-production -> production
6
7# Release branches for versioned software
8git checkout -b release/2.0
9# Cherry-pick fixes back to main
10
11# Push rules enforce merge-down, cherry-pick-up:
12# main -> pre-production -> production (forward)
13# hotfix main -> cherry-pick to pre-production (backward)
14
15# GitLab CI/CD auto-deploys per environment:
16# main -> dev environment
17# pre-production -> staging
18# production -> live
Trunk-Based Development

Trunk-based development means everyone commits to main (the trunk) frequently — ideally multiple times per day. Feature flags gate incomplete work instead of long-lived branches.

trunk-based.sh
Bash
1# Trunk-based: short-lived branches, frequent merges
2git checkout main && git pull
3git checkout -b feat/dark-mode
4
5# Small, frequent commits
6git commit -m "feat: add theme provider"
7git commit -m "feat: add dark mode toggle component"
8git commit -m "test: add dark mode tests"
9
10# Merge quickly (hours, not days)
11git push && gh pr create
12
13# Feature flags gate incomplete work
14# In code:
15if (featureFlags.isEnabled("dark-mode")) {
16 return <DarkMode />;
17}
18
19# Release from main — no release branches
20git tag v2.0.0
21git push origin v2.0.0

best practice

Trunk-based development requires strong CI/CD, feature flags, and short PR review cycles. It minimizes merge conflicts and enables continuous deployment. It's the highest-velocity workflow for teams with mature tooling.
Feature Branching Best Practices
feature-branching.sh
Bash
1# Keep branches short-lived (< 2 days ideal)
2# Rebase before merging to keep history linear
3git checkout feature/my-feature
4git fetch origin
5git rebase origin/main
6# Resolve conflicts if any
7git push --force-with-lease # Safe force push after rebase
8
9# Squash merge for clean history
10git checkout main
11git merge --squash feature/my-feature
12git commit -m "feat: add user authentication system"
13
14# Or rebase merge for preserving individual commits
15git checkout feature/my-feature
16git rebase main
17git checkout main
18git merge --ff-only feature/my-feature
19
20# Clean up merged branches
21git branch -d feature/my-feature
22git push origin --delete feature/my-feature
23
24# Prune stale remote-tracking branches
25git fetch --prune

info

Use --force-with-lease instead of --force when pushing after rebase. It fails if someone else pushed to the same branch, preventing accidental overwrites.
Release Management
releases.sh
Bash
1# Semantic Versioning: MAJOR.MINOR.PATCH
2# 1.0.0 -> 1.0.1 (patch: bug fix)
3# 1.0.1 -> 1.1.0 (minor: new feature, backwards compatible)
4# 1.1.0 -> 2.0.0 (major: breaking change)
5
6# Create a release
7git tag -a v2.1.0 -m "Release 2.1.0: dark mode, performance improvements"
8git push origin v2.1.0
9
10# Generate changelog automatically
11git log --pretty=format:"- %s" v2.0.0..v2.1.0 > CHANGELOG.md
12
13# Automated release with GitHub Actions
14# .github/workflows/release.yml:
15# on:
16# push:
17# tags: ['v*']
18# jobs:
19# release:
20# steps:
21# - uses: actions/create-release@v1
22# with:
23# tag_name: ${{ github.ref }}
24# release_name: Release ${{ github.ref_name }}

best practice

Use conventional commits (feat:, fix:, BREAKING CHANGE:) to automate changelogs and determine version bumps. Tools like semantic-release can fully automate the release process.
Advanced Patterns

Extra depth for production teams — conflict strategies, automation, and recovery.

Automation-friendly flags

automation.sh
Bash
1git status --porcelain=v1
2git diff --name-only --diff-filter=ACMR
3git log -1 --pretty=format:%H
4git merge-base HEAD origin/main
5git rev-list --count origin/main..HEAD

Recovery drill

recovery.sh
Bash
1git reflog | head -20
2git fsck --lost-found | head
3git branch rescue HEAD@{1}
4git log --oneline rescue -5
🔥

pro tip

Practice recovery in /tmp labs before you need it on a deadline.
Production Checklist
  • No secrets in history for this change set
  • CI green on the PR
  • Rebased or merged with latest main
  • Rollback plan: revert SHA known
  • Tags/releases updated if needed
prod-check.sh
Bash
1git status -sb
2git log --oneline origin/main..HEAD
3git diff --check
4git rev-parse HEAD
Additional Examples
more-a.sh
Bash
1# Cherry-pick a range onto a release branch
2git switch release/1.2
3git cherry-pick abc123^..def456
4# conflict?
5git status
6# fix, then:
7git add -A && git cherry-pick --continue
8# or abort:
9# git cherry-pick --abort
more-b.sh
Bash
1# Bisect with a script
2git bisect start
3git bisect bad HEAD
4git bisect good v1.0.0
5git bisect run ./scripts/test-bug.sh
6git bisect reset
more-c.sh
Bash
1# Submodule bump
2git submodule update --remote --merge libs/shared
3git add libs/shared
4git commit -m "chore(deps): bump shared submodule"
5git submodule status
more-d.sh
Bash
1# Workflow: trunk-based short PR
2git fetch origin
3git switch -c fix/timeout origin/main
4# change + test
5git commit -am "fix: request timeout"
6git push -u origin HEAD
7gh pr create --fill
8gh pr checks
9gh pr merge --squash --delete-branch
Choosing & Operating a Workflow

Workflow choice is a team contract. Pick one, write it down, and automate enforcement with branch protection and CI.

Trunk-based (recommended default)

wf-trunk.sh
Bash
1git fetch origin
2git switch -c feature/small origin/main
3# ship in < 2 days
4git push -u origin HEAD
5gh pr create --fill
6gh pr merge --squash --delete-branch

Git Flow excerpt

wf-gitflow.sh
Bash
1git switch -c develop origin/develop
2git switch -c feature/x
3# ...
4git switch develop && git merge --no-ff feature/x
5git switch -c release/1.3 develop
6git switch main && git merge --no-ff release/1.3
7git tag -a v1.3.0 -m "v1.3.0"
8git switch develop && git merge --no-ff release/1.3

Hotfix path

wf-hotfix.sh
Bash
1git fetch origin
2git switch -c hotfix/sev1 origin/main
3# fix + test
4git push -u origin HEAD
5gh pr create --base main --fill
6# cherry-pick onto release branch if needed
7git switch release/1.2
8git cherry-pick <hotfix-sha>

Decision table

  • Single deployable product, strong CI → trunk-based
  • Multiple supported release lines → release branches + cherry-pick
  • Open source with many forks → fork + PR
  • Regulated change control → Git Flow-like with protected releases

best practice

wf-lab.sh
Bash
1# Simulate trunk-based locally with bare remote
2rm -rf /tmp/wf && mkdir -p /tmp/wf/remote
3git init --bare /tmp/wf/remote/app.git
4git clone /tmp/wf/remote/app.git /tmp/wf/dev
5cd /tmp/wf/dev
6git config user.email a@b.c && git config user.name Dev
7echo x > f && git add f && git commit -m init && git push -u origin main
8git switch -c feature/x
9echo y > f && git commit -am feat && git push -u origin HEAD
10git switch main && git merge --no-ff feature/x -m merge && git push
11git log --oneline --graph
$Blueprint — Engineering Documentation·Section ID: GIT-WF-01·Revision: 1.0

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.