Learn professional Git workflows used by development teams. Master Feature Branch, Gitflow, and trunk-based development patterns.
A Git workflow is a recipe or recommendation for how to use Git to accomplish work in a consistent and productive manner. Different teams use different workflows depending on their size, project type, and release cycle.
In this lesson, you'll learn the most popular Git workflows used in professional development. From the simple Feature Branch workflow to the more structured Gitflow model, you'll understand when and how to use each approach.
Choosing the right workflow can dramatically improve your team's productivity and code quality.
Without an agreed-upon workflow, teams run into problems:
Common Problems Without a Workflow:
Benefits of a Defined Workflow:
Workflow Spectrum:
1Simple Complex
2 ↓ ↓
3Centralized → Feature Branch → Gitflow → Custom
4
5Small teams, Large teams,
6Simple projects Complex releasesKey Workflow Components:
| Component | Purpose |
|-----------|---------|
| Main branch | Production-ready code |
| Feature branches | Isolated development |
| Release branches | Release preparation |
| Hotfix branches | Emergency fixes |
| Pull requests | Code review gateway |
The Feature Branch workflow is the most common and recommended workflow for most teams. It's simple, effective, and scales well.
Core Principle:
All feature development takes place in dedicated branches instead of the main branch.
The Process:
1# 1. Start from updated main
2git switch main
3git pull origin main
4
5# 2. Create feature branch
6git switch -c feature/user-authentication
7
8# 3. Work on the feature (multiple commits)
9git add .
10git commit -m "Add login form"
11
12git add .
13git commit -m "Add password validation"
14
15git add .
16git commit -m "Add session management"
17
18# 4. Push to remote
19git push -u origin feature/user-authentication
20
21# 5. Create Pull Request on GitHub/GitLab
22# (Done through web interface)
23
24# 6. After code review and approval, merge
25# (Usually done through PR interface)
26
27# 7. Clean up
28git switch main
29git pull origin main
30git branch -d feature/user-authenticationVisual Representation:
1main A ← B ← C ← D ← E ← F ← G (merge commit)
2 ↘ ↗
3feature X ← Y ← Z
4 (feature work)Key Rules:
Naming Convention:
1feature/add-user-login
2feature/implement-payment-gateway
3feature/redesign-dashboard
4bugfix/fix-login-redirect
5bugfix/resolve-memory-leakWhen to Use Feature Branch:
Gitflow is a more structured workflow designed for projects with scheduled releases. It uses multiple long-running branches.
Branch Types in Gitflow:
| Branch | Purpose | Lifetime |
|--------|---------|----------|
| main | Production code | Permanent |
| develop | Integration branch | Permanent |
| feature/* | New features | Temporary |
| release/* | Release preparation | Temporary |
| hotfix/* | Emergency fixes | Temporary |
Visual Structure:
1main A ←←←←←←←←←←←←← B (release) ←←← C (hotfix)
2 ↘ ↗ ↗
3develop D ← E ← F ← G ← H ← I ← J ← K
4 ↘ ↗ ↘ ↗
5features X-Y Z-WFeature Development:
1# Start feature from develop
2git switch develop
3git pull origin develop
4git switch -c feature/new-feature
5
6# Work on feature
7git add .
8git commit -m "Implement feature"
9
10# Merge back to develop
11git switch develop
12git merge --no-ff feature/new-feature
13git push origin develop
14git branch -d feature/new-featureCreating a Release:
1# Start release from develop
2git switch develop
3git switch -c release/v1.2.0
4
5# Bump version, fix bugs
6git commit -m "Bump version to 1.2.0"
7git commit -m "Fix release bug"
8
9# Merge to main AND develop
10git switch main
11git merge --no-ff release/v1.2.0
12git tag -a v1.2.0 -m "Version 1.2.0"
13git push origin main --tags
14
15git switch develop
16git merge --no-ff release/v1.2.0
17git push origin develop
18
19git branch -d release/v1.2.0Hotfix Process:
1# Emergency fix from main
2git switch main
3git switch -c hotfix/critical-bug
4
5# Make the fix
6git commit -m "Fix critical security issue"
7
8# Merge to BOTH main and develop
9git switch main
10git merge --no-ff hotfix/critical-bug
11git tag -a v1.2.1 -m "Hotfix 1.2.1"
12
13git switch develop
14git merge --no-ff hotfix/critical-bug
15
16git branch -d hotfix/critical-bugWhen to Use Gitflow:
Trunk-based development emphasizes keeping a single main branch (trunk) always deployable. Developers commit directly to main or use very short-lived branches.
Core Principles:
Two Flavors:
1. Direct to Trunk (Small Teams):
1# Pull latest
2git pull origin main --rebase
3
4# Make small, complete changes
5git add .
6git commit -m "Add button to dashboard"
7
8# Push immediately
9git push origin main
10
11# CI/CD automatically tests and deploys2. Short-Lived Branches (Larger Teams):
1# Create branch
2git switch -c add-button
3
4# Work for a few hours (max 1-2 days)
5git add .
6git commit -m "Add button to dashboard"
7
8# Push and create PR
9git push -u origin add-button
10# Create PR, get quick review, merge same day
11
12# Delete branch
13git switch main
14git pull
15git branch -d add-buttonFeature Flags:
1// Instead of long-running branches, use feature flags
2if (featureFlags.newDashboard) {
3 renderNewDashboard();
4} else {
5 renderOldDashboard();
6}
7
8// This allows:
9// - Incomplete features in main
10// - Gradual rollout
11// - Easy rollback
12// - A/B testingBranch Naming (Trunk-Based):
1# Very short, task-focused names
2add-button
3fix-typo
4update-deps
5refactor-api
6
7# NOT feature/user-authentication-with-oauth-and-mfaWhen to Use Trunk-Based:
Trade-offs:
| Aspect | Trunk-Based | Feature Branch |
|--------|-------------|----------------|
| Speed | Faster integration | More review time |
| Risk | Higher (needs good tests) | Lower |
| Complexity | Feature flags needed | Simpler |
| Team Size | Any, needs discipline | Any |
GitHub Flow is a simplified workflow designed around pull requests. It's essentially Feature Branch workflow optimized for GitHub.
The Six Steps:
1. Create a Branch
1git switch main
2git pull origin main
3git switch -c descriptive-branch-name2. Add Commits
1# Make changes
2git add .
3git commit -m "Add feature component"
4
5# More changes
6git add .
7git commit -m "Add tests for feature"3. Open a Pull Request
1git push -u origin descriptive-branch-name
2# Then use GitHub UI to create PR4. Discuss and Review
5. Deploy and Test
1# Deploy to staging/preview environment
2# Run automated tests
3# Manual QA if needed6. Merge
1# Via GitHub interface:
2# - Squash and merge (clean history)
3# - Create merge commit (preserve history)
4# - Rebase and merge (linear history)Pull Request Best Practices:
1## PR Title
2Add user authentication feature
3
4## Description
5This PR implements user authentication using JWT tokens.
6
7### Changes
8- Add login/logout endpoints
9- Implement JWT token generation
10- Add authentication middleware
11- Add tests for auth flow
12
13### Screenshots
14[If UI changes, add screenshots]
15
16### Testing
17- [x] Unit tests pass
18- [x] Integration tests pass
19- [x] Manual testing completed
20
21### Related Issues
22Closes #123
23Related to #100
24
25### Checklist
26- [x] Code follows style guidelines
27- [x] Tests added/updated
28- [x] Documentation updatedReview Checklist:
1As a reviewer, check:
2- [ ] Code is readable and maintainable
3- [ ] Logic is correct
4- [ ] Tests are adequate
5- [ ] No security vulnerabilities
6- [ ] Performance is acceptable
7- [ ] Documentation is updatedDifferent situations call for different workflows. Here's how to choose.
Decision Matrix:
| Factor | Feature Branch | Gitflow | Trunk-Based |
|--------|---------------|---------|-------------|
| Team Size | 2-20 | 10+ | Any |
| Release Cycle | Continuous | Scheduled | Continuous |
| Deploy Frequency | Daily/Weekly | Monthly/Quarterly | Multiple/Day |
| Complexity | Low | High | Medium |
| Required Discipline | Medium | Medium | High |
Workflow by Project Type:
SaaS Web App:
1Recommended: Feature Branch or Trunk-Based
2- Continuous deployment
3- Fast iteration needed
4- Single version in productionMobile App:
1Recommended: Gitflow
2- App store review cycles
3- Multiple versions in field
4- Scheduled releasesOpen Source Project:
1Recommended: Feature Branch (GitHub Flow)
2- External contributors
3- PRs for all changes
4- Async collaborationEnterprise Software:
1Recommended: Gitflow
2- Formal release process
3- Multiple environments
4- Long-term support versionsStartup MVP:
1Recommended: Trunk-Based or Simple Feature Branch
2- Speed is priority
3- Small team
4- Pivoting frequentlyHybrid Approaches:
Most teams adapt workflows to their needs:
1# Example: Simplified Gitflow
2# - Use main + develop only
3# - Skip release branches for minor releases
4# - Use feature branches for all work
5# - Hotfix directly on main
6
7# Example: Protected Trunk-Based
8# - Main branch protected
9# - PRs required but reviewed quickly
10# - Feature flags for big changes
11# - Continuous deploymentMigration Tips:
1# Moving from Chaos to Feature Branch:
21. Protect main branch
32. Require PRs
43. Add CI checks
54. Document process
65. Train team
7
8# Moving from Gitflow to Trunk-Based:
91. Remove develop branch
102. Shorten branch lifespan
113. Implement feature flags
124. Improve CI/CD pipeline
135. Build review cultureCompare different Git workflows visually and see how they handle common development scenarios.
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Git Workflow Comparison</title>
7 <style>
8 * {
9 margin: 0;
10 padding: 0;
11 box-sizing: border-box;
12 }
13
14 body {
15 font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
16 background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
17 min-height: 100vh;
18 color: #e0e0e0;
19 padding: 20px;
20 }
21
22 .container {
23 max-width: 1100px;
24 margin: 0 auto;
25 }
26
27 h1 {
28 text-align: center;
29 color: #f5a623;
30 margin-bottom: 10px;
31 font-size: 1.8rem;
32 }
33
34 .subtitle {
35 text-align: center;
36 color: #888;
37 margin-bottom: 30px;
38 }
39
40 .workflow-selector {
41 display: flex;
42 justify-content: center;
43 gap: 15px;
44 margin-bottom: 30px;
45 flex-wrap: wrap;
46 }
47
48 .workflow-btn {
49 padding: 12px 24px;
50 border: 2px solid transparent;
51 border-radius: 8px;
52 cursor: pointer;
53 font-weight: bold;
54 font-family: inherit;
55 font-size: 0.85rem;
56 transition: all 0.3s ease;
57 background: rgba(0, 0, 0, 0.3);
58 color: #888;
59 }
60
61 .workflow-btn:hover {
62 border-color: #f5a623;
63 color: #f5a623;
64 }
65
66 .workflow-btn.active {
67 background: linear-gradient(135deg, #f5a623, #ff8c00);
68 color: #1a1a2e;
69 border-color: transparent;
70 }
71
72 .workflow-display {
73 background: rgba(0, 0, 0, 0.4);
74 border-radius: 15px;
75 padding: 25px;
76 margin-bottom: 25px;
77 }
78
79 .workflow-header {
80 display: flex;
81 justify-content: space-between;
82 align-items: center;
83 margin-bottom: 20px;
84 flex-wrap: wrap;
85 gap: 15px;
86 }
87
88 .workflow-title {
89 color: #00d4aa;
90 font-size: 1.3rem;
91 }
92
93 .workflow-tags {
94 display: flex;
95 gap: 10px;
96 flex-wrap: wrap;
97 }
98
99 .tag {
100 padding: 5px 12px;
101 border-radius: 15px;
102 font-size: 0.75rem;
103 font-weight: bold;
104 }
105
106 .tag.simple { background: #6bcb77; color: #1a1a2e; }
107 .tag.moderate { background: #ffd93d; color: #1a1a2e; }
108 .tag.complex { background: #ff6b6b; color: white; }
109
110 .workflow-description {
111 color: #aaa;
112 margin-bottom: 20px;
113 line-height: 1.6;
114 }
115
116 .branch-diagram {
117 background: #1a1a2e;
118 border-radius: 10px;
119 padding: 20px;
120 margin-bottom: 20px;
121 overflow-x: auto;
122 }
123
124 .branch-row {
125 display: flex;
126 align-items: center;
127 margin-bottom: 15px;
128 }
129
130 .branch-label {
131 min-width: 100px;
132 padding: 6px 12px;
133 border-radius: 5px;
134 font-size: 0.8rem;
135 font-weight: bold;
136 text-align: center;
137 }
138
139 .branch-main { background: #6bcb77; color: #1a1a2e; }
140 .branch-develop { background: #4facfe; color: #1a1a2e; }
141 .branch-feature { background: #f093fb; color: #1a1a2e; }
142 .branch-release { background: #ffd93d; color: #1a1a2e; }
143 .branch-hotfix { background: #ff6b6b; color: white; }
144
145 .branch-line {
146 display: flex;
147 align-items: center;
148 margin-left: 15px;
149 gap: 5px;
150 }
151
152 .commit {
153 width: 25px;
154 height: 25px;
155 border-radius: 50%;
156 display: flex;
157 align-items: center;
158 justify-content: center;
159 font-size: 0.7rem;
160 font-weight: bold;
161 }
162
163 .commit-main { background: #6bcb77; color: #1a1a2e; }
164 .commit-develop { background: #4facfe; color: #1a1a2e; }
165 .commit-feature { background: #f093fb; color: #1a1a2e; }
166 .commit-merge { background: #ffd93d; color: #1a1a2e; }
167
168 .arrow {
169 color: #666;
170 font-size: 1rem;
171 }
172
173 .workflow-steps {
174 display: grid;
175 grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
176 gap: 15px;
177 }
178
179 .step-card {
180 background: rgba(255, 255, 255, 0.05);
181 border-radius: 10px;
182 padding: 15px;
183 border-left: 3px solid #f5a623;
184 }
185
186 .step-num {
187 color: #f5a623;
188 font-weight: bold;
189 margin-bottom: 8px;
190 }
191
192 .step-text {
193 color: #ccc;
194 font-size: 0.85rem;
195 }
196
197 .comparison-grid {
198 display: grid;
199 grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
200 gap: 20px;
201 margin-top: 25px;
202 }
203
204 .compare-card {
205 background: rgba(0, 0, 0, 0.3);
206 border-radius: 10px;
207 padding: 20px;
208 }
209
210 .compare-card h3 {
211 color: #f5a623;
212 margin-bottom: 15px;
213 font-size: 0.95rem;
214 }
215
216 .compare-item {
217 display: flex;
218 justify-content: space-between;
219 padding: 8px 0;
220 border-bottom: 1px solid rgba(255, 255, 255, 0.05);
221 font-size: 0.85rem;
222 }
223
224 .compare-item:last-child {
225 border-bottom: none;
226 }
227
228 .compare-label {
229 color: #888;
230 }
231
232 .compare-value {
233 color: #00d4aa;
234 font-weight: bold;
235 }
236
237 @media (max-width: 600px) {
238 .workflow-selector {
239 flex-direction: column;
240 }
241 .branch-row {
242 flex-direction: column;
243 align-items: flex-start;
244 gap: 10px;
245 }
246 }
247 </style>
248</head>
249<body>
250 <div class="container">
251 <h1>Git Workflow Comparison</h1>
252 <p class="subtitle">Explore different Git workflows and find the right one for your team</p>
253
254 <div class="workflow-selector">
255 <button class="workflow-btn active" onclick="showWorkflow('feature')">Feature Branch</button>
256 <button class="workflow-btn" onclick="showWorkflow('gitflow')">Gitflow</button>
257 <button class="workflow-btn" onclick="showWorkflow('trunk')">Trunk-Based</button>
258 <button class="workflow-btn" onclick="showWorkflow('github')">GitHub Flow</button>
259 </div>
260
261 <div class="workflow-display" id="workflow-display">
262 <!-- Content injected by JavaScript -->
263 </div>
264
265 <div class="comparison-grid">
266 <div class="compare-card">
267 <h3>Best For</h3>
268 <div class="compare-item">
269 <span class="compare-label">Feature Branch</span>
270 <span class="compare-value">Most teams</span>
271 </div>
272 <div class="compare-item">
273 <span class="compare-label">Gitflow</span>
274 <span class="compare-value">Scheduled releases</span>
275 </div>
276 <div class="compare-item">
277 <span class="compare-label">Trunk-Based</span>
278 <span class="compare-value">Fast iteration</span>
279 </div>
280 <div class="compare-item">
281 <span class="compare-label">GitHub Flow</span>
282 <span class="compare-value">Open source</span>
283 </div>
284 </div>
285
286 <div class="compare-card">
287 <h3>Complexity</h3>
288 <div class="compare-item">
289 <span class="compare-label">Feature Branch</span>
290 <span class="compare-value" style="color: #6bcb77;">Simple</span>
291 </div>
292 <div class="compare-item">
293 <span class="compare-label">Gitflow</span>
294 <span class="compare-value" style="color: #ff6b6b;">Complex</span>
295 </div>
296 <div class="compare-item">
297 <span class="compare-label">Trunk-Based</span>
298 <span class="compare-value" style="color: #ffd93d;">Moderate</span>
299 </div>
300 <div class="compare-item">
301 <span class="compare-label">GitHub Flow</span>
302 <span class="compare-value" style="color: #6bcb77;">Simple</span>
303 </div>
304 </div>
305
306 <div class="compare-card">
307 <h3>Deploy Frequency</h3>
308 <div class="compare-item">
309 <span class="compare-label">Feature Branch</span>
310 <span class="compare-value">Daily/Weekly</span>
311 </div>
312 <div class="compare-item">
313 <span class="compare-label">Gitflow</span>
314 <span class="compare-value">Monthly</span>
315 </div>
316 <div class="compare-item">
317 <span class="compare-label">Trunk-Based</span>
318 <span class="compare-value">Multiple/Day</span>
319 </div>
320 <div class="compare-item">
321 <span class="compare-label">GitHub Flow</span>
322 <span class="compare-value">Continuous</span>
323 </div>
324 </div>
325 </div>
326 </div>
327
328 <script>
329 const workflows = {
330 feature: {
331 title: 'Feature Branch Workflow',
332 tags: [{ text: 'Simple', class: 'simple' }, { text: 'Most Popular', class: 'moderate' }],
333 description: 'All development takes place in dedicated feature branches. Main branch is always deployable. Pull requests required for merging.',
334 branches: [
335 { name: 'main', class: 'main', commits: ['A', 'B', 'M', 'C'] },
336 { name: 'feature', class: 'feature', commits: ['X', 'Y', 'Z'] }
337 ],
338 steps: [
339 'Pull latest main',
340 'Create feature branch',
341 'Make commits',
342 'Push and create PR',
343 'Code review',
344 'Merge and delete branch'
345 ]
346 },
347 gitflow: {
348 title: 'Gitflow Workflow',
349 tags: [{ text: 'Complex', class: 'complex' }, { text: 'Scheduled Releases', class: 'moderate' }],
350 description: 'Structured workflow with dedicated branches for features, releases, and hotfixes. Best for projects with scheduled release cycles.',
351 branches: [
352 { name: 'main', class: 'main', commits: ['A', 'R', 'H'] },
353 { name: 'develop', class: 'develop', commits: ['B', 'C', 'M', 'D'] },
354 { name: 'feature', class: 'feature', commits: ['X', 'Y'] },
355 { name: 'release', class: 'release', commits: ['V'] }
356 ],
357 steps: [
358 'Feature from develop',
359 'Merge to develop',
360 'Create release branch',
361 'Test and fix',
362 'Merge to main + develop',
363 'Tag release'
364 ]
365 },
366 trunk: {
367 title: 'Trunk-Based Development',
368 tags: [{ text: 'Moderate', class: 'moderate' }, { text: 'Fast Iteration', class: 'simple' }],
369 description: 'Developers commit to main frequently. Short-lived branches (hours, not days). Requires feature flags and strong CI/CD.',
370 branches: [
371 { name: 'main', class: 'main', commits: ['A', 'B', 'C', 'D', 'E', 'F'] },
372 { name: 'short', class: 'feature', commits: ['X'] }
373 ],
374 steps: [
375 'Pull main',
376 'Small change (hours)',
377 'Push or quick PR',
378 'Automated tests',
379 'Auto deploy',
380 'Feature flags for big changes'
381 ]
382 },
383 github: {
384 title: 'GitHub Flow',
385 tags: [{ text: 'Simple', class: 'simple' }, { text: 'PR-Centric', class: 'moderate' }],
386 description: 'Simplified workflow centered around pull requests. Branch, commit, PR, discuss, deploy, merge. Perfect for GitHub-hosted projects.',
387 branches: [
388 { name: 'main', class: 'main', commits: ['A', 'B', 'M', 'C', 'M'] },
389 { name: 'feature-1', class: 'feature', commits: ['X', 'Y'] },
390 { name: 'feature-2', class: 'develop', commits: ['Z'] }
391 ],
392 steps: [
393 'Create branch',
394 'Add commits',
395 'Open Pull Request',
396 'Discuss & review',
397 'Deploy to test',
398 'Merge PR'
399 ]
400 }
401 };
402
403 function showWorkflow(type) {
404 // Update buttons
405 document.querySelectorAll('.workflow-btn').forEach(btn => {
406 btn.classList.remove('active');
407 });
408 event.target.classList.add('active');
409
410 const wf = workflows[type];
411 const display = document.getElementById('workflow-display');
412
413 const tagsHtml = wf.tags.map(t =>
414 `<span class="tag ${t.class}">${t.text}</span>`
415 ).join('');
416
417 const branchesHtml = wf.branches.map(b => `
418 <div class="branch-row">
419 <div class="branch-label branch-${b.class}">${b.name}</div>
420 <div class="branch-line">
421 ${b.commits.map(c => `
422 <span class="arrow">←</span>
423 <div class="commit commit-${c === 'M' ? 'merge' : b.class}">${c}</div>
424 `).join('')}
425 </div>
426 </div>
427 `).join('');
428
429 const stepsHtml = wf.steps.map((s, i) => `
430 <div class="step-card">
431 <div class="step-num">Step ${i + 1}</div>
432 <div class="step-text">${s}</div>
433 </div>
434 `).join('');
435
436 display.innerHTML = `444`;
445 }
446
447 // Initialize
448 showWorkflow('feature');
449 </script>
450</body>
451</html>This interactive tool compares Git workflows:
Four Workflows Compared:
Comparison Metrics:
Choosing Your Workflow:
Now that you understand workflows, the next lesson covers rebasing - a powerful technique for maintaining clean, linear Git history. You'll learn when to rebase vs merge and how to use interactive rebasing effectively.
Your progress is saved in this browser, on this device only.