Advanced Git: Mastering Power Tools and Recovery Techniques

Interactive Rebase: Rewriting History Like a Time Lord

Interactive rebase is like having a time machine that lets you reorganize, edit, and clean up your commit history before sharing it with others.

Interactive Rebase Commands

git rebase -i HEAD~5  # Rebase last 5 commits

# This opens your editor with:
pick abc123 Add feature
pick def456 WIP
pick ghi789 Fix typo
pick jkl012 More WIP
pick mno345 Final fix

# Change to:
pick abc123 Add feature
squash def456 WIP          # Combine with previous
fixup ghi789 Fix typo      # Combine, discard message
squash jkl012 More WIP
reword mno345 Final fix    # Change commit message
        
Command Action Use Case
pick Use commit as-is Keep good commits
reword Change commit message Fix typos or clarify
edit Stop to amend commit Add forgotten files
squash Combine with previous, keep messages Group related changes
fixup Combine with previous, discard message Hide "oops" commits
drop Remove commit entirely Delete unwanted changes

Git Bisect: Binary Search for Bugs

Git bisect is like playing "20 questions" with your code to find exactly when a bug was introduced.

graph LR A[Good: v1.0] --> B[?] B --> C[?] C --> D[?] D --> E[?] E --> F[?] F --> G[Bad: Current] B -.Test.-> B1[Good ✓] D -.Test.-> D1[Bad ✗] C -.Test.-> C1[Bad ✗] style A fill:#9f9,stroke:#333,stroke-width:2px style G fill:#f99,stroke:#333,stroke-width:2px style C fill:#faa,stroke:#333,stroke-width:2px style D fill:#faa,stroke:#333,stroke-width:2px

Bisect Workflow Example: Finding When Tests Broke

# Start bisecting
git bisect start
git bisect bad                  # Current version is broken
git bisect good v1.0            # v1.0 was working

# Git checks out a commit in the middle
# You test it...
npm test                        # Run your tests

# Tell git the result
git bisect bad                  # This commit is also broken

# Git narrows it down, checks out another
npm test
git bisect good                 # This one works!

# Continue until git finds the exact commit
Bisecting: 0 revisions left to test
b47c3a2 is the first bad commit

# Clean up
git bisect reset
            

Automated Bisect with Scripts

# Create a test script
echo 'npm test | grep "passing"' > test.sh
chmod +x test.sh

# Let git automatically find the bad commit
git bisect start HEAD v1.0
git bisect run ./test.sh

# Git will automatically test each commit!
        

Git Reflog: Your Safety Net

The reflog is like a flight recorder for your repository - it tracks every move you make, even "lost" commits!

Recovering "Lost" Work

# View the reflog
git reflog
abc123 HEAD@{0}: reset: moving to HEAD~3
def456 HEAD@{1}: commit: Important feature I accidentally deleted!
ghi789 HEAD@{2}: commit: Another commit

# Recover the "lost" commit
git checkout def456        # View the lost commit
git branch recovered-work  # Create branch from it

# Or restore directly
git reset --hard HEAD@{1}  # Go back to that state
        

Git Hooks: Automation at Every Step

Git hooks are like security checkpoints or automatic tasks that run at specific moments in your Git workflow.

graph TD A[Developer Action] --> B{Git Hook Triggers} B --> C[pre-commit
Before commit] B --> D[commit-msg
Validate message] B --> E[pre-push
Before push] B --> F[post-merge
After merge] C --> G[Run Tests] C --> H[Format Code] D --> I[Check Message Format] E --> J[Run Full Test Suite] F --> K[Install Dependencies] style B fill:#f96,stroke:#333,stroke-width:3px

Common Hook Examples

Pre-commit Hook: Auto-format Code

#!/bin/sh
# .git/hooks/pre-commit

# Format all JavaScript files
files=$(git diff --cached --name-only --diff-filter=ACM | grep '\.js$')
if [ "$files" != "" ]; then
    echo "Formatting JavaScript files..."
    npx prettier --write $files
    git add $files
fi

# Run linter
echo "Running ESLint..."
npx eslint . || exit 1

echo "✅ Pre-commit checks passed!"
            

Commit-msg Hook: Enforce Conventional Commits

#!/bin/sh
# .git/hooks/commit-msg

commit_regex='^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?: .{1,50}'

if ! grep -qE "$commit_regex" "$1"; then
    echo "❌ Invalid commit message format!"
    echo "📝 Format: type(scope): description"
    echo "Example: feat(auth): add login functionality"
    exit 1
fi
            

Advanced Reset and Checkout Strategies

When to Use Each Reset Mode

Reset Type Changes Use Case Example
--soft Only moves HEAD Undo commits but keep changes staged Combining multiple commits
--mixed (default) Moves HEAD and clears staging Undo commits and unstage Start over with staging
--hard Discards all changes Complete reset to previous state Abandon all work

Git Stash: Your Quick Save Feature

Stash is like pressing pause on your current work to handle something urgent, then resuming exactly where you left off.

sequenceDiagram participant WD as Working Directory participant S as Stash Stack participant B as Different Branch WD->>S: git stash (save work) Note over WD: Clean working directory WD->>B: git checkout urgent-fix Note over B: Fix critical bug B->>WD: git checkout original-branch S->>WD: git stash pop (restore work) Note over WD: Continue where you left off

Advanced Stash Techniques

# Save with a descriptive message
git stash push -m "WIP: new authentication flow"

# Stash only specific files
git stash push -m "navbar changes" -- src/navbar.js src/navbar.css

# List all stashes
git stash list
stash@{0}: On main: WIP: new authentication flow
stash@{1}: On feature: navbar changes
stash@{2}: WIP on feature: 3a4b5c6 Previous commit

# Apply specific stash without removing it
git stash apply stash@{1}

# Create branch from stash
git stash branch new-feature-branch stash@{0}

# Show stash contents
git stash show -p stash@{0}

# Clear all stashes (careful!)
git stash clear
        

Submodules: Projects Within Projects

Submodules let you include other Git repositories within your project, perfect for shared libraries or components.

Working with Submodules

# Add a submodule
git submodule add https://github.com/company/shared-ui.git libs/ui
git commit -m "Add UI library submodule"

# Clone a project with submodules
git clone --recurse-submodules https://github.com/user/project.git

# Or initialize after cloning
git submodule init
git submodule update

# Update all submodules to latest
git submodule update --remote --merge

# Work within a submodule
cd libs/ui
git checkout main
git pull origin main
cd ../..
git add libs/ui
git commit -m "Update UI library to latest version"
        

Recovery Scenarios: Fixing Common Disasters

🆘 Scenario 1: Accidentally Deleted a Branch

# Oh no! Deleted important branch
git branch -D feature-important

# Don't panic! Check reflog
git reflog
abc123 HEAD@{5}: checkout: moving from feature-important to main

# Recreate the branch
git branch feature-important abc123
✅ Branch recovered!
            

🆘 Scenario 2: Committed to Wrong Branch

# Made commits to main instead of feature branch

# Create new branch with the commits
git branch feature-branch

# Reset main back (keep changes in working directory)
git reset --soft HEAD~3

# Or reset hard if you want to discard
git reset --hard origin/main

# Switch to feature branch with your commits
git checkout feature-branch
            

🆘 Scenario 3: Need to Undo a Merge

# Option 1: If haven't pushed yet
git reset --hard HEAD~1

# Option 2: If already pushed (creates new commit)
git revert -m 1 HEAD

# Option 3: Find pre-merge state
git reflog
git reset --hard HEAD@{2}
            

Git Worktrees: Multiple Working Directories

Worktrees let you have multiple branches checked out simultaneously in different directories - perfect for quick bug fixes!

graph TD A[Main Repository
.git] --> B[main branch
./project] A --> C[feature branch
./project-feature] A --> D[hotfix branch
./project-hotfix] style A fill:#f96,stroke:#333,stroke-width:3px style B fill:#9f9,stroke:#333,stroke-width:2px style C fill:#99f,stroke:#333,stroke-width:2px style D fill:#f99,stroke:#333,stroke-width:2px
# Add a new worktree for a hotfix
git worktree add ../project-hotfix hotfix-branch

# List all worktrees
git worktree list
/home/user/project         abc123 [main]
/home/user/project-hotfix  def456 [hotfix-branch]

# Work in different directories simultaneously!
cd ../project-hotfix
# Fix bug here while feature work continues in main directory

# Remove worktree when done
git worktree remove ../project-hotfix
        

Performance Optimization for Large Repositories

Techniques for Faster Git Operations

1. Shallow Clones

# Clone only recent history
git clone --depth 1 https://github.com/large/repo.git

# Get more history later if needed
git fetch --deepen=100
            

2. Partial Clones

# Clone without blobs initially
git clone --filter=blob:none https://github.com/large/repo.git

# Clone only specific paths
git clone --filter=blob:none --sparse https://github.com/large/repo.git
cd repo
git sparse-checkout init --cone
git sparse-checkout set src/frontend
            

3. Git Maintenance

# Optimize repository
git gc --aggressive

# Enable automatic maintenance
git maintenance start

# Pack refs for better performance
git pack-refs --all
            

Next Steps

Incredible work! You've mastered advanced Git techniques that many developers never learn. In our final lesson, we'll cover:

🎯 You now have the power tools to handle any Git situation! Remember: with great power comes great responsibility. Always think before using destructive commands, and when in doubt, make a backup branch first!