🌳 Git Branching Strategy Crash Course

Master Professional Git Workflows

Lesson 1: Git Basics & Branching Fundamentals

Why Branching Strategy Matters

A solid branching strategy enables teams to work in parallel, maintain stable production code, and release features systematically. Without it, teams face merge conflicts, broken builds, and deployment chaos.

Key Benefit: Branching strategies isolate work, protect production code, and enable continuous delivery.

Understanding Git Branches

A branch is a lightweight movable pointer to a commit. It allows you to diverge from the main line of development and continue work without affecting the main codebase.

# Create a new branch git branch feature/user-authentication # Switch to the branch git checkout feature/user-authentication # Or do both in one command git checkout -b feature/user-authentication # Modern Git (2.23+) git switch -c feature/user-authentication # List all branches git branch -a # Delete a branch git branch -d feature/user-authentication # Force delete (if not merged) git branch -D feature/user-authentication

Basic Branch Types

Branch Type Purpose Naming Convention
Main/Master Production-ready code main or master
Develop Integration branch for features develop or dev
Feature New features or enhancements feature/feature-name
Hotfix Emergency production fixes hotfix/issue-description
Release Prepare for production release release/v1.0.0
Bugfix Non-critical bug fixes bugfix/bug-description

Visualizing Branches

main
──
──
feature/login
──
main
──
← merge feature

Essential Git Commands

# Check current branch git branch --show-current # See branch history git log --oneline --graph --all --decorate # Beautiful visualization git log --graph --pretty=format:'%C(yellow)%h%Creset -%C(red)%d%Creset %s %C(green)(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit # Push new branch to remote git push -u origin feature/user-authentication # Pull latest changes from remote git pull origin develop # Fetch all branches git fetch --all # Track remote branch git branch --set-upstream-to=origin/develop develop

Branch Naming Best Practices

  • Use prefixes: feature/, bugfix/, hotfix/, release/
  • Be descriptive: feature/add-payment-gateway not feature/update
  • Use lowercase: feature/user-auth not Feature/User-Auth
  • Use hyphens: feature/social-login not feature/social_login
  • Include ticket numbers: feature/JIRA-123-user-profile
  • Keep it short: Aim for 2-4 words after prefix
Pro Tip: Set up branch naming conventions in your team documentation and enforce them with Git hooks or CI/CD pipelines.

Common Branching Mistakes

Avoid These:
• Working directly on main/master
• Creating branches from wrong base branch
• Using vague branch names (update, fix, test)
• Keeping branches alive for months
• Not updating branch before merging
• Forgetting to delete merged branches

Test Your Knowledge - Lesson 1

1. What is the purpose of a feature branch?

2. Which command creates and switches to a new branch?

3. What is the best naming convention for a feature branch?

Lesson 2: GitFlow Strategy

What is GitFlow?

GitFlow is a branching model designed by Vincent Driessen. It defines a strict branching model for project releases, making it ideal for projects with scheduled releases.

Best For: Projects with scheduled releases, multiple versions in production, and large teams requiring strict process.

GitFlow Branch Structure

main
──────────────────
── v1.0
hotfix
↑↓
develop
──
──
feature/A
──
feature/B
──

Main Branches (Long-lived)

Branch Purpose Rules
main Production-ready code only Never commit directly, only merge from release/hotfix
develop Integration branch for next release Merge completed features here, always deployable to staging

Supporting Branches (Short-lived)

Branch Type Created From Merged Into Lifespan
feature/* develop develop Days to weeks
release/* develop main + develop Hours to days
hotfix/* main main + develop Minutes to hours

GitFlow Workflow - Feature Development

# 1. Start a new feature git checkout develop git pull origin develop git checkout -b feature/payment-integration # 2. Work on feature (make commits) git add . git commit -m "Add payment API integration" git commit -m "Add payment form UI" git commit -m "Add payment validation" # 3. Keep feature branch updated git checkout develop git pull origin develop git checkout feature/payment-integration git merge develop # Or use rebase for cleaner history git rebase develop # 4. Finish feature (merge to develop) git checkout develop git merge --no-ff feature/payment-integration git push origin develop # 5. Delete feature branch git branch -d feature/payment-integration git push origin --delete feature/payment-integration
The --no-ff Flag: Creates a merge commit even if fast-forward is possible. This preserves feature branch history and makes it easy to revert entire features.

GitFlow Workflow - Release

# 1. Create release branch from develop git checkout develop git pull origin develop git checkout -b release/v1.2.0 # 2. Version bumps and minor fixes only # Update version in package.json, README, etc. git commit -m "Bump version to 1.2.0" git commit -m "Update changelog" git commit -m "Fix typo in documentation" # 3. Merge to main (production) git checkout main git merge --no-ff release/v1.2.0 git tag -a v1.2.0 -m "Version 1.2.0" git push origin main --tags # 4. Merge back to develop (to include release fixes) git checkout develop git merge --no-ff release/v1.2.0 git push origin develop # 5. Delete release branch git branch -d release/v1.2.0 git push origin --delete release/v1.2.0

GitFlow Workflow - Hotfix

# 1. Create hotfix from main git checkout main git pull origin main git checkout -b hotfix/security-patch # 2. Fix the critical bug git commit -m "Fix SQL injection vulnerability" # 3. Merge to main git checkout main git merge --no-ff hotfix/security-patch git tag -a v1.2.1 -m "Hotfix: Security patch" git push origin main --tags # 4. Merge to develop (to include fix in future releases) git checkout develop git merge --no-ff hotfix/security-patch git push origin develop # 5. Delete hotfix branch git branch -d hotfix/security-patch git push origin --delete hotfix/security-patch

GitFlow Advantages

  • Clear structure: Well-defined branch purposes and workflows
  • Parallel development: Multiple features can be developed simultaneously
  • Production stability: Main branch always reflects production
  • Version control: Easy to maintain multiple versions
  • Emergency fixes: Hotfix workflow handles urgent production issues

GitFlow Disadvantages

Challenges:
• Complex for simple projects or continuous deployment
• Long-lived feature branches can cause merge conflicts
• Release branches add overhead for frequent releases
• Not ideal for web apps with single production version
• Requires discipline and clear communication
When to Use GitFlow:
āœ“ Desktop/mobile apps with versioned releases
āœ“ Products supporting multiple versions
āœ“ Scheduled release cycles (monthly, quarterly)
āœ“ Large teams needing strict process
āœ“ Projects requiring extensive QA before release

Test Your Knowledge - Lesson 2

1. In GitFlow, where should feature branches be created from?

2. What is the purpose of the --no-ff flag in git merge?

3. Where should a hotfix branch be merged after fixing a production bug?

Lesson 3: GitHub Flow & Trunk-Based Development

GitHub Flow

GitHub Flow is a lightweight, branch-based workflow perfect for teams practicing continuous deployment. It's simpler than GitFlow and ideal for web applications.

Best For: Web applications, continuous deployment, fast-paced teams, SaaS products.

GitHub Flow Principles

main
──
──
──
feature
──
→ PR → merge

GitHub Flow Workflow

  1. Create a branch: Branch off from main with descriptive name
  2. Add commits: Make changes and commit regularly
  3. Open Pull Request: Request feedback and start discussion
  4. Discuss and review: Team reviews code, suggests changes
  5. Deploy for testing: Deploy from PR branch to test environment
  6. Merge to main: Once approved and tested, merge and deploy
# GitHub Flow Workflow # 1. Always start from updated main git checkout main git pull origin main # 2. Create a branch git checkout -b add-user-profile-page # 3. Make changes and commit git add . git commit -m "Add user profile page component" git commit -m "Add profile edit functionality" git commit -m "Add unit tests for profile page" # 4. Push branch to GitHub git push -u origin add-user-profile-page # 5. Open Pull Request on GitHub # (Done via GitHub web interface) # 6. Address review comments git commit -m "Fix styling issues from review" git push # 7. After approval, merge via GitHub # (Usually done via GitHub UI with "Squash and merge" or "Merge") # 8. Pull latest main locally git checkout main git pull origin main # 9. Delete local branch git branch -d add-user-profile-page

GitHub Flow Key Rules

Golden Rules:
• Main branch is ALWAYS deployable
• Branch names are descriptive
• Pull Requests are mandatory (no direct commits to main)
• CI/CD runs on every PR
• Deploy immediately after merge
• Keep branches short-lived (days, not weeks)

Trunk-Based Development

Developers work in short-lived feature branches (or directly on trunk) and merge frequently to a single branch (trunk/main). Emphasizes small, frequent integrations.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ Trunk-Based Development Flow │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ main (trunk) ā—ā”€ā”€ā”€ā—ā”€ā”€ā”€ā—ā”€ā”€ā”€ā—ā”€ā”€ā”€ā—ā”€ā”€ā”€ā—ā”€ā”€ā”€ā— ↑ ↑ ↑ ↑ │ │ │ │ feature1 ā”€ā”€ā”€ā”€ā”€ā”€ā—ā”€ā”€ā”€ā— │ │ │ │ feature2 ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā—ā”€ā”€ā”€ā— │ │ feature3 ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā— • Features merged multiple times per day • Branches live for hours to 1-2 days max • Feature flags for incomplete features

Trunk-Based Development Workflow

# Trunk-Based Development # 1. Pull latest from trunk git checkout main git pull origin main # 2. Create short-lived branch (optional) git checkout -b quick-fix # 3. Make small, focused change git commit -m "Fix button alignment on homepage" # 4. Push and create PR immediately git push -u origin quick-fix # 5. Get quick review and merge (same day) # Merge via GitHub or: git checkout main git pull origin main git merge quick-fix git push origin main # 6. Delete branch immediately git branch -d quick-fix git push origin --delete quick-fix # Alternative: Commit directly to trunk (for very small changes) git checkout main git pull origin main # Make change git commit -m "Update copyright year" git push origin main

Feature Flags with Trunk-Based

Use feature flags to merge incomplete features without exposing them to users.

// Example: Feature flag in code const FEATURES = { newCheckoutFlow: process.env.FEATURE_NEW_CHECKOUT === 'true' }; function renderCheckout() { if (FEATURES.newCheckoutFlow) { return ; // Work in progress } return ; // Stable version } // Deploy to production with flag OFF // Enable flag when feature is complete // Gradually roll out: 10% users → 50% → 100% // Remove flag and old code after successful rollout

Comparison: GitHub Flow vs Trunk-Based

Aspect GitHub Flow Trunk-Based Development
Branch lifespan Days to 1-2 weeks Hours to 1-2 days
Merge frequency Multiple times per week Multiple times per day
Feature flags Optional Essential
Code review Always via PR PR or pair programming
CI/CD maturity Moderate to High High (required)
Team size Any size Works best with small to medium teams

Benefits of Simpler Workflows

  • Faster delivery: Features reach production quickly
  • Fewer conflicts: Frequent merges reduce merge hell
  • Easier to learn: Simple process for new team members
  • Always deployable: Main branch is production-ready
  • Better for CI/CD: Aligns with continuous deployment
Requirements:
• Strong CI/CD pipeline with automated tests
• Fast test suite (under 10 minutes)
• Team discipline and communication
• Ability to roll back quickly
• Monitoring and alerting in production

Test Your Knowledge - Lesson 3

1. In GitHub Flow, which branch should always be deployable?

2. What is the maximum recommended lifespan for branches in Trunk-Based Development?

3. Why are feature flags important in Trunk-Based Development?

Lesson 4: Release Management & Tagging

Semantic Versioning

Semantic Versioning (SemVer) is a versioning scheme that conveys meaning about the underlying changes. Format: MAJOR.MINOR.PATCH

Version Format: MAJOR.MINOR.PATCH (e.g., 2.4.1)
• MAJOR: Breaking changes (incompatible API changes)
• MINOR: New features (backward-compatible)
• PATCH: Bug fixes (backward-compatible)
# Semantic Versioning Examples 1.0.0 → Initial release 1.0.1 → Bug fix (patch) 1.1.0 → New feature, backward-compatible (minor) 2.0.0 → Breaking change (major) # Pre-release versions 1.0.0-alpha.1 → Alpha release 1.0.0-beta.2 → Beta release 1.0.0-rc.1 → Release candidate # Build metadata 1.0.0+20130313144700 1.0.0-beta+exp.sha.5114f85

Git Tags

Tags are references that point to specific commits. Use them to mark release points (v1.0, v2.0, etc.).

# Create annotated tag (recommended) git tag -a v1.0.0 -m "Release version 1.0.0" # Create lightweight tag git tag v1.0.0 # Tag specific commit git tag -a v1.0.0 9fceb02 -m "Release version 1.0.0" # List all tags git tag git tag -l "v1.*" # Show tag information git show v1.0.0 # Push tag to remote git push origin v1.0.0 # Push all tags git push origin --tags # Delete local tag git tag -d v1.0.0 # Delete remote tag git push origin --delete v1.0.0 # Checkout specific tag git checkout v1.0.0

Release Workflow

# Complete Release Process # 1. Prepare release git checkout develop git pull origin develop git checkout -b release/v1.5.0 # 2. Update version numbers # Update package.json, version files, changelogs git commit -m "Bump version to 1.5.0" # 3. Run final tests npm test npm run build # 4. Merge to main git checkout main git pull origin main git merge --no-ff release/v1.5.0 # 5. Tag the release git tag -a v1.5.0 -m "Release version 1.5.0 New Features: - User authentication - Password reset - Email notifications Bug Fixes: - Fix login redirect issue - Fix mobile responsiveness Breaking Changes: - API endpoint /api/user changed to /api/users" # 6. Push to remote git push origin main git push origin v1.5.0 # 7. Merge back to develop git checkout develop git merge --no-ff release/v1.5.0 git push origin develop # 8. Clean up git branch -d release/v1.5.0 # 9. Create GitHub Release # Go to GitHub → Releases → Draft new release # Select tag, add release notes, attach binaries if needed

Changelog Management

Keep a CHANGELOG.md file to track all notable changes in each version.

# CHANGELOG.md # Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). ## [Unreleased] ### Added - New feature in development ## [1.5.0] - 2024-03-15 ### Added - User authentication system - Password reset functionality - Email notification service ### Changed - Updated API endpoint structure - Improved error handling ### Fixed - Login redirect issue - Mobile responsiveness on profile page ### Security - Fixed SQL injection vulnerability ## [1.4.2] - 2024-02-28 ### Fixed - Critical bug in payment processing - Memory leak in image upload ## [1.4.1] - 2024-02-20 ### Fixed - Minor UI glitches - Typos in error messages

Release Strategies

Strategy Description Best For
Scheduled Releases Fixed intervals (weekly, monthly) Enterprise software, mobile apps
Feature-Based Release when feature is complete Product development
Continuous Deployment Every merge to main triggers deployment SaaS, web applications
Canary Releases Gradual rollout to small user percentage High-traffic applications
Blue-Green Two identical environments, switch traffic Zero-downtime deployments

Automated Release Tools

# semantic-release (automated versioning & changelog) npm install --save-dev semantic-release # .releaserc.json { "branches": ["main"], "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", "@semantic-release/changelog", "@semantic-release/npm", "@semantic-release/github", "@semantic-release/git" ] } # Commit message format (Conventional Commits) feat: add user authentication fix: resolve login redirect issue docs: update API documentation chore: update dependencies BREAKING CHANGE: change API endpoint structure # Release runs automatically on CI/CD # Analyzes commits, bumps version, generates changelog, creates tag

Release Checklist

Before Every Release:
ā˜‘ All tests passing
ā˜‘ Code reviewed and approved
ā˜‘ Version numbers updated
ā˜‘ Changelog updated
ā˜‘ Documentation updated
ā˜‘ Database migrations tested
ā˜‘ Deployment scripts verified
ā˜‘ Rollback plan prepared
ā˜‘ Stakeholders notified
ā˜‘ Monitoring alerts configured
Common Release Mistakes:
• Forgetting to update version numbers
• Not testing on production-like environment
• Missing database migrations
• No rollback plan
• Poor communication with team
• Releasing on Friday afternoon

Test Your Knowledge - Lesson 4

1. In Semantic Versioning (1.2.3), what does the "2" represent?

2. What command creates an annotated Git tag?

3. Which file is commonly used to track version changes?

Lesson 5: Merge Strategies & Conflict Resolution

Git Merge Strategies

Understanding different merge strategies helps you maintain clean history and resolve conflicts effectively.

1. Merge Commit (Default)

# Creates a merge commit git checkout main git merge feature-branch # With --no-ff (no fast-forward) git merge --no-ff feature-branch # Pros: # āœ“ Preserves complete history # āœ“ Shows when feature was integrated # āœ“ Easy to revert entire feature # Cons: # āœ— Creates merge commits (can clutter history) # āœ— Non-linear history

2. Fast-Forward Merge

# Fast-forward (if possible) git checkout main git merge feature-branch # Force fast-forward (fails if not possible) git merge --ff-only feature-branch # Pros: # āœ“ Linear history # āœ“ No merge commits # āœ“ Clean, simple history # Cons: # āœ— Loses information about feature branches # āœ— Harder to revert features

3. Rebase

# Rebase feature onto main git checkout feature-branch git rebase main # Interactive rebase (squash, reorder, edit commits) git rebase -i main # After rebase, force push (if already pushed) git push --force-with-lease # Pros: # āœ“ Linear, clean history # āœ“ No merge commits # āœ“ Easy to follow # Cons: # āœ— Rewrites history (dangerous on shared branches) # āœ— Can be confusing for beginners # āœ— Loses merge context
āš ļø Golden Rule of Rebasing:
Never rebase commits that have been pushed to a shared/public branch!
Only rebase local commits or your own feature branches.

4. Squash and Merge

# Squash all commits into one git checkout main git merge --squash feature-branch git commit -m "Add user authentication feature" # Or via GitHub UI: "Squash and merge" button # Pros: # āœ“ Clean, linear history # āœ“ One commit per feature # āœ“ Easy to revert # Cons: # āœ— Loses individual commit history # āœ— Makes it harder to find specific changes

Merge Strategy Comparison

Strategy History Use Case Revert
Merge Commit Non-linear GitFlow, preserving context Easy (revert merge)
Fast-Forward Linear Small changes, simple workflows Hard (revert individual commits)
Rebase Linear Feature branches, clean history Hard (commits rewritten)
Squash Linear GitHub Flow, one feature = one commit Easy (revert single commit)

Handling Merge Conflicts

Conflicts occur when Git can't automatically merge changes. Here's how to resolve them:

# Attempt merge git merge feature-branch # Output: CONFLICT (content): Merge conflict in file.js # 1. Check status git status # Shows: both modified: file.js # 2. Open conflicted file # You'll see conflict markers: <<<<<<< HEAD current branch code ======= incoming branch code >>>>>>> feature-branch # 3. Resolve conflict manually # Edit file to desired state, remove markers # 4. Mark as resolved git add file.js # 5. Complete merge git commit -m "Merge feature-branch, resolve conflicts in file.js" # Or abort merge git merge --abort

Conflict Resolution Tools

# Use merge tool git mergetool # Configure merge tool (VS Code) git config --global merge.tool vscode git config --global mergetool.vscode.cmd 'code --wait $MERGED' # Other popular merge tools: # - Beyond Compare # - KDiff3 # - P4Merge # - Meld # View conflicts in diff format git diff # Accept all changes from one side git checkout --ours file.js # Keep current branch git checkout --theirs file.js # Take incoming branch

Preventing Merge Conflicts

  • Merge frequently: Sync with main/develop daily
  • Keep branches small: Short-lived branches have fewer conflicts
  • Communicate: Coordinate when working on same files
  • Pull before push: Always pull latest changes first
  • Modular code: Well-separated concerns reduce overlapping changes
  • Use .gitattributes: Define merge strategies for specific files

Advanced: Custom Merge Strategies

# .gitattributes - Custom merge strategies # Always use ours for specific files database.lock merge=ours # Always use theirs config.generated merge=theirs # Binary files *.png binary *.jpg binary # Configure custom merge driver git config --global merge.ours.driver true git config --global merge.theirs.driver "git checkout-index -f --stage=3 %A"

Rebase vs Merge: When to Use What

Use Merge When:
āœ“ Working on public/shared branches
āœ“ Need to preserve exact history
āœ“ Following GitFlow
āœ“ Want to see when features were integrated
Use Rebase When:
āœ“ Cleaning up local commits before pushing
āœ“ Want linear history
āœ“ Updating feature branch with latest main
āœ“ Working on your own feature branch

Interactive Rebase Example

# Clean up last 3 commits git rebase -i HEAD~3 # Interactive menu: pick abc1234 Add login form pick def5678 Fix typo pick ghi9012 Update styles # Change to: pick abc1234 Add login form squash def5678 Fix typo squash ghi9012 Update styles # Result: One clean commit with all changes # Other rebase commands: # pick - keep commit # reword - change commit message # edit - stop to amend commit # squash - combine with previous # fixup - like squash but discard message # drop - remove commit

Test Your Knowledge - Lesson 5

1. What is the golden rule of rebasing?

2. What does "Squash and merge" do?

3. How do you abort a merge that has conflicts?

Lesson 6: Best Practices & Team Workflows

Commit Best Practices

Good commits are the foundation of effective version control and collaboration.

Writing Good Commit Messages

# Conventional Commits Format ():
# Types: feat: New feature fix: Bug fix docs: Documentation changes style: Code style (formatting, no logic change) refactor: Code restructuring (no behavior change) perf: Performance improvement test: Add or update tests chore: Build, dependencies, tooling ci: CI/CD changes revert: Revert previous commit # Examples: feat(auth): add OAuth2 login support fix(api): resolve race condition in user creation docs(readme): update installation instructions refactor(utils): simplify date formatting logic # Good commit message: git commit -m "fix(checkout): prevent duplicate order submission Added request deduplication to prevent users from accidentally submitting orders multiple times by double-clicking the submit button. Fixes #432" # Bad commit messages: git commit -m "fixed stuff" git commit -m "updates" git commit -m "asdf" git commit -m "WIP"

Atomic Commits

Atomic Commit Principle: Each commit should be a single, complete unit of change.

āœ“ Makes code review easier
āœ“ Simplifies reverting changes
āœ“ Improves git bisect effectiveness
āœ“ Creates clear project history
# Bad: Multiple unrelated changes in one commit git add authentication.js payment.js homepage.css git commit -m "various updates" # Good: Separate commits for separate concerns git add authentication.js git commit -m "feat(auth): add two-factor authentication" git add payment.js git commit -m "fix(payment): resolve Stripe webhook timeout" git add homepage.css git commit -m "style(home): update hero section layout" # Stage parts of a file git add -p filename.js

Branch Protection Rules

Protect important branches from accidental or malicious changes.

# GitHub Branch Protection Rules (via Settings > Branches) āœ“ Require pull request reviews before merging - Number of required approvals: 2 - Dismiss stale reviews when new commits are pushed - Require review from Code Owners āœ“ Require status checks to pass before merging - Require branches to be up to date - Status checks: CI/CD, tests, linting āœ“ Require conversation resolution before merging āœ“ Require signed commits āœ“ Include administrators (enforce rules on admins too) āœ“ Restrict who can push to matching branches āœ“ Allow force pushes: Never āœ“ Allow deletions: Never

Pull Request Best Practices

Practice Description Benefit
Small PRs Under 400 lines changed Faster reviews, fewer bugs
Descriptive titles Clear summary of changes Easy to understand at a glance
Complete description Context, testing, screenshots Reviewers understand the why
Link issues Reference related tickets Traceability
Self-review first Review your own code before requesting Catch obvious issues
Request specific reviewers Tag domain experts Better quality reviews

PR Template Example

# .github/pull_request_template.md ## Description Brief summary of changes ## Type of Change - [ ] Bug fix (non-breaking change) - [ ] New feature (non-breaking change) - [ ] Breaking change - [ ] Documentation update ## Related Issues Fixes #(issue number) ## How Has This Been Tested? - [ ] Unit tests - [ ] Integration tests - [ ] Manual testing ## Checklist - [ ] My code follows the project style guidelines - [ ] I have performed a self-review - [ ] I have commented my code where necessary - [ ] I have updated the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix/feature works - [ ] New and existing tests pass locally - [ ] Any dependent changes have been merged ## Screenshots (if applicable) [Add screenshots here]

Code Review Guidelines

As a Reviewer:
āœ“ Be constructive and kind
āœ“ Ask questions, don't demand
āœ“ Explain the "why" behind suggestions
āœ“ Praise good solutions
āœ“ Distinguish between blocking and non-blocking comments
āœ“ Review within 24 hours
āœ“ Focus on code, not the person
As a PR Author:
āœ“ Respond to all comments
āœ“ Don't take feedback personally
āœ“ Ask for clarification if needed
āœ“ Mark conversations as resolved
āœ“ Thank reviewers
āœ“ Update PR based on feedback

Git Hooks for Automation

# .git/hooks/pre-commit #!/bin/bash # Run linter before commit npm run lint if [ $? -ne 0 ]; then echo "āŒ Linting failed. Please fix errors before committing." exit 1 fi npm test if [ $? -ne 0 ]; then echo "āŒ Tests failed. Please fix tests before committing." exit 1 fi echo "āœ… Pre-commit checks passed!" # Make executable chmod +x .git/hooks/pre-commit # Use Husky for easier hook management npm install --save-dev husky npx husky install npx husky add .git/hooks/pre-commit "npm run lint && npm test"

Team Workflow Example

# Complete Team Workflow # 1. Pick up ticket from board (Jira, GitHub Issues) # Status: To Do → In Progress # 2. Create feature branch git checkout main git pull origin main git checkout -b feature/JIRA-123-user-dashboard # 3. Make changes with atomic commits git commit -m "feat(dashboard): add dashboard layout" git commit -m "feat(dashboard): add user stats widget" git commit -m "test(dashboard): add dashboard component tests" # 4. Keep branch updated git fetch origin main git rebase origin/main # 5. Push to remote git push -u origin feature/JIRA-123-user-dashboard # 6. Create Pull Request on GitHub # - Add description # - Link to JIRA-123 # - Request 2 reviewers # - Add labels # 7. Address review comments git commit -m "refactor(dashboard): extract stats logic per review" git push # 8. Merge after approval # Use "Squash and merge" on GitHub # 9. Delete branch git checkout main git pull origin main git branch -d feature/JIRA-123-user-dashboard # 10. Update ticket status # Status: In Review → Done

Monorepo vs Polyrepo

Aspect Monorepo Polyrepo
Structure All projects in one repo One repo per project
Code sharing Easy (import directly) Via packages/libraries
Atomic changes Yes (one commit, multiple projects) No (multiple PRs needed)
CI/CD Complex (build only changed) Simple (one pipeline per repo)
Access control Difficult (all or nothing) Easy (per repo)
Examples Google, Facebook, Twitter Most companies

Essential Git Configuration

# User information git config --global user.name "Your Name" git config --global user.email "your.email@example.com" # Default editor git config --global core.editor "code --wait" # Default branch name git config --global init.defaultBranch main # Auto-correct typos git config --global help.autocorrect 1 # Better diffs git config --global diff.algorithm histogram # Prune on fetch git config --global fetch.prune true # Reuse recorded conflict resolutions git config --global rerere.enabled true # Better log output git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit" # Show branch in prompt (add to .bashrc or .zshrc) parse_git_branch() { git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/' } export PS1="\u@\h \W \[\033[32m\]\$(parse_git_branch)\[\033[00m\] $ "
Final Tips for Success:
• Document your team's workflow in README
• Automate everything possible (hooks, CI/CD)
• Review and improve workflow regularly
• Prioritize communication over process
• Keep it simple - don't over-engineer
• Train new team members thoroughly
• Use visual tools (GitKraken, SourceTree) if helpful

Test Your Knowledge - Lesson 6

1. What is an atomic commit?

2. What is the recommended maximum lines changed in a Pull Request?

3. What do Git hooks allow you to do?