From First Commit to Enterprise-Grade Delivery
Best title:
Git Workflow Master Guide: Branching Strategies, Pull Requests, Releases, CI/CD, and Team Governance
1. What is a Git workflow?
A Git workflow is the agreed way a team uses Git to move code from an idea to production safely.
It answers questions like:
- Where do developers create changes?
- Which branch is production?
- When do we create pull requests or merge requests?
- Who reviews code?
- How do we release?
- How do we hotfix production?
- How do we keep history clean?
- How do we avoid breaking
main? - How does CI/CD fit into Git?
Git itself provides commands such as branch, merge, rebase, tag, fetch, pull, push, cherry-pick, revert, and bisect; a workflow is the human and automation policy built around those commands. Gitโs official reference groups these commands under areas like branching, merging, sharing, updating, inspection, patching, and debugging.
2. The one-line mental model
Git workflow is not about branches.
Git workflow is about controlling risk while increasing delivery speed.
Branches, pull requests, tags, reviews, CI checks, protected branches, release branches, and hotfix branches are only tools.
The real goal is:
Deliver correct code faster, with traceability, review, rollback, and confidence.
3. Four layers of Git workflow
Most people confuse Git commands with Git workflow. A serious team separates Git into four layers.
flowchart TD
A[Git Commands] --> B[Branching Strategy]
B --> C[Collaboration Workflow]
C --> D[Release & Deployment Governance]
A1[commit, branch, merge, rebase, tag] --> A
B1[Gitflow, GitHub Flow, GitLab Flow, Trunk-Based] --> B
C1[PR/MR, reviews, approvals, CI checks] --> C
D1[environments, releases, hotfixes, rollback, audit] --> D
Code language: CSS (css)
| Layer | What it means | Example |
|---|---|---|
| Git commands | Technical operations | git commit, git merge, git rebase |
| Branching strategy | Branch structure | Gitflow, trunk-based development |
| Collaboration workflow | How humans review and integrate work | Pull requests, code owners, approvals |
| Release governance | How code reaches users | Tags, releases, CI/CD, rollback |
4. Core Git concepts every workflow depends on
4.1 Repository
A repository is the complete project history.
It contains:
- Files
- Commits
- Branches
- Tags
- Remote references
- Configuration
git init
git clone <repo-url>
Code language: HTML, XML (xml)
4.2 Commit
A commit is a snapshot of the repository at a point in time.
A commit has:
- A unique hash
- Author
- Timestamp
- Message
- Parent commit or commits
- File changes
git add .
git commit -m "feat: add user login"
Code language: JavaScript (javascript)
4.3 Branch
A branch is a movable pointer to a commit.
This is the most important sentence in Git.
A branch is not a folder.
A branch is not a copy of the full project.
A branch is a lightweight pointer.
gitGraph
commit id: "A"
commit id: "B"
branch feature/login
checkout feature/login
commit id: "C"
commit id: "D"
checkout main
commit id: "E"
Code language: JavaScript (javascript)
4.4 Main branch
The primary branch is usually called:
mainmastertrunk
Modern repositories usually prefer main.
In trunk-based development, developers collaborate around a single branch often called trunk, main, or mainline, and avoid long-lived shared development branches.
4.5 Remote
A remote is another copy of the repository, usually hosted in GitHub, GitLab, Bitbucket, Azure DevOps, or an internal Git server.
git remote -v
git fetch origin
git push origin main
4.6 HEAD
HEAD means:
Where your working directory currently points.
Usually, HEAD points to the latest commit of your current branch.
git status
git log --oneline --decorate --graph
4.7 Tag
A tag marks an important commit, usually a release.
git tag v1.2.0
git push origin v1.2.0
Code language: CSS (css)
Tags are often used with release automation, changelog generation, deployment records, and rollback.
5. Git workflow vocabulary
| Term | Meaning |
|---|---|
| Branching strategy | Rules for how branches are created and merged |
| Git workflow | Full process from coding to production |
| Feature branch | Temporary branch for a feature or task |
| Pull request / merge request | Review request before merging code |
| Protected branch | Branch with rules preventing unsafe changes |
| Release branch | Branch prepared for a versioned release |
| Hotfix branch | Emergency branch to fix production |
| Trunk | Main integration branch |
| CI | Continuous integration: automated checks on code |
| CD | Continuous delivery/deployment: automated release pipeline |
| Rebase | Move commits onto a new base |
| Merge | Combine histories |
| Squash | Combine multiple commits into one |
| Cherry-pick | Copy one commit to another branch |
| Revert | Create a new commit that undoes another commit |
6. The Git workflow maturity ladder
flowchart TD
L1[Level 1: Solo Git usage] --> L2[Level 2: Feature branches]
L2 --> L3[Level 3: Pull requests]
L3 --> L4[Level 4: Protected main branch]
L4 --> L5[Level 5: CI required before merge]
L5 --> L6[Level 6: Automated releases]
L6 --> L7[Level 7: Trunk-based delivery with feature flags]
L7 --> L8[Level 8: Progressive delivery, rollback, audit, compliance]
Code language: CSS (css)
| Level | Team behavior | Risk |
|---|---|---|
| 1 | Everyone commits anywhere | Very high |
| 2 | Feature branches exist | Medium-high |
| 3 | PR review required | Medium |
| 4 | Main branch protected | Lower |
| 5 | Tests required before merge | Lower |
| 6 | Releases automated | Low |
| 7 | Small frequent merges | Very low when done well |
| 8 | Full delivery governance | Enterprise-grade |
GitHub branch protection rules can require pull request reviews, passing status checks, and other constraints before code can merge into important branches.
7. The daily developer Git workflow
This is the workflow every developer should master before learning advanced branching models.
7.1 Start clean
git status
git checkout main
git pull --ff-only origin main
Why --ff-only?
Because it avoids unexpected merge commits during pull.
7.2 Create a branch
git checkout -b feature/login-api
Recommended branch naming:
feature/login-api
bugfix/payment-timeout
hotfix/fix-prod-crash
chore/update-dependencies
docs/git-workflow-guide
refactor/auth-service-cleanup
experiment/new-cache-strategy
Code language: JavaScript (javascript)
7.3 Make small commits
git add src/auth/login.go
git commit -m "feat(auth): add login API"
Code language: JavaScript (javascript)
Good commits are:
- Small
- Focused
- Reversible
- Reviewable
- Understandable
- Linked to purpose
Bad commit:
changes
Good commit:
fix(payment): handle timeout from gateway
Code language: JavaScript (javascript)
Conventional Commits defines a lightweight structure such as <type>[optional scope]: <description>, with optional body and footers, to make commit history easier for humans and automation to understand.
7.4 Keep your branch updated
Option A: merge from main.
git fetch origin
git merge origin/main
Option B: rebase onto main.
git fetch origin
git rebase origin/main
Git rebase rewrites a series of commits onto a new base, and Gitโs own documentation describes commands such as git rebase --continue, git rebase --abort, and git rebase --skip for conflict handling during rebase.
7.5 Push your branch
git push -u origin feature/login-api
7.6 Open a pull request
A pull request should answer:
- What changed?
- Why changed?
- How tested?
- What risk exists?
- How to rollback?
- Screenshots/logs if applicable
- Related ticket/issue
7.7 Pass CI
Before merge, CI should run:
- Build
- Unit tests
- Integration tests
- Linting
- Formatting
- Security scan
- Secret scan
- Dependency scan
- Container image scan
- Terraform plan, if infra
- Kubernetes manifest validation, if platform
7.8 Merge safely
Common merge options:
| Merge type | Command / platform behavior | Best for |
|---|---|---|
| Merge commit | Preserves branch history | Complex features, audit-heavy teams |
| Squash merge | Combines PR into one commit | Clean main history |
| Rebase merge | Replays commits linearly | Linear history with meaningful commits |
GitHub branch protection can also enforce a linear commit history and block force pushes or deletion on protected branches.
7.9 Delete branch
git branch -d feature/login-api
git push origin --delete feature/login-api
Code language: JavaScript (javascript)
Short-lived branches should disappear after merge. This keeps the repository clean.
8. Golden rules of Git workflow
Rule 1: main must always be healthy
main should be:
- Buildable
- Testable
- Deployable
- Protected
- Recoverable
A broken main means the whole team slows down.
Rule 2: Branches should be short-lived
The longer a branch lives, the higher the merge risk.
xychart-beta
title "Branch Age vs Merge Risk"
x-axis ["1 day", "3 days", "1 week", "2 weeks", "1 month"]
y-axis "Merge Risk" 0 --> 100
bar [10, 20, 40, 70, 95]
Code language: JavaScript (javascript)
This is conceptual, not a measured universal law. The practical lesson is true in most teams: long-running branches drift away from the integration branch.
AWS DevOps guidance recommends trunk-based development paired with a pull-request workflow and short-lived feature branches as an effective branching strategy for DevOps, with the core benefit being better continuous integration.
Rule 3: Pull requests should be small
A pull request should ideally be reviewable in 10โ30 minutes.
| PR size | Review quality |
|---|---|
| 50 lines | Excellent |
| 300 lines | Good |
| 800 lines | Risky |
| 2,000 lines | Rubber-stamp danger |
| 10,000 lines | Archaeology, not review |
Rule 4: Commit messages are part of engineering quality
Commit messages are not decoration.
They help:
- Debug production
- Generate changelogs
- Review history
- Understand intent
- Automate releases
- Track breaking changes
Rule 5: Never rewrite shared history casually
Safe:
git rebase -i HEAD~3
on your local branch before pushing.
Dangerous:
git push --force origin main
Use:
git push --force-with-lease
Code language: JavaScript (javascript)
only when rewriting your own branch and you understand the risk.
Rule 6: Prefer revert over history deletion for production
Bad production fix:
git reset --hard <old-commit>
git push --force
Code language: HTML, XML (xml)
Better production fix:
git revert <bad-commit>
git push origin main
Code language: HTML, XML (xml)
git revert creates a new commit that undoes a previous commit, preserving traceability.
9. The five major Git workflows
There are many variants, but most real-world teams use one of these:
mindmap
root((Git Workflows))
Centralized Workflow
Simple
Small teams
Main only
Feature Branch Workflow
Branch per task
Pull requests
GitHub Flow
Main + short branches
Deploy from main
GitLab Flow
Main + environment/release branches
Issue/MR centric
Gitflow
Main + develop + release + hotfix
Versioned releases
Trunk-Based Development
Single trunk
Very short branches
Feature flags
Code language: JavaScript (javascript)
10. Workflow 1: Centralized workflow
What it is
Everyone commits to one main branch.
gitGraph
commit id: "A"
commit id: "B"
commit id: "C"
commit id: "D"
Code language: JavaScript (javascript)
When it works
- Solo developer
- Tiny prototype
- Throwaway project
- Learning Git
When it fails
- Multiple developers
- Production product
- Review required
- CI/CD required
- Compliance required
Verdict
Good for learning.
Bad for professional delivery.
11. Workflow 2: Feature branch workflow
What it is
Each task gets its own branch.
gitGraph
commit id: "main-1"
branch feature/login
checkout feature/login
commit id: "login-1"
commit id: "login-2"
checkout main
branch feature/payment
checkout feature/payment
commit id: "payment-1"
checkout main
merge feature/login
merge feature/payment
Code language: JavaScript (javascript)
Process
git checkout main
git pull --ff-only
git checkout -b feature/user-profile
# work
git add .
git commit -m "feat(profile): add user profile page"
git push -u origin feature/user-profile
Code language: PHP (php)
Then:
- Open PR/MR
- Review
- CI runs
- Merge
- Delete branch
Best for
- Most modern teams
- Product teams
- Web apps
- Backend services
- DevOps/IaC repos
Main risk
Feature branches become long-lived.
Best practice
Keep feature branches under a few days. For larger work, split into smaller PRs.
12. Workflow 3: GitHub Flow
What it is
GitHub Flow is a lightweight branch-based workflow where work branches from main, changes are proposed through pull requests, reviewed, tested, and merged back to main. GitHubโs own documentation describes it as a lightweight branch-based workflow.
flowchart LR
A[Create branch from main] --> B[Make commits]
B --> C[Open pull request]
C --> D[Discuss and review]
D --> E[Run CI checks]
E --> F[Merge to main]
F --> G[Deploy]
Code language: CSS (css)
Branch structure
main
feature/*
bugfix/*
chore/*
docs/*
Example
git checkout main
git pull --ff-only origin main
git checkout -b feature/add-search
git commit -am "feat(search): add basic search endpoint"
git push -u origin feature/add-search
Code language: JavaScript (javascript)
When to use GitHub Flow
Use it when:
maincan be deployed frequently- CI is reliable
- You do not need complex release branches
- The team can review quickly
- You operate web services, SaaS, APIs, internal platforms
When not to use it
Avoid pure GitHub Flow when:
- You support many old versions
- You release desktop/mobile apps with long approval cycles
- You need parallel release trains
- Production cannot receive every merged change
13. Workflow 4: GitLab Flow
What it is
GitLab Flow combines feature branches and merge requests with additional guidance for production, environment branches, or release branches. GitLabโs documentation positions GitLab Flow as adding structure around deployments, environments, releases, and issue tracking beyond simple GitHub Flow.
flowchart TD
F[Feature Branch] --> MR[Merge Request]
MR --> MAIN[main]
MAIN --> STAGING[staging]
STAGING --> PROD[production]
Code language: CSS (css)
Common GitLab Flow models
Model A: Production branch
main
production
main is where developers integrate.production is what is deployed.
Model B: Environment branches
main
staging
production
gitGraph
commit id: "A"
commit id: "B"
branch staging
checkout staging
commit id: "Deploy staging"
branch production
checkout production
commit id: "Deploy prod"
Code language: JavaScript (javascript)
Model C: Release branches
main
release/1.0
release/1.1
release/2.0
GitLab describes options such as production branches, environment branches, and release branches as part of GitLab Flow-style branching strategies.
When to use GitLab Flow
Use it when:
- You need environment branches
- You deploy through staging before production
- You want issue/MR-driven process
- You need more release control than GitHub Flow
- You want less complexity than Gitflow
Practical example
git checkout main
git checkout -b feature/payment-retry
git commit -m "feat(payment): retry failed gateway calls"
git push -u origin feature/payment-retry
Code language: JavaScript (javascript)
After MR approval:
git checkout main
git pull --ff-only
git checkout staging
git merge main
git push origin staging
After validation:
git checkout production
git merge staging
git push origin production
14. Workflow 5: Gitflow
What it is
Gitflow is a structured branching model with multiple long-lived branches, commonly including main, develop, feature/*, release/*, and hotfix/*. Atlassian describes Gitflow as an alternative branching model using feature branches and multiple primary branches, originally popularized by Vincent Driessen.
gitGraph
commit id: "prod-1"
branch develop
checkout develop
commit id: "dev-1"
branch feature/login
checkout feature/login
commit id: "login"
checkout develop
merge feature/login
branch release/1.1.0
checkout release/1.1.0
commit id: "stabilize"
checkout main
merge release/1.1.0 tag: "v1.1.0"
checkout develop
merge release/1.1.0
checkout main
branch hotfix/1.1.1
checkout hotfix/1.1.1
commit id: "prod-fix"
checkout main
merge hotfix/1.1.1 tag: "v1.1.1"
checkout develop
merge hotfix/1.1.1
Code language: JavaScript (javascript)
Branch roles
| Branch | Purpose |
|---|---|
main | Production-ready code |
develop | Integration branch for next release |
feature/* | New feature work |
release/* | Stabilization before release |
hotfix/* | Emergency production fix |
support/* | Optional long-term support branch |
The original Gitflow model was presented by Vincent Driessen as a branching strategy for developing and releasing version-based software.
Gitflow process
Start feature
git checkout develop
git pull --ff-only origin develop
git checkout -b feature/invoice-export
Code language: JavaScript (javascript)
Finish feature
git checkout develop
git merge --no-ff feature/invoice-export
git branch -d feature/invoice-export
git push origin develop
Code language: JavaScript (javascript)
Start release
git checkout develop
git checkout -b release/1.4.0
Finish release
git checkout main
git merge --no-ff release/1.4.0
git tag v1.4.0
git checkout develop
git merge --no-ff release/1.4.0
git branch -d release/1.4.0
git push origin main develop --tags
Hotfix
git checkout main
git checkout -b hotfix/1.4.1
# fix production issue
git commit -am "fix: prevent crash on empty invoice"
git checkout main
git merge --no-ff hotfix/1.4.1
git tag v1.4.1
git checkout develop
git merge --no-ff hotfix/1.4.1
git branch -d hotfix/1.4.1
git push origin main develop --tags
Code language: PHP (php)
When Gitflow is good
Use Gitflow when:
- You release versioned software
- You support multiple release versions
- You have scheduled release windows
- You need stabilization branches
- You ship mobile apps, desktop apps, firmware, SDKs, or on-prem products
- Production releases are not continuous
When Gitflow hurts
Gitflow can slow teams when:
- You deploy multiple times per day
- CI/CD is mature
- Features can be hidden with flags
- Releases are small and frequent
- Long-lived branches cause merge pain
Atlassian notes that compared with trunk-based development, Gitflow has more long-lived branches and larger commits.
15. Workflow 6: Trunk-based development
What it is
Trunk-based development means developers integrate small changes into a single shared branch frequently. The trunk-based development reference site defines it as a model where developers collaborate on code in a single branch called trunk and resist creating long-lived development branches by using supporting techniques.
gitGraph
commit id: "A"
commit id: "B"
branch small-change-1
checkout small-change-1
commit id: "C"
checkout main
merge small-change-1
branch small-change-2
checkout small-change-2
commit id: "D"
checkout main
merge small-change-2
commit id: "E"
Code language: JavaScript (javascript)
Core idea
Instead of:
Big feature branch for 3 weeks
Do:
Tiny branch โ PR โ tests โ merge โ hidden behind feature flag
Tiny branch โ PR โ tests โ merge โ hidden behind feature flag
Tiny branch โ PR โ tests โ merge โ hidden behind feature flag
Trunk-based rules
| Rule | Meaning |
|---|---|
| One main integration branch | Usually main or trunk |
| Very short-lived branches | Hours or days, not weeks |
| Small PRs | Easy to review |
| Strong CI | Main must stay green |
| Feature flags | Incomplete features hidden |
| Fast rollback | Revert or disable flag |
| Continuous integration | Merge frequently |
The trunk-based development reference explicitly discusses short-lived feature branches that are deleted after merge/integration.
When trunk-based development is excellent
Use it when:
- You have strong automated tests
- CI is fast and trusted
- Developers are comfortable with small changes
- You use feature flags
- You deploy frequently
- You want continuous delivery
When it is risky
Avoid jumping directly to trunk-based development when:
- Tests are weak
- Reviews are slow
- Developers create huge PRs
- Main often breaks
- No feature flag system exists
- Release and deployment are manual
Trunk-based development with pull requests
This is the practical modern version:
flowchart LR
A[Small local change] --> B[Short-lived branch]
B --> C[Pull request]
C --> D[CI + review]
D --> E[Merge to main]
E --> F[Deploy or release]
Code language: CSS (css)
This is usually better than allowing everyone to push directly to main.
16. Gitflow vs trunk-based development
| Area | Gitflow | Trunk-based development |
|---|---|---|
| Main idea | Controlled release branches | Continuous integration into trunk |
| Primary branches | main, develop, release, hotfix | Mostly main / trunk |
| Branch lifetime | Longer | Very short |
| Release style | Scheduled/versioned | Frequent/continuous |
| CI requirement | Important | Critical |
| Feature flags | Useful | Almost required |
| Merge pain | Higher if branches live long | Lower if changes are tiny |
| Best for | Versioned products, slower release cadence | Web services, SaaS, fast teams |
| Team maturity needed | Medium | High |
| Operational speed | Medium | High |
| Governance clarity | High | Depends on automation |
Simple decision
flowchart TD
A[Choose Git Workflow] --> B{Can main be deployed frequently?}
B -- Yes --> C{Strong CI and tests?}
C -- Yes --> D[Trunk-Based Development]
C -- No --> E[GitHub Flow / Feature Branch Workflow]
B -- No --> F{Need release stabilization?}
F -- Yes --> G[Gitflow or GitLab Flow with release branches]
F -- No --> H[GitLab Flow with environment branches]
Code language: JavaScript (javascript)
17. GitHub Flow vs GitLab Flow vs Gitflow vs Trunk-Based
| Workflow | Best summary | Best team type |
|---|---|---|
| GitHub Flow | Simple PR-based flow from main | Web/service teams |
| GitLab Flow | GitHub Flow plus environment/release structure | Teams with staging/prod promotion |
| Gitflow | Heavy release management model | Versioned products |
| Trunk-based | Small frequent integration into trunk | High-performing CI/CD teams |
GitLab describes GitLab Flow as a simpler alternative to Gitflow that combines feature-driven development and feature branches with issue tracking, while allowing production and stable branches.
18. Recommended workflow by project type
| Project type | Recommended workflow |
|---|---|
| Solo learning project | Centralized or simple feature branch |
| Startup web app | GitHub Flow |
| SaaS backend | Trunk-based with PRs |
| Kubernetes manifests | GitOps-style trunk or environment branches |
| Terraform IaC | Feature branch + PR + plan checks |
| Mobile app | Gitflow or GitLab Flow with release branches |
| Desktop app | Gitflow |
| SDK/library | Gitflow or release-branch model |
| Firmware | Gitflow with support branches |
| Enterprise platform | GitLab Flow or trunk-based with strong governance |
| Monorepo | Trunk-based with CODEOWNERS and selective CI |
| Open source | Feature branch/fork PR workflow |
19. The best modern default workflow
For most modern engineering teams, use this:
main
feature/*
bugfix/*
hotfix/*
release/* only when needed
With rules:
mainis always deployable.- No direct push to
main. - Every change goes through PR/MR.
- CI must pass before merge.
- At least one approval required.
- Use squash merge or rebase merge for clean history.
- Use tags for releases.
- Use feature flags for incomplete features.
- Hotfixes branch from production commit.
- Delete branches after merge.
flowchart TD
A[Issue / Task] --> B[Create short-lived branch]
B --> C[Small commits]
C --> D[Open PR]
D --> E[CI checks]
D --> F[Code review]
E --> G{Pass?}
F --> H{Approved?}
G -- No --> C
H -- No --> C
G -- Yes --> I[Merge to main]
H -- Yes --> I
I --> J[Deploy to staging]
J --> K[Promote to production]
K --> L[Tag release]
20. Branch naming standard
Recommended format
<type>/<ticket-id>-<short-description>
Code language: HTML, XML (xml)
Examples:
feature/EVP-123-add-device-search
bugfix/EVP-221-fix-login-timeout
hotfix/EVP-911-fix-prod-crash
chore/EVP-301-upgrade-node
docs/EVP-404-update-runbook
refactor/EVP-510-clean-auth-module
Code language: JavaScript (javascript)
Branch type guide
| Prefix | Use for |
|---|---|
feature/ | New user-visible or system capability |
bugfix/ | Non-production bug fix |
hotfix/ | Emergency production fix |
chore/ | Maintenance |
docs/ | Documentation |
test/ | Test-only change |
refactor/ | Internal code restructure |
perf/ | Performance improvement |
security/ | Security fix |
experiment/ | Temporary exploration |
21. Commit message standard
Recommended format
<type>(optional-scope): <short summary>
Optional body explaining why.
Optional footer:
BREAKING CHANGE: description
Refs: TICKET-123
Code language: HTML, XML (xml)
Examples:
feat(auth): add Okta login callback
Code language: HTTP (http)
fix(kafka): retry transient producer failures
Code language: HTTP (http)
chore(terraform): upgrade AWS provider to v6
Code language: HTTP (http)
docs(runbook): add EKS incident rollback steps
Code language: HTTP (http)
Conventional Commits aligns well with SemVer because commit types such as features, fixes, and breaking changes can drive automated changelog and version decisions.
22. Commit types
| Type | Meaning | Version impact |
|---|---|---|
feat | New feature | Minor |
fix | Bug fix | Patch |
perf | Performance improvement | Patch or minor |
refactor | Code change without behavior change | Usually none |
docs | Documentation | None |
test | Tests only | None |
build | Build system or dependencies | Depends |
ci | CI/CD pipeline | None |
chore | Maintenance | None |
revert | Revert previous commit | Depends |
Semantic Versioning uses MAJOR.MINOR.PATCH, where major versions indicate incompatible API changes, minor versions add backward-compatible functionality, and patch versions add backward-compatible bug fixes.
23. Pull request template
Use this as a high-quality PR template.
## Summary
Explain what changed in 2โ5 lines.
## Why
Explain the reason, ticket, incident, or user problem.
## Changes
- Added:
- Changed:
- Removed:
- Fixed:
## Testing
- [ ] Unit tests
- [ ] Integration tests
- [ ] Manual test
- [ ] Local run
- [ ] Staging validation
## Risk
Low / Medium / High
Explain risk.
## Rollback Plan
How can this be reverted or disabled?
## Screenshots / Logs
Add screenshots, logs, traces, or curl output if useful.
## Checklist
- [ ] Small enough to review
- [ ] CI passed
- [ ] No secrets committed
- [ ] Docs updated
- [ ] Monitoring/alerts considered
- [ ] Backward compatibility considered
Code language: PHP (php)
24. Pull request size policy
| PR size | Policy |
|---|---|
| 1โ200 lines | Ideal |
| 200โ500 lines | Acceptable |
| 500โ1,000 lines | Needs explanation |
| 1,000+ lines | Split unless generated code |
| 5,000+ lines | Should almost never be reviewed manually |
Generated files should be clearly marked.
Example:
Note: 3,200 lines are generated OpenAPI client files.
Human review should focus on:
- api.yaml
- client config
- usage changes
Code language: CSS (css)
25. Code review rules
Reviewer should check
- Correctness
- Simplicity
- Security
- Tests
- Observability
- Backward compatibility
- Failure handling
- Performance impact
- Migration safety
- Rollback path
Reviewer should not focus only on
- Personal style
- Tiny naming preferences
- Formatting already handled by tools
- โI would have written it differentlyโ
Review comment levels
| Level | Meaning |
|---|---|
blocking | Must fix before merge |
suggestion | Better but not required |
question | Clarification needed |
nit | Tiny non-blocking comment |
praise | Good pattern worth reinforcing |
26. Protected branch rules
For main, enable:
| Rule | Recommendation |
|---|---|
| Direct push | Disabled |
| PR/MR required | Yes |
| Required approvals | 1โ2 |
| CODEOWNERS | Yes for critical areas |
| Status checks | Required |
| Conversation resolution | Required |
| Force push | Disabled |
| Branch deletion | Disabled |
| Signed commits | Optional/required for regulated teams |
| Linear history | Optional |
| Admin bypass | Avoid or audit |
GitHub protected branch rules can require approving reviews and passing status checks before merge, and can restrict force pushes or branch deletion.
27. Merge strategies explained
27.1 Merge commit
git merge --no-ff feature/login
gitGraph
commit id: "A"
branch feature
checkout feature
commit id: "B"
commit id: "C"
checkout main
commit id: "D"
merge feature id: "Merge"
Code language: JavaScript (javascript)
Pros
- Preserves full branch context
- Good audit trail
- Easy to see feature grouping
Cons
- Noisy history
- Many merge commits
Use when
- You need traceability
- Feature branch history matters
- Enterprise audit is important
27.2 Squash merge
git merge --squash feature/login
git commit -m "feat(auth): add login flow"
Code language: JavaScript (javascript)
gitGraph
commit id: "A"
commit id: "B"
commit id: "Squashed feature"
Code language: JavaScript (javascript)
Pros
- Very clean
main - One PR equals one commit
- Easy revert
Cons
- Loses individual commit details from branch
- Harder to preserve granular history
Use when
- Team writes messy local commits
- You want readable main history
- PR is the unit of change
27.3 Rebase merge
git checkout feature/login
git rebase main
git checkout main
git merge --ff-only feature/login
gitGraph
commit id: "A"
commit id: "B"
commit id: "C"
commit id: "D"
Code language: JavaScript (javascript)
Pros
- Linear history
- Clean bisecting
- No merge commits
Cons
- Rewrites commit history
- Dangerous if used carelessly on shared branches
GitHub describes rebase as a command that can change a series of commits, including reordering, editing, or squashing them.
28. Which merge strategy should your team choose?
| Team style | Recommended merge |
|---|---|
| Small web team | Squash merge |
| DevOps/IaC team | Squash or merge commit |
| Regulated enterprise | Merge commit |
| Open-source library | Rebase or merge commit |
| Monorepo | Squash merge |
| High-quality commit culture | Rebase merge |
| New team | Squash merge |
My practical recommendation:
Use squash merge by default.
Use merge commits for release branches or complex multi-commit features.
Use rebase locally to clean your branch before PR.
Code language: JavaScript (javascript)
29. Rebase vs merge
| Question | Merge | Rebase |
|---|---|---|
| Preserves original history? | Yes | No, rewrites branch commits |
| Creates merge commit? | Usually yes | No |
| Good for shared branches? | Yes | Risky |
| Good for local cleanup? | Less useful | Excellent |
| Easier for beginners? | Yes | No |
| Cleaner history? | Sometimes noisy | Yes |
| Conflict resolution repeated? | Usually once | Can be multiple times |
Safe rebase rule
Rebase your own local branch.
Do not rebase shared branches unless the team explicitly agrees.
Code language: PHP (php)
30. Conflict resolution
What is a conflict?
A conflict happens when Git cannot automatically combine changes.
Example:
<<<<<<< HEAD
timeout = 30
=======
timeout = 60
>>>>>>> feature/increase-timeout
You must decide final content:
timeout = 60
Then:
git add config.yml
git rebase --continue
Code language: JavaScript (javascript)
or:
git add config.yml
git commit
Code language: CSS (css)
depending on whether you are rebasing or merging.
Conflict survival workflow
flowchart TD
A[Conflict appears] --> B[Read both sides]
B --> C[Understand intent]
C --> D[Edit final version]
D --> E[Run tests]
E --> F[git add file]
F --> G{Merge or rebase?}
G -- Merge --> H[git commit]
G -- Rebase --> I[git rebase --continue]
Code language: PHP (php)
Never resolve conflicts blindly
Bad:
Accept current change
Accept incoming change
Good:
Understand both changes, then produce correct final code.
Code language: PHP (php)
31. Stash workflow
Use stash when you need to temporarily save unfinished work.
git stash push -m "WIP login refactor"
git checkout main
git pull --ff-only
git checkout feature/login
git stash pop
Code language: JavaScript (javascript)
List stashes:
git stash list
Code language: PHP (php)
Apply without deleting stash:
git stash apply stash@{0}
Code language: CSS (css)
Drop stash:
git stash drop stash@{0}
Code language: CSS (css)
32. Cherry-pick workflow
Use cherry-pick when one specific commit must move to another branch.
git checkout release/1.2
git cherry-pick abc1234
Good use cases:
- Move a hotfix to release branch
- Backport a bug fix
- Apply one safe commit without merging a whole branch
Bad use cases:
- Replacing proper release process
- Randomly copying many commits
- Avoiding integration discipline
33. Revert workflow
Use revert to undo safely.
git revert abc1234
git push origin main
For merge commits:
git revert -m 1 <merge-commit-sha>
Code language: HTML, XML (xml)
Use revert when:
- Bad commit reached shared branch
- Production rollback needs traceability
- You want an audit-safe undo
34. Reset workflow
reset moves branch pointers.
Soft reset:
git reset --soft HEAD~1
Keeps changes staged.
Mixed reset:
git reset HEAD~1
Keeps changes unstaged.
Hard reset:
git reset --hard HEAD~1
Deletes local changes.
Warning
Never use reset --hard casually.
Never force-push reset history to shared branches unless you fully understand the impact.
35. Tagging and release workflow
Lightweight tag
git tag v1.2.0
Code language: CSS (css)
Annotated tag
git tag -a v1.2.0 -m "Release v1.2.0"
Code language: CSS (css)
Push tags
git push origin v1.2.0
Code language: CSS (css)
Recommended release tag format
vMAJOR.MINOR.PATCH
Code language: CSS (css)
Examples:
v1.0.0
v1.1.0
v1.1.1
v2.0.0
Code language: CSS (css)
Semantic Versioning defines version numbers in a way that communicates meaning about the underlying code and compatibility.
36. Release models
Model A: Deploy every merge to main
flowchart LR
A[Merge to main] --> B[CI]
B --> C[Deploy staging]
C --> D[Deploy production]
Code language: CSS (css)
Best for:
- SaaS
- APIs
- Internal tools
- Mature CI/CD teams
Model B: Manual promotion
flowchart LR
A[Merge to main] --> B[Deploy dev]
B --> C[Deploy staging]
C --> D[Manual approval]
D --> E[Deploy production]
Code language: CSS (css)
Best for:
- Enterprise services
- Moderate risk systems
- Teams needing approval gates
Model C: Release branch
flowchart LR
A[main/develop] --> B[release/1.5.0]
B --> C[Bug fixes only]
C --> D[Tag v1.5.0]
D --> E[Production]
Code language: CSS (css)
Best for:
- Mobile apps
- Versioned software
- Slow release cycles
- Compliance-heavy products
Model D: GitOps environment branches
main
env/dev
env/staging
env/prod
flowchart TD
A[Application source repo] --> B[Build image]
B --> C[Update GitOps repo]
C --> D[env/dev]
D --> E[env/staging]
E --> F[env/prod]
F --> G[Argo CD / Flux deploys]
Code language: CSS (css)
Best for:
- Kubernetes
- Argo CD
- Flux
- Platform teams
- Environment-specific promotion
37. CI/CD integration
A Git workflow is incomplete without CI/CD.
Minimum CI checks
flowchart TD
A[Pull Request] --> B[Checkout code]
B --> C[Install dependencies]
C --> D[Lint]
D --> E[Unit tests]
E --> F[Build]
F --> G[Security scan]
G --> H[Integration tests]
H --> I[Result: pass/fail]
Code language: CSS (css)
For application repos
| Check | Purpose |
|---|---|
| Format | Consistent style |
| Lint | Static mistakes |
| Unit test | Code correctness |
| Integration test | Component behavior |
| Build | Package validity |
| Secret scan | Prevent leaked keys |
| SAST | Static security |
| Dependency scan | Vulnerable libraries |
| Container scan | Image vulnerabilities |
| License scan | Compliance |
For Terraform/IaC repos
| Check | Purpose |
|---|---|
terraform fmt | Formatting |
terraform validate | Syntax/provider validation |
terraform plan | Review infra change |
| TFLint | Best practices |
| Checkov/tfsec | Security |
| Infracost | Cost visibility |
| OPA/Conftest | Policy checks |
| Manual approval | Production safety |
For Kubernetes repos
| Check | Purpose |
|---|---|
| YAML lint | Syntax |
| kubeconform/kubeval | Schema validation |
| Helm lint | Chart validity |
| Kustomize build | Render validation |
| Conftest/OPA | Policy |
| Polaris/Kyverno | Best practices |
| Image scan | Supply chain security |
38. Git workflow for infrastructure teams
Infrastructure Git workflow must be stricter than application workflow because mistakes can delete production resources.
Recommended IaC workflow
flowchart TD
A[Create branch] --> B[Edit Terraform]
B --> C[terraform fmt]
C --> D[terraform validate]
D --> E[Open PR]
E --> F[CI plan]
F --> G[Security/cost checks]
G --> H[Review plan output]
H --> I[Approve]
I --> J[Merge]
J --> K[Apply via pipeline]
Code language: CSS (css)
IaC branch policy
| Branch | Purpose |
|---|---|
main | Source of truth |
feature/* | Infra change |
hotfix/* | Emergency infra fix |
env/* | Optional environment branch model |
IaC PR must include
- Terraform plan
- Risk summary
- Blast radius
- Rollback plan
- State impact
- Resource replacement warning
- Cost impact
- Security impact
Dangerous Terraform PR signs
-/+ resource replacement
destroy
forces replacement
public access
0.0.0.0/0
delete database
recreate cluster
change encryption key
remove backup
Code language: PHP (php)
39. Git workflow for Kubernetes teams
Kubernetes workflow should separate:
- Application source
- Container image
- Deployment manifests
- GitOps promotion
flowchart LR
A[App repo] --> B[Build image]
B --> C[Push image tag]
C --> D[GitOps repo PR]
D --> E[Merge env/dev]
E --> F[Promote staging]
F --> G[Promote prod]
Code language: CSS (css)
Recommended image tag strategy
Use immutable tags:
app:v1.4.2
app:git-sha-abc1234
app:2026-07-07-abc1234
Code language: CSS (css)
Avoid relying only on:
latest
Kubernetes GitOps branch models
Option A: Folder per environment
clusters/
dev/
staging/
prod/
Option B: Branch per environment
env/dev
env/staging
env/prod
Option C: Directory per cluster
clusters/
ap-northeast-1/dev/
ap-northeast-1/prod/
For most teams, folder per environment is simpler than branch per environment.
40. Monorepo Git workflow
A monorepo has many services in one repository.
repo/
services/
auth/
payment/
telematics/
libs/
common/
infra/
docs/
Monorepo workflow rules
| Problem | Solution |
|---|---|
| Too many CI jobs | Path-based CI |
| Too many reviewers | CODEOWNERS |
| Slow builds | Build affected projects only |
| Risky shared libraries | Strong tests |
| Large PRs | Smaller changes |
| Ownership confusion | Directory ownership |
CODEOWNERS example
/services/auth/ @auth-team
/services/payment/ @payment-team
/infra/ @platform-team
/.github/workflows/ @devops-team
Monorepo PR checklist
- Which service changed?
- Which shared libraries changed?
- Which downstream services may break?
- Which CI jobs are required?
- Which owners must review?
41. Branch by abstraction
Branch by abstraction is an advanced trunk-based technique.
Instead of creating a long branch for a big rewrite, create an abstraction layer and migrate gradually.
flowchart TD
A[Old implementation] --> B[Introduce interface/abstraction]
B --> C[Route old behavior through abstraction]
C --> D[Add new implementation behind flag]
D --> E[Migrate callers gradually]
E --> F[Remove old implementation]
Code language: CSS (css)
Example:
PaymentGateway interface
โโโ OldStripeGateway
โโโ NewAdyenGateway
Code language: PHP (php)
Feature flag:
payment.provider = stripe | adyen
This allows incomplete work to merge safely into main.
The trunk-based development reference lists branch by abstraction as one of the techniques used to avoid long-lived development branches.
42. Feature flags and Git workflow
Feature flags separate merge from release.
Without feature flags:
Merge = users get feature
Code language: JavaScript (javascript)
With feature flags:
Merge = code integrated
Release = flag enabled
flowchart LR
A[Code merged to main] --> B[Feature flag OFF]
B --> C[Deploy safely]
C --> D[Enable for internal users]
D --> E[Enable for 10%]
E --> F[Enable for 100%]
Code language: CSS (css)
Feature flag types
| Type | Purpose |
|---|---|
| Release flag | Hide incomplete feature |
| Experiment flag | A/B testing |
| Ops flag | Kill switch |
| Permission flag | Customer/role access |
| Migration flag | Gradual backend switch |
Feature flag rules
- Every flag must have an owner.
- Every flag must have an expiry date.
- Old flags must be removed.
- Flags must be observable.
- Critical flags need audit logs.
43. Hotfix workflow
Hotfix in simple main-based workflow
flowchart TD
A[Production incident] --> B[Create hotfix branch from main or prod tag]
B --> C[Fix]
C --> D[Emergency PR]
D --> E[CI critical tests]
E --> F[Merge]
F --> G[Deploy]
G --> H[Tag patch release]
H --> I[Postmortem]
Code language: CSS (css)
Commands:
git checkout main
git pull --ff-only origin main
git checkout -b hotfix/fix-payment-crash
# fix
git commit -am "fix(payment): prevent crash on missing token"
git push -u origin hotfix/fix-payment-crash
Code language: PHP (php)
After PR merge:
git checkout main
git pull --ff-only
git tag -a v1.4.1 -m "Hotfix v1.4.1"
git push origin v1.4.1
Code language: CSS (css)
Hotfix in Gitflow
Hotfix branches start from main, then merge back to both main and develop.
flowchart TD
A[main production] --> B[hotfix/1.4.1]
B --> C[Fix + test]
C --> D[Merge to main]
D --> E[Tag v1.4.1]
C --> F[Merge to develop]
Code language: CSS (css)
44. Release branch workflow
Use release branches when production needs stabilization before release.
gitGraph
commit id: "dev-1"
commit id: "dev-2"
branch release/2.0.0
checkout release/2.0.0
commit id: "fix-rc1"
commit id: "fix-rc2"
checkout main
merge release/2.0.0 tag: "v2.0.0"
Code language: JavaScript (javascript)
Release branch rules
Allowed:
- Bug fixes
- Version bumps
- Release notes
- Stabilization
- Documentation updates
Not allowed:
- New features
- Big refactors
- Risky dependency upgrades
- Experimental changes
45. Backport workflow
Backport means applying a fix from newer code to an older supported release.
flowchart LR
A[Fix in main] --> B[Cherry-pick to release/1.5]
A --> C[Cherry-pick to release/1.4]
B --> D[Tag v1.5.3]
C --> E[Tag v1.4.9]
Code language: CSS (css)
Commands:
git checkout release/1.5
git cherry-pick <fix-commit-sha>
git push origin release/1.5
Code language: HTML, XML (xml)
Backport PR title:
[Backport release/1.5] fix(auth): handle expired token
Code language: CSS (css)
46. Rollback strategy
There are four common rollback methods.
| Rollback type | How | Best for |
|---|---|---|
| Git revert | git revert | Bad code commit |
| Redeploy previous artifact | Deploy old image/package | Bad deployment |
| Disable feature flag | Turn flag off | Bad feature |
| Database rollback/fix-forward | Migration strategy | Data issues |
Best production rollback model
flowchart TD
A[Incident detected] --> B{Feature flag?}
B -- Yes --> C[Disable flag]
B -- No --> D{Bad deploy artifact?}
D -- Yes --> E[Redeploy previous artifact]
D -- No --> F{Bad commit?}
F -- Yes --> G[Revert commit]
F -- No --> H[Fix forward]
47. Database migration workflow
Database changes are where Git workflow often becomes dangerous.
Safe migration pattern
Expand โ Migrate โ Contract
flowchart LR
A[Expand schema] --> B[Deploy app compatible with old and new]
B --> C[Backfill data]
C --> D[Switch reads/writes]
D --> E[Remove old schema]
Code language: CSS (css)
Example
Bad:
ALTER TABLE users DROP COLUMN name;
Good:
- Add new column.
- Deploy code that writes both old and new.
- Backfill.
- Switch reads to new column.
- Wait.
- Drop old column later.
Database PR must include
- Migration direction
- Rollback safety
- Backfill plan
- Locking risk
- Data volume estimate
- Production execution plan
48. Security workflow
Git workflow must prevent secrets and unsafe code from reaching the repository.
Security checks before merge
| Check | Why |
|---|---|
| Secret scanning | Prevent leaked credentials |
| Dependency scanning | Detect vulnerable libraries |
| SAST | Detect code-level security issues |
| IaC scanning | Detect cloud misconfigurations |
| Container scanning | Detect vulnerable images |
| License scanning | Avoid legal risk |
| CODEOWNERS | Require expert review |
Never commit
.env
private keys
AWS credentials
GCP service account keys
SSH private keys
database dumps
customer data
production kubeconfig
Terraform state files
Code language: PHP (php)
Add protection
git-secrets
pre-commit
detect-secrets
gitleaks
trufflehog
49. Pre-commit hooks
Pre-commit hooks catch issues before code leaves the laptop.
Example .pre-commit-config.yaml:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-json
- id: detect-private-key
Code language: PHP (php)
Install:
pip install pre-commit
pre-commit install
pre-commit run --all-files
50. Git workflow for open source
Open-source projects often use fork-based workflow.
flowchart LR
A[Upstream repo] --> B[User fork]
B --> C[Feature branch in fork]
C --> D[Pull request to upstream]
D --> E[Maintainer review]
E --> F[Merge]
Code language: CSS (css)
Contributor commands:
git clone <your-fork-url>
cd project
git remote add upstream <original-project-url>
git fetch upstream
git checkout -b fix/readme-typo upstream/main
Code language: HTML, XML (xml)
Sync fork:
git fetch upstream
git checkout main
git merge upstream/main
git push origin main
51. Git workflow for emergency production incidents
During an incident, optimize for:
- Safety
- Speed
- Traceability
- Rollback
- Communication
Incident hotfix flow
sequenceDiagram
participant Dev as Developer
participant Git as Git Repo
participant CI as CI Pipeline
participant Prod as Production
Dev->>Git: Create hotfix branch
Dev->>Git: Commit minimal fix
Dev->>Git: Open emergency PR
CI->>Git: Run critical checks
Git->>Prod: Deploy after approval
Prod->>Dev: Validate metrics/logs
Dev->>Git: Tag release
Code language: JavaScript (javascript)
Emergency PR template
## Incident
Production issue:
## Root cause
Known / suspected:
## Fix
Minimal change:
## Validation
- [ ] Critical tests passed
- [ ] Staging validated
- [ ] Production smoke test ready
## Rollback
Exact rollback command or plan:
## Follow-up
Post-incident cleanup ticket:
Code language: PHP (php)
52. Git workflow anti-patterns
Anti-pattern 1: Long-lived feature branches
feature/big-rewrite lives for 2 months
Result:
- Huge merge conflicts
- Delayed feedback
- Broken assumptions
- Big-bang release risk
Fix:
- Split work
- Use feature flags
- Use branch by abstraction
- Merge smaller PRs
Anti-pattern 2: Shared develop branch without discipline
develop can become a dumping ground.
Symptoms:
- Always unstable
- Nobody owns it
- Hard to release
- Test failures ignored
Fix:
- Protect
develop - Require PRs
- Require CI
- Consider removing it if not needed
Anti-pattern 3: โFix directly on serverโ
Never hotfix production manually without Git.
Bad:
SSH to server
vim file
restart service
Good:
hotfix branch โ PR โ CI โ deploy โ tag
Anti-pattern 4: Giant PR
Symptoms:
- Reviewers approve without understanding
- Bugs hidden in noise
- Rollback is hard
Fix:
- Split by behavior
- Split by layer
- Split by risk
- Use stacked PRs
Anti-pattern 5: Merge without green CI
This destroys trust.
Rule:
Red CI means stop.
Green CI means continue.
Flaky CI means fix CI.
Code language: JavaScript (javascript)
Anti-pattern 6: Feature branches used as environments
Bad:
branch dev
branch qa
branch staging
branch prod
This can work in some GitLab Flow or GitOps models, but it becomes dangerous when teams randomly merge between branches without clear promotion rules.
Fix:
- Use environment folders
- Use deployment pipeline promotions
- Use tags/artifacts
- Keep source branch strategy simple
53. Advanced PR splitting
Large feature?
Do not create one huge PR.
Use this sequence:
flowchart TD
A[PR 1: Add database column, unused] --> B[PR 2: Add backend support behind flag]
B --> C[PR 3: Add API response field]
C --> D[PR 4: Add frontend hidden UI]
D --> E[PR 5: Enable for internal users]
E --> F[PR 6: Enable for all users]
F --> G[PR 7: Remove old path]
Code language: CSS (css)
Splitting strategies
| Strategy | Example |
|---|---|
| By layer | DB โ backend โ frontend |
| By risk | Safe refactor โ behavior change |
| By flag | Hidden code โ enabled code |
| By endpoint | One endpoint per PR |
| By module | One service/package per PR |
| By migration phase | Expand โ migrate โ contract |
54. Stacked PR workflow
Stacked PRs are useful when changes depend on each other.
gitGraph
commit id: "main"
branch pr-1-base-refactor
checkout pr-1-base-refactor
commit id: "refactor"
branch pr-2-new-api
checkout pr-2-new-api
commit id: "api"
branch pr-3-ui
checkout pr-3-ui
commit id: "ui"
Code language: JavaScript (javascript)
Use stacked PRs when
- A feature needs multiple dependent steps
- Each step can be reviewed separately
- You do not want one huge PR
Be careful
Stacked PRs require discipline. Rebase carefully and keep reviewers informed.
55. Repository hygiene
Delete merged branches
git branch --merged
git branch -d feature/old-branch
git push origin --delete feature/old-branch
Code language: JavaScript (javascript)
Prune deleted remote branches
git fetch --prune
Find stale branches
git branch -r --sort=committerdate
Clean local untracked files
Preview:
git clean -nd
Delete:
git clean -fd
56. Useful Git aliases
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.cm commit
git config --global alias.lg "log --oneline --decorate --graph --all"
git config --global alias.last "log -1 HEAD --stat"
git config --global alias.unstage "restore --staged"
Code language: PHP (php)
Now:
git lg
git st
57. Debugging with Git
Find who changed a line
git blame path/to/file
Search history
git log --grep="timeout"
git log -S "functionName"
git log -- path/to/file
Code language: JavaScript (javascript)
Find bad commit with bisect
git bisect start
git bisect bad
git bisect good v1.2.0
Code language: CSS (css)
Then Git walks you through commits.
Mark each:
git bisect good
git bisect bad
Finish:
git bisect reset
58. Clean history before PR
Before opening PR:
git fetch origin
git rebase origin/main
git log --oneline origin/main..HEAD
Interactive rebase:
git rebase -i origin/main
You can:
pick
reword
edit
squash
fixup
drop
Use it to clean local commits.
59. Example complete workflow: application team
sequenceDiagram
participant Dev as Developer
participant Git as GitHub/GitLab
participant CI as CI
participant Staging as Staging
participant Prod as Production
Dev->>Git: Create feature branch
Dev->>Git: Push commits
Dev->>Git: Open PR
CI->>Git: Run tests and scans
Git->>Dev: Review comments
Dev->>Git: Push fixes
CI->>Git: Pass
Git->>Git: Merge to main
CI->>Staging: Deploy
Staging->>Prod: Promote after approval
Code language: JavaScript (javascript)
Commands
git checkout main
git pull --ff-only origin main
git checkout -b feature/EVP-123-add-alerts
# edit files
git add .
git commit -m "feat(alerts): add threshold alert config"
git push -u origin feature/EVP-123-add-alerts
Code language: PHP (php)
After review and merge:
git checkout main
git pull --ff-only origin main
git branch -d feature/EVP-123-add-alerts
git fetch --prune
60. Example complete workflow: Terraform team
flowchart TD
A[Ticket: add NAT Gateway] --> B[Create branch]
B --> C[Edit Terraform]
C --> D[terraform fmt]
D --> E[terraform validate]
E --> F[Open PR]
F --> G[CI generates plan]
G --> H[Review resource changes]
H --> I[Security/cost review]
I --> J[Approval]
J --> K[Merge]
K --> L[Apply through controlled pipeline]
Code language: CSS (css)
PR title
feat(network): add NAT gateway per AZ for staging
Code language: HTTP (http)
PR body
## Summary
Adds one NAT Gateway per AZ for staging private subnets.
## Terraform plan summary
- Creates:
- 2 NAT Gateways
- 2 Elastic IP associations
- Route updates for private subnets
## Risk
Medium. Route table changes affect outbound traffic from private subnets.
## Rollback
Revert PR and re-apply previous Terraform configuration.
## Validation
- terraform fmt
- terraform validate
- terraform plan
- connectivity test from private subnet
Code language: PHP (php)
61. Example complete workflow: Kubernetes GitOps team
flowchart LR
A[Code PR merged] --> B[Build image sha-abc123]
B --> C[Open GitOps PR]
C --> D[Update dev manifest]
D --> E[Argo CD sync dev]
E --> F[Promote same image to staging]
F --> G[Promote same image to prod]
Code language: CSS (css)
Important rule
Build once, promote the same artifact.
Bad:
Build separate image for dev, staging, prod
Good:
Build one immutable image and promote it
62. Team policy: recommended default
Use this as an internal engineering standard.
Branches
main
feature/*
bugfix/*
hotfix/*
release/*
Rules
| Rule | Policy |
|---|---|
Direct push to main | Not allowed |
| PR required | Yes |
| CI required | Yes |
| Review required | At least 1 |
| CODEOWNERS | Required for critical directories |
| Squash merge | Default |
| Release tags | Required for production |
| Hotfix branch | Required for emergency fixes |
| Branch deletion | Delete after merge |
| Secrets scan | Required |
Main branch definition
main is always production-ready.
Pull request definition
A PR is not a storage place for unfinished work.
A PR is a reviewable unit of change.
Release definition
A release is a tagged, traceable, deployable artifact.
63. Choosing a workflow: final decision matrix
| Condition | Choose |
|---|---|
| New team, simple app | GitHub Flow |
| Strong CI/CD, frequent deploys | Trunk-based |
| Need staging โ prod promotion | GitLab Flow |
| Versioned software with release windows | Gitflow |
| Mobile app approval cycle | Gitflow or release branches |
| Kubernetes GitOps | Main + environment folders |
| Terraform infrastructure | Feature branch + protected main |
| Highly regulated system | Gitflow or GitLab Flow with strict controls |
| Monorepo | Trunk-based with CODEOWNERS |
| Open source | Fork + PR workflow |
64. The โworld-classโ Git workflow blueprint
This is the final architecture I recommend for serious teams.
flowchart TD
A[Work item created] --> B[Create short-lived branch]
B --> C[Local commits with Conventional Commit style]
C --> D[Pre-commit checks]
D --> E[Push branch]
E --> F[Open PR/MR]
F --> G[Automated CI]
F --> H[Code review]
G --> I{Checks pass?}
H --> J{Approved?}
I -- No --> C
J -- No --> C
I -- Yes --> K[Merge to protected main]
J -- Yes --> K
K --> L[Build immutable artifact]
L --> M[Deploy to dev/staging]
M --> N{Production approval or auto-deploy?}
N -- Approval --> O[Deploy production]
N -- Auto --> O
O --> P[Tag release]
P --> Q[Monitor]
Q --> R{Issue?}
R -- Yes --> S[Rollback/revert/hotfix]
R -- No --> T[Done]
Code language: JavaScript (javascript)
Blueprint policies
Branching
main
feature/<ticket>-<description>
bugfix/<ticket>-<description>
hotfix/<ticket>-<description>
release/<version>
Code language: HTML, XML (xml)
Commit format
feat(scope): summary
fix(scope): summary
chore(scope): summary
docs(scope): summary
Code language: HTTP (http)
Merge strategy
Default: squash merge
Exceptions: release branches and complex audited features may use merge commits
Code language: PHP (php)
Release strategy
Every production deployment maps to:
- Git commit SHA
- Build artifact
- Container image digest
- Git tag or release record
- CI/CD run
- Approver, if manual approval exists
CI/CD gates
No green CI, no merge.
No review, no merge.
No rollback plan, no production release.
65. Git command cheat sheet
Daily commands
git status
git fetch origin
git pull --ff-only
git checkout -b feature/name
git add .
git commit -m "feat: message"
git push -u origin feature/name
Code language: JavaScript (javascript)
History
git log --oneline --decorate --graph --all
git show <sha>
git diff
git diff main...HEAD
Code language: HTML, XML (xml)
Branches
git branch
git branch -a
git checkout main
git switch main
git checkout -b feature/name
git branch -d feature/name
Code language: JavaScript (javascript)
Merge/rebase
git merge main
git rebase main
git rebase --continue
git rebase --abort
Code language: JavaScript (javascript)
Undo
git restore file.txt
git restore --staged file.txt
git reset --soft HEAD~1
git revert <sha>
Code language: CSS (css)
Tags
git tag
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
Code language: CSS (css)
Cleanup
git fetch --prune
git branch --merged
git clean -nd
66. The final advice
A beginner thinks:
Git workflow means which branch name to use.
A senior engineer thinks:
Git workflow means how we protect production while helping developers move fast.
An architect thinks:
Git workflow is a delivery control system: source control, review, testing, release, rollback, audit, and learning.
The best workflow is not the most complex one.
The best workflow is the one where:
- Developers understand it.
- CI enforces it.
- Releases are traceable.
- Rollbacks are simple.
- Branches are short-lived.
- Production is protected.
- Teams can move fast without fear.
For most modern teams, start with:
Protected main
Short-lived feature branches
Pull requests
Required CI
Squash merge
Tags for releases
Feature flags for incomplete work
Hotfix branches for emergencies
Code language: PHP (php)
Then evolve toward trunk-based development when your tests, CI, reviews, and release automation are strong enough.
Iโm a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I have worked at Cotocus. I share tech blog at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at TrueReviewNow , and SEO strategies at Wizbrand.
Do you want to learn Quantum Computing?
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at WIZBRAND
Find Trusted Cardiac Hospitals
Compare heart hospitals by city and services โ all in one place.
Explore Hospitals