Portal | Level: L0: Entry | Topics: Git | Domain: DevOps & Tooling
Git Drills¶
Remember: Git undo safety levels:
--soft(safest, keeps everything staged),--mixed(default, unstages but keeps files),--hard(destructive, discards everything). Mnemonic: "Soft keeps Staged, Mixed moves to Modified, Hard destroys." When in doubt, use--soft— you can always unstage later.--hardcannot be undone (except via reflog within 90 days).Gotcha:
git reflogis your emergency parachute. It records every HEAD movement for the last 90 days, even after rebase, reset, or amend. If you accidentally lose commits,git reflogshows where HEAD was before, andgit reset --hard <reflog-SHA>recovers them.
Drill 1: Undo Last Commit (Keep Changes)¶
Difficulty: Easy
Q: You committed too soon. How do you undo the last commit but keep the changes staged?
Answer
| Flag | Commit | Index (staging) | Working dir | |------|--------|----------------|-------------| | `--soft` | Undone | Kept | Kept | | `--mixed` | Undone | Undone | Kept | | `--hard` | Undone | Undone | Undone |Drill 2: Interactive Rebase¶
Difficulty: Medium
Q: You have 5 messy commits on a feature branch. Squash them into 2 clean commits before merging.
Answer
Commands: - `pick` — keep the commit - `squash` (or `s`) — merge into previous commit - `fixup` (or `f`) — squash but discard the commit message - `reword` (or `r`) — change the commit message - `drop` (or `d`) — delete the commit Result: 2 clean commits instead of 5 messy ones.Drill 3: Cherry-Pick¶
Difficulty: Easy
Q: A bugfix on develop needs to go to release immediately. How?
Answer
Cherry-pick creates a new commit with the same changes but a different hash. The original commit stays on its branch.Drill 4: Stash¶
Difficulty: Easy
Q: You're mid-feature but need to switch branches for an urgent fix. Save your work without committing.
Answer
# Save current changes
git stash push -m "WIP: user registration form"
# Switch and fix
git checkout main
# ... fix the bug, commit ...
# Come back
git checkout feature/user-reg
# List stashes
git stash list
# Restore
git stash pop # Apply and remove from stash
# Or:
git stash apply stash@{0} # Apply but keep in stash
# Include untracked files
git stash push -u -m "Including new files"
Drill 5: Resolve Merge Conflict¶
Difficulty: Medium
Q: Merge conflict in config.yaml. Walk through the resolution.
Answer
git merge feature-branch
# CONFLICT in config.yaml
# The file now contains:
<<<<<<< HEAD
max_connections: 100
=======
max_connections: 200
>>>>>>> feature-branch
# 1. Edit the file — pick the right value (or combine)
max_connections: 200
# 2. Mark as resolved
git add config.yaml
# 3. Complete the merge
git commit
# (Git provides a default merge commit message)
Drill 6: Bisect¶
Difficulty: Hard
Q: A bug was introduced somewhere in the last 50 commits. Find the exact commit that broke things.
Answer
# Start bisect
git bisect start
# Mark current (broken) as bad
git bisect bad
# Mark a known good commit
git bisect good v1.0.0 # or a specific hash
# Git checks out a middle commit
# Test it, then mark:
git bisect good # if this commit works
git bisect bad # if this commit is broken
# Repeat (binary search: ~6 steps for 50 commits)
# Git finds the exact commit that introduced the bug
# Automated bisect with a test script:
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
git bisect run ./test.sh # Returns 0 = good, 1 = bad
# Done, reset to original state
git bisect reset
Drill 7: Reflog Recovery¶
Difficulty: Hard
Q: You accidentally ran git reset --hard and lost commits. How do you recover?
Answer
# Reflog records every HEAD movement
git reflog
# Shows:
# abc1234 HEAD@{0}: reset: moving to HEAD~5
# def5678 HEAD@{1}: commit: Add user API
# ghi9012 HEAD@{2}: commit: Add user model
# Recover to before the reset
git reset --hard def5678
# Or create a branch from the lost commit:
git branch recovery def5678
Drill 8: Git Hooks¶
Difficulty: Medium
Q: Set up a pre-commit hook that rejects commits containing TODO or console.log.
Answer
#!/bin/sh
# .git/hooks/pre-commit (must be executable)
# Check for TODO
if git diff --cached --name-only | xargs grep -l 'TODO' 2>/dev/null; then
echo "ERROR: Remove TODO comments before committing"
exit 1
fi
# Check for console.log
if git diff --cached --diff-filter=ACM -- '*.js' '*.ts' | grep '+.*console\.log' ; then
echo "ERROR: Remove console.log statements before committing"
exit 1
fi
exit 0
Drill 9: Rebase vs Merge¶
Difficulty: Medium
Q: When do you rebase vs merge? What's the golden rule of rebasing?
Answer
**Merge**: Creates a merge commit. Preserves full history. **Rebase**: Replays your commits on top of the target. Linear history. **Golden rule**: Never rebase commits that have been pushed and shared with others. Rebase rewrites history — if others have those commits, they'll get conflicts. | Scenario | Use | |----------|-----| | Update feature branch with latest main | Rebase | | Merge feature into main | Merge (or squash merge) | | Shared/public branch | Merge only | | Local-only cleanup | Rebase freely |Drill 10: Git Blame and Log¶
Difficulty: Easy
Q: Find out who last changed line 42 of server.py and see all commits that touched that file.
Answer
# Who changed line 42
git blame server.py -L 42,42
# Who changed lines 40-50
git blame server.py -L 40,50
# All commits that touched this file
git log --oneline -- server.py
# See changes per commit for this file
git log -p -- server.py
# Search for when a function was added/removed
git log -S "def process_request" -- server.py
# See changes to a specific function
git log -L :process_request:server.py
Wiki Navigation¶
Prerequisites¶
- Git for DevOps (Topic Pack, L0)
Related Content¶
- Git Advanced (Topic Pack, L2) — Git
- Git Flashcards (CLI) (flashcard_deck, L1) — Git
- Git for DevOps (Topic Pack, L0) — Git
- Interview: Secret Leaked to Git (Scenario, L2) — Git
- Mental Models (Core Concepts) (Topic Pack, L0) — Git
- RHCE (EX294) Exam Preparation (Topic Pack, L2) — Git
- Repository Flashcards (CLI) (flashcard_deck, L1) — Git
- Skillcheck: Git (Assessment, L0) — Git
- Track: Foundations (Reference, L0) — Git