正在加载,请稍候…

Git Advanced Commands: Rebase, Cherry-pick, Bisect, and Stash

Master advanced Git commands beyond the basics: interactive rebase, cherry-pick specific commits, bisect for bug hunting, reflog recovery, and powerful stash workflows.

Beyond git add and git commit

Most developers use about 10% of Git's capabilities. The remaining 90% — when you need it — makes the difference between spending 2 minutes or 2 hours solving a problem. This guide covers the Git commands that transform how you work.

Interactive Rebase: Rewrite History

# Clean up last 5 commits before pushing
git rebase -i HEAD~5

# Opens editor with:
pick a1b2c3d Fix: handle null user
pick b2c3d4e WIP: add validation
pick c3d4e5f Add more validation
pick d4e5f6g Fix typo in validation
pick e5f6g7h Add tests for validation

# Change 'pick' to:
# r/reword — change commit message
# s/squash — merge into previous commit (keeps both messages)
# f/fixup  — merge into previous (discard this commit's message)
# d/drop   — remove commit entirely
# e/edit   — pause and let you amend the commit

# Result: clean history that tells a story
pick a1b2c3d Fix: handle null user
reword c3d4e5f Add user input validation
squash d4e5f6g fix typo
fixup b2c3d4e WIP cleanup
pick e5f6g7h Add tests for validation
# Rebase feature branch onto updated main
git checkout feature/my-feature
git rebase main

# If conflicts occur:
git rebase --continue  # After resolving
git rebase --abort     # Start over

# Rebase with autosquash (squash! prefix in commit messages)
git commit --fixup HEAD~2  # Creates "fixup! <original message>"
git rebase -i --autosquash HEAD~5  # Auto-merges fixup commits

Cherry-pick: Apply Specific Commits

# Apply a single commit from another branch to current branch
git cherry-pick a1b2c3d

# Cherry-pick range of commits
git cherry-pick a1b2c3d..e5f6g7h  # Exclusive of first
git cherry-pick a1b2c3d^..e5f6g7h # Inclusive of first

# Cherry-pick without committing (review first)
git cherry-pick --no-commit a1b2c3d

# Cherry-pick and edit the commit message
git cherry-pick -e a1b2c3d

# Common use case: hot-fix deployed to main and feature branches
git checkout main
git cherry-pick fix-commit-hash
git checkout feature/new-feature
git cherry-pick fix-commit-hash

git bisect: Binary Search for Bugs

When you know "this worked in version X but broke in version Y":

# Start bisect
git bisect start

# Mark current commit as bad (bug exists here)
git bisect bad

# Mark last known good commit
git bisect good v1.2.0   # tag
# or
git bisect good a1b2c3d  # commit hash

# Git checks out the middle commit — test it
# If bug exists:
git bisect bad
# If bug doesn't exist:
git bisect good

# Git narrows down until it finds the culprit
# Bisecting: 25 revisions left to test after this (roughly 5 steps)
# [a1b2c3d] Add new feature X
# ...
# [c3d4e5f] is the first bad commit!

# End bisect session
git bisect reset

# Automated bisect (with a test script)
git bisect start HEAD v1.2.0
git bisect run npm test  # Automatically runs test on each commit

git stash: Temporary Shelving

# Stash all changes (staged and unstaged)
git stash

# Stash with a descriptive message
git stash push -m "WIP: adding payment validation"

# Include untracked files
git stash push --include-untracked

# List all stashes
git stash list
# stash@{0}: WIP: adding payment validation
# stash@{1}: On main: quick fix attempt

# Apply most recent stash (keep it in stash list)
git stash apply

# Apply and remove from stash list
git stash pop

# Apply specific stash
git stash apply stash@{2}

# Create a branch from a stash
git stash branch feature/payment-from-stash stash@{0}

# Drop a stash
git stash drop stash@{0}

# Clear all stashes
git stash clear

git reflog: Time Machine

The reflog records every HEAD movement — your safety net:

# See all recent HEAD changes
git reflog
# a1b2c3d HEAD@{0}: commit: Add new feature
# b2c3d4e HEAD@{1}: rebase finished: returning to refs/heads/main
# c3d4e5f HEAD@{2}: reset: moving to HEAD~1
# d4e5f6g HEAD@{3}: commit: WIP: new feature

# Recover "lost" commits after accidental reset
git reset --hard HEAD~3  # "I deleted my last 3 commits!"
git reflog               # Find the commit hash
git reset --hard HEAD@{3}  # Recover!

# Undo a bad rebase
git reflog  # Find commit before rebase
git reset --hard HEAD@{before-rebase}

Advanced Diff and Log

# Visual branch graph
git log --oneline --graph --all --decorate

# Changes between branches
git diff main..feature/my-branch

# Show changes in a commit
git show a1b2c3d

# Who changed this line? (blame with context)
git blame -L 42,56 src/auth.ts
git log -S "functionName" --source --all  # Find when a string appeared/disappeared

# Changes to a specific file
git log --follow --all -p -- src/deleted-file.ts

# Commits not in main yet
git log main..HEAD --oneline

Powerful Aliases

# Add to ~/.gitconfig
[alias]
  # Compact status
  st = status -sb
  
  # Pretty log
  lg = log --oneline --graph --all --decorate
  
  # Recent branches
  recent = for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)'
  
  # Undo last commit (keep changes staged)
  undo = reset --soft HEAD~1
  
  # Amend last commit without changing message
  amend = commit --amend --no-edit
  
  # Clean up merged branches
  cleanup = "!git branch --merged main | grep -v main | xargs -n 1 git branch -d"
  
  # What did I do today?
  today = log --since=midnight --author="$(git config user.name)" --oneline

Useful Git Workflows

# Scenario: Need to quickly fix a bug while in the middle of a feature
git stash push -m "WIP: feature X"   # Save current work
git checkout main
git checkout -b fix/critical-bug
# ... make fix ...
git commit -am "Fix: critical bug"
git checkout main
git merge fix/critical-bug
git checkout feature/x
git stash pop                          # Restore work

# Scenario: Committed to wrong branch
git log --oneline -3                  # Find the commits
git reset --soft HEAD~1               # Uncommit (keep changes)
git stash
git checkout correct-branch
git stash pop
git commit -m "Same message"

# Scenario: Include only some changes from a file
git add -p src/feature.ts            # Interactive staging — choose hunks

→ Use the built-in Git Memo for a quick reference of common Git commands.