Navigation

DevOps & Deployment

Advanced Git Commands: Master Rebase, Cherry-Pick & Bisect

Master advanced Git commands like rebase, cherry-pick, and bisect. Learn powerful techniques for managing commits, debugging issues, and maintaining clean Git history in 2025.

Table Of Contents

Introduction

Git is more than just a version control system—it's a powerful toolkit that can transform how you manage code. While most developers are comfortable with basic commands like git add, git commit, and git push, the real power of Git lies in its advanced features.

In this comprehensive guide, we'll explore three game-changing Git commands that will elevate your development workflow: rebase, cherry-pick, and bisect. These commands will help you maintain cleaner commit histories, selectively apply changes, and efficiently track down bugs.

By mastering these advanced Git techniques, you'll be able to handle complex version control scenarios with confidence and maintain professional-grade repositories that your team will thank you for.

Understanding Git Rebase: The Art of Rewriting History

What is Git Rebase?

Git rebase is a powerful command that allows you to move or combine a sequence of commits to a new base commit. Unlike merge, which creates a new commit that ties together the histories of two branches, rebase rewrites the project history by creating brand new commits for each commit in the original branch.

When to Use Rebase

Rebase is ideal for:

  • Keeping a linear project history
  • Cleaning up local commits before pushing
  • Integrating upstream changes into your feature branch
  • Squashing multiple commits into one coherent change

Basic Rebase Commands

# Rebase current branch onto main
git rebase main

# Interactive rebase for the last 3 commits
git rebase -i HEAD~3

# Continue rebase after resolving conflicts
git rebase --continue

# Abort a rebase operation
git rebase --abort

Interactive Rebase: Your Commit History Editor

Interactive rebase is where the real magic happens. It allows you to:

  1. Reorder commits: Change the sequence of commits
  2. Squash commits: Combine multiple commits into one
  3. Edit commits: Modify commit messages or content
  4. Drop commits: Remove unwanted commits entirely

Example workflow:

# Start interactive rebase
git rebase -i HEAD~4

# In the editor, you'll see:
pick abc1234 Add user authentication
pick def5678 Fix typo in auth module
pick ghi9012 Update documentation
pick jkl3456 Add unit tests

# Change to:
pick abc1234 Add user authentication
squash def5678 Fix typo in auth module
pick ghi9012 Update documentation
pick jkl3456 Add unit tests

Best Practices for Rebasing

  • Never rebase public branches: Only rebase commits that haven't been pushed to a shared repository
  • Use rebase for feature branches: Keep your feature branch up-to-date with the main branch
  • Backup before rebasing: Create a backup branch before complex rebase operations
  • Test after rebasing: Always verify your code works after rebasing

Cherry-Pick: Selective Commit Application

Understanding Cherry-Pick

Git cherry-pick allows you to apply specific commits from one branch to another. It's like picking individual cherries from a tree—you select exactly which changes you want to apply without merging entire branches.

When to Use Cherry-Pick

Cherry-pick is perfect for:

  • Applying hotfixes to multiple branches
  • Pulling specific features without merging entire branches
  • Recovering lost commits
  • Backporting fixes to older versions

Cherry-Pick Commands and Examples

# Cherry-pick a single commit
git cherry-pick abc1234

# Cherry-pick multiple commits
git cherry-pick abc1234 def5678

# Cherry-pick a range of commits
git cherry-pick abc1234..def5678

# Cherry-pick without committing (stage changes only)
git cherry-pick -n abc1234

# Continue after resolving conflicts
git cherry-pick --continue

# Abort cherry-pick operation
git cherry-pick --abort

Advanced Cherry-Pick Scenarios

Scenario 1: Hotfix Application

# Switch to production branch
git checkout production

# Apply the hotfix commit from development
git cherry-pick 7d3f1a8

# Push to production
git push origin production

Scenario 2: Feature Extraction

# Create a new feature branch
git checkout -b extracted-feature

# Cherry-pick specific commits that implement the feature
git cherry-pick 3a4b5c6 7d8e9f0 1a2b3c4

# Clean up the commit history
git rebase -i HEAD~3

Cherry-Pick Best Practices

  • Document cherry-picks: Add notes about why commits were cherry-picked
  • Avoid duplicate commits: Be careful not to cherry-pick commits that will be merged later
  • Resolve conflicts carefully: Cherry-picked commits may conflict with the target branch
  • Consider alternatives: Sometimes a merge or rebase might be more appropriate

Git Bisect: Binary Search for Bugs

What is Git Bisect?

Git bisect is a powerful debugging tool that uses binary search to find the specific commit that introduced a bug. It systematically checks commits between a known good state and a known bad state, helping you identify the exact point where things went wrong.

How Bisect Works

  1. Mark a commit where the bug exists (bad)
  2. Mark a commit where the bug didn't exist (good)
  3. Git checks out a commit halfway between them
  4. You test and mark it as good or bad
  5. Repeat until the problematic commit is found

Basic Bisect Workflow

# Start bisect session
git bisect start

# Mark current commit as bad
git bisect bad

# Mark a known good commit
git bisect good v2.0.0

# Git checks out a commit for testing
# After testing, mark it:
git bisect good  # if the bug is not present
git bisect bad   # if the bug is present

# When finished, Git identifies the problematic commit
# Reset to original state
git bisect reset

Automated Bisecting

For reproducible bugs, you can automate the bisect process:

# Create a test script that returns 0 for good, 1 for bad
cat > test-bug.sh << 'EOF'
#!/bin/bash
# Run your test
npm test specific-test.js
EOF

chmod +x test-bug.sh

# Run automated bisect
git bisect start
git bisect bad HEAD
git bisect good v2.0.0
git bisect run ./test-bug.sh

Advanced Bisect Techniques

Skipping Commits

# Skip commits that can't be tested
git bisect skip

# Skip a range of commits
git bisect skip v2.2..v2.3

Visualizing Bisect Progress

# View bisect log
git bisect log

# Visualize remaining commits
git bisect visualize

Bisect Best Practices

  • Write reproducible tests: Automated bisecting requires consistent test results
  • Use descriptive markers: Document why commits are marked good or bad
  • Save bisect logs: Keep records of bisect sessions for future reference
  • Consider build time: Factor in compilation time when bisecting large projects

Combining Advanced Git Commands

Real-World Workflow Example

Here's how these commands work together in practice:

# 1. Use bisect to find a bug
git bisect start
git bisect bad HEAD
git bisect good v1.0.0
# ... bisect process ...
# Bug found in commit abc1234

# 2. Create a fix branch
git checkout -b bugfix/issue-123

# 3. Cherry-pick any necessary commits
git cherry-pick def5678  # Related fix from another branch

# 4. Make your fix
# ... edit files ...
git commit -am "Fix issue #123"

# 5. Clean up history with rebase
git rebase -i HEAD~3
# Squash commits and write clear message

# 6. Rebase onto latest main
git rebase main

# 7. Push clean history
git push origin bugfix/issue-123

Common Pitfalls and How to Avoid Them

Rebase Pitfalls

  • Force pushing shared branches: Always communicate before force pushing
  • Losing commits: Use git reflog to recover lost commits
  • Merge conflicts: Resolve conflicts commit by commit

Cherry-Pick Pitfalls

  • Duplicate commits: Track cherry-picked commits to avoid duplication
  • Missing dependencies: Ensure cherry-picked commits don't depend on others
  • Context loss: Document why commits were cherry-picked

Bisect Pitfalls

  • Non-deterministic bugs: Ensure bugs are reproducible
  • Build failures: Skip unbuildable commits
  • Wrong good/bad markers: Double-check your initial markers

Performance Tips and Optimization

Speeding Up Rebase

# Use --autosquash for automatic squashing
git rebase -i --autosquash HEAD~10

# Prepare commits for autosquash
git commit --fixup=abc1234

Efficient Cherry-Picking

# Cherry-pick multiple commits at once
git cherry-pick branch-name~3..branch-name

# Use -x to add source commit reference
git cherry-pick -x abc1234

Optimizing Bisect

# Limit bisect to specific paths
git bisect start -- src/components/

# Use terms other than good/bad
git bisect start --term-old=working --term-new=broken

Tools and GUI Applications

Command-Line Enhancements

  • tig: Text-mode interface for Git
  • lazygit: Terminal UI for Git commands
  • git-extras: Additional Git commands collection

GUI Tools Supporting Advanced Features

  • GitKraken: Visual interface for rebase and cherry-pick
  • SourceTree: Comprehensive Git GUI with bisect support
  • Git Extensions: Windows-focused Git GUI
  • Fork: Modern Git client for Mac and Windows

Integration with CI/CD Pipelines

Automated Rebase Checks

# GitHub Actions example
name: Rebase Check
on: pull_request
jobs:
  rebase:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Check if PR needs rebase
        run: |
          git fetch origin main
          git rebase origin/main

Cherry-Pick Automation

# Script for automated backporting
#!/bin/bash
COMMIT=$1
BRANCHES=("release-1.0" "release-2.0")

for branch in "${BRANCHES[@]}"; do
  git checkout $branch
  git cherry-pick $COMMIT
  git push origin $branch
done

FAQ Section

Q: When should I use rebase vs. merge?

Use rebase for cleaning up local commits and maintaining linear history. Use merge for combining work from multiple developers or preserving the context of feature development.

Q: Can I cherry-pick merge commits?

Yes, use git cherry-pick -m 1 <merge-commit> to specify which parent to follow. However, it's often better to cherry-pick the individual commits instead.

Q: How do I recover from a bad rebase?

Use git reflog to find the commit before the rebase, then git reset --hard <commit> to restore your branch to that state.

Q: Can bisect work with non-linear history?

Yes, bisect handles merge commits intelligently, testing the merge result rather than individual parent commits.

Q: What's the difference between cherry-pick and rebase?

Cherry-pick copies specific commits to your current branch, while rebase moves your entire branch to a new base, rewriting history in the process.

Q: How do I bisect when tests take a long time?

Use git bisect skip to skip commits that take too long to test, or narrow the search space with path restrictions.

Conclusion

Mastering Git's advanced commands—rebase, cherry-pick, and bisect—transforms you from a Git user into a Git power user. These tools provide precise control over your repository's history and enable efficient debugging and code management.

Key takeaways:

  • Rebase helps maintain clean, linear commit histories
  • Cherry-pick allows selective application of specific changes
  • Bisect efficiently identifies problematic commits through binary search
  • Combining these commands creates powerful workflows
  • Always prioritize communication when rewriting shared history

Start practicing these commands in your daily workflow, beginning with simple scenarios and gradually tackling more complex situations. Remember, with great power comes great responsibility—use these commands wisely to enhance, not complicate, your team's development process.

Ready to level up your Git skills? Start experimenting with these commands in a test repository today, and don't forget to share your experiences and tips in the comments below!

Share this article

Add Comment

No comments yet. Be the first to comment!

More from DevOps & Deployment