Handling Rebase Conflicts
# Conflict during rebase — Git pauses and tells you which file
git rebase main
# CONFLICT (content): Merge conflict in src/auth/middleware.ts
# error: could not apply a3f1c2d... Add JWT middleware
# 1. Fix the conflict in the file
# 2. Stage it
git add src/auth/middleware.ts
# 3. Continue the rebase (NOT git commit!)
git rebase --continue
# Made a mistake? Abort and return to original state
git rebase --abort
# Skip a commit entirely (be careful — you might lose changes)
git rebase --skip
Cherry-Pick: Surgical Commit Transplants
Cherry-pick copies one or more commits from one branch to another. The primary use case is hotfix backporting: a bug is fixed on main and needs to go into the release/1.x and release/2.x branches without merging unrelated changes.
# Cherry-pick a single commit
git cherry-pick a3f1c2d
# Cherry-pick a range of commits (inclusive)
git cherry-pick a3f1c2d..h0k8j9k
# Cherry-pick without committing (stage the changes, let you review first)
git cherry-pick --no-commit a3f1c2d
# Cherry-pick and edit the commit message
git cherry-pick --edit a3f1c2d
# Backport workflow: fix is on main, need it on release/1.x
git log --oneline -5 main
# a3f1c2d Fix SQL injection in user search (this is the fix)
git checkout release/1.x
git cherry-pick a3f1c2d
# If it applies cleanly: done. If conflict: resolve like a rebase conflict.
# Cherry-pick multiple specific commits
git cherry-pick a3f1c2d b4e2d3e c5f3e4f
Git Bisect: Binary Search for Regressions
Bisect performs a binary search through your commit history to find which commit introduced a bug. Given a “good” commit and a “bad” commit, it checks out the midpoint, asks you to test, and narrows down to the exact commit in O(log n) steps.
# Start bisect
git bisect start
# Mark current state as bad (the bug exists)
git bisect bad HEAD
# Mark the last known good commit (tests passed)
git bisect good v2.3.0
# or by commit hash:
git bisect good abc1234
# Git checks out the midpoint commit. Test it, then:
git bisect bad # if the bug exists here
git bisect good # if the bug does not exist here
# Git keeps narrowing down. After 7-8 steps for 100 commits, you get:
# a3f1c2d is the first bad commit
# commit a3f1c2d
# Author: Dev Name
# Date: ...
# Refactor user search to use LIKE query
# Clean up — return to HEAD
git bisect reset
Automated bisect with a test script. This is the power mode — bisect runs the script at each step:
# Write a test script that exits 0 for good, non-zero for bad
cat > /tmp/test-regression.sh << 'SCRIPT'
#!/bin/bash
npm run build --silent 2>/dev/null || exit 125 # skip un-buildable commits
npm test -- --testPathPattern="user-search" --silent 2>/dev/null
SCRIPT
chmod +x /tmp/test-regression.sh
# Run automated bisect
git bisect start
git bisect bad HEAD
git bisect good v2.3.0
git bisect run /tmp/test-regression.sh
# Git runs the script at each midpoint and narrows down automatically
# Exit 125 means "skip this commit" (use for broken builds that aren't the bug)
# When done
git bisect reset
Reflog: Recovering Lost Work
The reflog is Git’s safety net. Every time HEAD moves — commit, checkout, rebase, reset — Git records it. You can recover from almost any disaster if you act quickly.
# View the reflog
git reflog
# HEAD@{0}: rebase (finish): returning to refs/heads/feature/auth
# HEAD@{1}: rebase (pick): Add JWT middleware
# HEAD@{2}: rebase (pick): Add auth schema
# HEAD@{3}: rebase (start): checkout main
# HEAD@{4}: commit: WIP save before rebase
# HEAD@{5}: checkout: moving from main to feature/auth
# Recover a commit after accidental reset --hard
git reset --hard HEAD~3 # oops, went back 3 commits
git reflog # find the commit you were at
git reset --hard HEAD@{3} # restore to that point
# Recover a deleted branch
git branch -D feature/old-work # oops
git reflog | grep "feature/old-work"
# HEAD@{12}: checkout: moving from feature/old-work to main
git checkout -b feature/old-work HEAD@{12}
# Find a dangling commit (detached HEAD work that got lost)
git fsck --lost-found
# Lists unreachable commits, blobs
git show
git cherry-pick
Git Worktrees: Multiple Branches Simultaneously
Worktrees let you check out multiple branches in separate directories simultaneously. No stashing, no context switching — open a hotfix in a new directory while keeping your feature branch untouched.
# List existing worktrees
git worktree list
# Add a worktree for a hotfix
git worktree add ../myapp-hotfix release/1.x
# Creates ../myapp-hotfix/ directory checked out to release/1.x
# Work in the hotfix worktree
cd ../myapp-hotfix
git checkout -b hotfix/sql-injection
# ... make fixes ...
git commit -m "fix(auth): patch SQL injection in user search"
# Back in main worktree, cherry-pick if needed
cd ../myapp
git cherry-pick hotfix/sql-injection
# Remove worktree when done
git worktree remove ../myapp-hotfix
Advanced Log and Diff Commands
# Compact, visual branch graph
git log --oneline --graph --decorate --all
# Find commits that changed a specific file
git log --follow -p -- src/auth/middleware.ts
# Find commits by message content
git log --grep="SQL injection" --oneline
# Find commits by author in a date range
git log --author="dev" --since="2 weeks ago" --oneline
# Show what changed between two branches
git diff main..feature/auth --stat
# Show commits in feature/auth not in main
git log main..feature/auth --oneline
# Find which branch a commit is on
git branch --contains a3f1c2d
# Show the diff of a specific commit
git show a3f1c2d
# Show files changed in a commit
git show --stat a3f1c2d
# Diff between two tags
git diff v2.3.0..v2.4.0 -- src/
People Also Ask
Is git rebase safe to use on shared branches?
Never rebase a branch that other people have pulled. Rebase rewrites commit hashes — if someone has the old hashes, pushing the rebased version forces them to reset their local branch. Safe rule: rebase your own feature branches before they are merged, never after. The golden rule of rebase is: do not rebase commits that exist outside your repository.
When should I use cherry-pick vs merge vs rebase?
Use cherry-pick when you need specific commits from one branch without bringing the entire branch. Classic use case: backporting a security fix to multiple release branches. Use merge when you want to bring a complete feature branch into main with history preserved. Use rebase when you want to replay your feature branch on top of the latest main before merging, for a linear history.
How does git bisect find bugs faster than manual searching?
Bisect uses binary search — each test eliminates half the remaining commits. For 1,000 commits, it takes at most 10 tests to find the exact bad commit. Manual linear searching would take up to 1,000 tests. Combined with an automated test script (git bisect run), bisect can find a regression in seconds without any human steps.
For Git workflow templates, CI/CD setup guides, and developer automation tools, visit WOWHOW developer tools. Browse all productivity and DevOps resources at the full catalog.
Comments · 0
Beta: comments are stored locally on your device and not visible to other readers.
No comments yet. Be the first to share your thoughts.