Intermediate — Cheat Sheet
Git · 4 topics. Download the PDF or the Instagram carousel and share it.
Merge vs Rebase — When to Use Which
Merge preserves true history with a merge commit; rebase replays commits onto a new base for a clean linear history. The golden rule: never rebase commits that have been pushed to a shared branch.
- ✓Merge creates a merge commit and preserves true history — you can see when and how branches were integrated
- ✓Rebase replays commits with new hashes onto a new base — produces linear history, easier to read
- ✓Golden rule: NEVER rebase commits that have been pushed to a shared/remote branch
- ✓Typical workflow: rebase feature onto main before PR, then merge (or squash merge) PR into main
- ✓git rebase --abort undoes an in-progress rebase completely — safe escape hatch
// BEFORE MERGE // // main: A ── B ── E ── F // â””── C ── D ↠feature/cart // // git switch main // git merge feature/cart // // AFTER MERGE // // main: A ── B ── E ── F ── M ↠merge commit // â””── C ── D ───┘ // // The merge commit M has TWO parents: F and D // History clearly shows the branch existed git switch main git merge feature/cart git log --oneline --graph # * a3f8c12 Merge branch 'feature/cart' # |# | * 7b2e441 Add cart animation # | * 3d9f2e0 Implement cart data structure # * | 9c1a8b7 Fix checkout bug # |/ # * 1a2b3c4 Initial commit
Undoing Changes — reset, revert, restore, stash
Git has four main undo mechanisms for different situations: restore (discard working changes), reset (move HEAD and optionally unstage/discard), revert (create a new commit that undoes a past commit), and stash (temporarily shelve work).
- ✓git restore: safe — only touches working directory or staging area, never commit history
- ✓git reset --soft: undo commit, keep changes staged. --mixed: unstage. --hard: discard everything âš ï¸
- ✓git revert: creates a new "undo commit" — the only safe way to undo pushed commits
- ✓git stash: temporary clipboard — save work in progress, switch context, restore later
- ✓git reset --hard permanently discards working directory changes — verify with git status first
// ┌─────────────────────────────────────────────────────────────â” // │ git restore — safe, only affects working dir or stage │ // â””─────────────────────────────────────────────────────────────┘ # Discard changes in working directory (IRREVERSIBLE for uncommitted) git restore src/auth.js # restore one file from last commit git restore src/ # restore entire directory git restore . # discard ALL working directory changes # Unstage (move from staging → working directory, keep the change) git restore --staged src/auth.js # Both: unstage AND discard working directory changes git restore --staged --worktree src/auth.js # Restore a file to a specific commit's version git restore --source=HEAD~3 src/auth.js
Git Log Mastery — History, Diff, Blame
git log, git diff, and git blame are your detective tools. Knowing how to filter, format, and search commit history is essential for debugging production issues, reviewing code, and understanding a codebase.
- ✓git log -S "string" (pickaxe) finds commits that added or removed a specific string — great for debugging
- ✓git log --graph --oneline --all gives the best quick visualisation of all branches
- ✓git diff --staged shows exactly what will be in the next commit — review before committing
- ✓git blame -L 10,25 file shows who wrote specific lines and in which commit
- ✓git bisect does O(log n) binary search to find the exact commit that introduced a bug
# Visual graph (bookmark this) git log --oneline --graph --all --decorate # Filter by author git log --author="Akshay" git log --author="akshay|john" # multiple authors (regex) # Filter by date git log --since="2024-01-01" git log --until="yesterday" git log --since="2 weeks ago" --until="1 week ago" # Filter by commit message git log --grep="payment" # case-sensitive git log --grep="payment" -i # case-insensitive git log --grep="fix" --grep="auth" --all-match # both terms # Find commits that added/removed a specific string (pickaxe) git log -S "validateEmail" # string added or removed git log -G "validate.*Email" # regex in diff content # Filter by file git log -- src/auth.js # commits touching this file git log -- "*.test.js" # all test files # Combine filters git log --author="Akshay" --since="1 month ago" -- src/payment/
Tagging Releases & Workflow Patterns
Tags are permanent named pointers to specific commits — ideal for releases. Understanding Git workflows (GitHub Flow, Git Flow, trunk-based) helps teams decide how to structure branches and releases.
- ✓Annotated tags (-a) store tagger name, date, and message — always use for releases; lightweight tags are just pointers
- ✓Tags must be pushed explicitly: git push origin --tags (they are not included in git push)
- ✓GitHub Flow: main is always deployable, short-lived feature branches, PR to merge
- ✓Git Flow: separate develop and main branches, feature/release/hotfix branch types
- ✓Trunk-based development: everyone on main, feature flags control visibility — scales best
# Create an annotated tag (recommended for releases) git tag -a v2.0.0 -m "Release 2.0.0 — payment gateway, cart redesign" # Tag a specific past commit git tag -a v1.9.1 9d2e441 -m "Hotfix: null pointer in checkout" # List all tags git tag git tag -l "v2.*" # filter by pattern # Show tag details git show v2.0.0 # tag v2.0.0 # Tagger: Akshay <a@example.com> # Date: Mon Jan 15 2024 # Release 2.0.0 — payment gateway, cart redesign # commit a3f8c12... # Push tags to remote (tags are NOT pushed by default) git push origin v2.0.0 # push one tag git push origin --tags # push all tags # Delete a tag git tag -d v2.0.0 # local git push origin --delete v2.0.0 # remote