Git Advanced: Rebase, Cherry-Pick, and Interactive History
Tech Setup2 min read
TS
Published August 2, 2026 · Editorial policy

Interactive Rebase
Interactive rebase lets you rewrite commit history — squash, reorder, edit, or drop commits.
Basic Syntax
# Rebase last 3 commits
git rebase -i HEAD~3
# Rebase since a specific commit
git rebase -i abc1234
The Editor
pick a1b2c3d Add login page
pick d4e5f6g Add password validation
pick h7i8j9k Fix typo in login
pick l0m1n2o Add remember me checkbox
Commands
| Command | Action |
|---|---|
pick | Keep commit as-is |
reword | Keep commit, edit message |
edit | Pause to amend commit content |
squash | Merge with previous commit |
fixup | Like squash, discard this message |
drop | Remove commit entirely |
Squash Example
pick a1b2c3d Add login page
squash d4e5f6g Add password validation
squash h7i8j9k Fix typo in login
pick l0m1n2o Add remember me checkbox
Result: First 3 commits become one.
Reorder Commits
Just reorder the lines:
pick l0m1n2o Add remember me checkbox
pick a1b2c3d Add login page
pick d4e5f6g Add password validation
pick h7i8j9k Fix typo in login
Cherry-Pick
Apply specific commits from one branch to another.
Single Commit
# Get commit hash from source branch
git log feature-branch --oneline
# a1b2c3d Fix critical bug
# Apply to current branch
git cherry-pick a1b2c3d
Multiple Commits
# Cherry-pick range (exclusive of start)
git cherry-pick abc123..def456
# Cherry-pick specific commits
git cherry-pick a1b2c3d d4e5f6g h7i8j9k
Cherry-Pick Without Committing
# Apply changes but don't commit
git cherry-pick --no-commit a1b2c3d
# Review changes
git diff --staged
# Commit manually
git commit -m "Applied fix from feature-branch"
Git Bisect
Binary search through commits to find when a bug was introduced.
# Start bisect
git bisect start
# Mark current commit as bad
git bisect bad
# Mark a known good commit
git bisect good abc1234
# Git checks out middle commit
# Test it, then mark as good or bad
git bisect good # or
git bisect bad
# Continue until Git finds the culprit
# Result: "xyz789 is the first bad commit"
# Return to original branch
git bisect reset
Automated Bisect
git bisect start
git bisect bad HEAD
git bisect good abc1234
# Git runs test script automatically
git bisect run npm test
# Returns the exact commit that broke tests
Reflog: Undo Anything
The reflog tracks every HEAD movement. Nothing is truly lost until garbage collected.
# View reflog
git reflog
# Output:
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: Add feature
# ghi9012 HEAD@{2}: commit: Fix bug
# jkl3456 HEAD@{3}: commit: Initial work
Recover Deleted Branch
# Find the commit where the branch pointed
git reflog
# Create branch at that commit
git checkout -b recovered-branch def5678
Undo a Bad Rebase
# Before rebase: abc1234 was HEAD
git reflog
# Find the pre-rebase commit
git reset --hard HEAD@{5} # or whatever the reflog shows
Stashing Advanced
Stash with Message
git stash push -m "WIP: half-done login feature"
Stash Specific Files
git stash push -m "login changes" src/login.ts src/auth.ts
Stash Untracked Files
git stash --include-untracked
Apply Stash Without Removing
git stash apply stash@{0}
Stash as Branch
git stash branch new-feature-branch stash@{0}
Worktrees
Work on multiple branches simultaneously without stashing.
# Create worktree for hotfix
git worktree add ../hotfix-branch hotfix-123
# Work in the hotfix directory
cd ../hotfix-branch
# ... fix bug, commit ...
# Return to main worktree
cd ../main-repo
# List worktrees
git worktree list
# Remove worktree
git worktree remove ../hotfix-branch
Cleaning Up
Remove Untracked Files
# Preview what will be deleted
git clean -fd --dry-run
# Delete untracked files and directories
git clean -fd
Remove Merged Branches
# List merged branches
git branch --merged main
# Delete merged branches (except main/master)
git branch --merged main | grep -v "main\|master" | xargs git branch -d
# Force delete unmerged branches
git branch --merged main | grep -v "main\|master" | xargs git branch -D
Commit Amendments
Change Last Commit Message
git commit --amend -m "New commit message"
Add Files to Last Commit
git add forgotten-file.ts
git commit --amend --no-edit
Undo Last Commit (Keep Changes)
git reset --soft HEAD~1
Undo Last Commit (Discard Changes)
git reset --hard HEAD~1
Blame and Search
Blame (Who Changed What)
git blame src/auth.ts
# Show changes within a range
git blame -L 10,20 src/auth.ts
# Ignore whitespace changes
git blame -w src/auth.ts
Search Commits
# Search commit messages
git log --grep="fix" --oneline
# Search code changes
git log -S "functionName" --oneline
# Search for pattern in diffs
git log -G "regex pattern" --oneline
aliases (Recommended)
Add to ~/.gitconfig:
[alias]
st = status
co = checkout
br = branch
cm = commit
lg = log --oneline --graph --decorate --all
unstage = reset HEAD --
last = log -1 HEAD
amend = commit --amend --no-edit
wip = !git add -A && git commit -m 'WIP'
undo = reset --soft HEAD~1
Visual = !gitk
Cheat Sheet
| Task | Command |
|---|---|
| Squash last 3 | git rebase -i HEAD~3 |
| Cherry-pick commit | git cherry-pick abc123 |
| Find bad commit | git bisect start |
| Recover deleted branch | git reflog → git checkout -b branch hash |
| Undo last commit | git reset --soft HEAD~1 |
| Stash with name | git stash push -m "name" |
| Work on 2 branches | git worktree add ../branch branch-name |
| Clean untracked | git clean -fd |
| Search code history | git log -S "function" --oneline |


