🔀 Week 3: Git & GitHub Mastery

Day 2: Branching & Merging - branch, checkout, merge, conflicts

Duration: 5 Hours

📚 Learning Objectives

By the end of this session, you will be able to:

  • Understand branching concepts and why they matter
  • Create, switch, and delete branches
  • Merge branches using different strategies
  • Resolve merge conflicts confidently
  • Apply branching strategies used in DevOps

📖 Core Concepts (2 Hours)

What are Branches?

Branches are independent lines of development. They let you work on features, fixes, or experiments without affecting the main codebase. Think of them as parallel universes for your code.

  • Why branches? Isolate work, parallel development, safe experimentation
  • main/master: The primary branch, always deployable
  • Feature branches: Temporary branches for specific work
  • HEAD: Pointer to current branch/commit you're working on

Branch Visualization

# Starting point - linear history main: A---B---C # Create feature branch main: A---B---C \ feature: D---E # After merging main: A---B---C-------F (merge commit) \ / feature: D---E---/

git branch - Manage Branches

# List all local branches git branch # * main (* indicates current branch) # feature-login # List all branches (including remote) git branch -a # List branches with last commit info git branch -v # Create a new branch git branch feature-login # Create and switch in one command git checkout -b feature-login # OR (newer syntax) git switch -c feature-login # Rename a branch git branch -m old-name new-name git branch -m new-name # Rename current branch # Delete a branch (safe - won't delete unmerged) git branch -d feature-login # Force delete (even if unmerged) git branch -D feature-login

git checkout / git switch - Change Branches

# Switch to existing branch git checkout main git checkout feature-login # Modern syntax (Git 2.23+) git switch main git switch feature-login # Create and switch to new branch git checkout -b new-feature git switch -c new-feature # Switch to previous branch git checkout - git switch - # Checkout specific commit (detached HEAD) git checkout abc1234 # Warning: You're in 'detached HEAD' state # Get back to branch git checkout main

Working with Branches

# See which branch you're on git branch git status # See branch in prompt (add to ~/.bashrc) PS1='[\u@\h \W$(git branch 2>/dev/null | grep "^*" | cut -d" " -f2 | sed "s/^/ (/;s/$/)/")]\$ ' # Compare branches git diff main..feature-login git log main..feature-login # Commits in feature not in main # See if branch is merged git branch --merged # Branches merged into current git branch --no-merged # Branches not yet merged

git merge - Combine Branches

# Basic merge workflow # 1. Switch to target branch (usually main) git checkout main # 2. Merge feature branch into main git merge feature-login # Types of merges: # Fast-forward merge (linear history) # When main hasn't changed since branch was created git merge feature-login # Updating abc123..def456 # Fast-forward # Three-way merge (merge commit) # When both branches have new commits git merge feature-login # Creates a new "merge commit" # Merge with commit message git merge feature-login -m "Merge feature-login into main" # No fast-forward (always create merge commit) git merge --no-ff feature-login # Abort a merge in progress git merge --abort

Merge Conflicts

# Conflicts happen when same lines changed in both branches # Git marks conflicts in files like this: <<<<<<< HEAD This is the content from main branch ======= This is the content from feature branch >>>>>>> feature-login # To resolve: # 1. Open the file # 2. Decide which content to keep (or combine) # 3. Remove the conflict markers (<<<<, ====, >>>>) # 4. Save the file # 5. Stage the resolved file git add resolved-file.txt # 6. Complete the merge git commit # See files with conflicts git status # Use merge tool git mergetool # Abort and start over git merge --abort

Resolving Conflicts - Example

# Original conflict in config.txt: <<<<<<< HEAD DEBUG=false LOG_LEVEL=info ======= DEBUG=true LOG_LEVEL=debug >>>>>>> feature-debug # After resolution (keeping debug settings for development): DEBUG=true LOG_LEVEL=debug # Or combining both: DEBUG=false LOG_LEVEL=info # Development settings (uncomment to enable): # DEBUG=true # LOG_LEVEL=debug # Then complete the merge: git add config.txt git commit -m "Merge feature-debug, keep production settings"

git rebase - Alternative to Merge

# Rebase replays commits on top of another branch # Creates linear history (cleaner than merge commits) # Before rebase: main: A---B---C \ feature: D---E # Rebase feature onto main git checkout feature git rebase main # After rebase: main: A---B---C \ feature: D'---E' # Then fast-forward merge git checkout main git merge feature # Fast-forward! # Interactive rebase (edit, squash, reorder commits) git rebase -i HEAD~3 # Last 3 commits git rebase -i main # All commits since branching # Abort rebase git rebase --abort # Continue after resolving conflicts git rebase --continue # WARNING: Never rebase public/shared branches!

Branching Strategies for DevOps

# Git Flow (Traditional) main ─────────────────────────── (production) \ / hotfix └──fix──┘ / \ / release └────────────────/ \ / develop ───────────────────────────── \ \ / feature └─────────└─────/ # GitHub Flow (Simpler, CI/CD friendly) main ───────────────────────────── \ \ / / feature └──────└────────/──────/ # Trunk-Based Development (DevOps preferred) main ───────────────────────────── \ / \ / \ / \ / feature └/ └/ └/ └/ (short-lived branches, frequent merges)

Common Branch Naming Conventions

# Feature branches feature/user-authentication feature/add-dashboard feat/JIRA-123-login-page # Bug fixes bugfix/fix-login-error fix/null-pointer-exception hotfix/security-patch # Release branches release/v1.0.0 release/2024-Q1 # Other common patterns docs/update-readme refactor/cleanup-api test/add-unit-tests chore/update-dependencies

🔬 Hands-on Lab (2.5 Hours)

Lab 1: Basic Branch Operations

  • Create a new branch
  • Make commits on the branch
  • Switch between branches
# Lab 1: Branch basics cd ~/git-practice # Make sure main is up to date git checkout main git log --oneline # Create and switch to feature branch git checkout -b feature/add-docs # Verify you're on new branch git branch git status # Create documentation mkdir docs cat > docs/INSTALL.md << 'EOF' # Installation Guide ## Prerequisites - Git 2.x or higher - Bash shell ## Steps 1. Clone the repository 2. Run setup script 3. Verify installation EOF # Commit on feature branch git add docs/ git commit -m "Add installation documentation" # Make another commit cat > docs/USAGE.md << 'EOF' # Usage Guide ## Basic Commands - `./hello.sh` - Run greeting script - `cat config.txt` - View configuration EOF git add docs/USAGE.md git commit -m "Add usage documentation" # View branch history git log --oneline # Switch back to main git checkout main # Notice docs/ folder is gone! ls # Switch back to feature git checkout feature/add-docs ls docs/

Lab 2: Merging Branches

  • Perform a fast-forward merge
  • Perform a three-way merge
  • View merge history
# Lab 2: Merging cd ~/git-practice # Merge feature into main git checkout main git merge feature/add-docs # This was a fast-forward merge # Check history git log --oneline --graph # Now let's create a situation for 3-way merge # Create another feature branch git checkout -b feature/improve-readme # Modify README echo "" >> README.md echo "## New Features" >> README.md echo "- Documentation added" >> README.md git add README.md git commit -m "Update README with features section" # Switch to main and make different changes git checkout main echo "" >> README.md echo "## License" >> README.md echo "MIT License" >> README.md git add README.md git commit -m "Add license to README" # Now merge feature branch (3-way merge needed) git merge feature/improve-readme -m "Merge feature/improve-readme" # View the merge graph git log --oneline --graph -10 # Clean up merged branch git branch -d feature/add-docs git branch -d feature/improve-readme

Lab 3: Resolving Merge Conflicts

  • Create conflicting changes
  • Understand conflict markers
  • Resolve conflicts manually
# Lab 3: Conflict resolution cd ~/git-practice # Create a branch for experiments git checkout -b feature/update-config # Modify config on feature branch cat > config.txt << 'EOF' APP_NAME=GitPractice VERSION=2.0 DEBUG=true LOG_LEVEL=debug AUTHOR=YourName EOF git add config.txt git commit -m "Update config for development" # Switch to main and make conflicting change git checkout main cat > config.txt << 'EOF' APP_NAME=GitPractice VERSION=1.5 DEBUG=false LOG_LEVEL=warning AUTHOR=YourName EOF git add config.txt git commit -m "Update config for production" # Try to merge - CONFLICT! git merge feature/update-config # CONFLICT (content): Merge conflict in config.txt # Check status git status # View the conflict cat config.txt # You'll see <<<<<<< HEAD, =======, >>>>>>> markers # Resolve the conflict (edit the file) cat > config.txt << 'EOF' APP_NAME=GitPractice VERSION=2.0 DEBUG=false LOG_LEVEL=info AUTHOR=YourName # Dev settings: DEBUG=true, LOG_LEVEL=debug EOF # Stage the resolved file git add config.txt # Complete the merge git commit -m "Merge feature/update-config, balance dev/prod settings" # Verify git log --oneline --graph -5 cat config.txt

Lab 4: Branching Workflow Simulation

  • Simulate a real development workflow
  • Work on multiple features simultaneously
  • Practice branch management
# Lab 4: Real workflow simulation cd ~/git-practice # Start fresh on main git checkout main # Developer A starts feature-login git checkout -b feature/login cat > src/login.sh << 'EOF' #!/bin/bash echo "=== Login System ===" read -p "Username: " user read -sp "Password: " pass echo "" if [[ "$user" == "admin" && "$pass" == "secret" ]]; then echo "Welcome, $user!" else echo "Invalid credentials" fi EOF chmod +x src/login.sh git add src/login.sh git commit -m "Add basic login script" # Developer B starts feature-backup (from main) git checkout main git checkout -b feature/backup cat > src/backup.sh << 'EOF' #!/bin/bash echo "=== Backup System ===" BACKUP_DIR="./backups/$(date +%Y%m%d)" mkdir -p "$BACKUP_DIR" cp -r config.txt "$BACKUP_DIR/" echo "Backup created in $BACKUP_DIR" EOF chmod +x src/backup.sh git add src/backup.sh git commit -m "Add backup script" # Meanwhile, Developer A finishes and merges git checkout main git merge feature/login -m "Merge feature/login" # Developer B finishes and merges git merge feature/backup -m "Merge feature/backup" # View final state git log --oneline --graph -10 ls src/ # Clean up git branch -d feature/login git branch -d feature/backup git branch # Only main should remain

📝 Practice Exercises (30 Minutes)

  1. Create a branch called feature/your-name and add a personal script
  2. Practice creating and resolving a merge conflict intentionally
  3. Use git log --graph to visualize your branch history
  4. Try rebasing a feature branch onto main
  5. Delete all merged branches and verify with git branch

✅ Day 2 Checklist

  • Understand why branches are useful
  • Can create branches (git branch, git checkout -b)
  • Can switch between branches (git checkout, git switch)
  • Can merge branches (git merge)
  • Can resolve merge conflicts
  • Understand fast-forward vs three-way merge
  • Know basic branching strategies
  • Can delete merged branches