Git Advanced Commands: Stash, Reflog, and Bisect
Beyond basic commands (commit, push, merge), Git offers advanced tools for managing complex workflows, recovering lost work, and debugging issues. Git stash saves temporary work, reflog is your lifesaver for recovery, and bisect finds bugs with binary search. Mastering these commands makes you a Git power user.
🎯 What You'll Learn
- Git stash for saving temporary work
- Git reflog for recovering "lost" commits
- Git bisect for finding commits that introduced bugs
- Worktree and submodules (bonus)
Git Stash: Your Temporary Notepad
git stash saves uncommitted changes in a temporary "stash", cleaning the
working directory. Useful when you need to switch branches quickly but current work isn't
ready for a commit.
# Situation: you're working on feature but urgent hotfix arrives
git status
# modified: src/component.ts
# modified: src/style.css
# Save changes to stash
git stash
# Output: Saved working directory and index state WIP on feature: abc1234 last commit
# Working directory is now clean
git status
# nothing to commit, working tree clean
# Switch branch and work on hotfix
git checkout main
# ... work on hotfix ...
# Return to feature branch
git checkout feature
# Recover changes from stash
git stash pop
# Reapply changes and remove the stash
Advanced Stash
# Stash with descriptive message
git stash save "WIP: refactoring authentication"
# Stash including untracked files
git stash -u
# Stash including everything (even .gitignore)
git stash -a
# List all stashes
git stash list
# stash@{{ '{' }}0{{ '}' }}: WIP on feature: abc1234 refactoring auth
# stash@{{ '{' }}1{{ '}' }}: On main: def5678 emergency fix
# stash@{{ '{' }}2{{ '}' }}: WIP on develop: ghi9012 new feature
# View stash content
git stash show stash@{{ '{' }}0{{ '}' }}
git stash show -p stash@{{ '{' }}0{{ '}' }} # With full diff
# Apply stash without removing it
git stash apply stash@{{ '{' }}1{{ '}' }}
# Remove specific stash
git stash drop stash@{{ '{' }}0{{ '}' }}
# Remove all stashes
git stash clear
# Create branch from stash
git stash branch new-feature-branch stash@{{ '{' }}0{{ '}' }}
Partial Stash
You can save only some files to stash, keeping others in the working directory:
# Interactive stash: choose what to save
git stash -p
# For each hunk:
# y = stash this hunk
# n = do not stash this hunk
# q = quit
# a = stash this and all remaining hunks
# d = do not stash this or any remaining hunks
# Stash only specific files
git stash push -m "Save only component" src/component.ts
# Stash everything except specific files (path spec)
git stash push -- '*.ts' '!src/test.ts'
Git Reflog: Your Lifesaver
git reflog records every HEAD movement, even deleted commits,
resets, aborted rebases. It's the backup that saves you when you think you've lost everything.
# View HEAD reflog
git reflog
# abc1234 HEAD@{{ '{' }}0{{ '}' }}: commit: fix bug
# def5678 HEAD@{{ '{' }}1{{ '}' }}: checkout: moving from main to feature
# ghi9012 HEAD@{{ '{' }}2{{ '}' }}: reset: moving to HEAD~1
# jkl3456 HEAD@{{ '{' }}3{{ '}' }}: commit: add feature
# mno7890 HEAD@{{ '{' }}4{{ '}' }}: commit: initial commit
# Reflog of specific branch
git reflog show feature
# Reflog with dates
git reflog --date=relative
git reflog --date=iso
Recovery with Reflog
Practical examples of how reflog saves your work:
# You did a reset and lost commits
git reset --hard HEAD~3
# Oh no! I only wanted HEAD~1
# Find lost commits in reflog
git reflog
# abc1234 HEAD@{{ '{' }}0{{ '}' }}: reset: moving to HEAD~3
# def5678 HEAD@{{ '{' }}1{{ '}' }}: commit: important feature ← I WANT THIS!
# Recover the commit
git reset --hard def5678
# Or
git reset --hard HEAD@{{ '{' }}1{{ '}' }}
# Commits recovered!
# You delete branch by mistake
git branch -D feature-important
# Deleted branch feature-important (was abc1234).
# Oh no! Need to recover it
git reflog
# Find last commit of deleted branch
# abc1234 HEAD@{{ '{' }}5{{ '}' }}: commit: last commit on feature
# Recreate the branch
git branch feature-important abc1234
# Branch recovered!
# Rebase goes wrong, you abort but lose work
git rebase --abort
# Find state before rebase
git reflog
# def5678 HEAD@{{ '{' }}1{{ '}' }}: rebase: aborting ← corrupted state
# ghi9012 HEAD@{{ '{' }}2{{ '}' }}: checkout: moving from feature to main
# abc1234 HEAD@{{ '{' }}3{{ '}' }}: commit: my work ← GOOD STATE
# Return to pre-rebase state
git reset --hard abc1234
Git Bisect: Debugging with Binary Search
git bisect uses binary search to find which commit introduced a bug.
Instead of manually checking hundreds of commits, bisect finds the culprit in log(n) steps.
# Situation: Bug exists now (HEAD) but didn't exist 10 days ago
# You have 100 commits in between: which introduced the bug?
# 1. Start bisect
git bisect start
# 2. Mark current commit as "bad" (has the bug)
git bisect bad
# 3. Mark old commit as "good" (didn't have the bug)
git bisect good abc1234
# Git checks out the commit in the middle
# Bisecting: 50 revisions left to test after this
# 4. Test if the bug exists
npm test
# If test fails:
git bisect bad
# If test passes:
git bisect good
# 5. Repeat until Git finds the culprit commit
# Bisecting: 25 revisions left...
# Bisecting: 12 revisions left...
# Bisecting: 6 revisions left...
# Bisecting: 3 revisions left...
# Bisecting: 1 revision left...
# def5678 is the first bad commit
# commit def5678
# Author: Developer <dev@example.com>
# Date: Mon Dec 1 10:00:00 2024
#
# refactor: change authentication logic ← THIS IS THE CULPRIT
# 6. End bisect
git bisect reset
# HEAD returns to original branch
Automated Bisect
You can automate bisect with a test script:
# test.sh - script that returns 0 if OK, 1 if bug present
#!/bin/bash
npm test | grep "PASS"
exit $?
# Automatic bisect
git bisect start
git bisect bad HEAD
git bisect good abc1234
git bisect run ./test.sh
# Git automatically tests each commit and finds the culprit!
# Final output:
# def5678 is the first bad commit
Git Worktree: Multiple Simultaneous Branches
git worktree allows having multiple branches checked out simultaneously in
different directories. Useful for working on hotfixes without stashing current work.
# Situation: you're on feature branch, urgent hotfix needed
# Instead of stash, create new worktree
# Create worktree for hotfix
git worktree add ../hotfix-worktree hotfix/critical-bug
# Now you have two directories:
# ./project (feature branch)
# ../hotfix-worktree (hotfix branch)
# Go to hotfix directory
cd ../hotfix-worktree
# Work on the fix
git commit -m "fix: critical bug"
git push
# Return to main project
cd ../project
# Continue work on feature without touching anything
# List worktrees
git worktree list
# /path/to/project abc1234 [feature]
# /path/to/hotfix-worktree def5678 [hotfix/critical-bug]
# Remove worktree when done
git worktree remove ../hotfix-worktree
Best Practices
✅ Stash
- Use descriptive messages:
git stash save "description" - Don't leave stashes for months (commit or discard)
- Use
git stash listregularly for cleanup
✅ Reflog
- Check reflog before dangerous reset/rebase
- Reflog is local, doesn't get pushed
- Reflog cleans up after 90 days (configurable)
✅ Bisect
- Automate with script for speed
- Make sure "good" commit is really good
- Use
git bisect skipif a commit doesn't compile
Bonus Commands
# Git fsck: verify repository integrity
git fsck
# Find corrupted or dangling objects
# Git gc: garbage collection (cleanup)
git gc --aggressive
# Git clean: remove untracked files
git clean -fd # -f force, -d directories
git clean -n # Dry run (see what would be removed)
# Git archive: create code archive
git archive --format=zip HEAD > code.zip
# Git blame: see who wrote each line
git blame file.ts
git blame -L 10,20 file.ts # Only lines 10-20
# Git shortlog: contribution summary
git shortlog -sn # -s summary, -n sorted by number
Conclusion
Git's advanced commands transform difficult situations into solvable problems. Stash manages temporary work, reflog recovers "lost" commits, and bisect finds bugs efficiently. Knowing these tools gives you confidence to explore, experiment, and recover from errors without fear.
🎯 Key Points
- Stash saves temporary work:
git stash/git stash pop - Reflog records everything:
git reflogfor recovery - Bisect finds bugs with binary search:
git bisect start/good/bad - Worktree for multiple simultaneous branches
- These commands save you in critical situations







