Git Cheatsheet

Rebasing

Use this Git reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Basic Rebase

Rebase replays commits from the current branch on top of another base commit, producing a linear history.

git rebase <branch>             # Rebase current branch onto <branch>
git rebase main                 # Most common: rebase current feature onto main
git rebase origin/main          # Rebase onto remote-tracking branch
git rebase <sha>                # Rebase onto a specific commit
git rebase --onto <newbase> <upstream> <branch>  # Three-argument form (see below)

Merge vs. Rebase

Before:
  main:    A---B---C
  feature:     D---E

git merge main → preserves fork:
  feature: A---B---C---M (merge commit)
                \   /
                 D-E

git rebase main → linear history:
  feature: A---B---C---D'---E'

Interactive Rebase

Rewrite, reorder, squash, edit, or drop commits in a range:

git rebase -i HEAD~3            # Interactively rebase the last 3 commits
git rebase -i HEAD~10           # Last 10 commits
git rebase -i <sha>             # Commits after a specific commit
git rebase -i <sha>^            # Include that commit too
git rebase -i --root            # Edit the entire history from the very first commit

Interactive Rebase Commands

CommandAliasAction
pickpKeep the commit as-is
rewordrKeep commit but edit the message
editePause to amend the commit (changes or message)
squashsMeld into the previous commit (keep both messages)
fixupfMeld into the previous commit (discard this message)
dropdRemove the commit entirely
execxRun a shell command after this commit
breakbPause here (use --continue to resume)
labellLabel the current HEAD for use by reset
resettReset HEAD to a label
mergemCreate a merge commit (preserves branches in rebase)
# Example: squash last 3 commits into one
git rebase -i HEAD~3
# In the editor, change "pick" to "squash" (or "fixup") for commits 2 and 3

Rebase Flow Control

git rebase --continue           # Continue after resolving a conflict
git rebase --skip               # Skip the current conflicting commit
git rebase --abort              # Abort the entire rebase, return to pre-rebase state
git rebase --quit               # Abort but leave HEAD where it is (Git ≥2.12)
git rebase --edit-todo          # Re-open the todo list in interactive rebase
git rebase --show-current-patch # Show the current conflicting patch

The --onto Flag

Replays commits from <upstream>...<branch> onto <newbase>:

git rebase --onto <newbase> <upstream> <branch>
# Move feature2 (branched from feature1) directly onto main
git rebase --onto main feature1 feature2

# Move the last 4 commits to a different base
git rebase --onto main HEAD~4 HEAD

# Remove a range of commits from the middle
git rebase --onto HEAD~5 HEAD~3 HEAD   # Drop the 2 commits at HEAD~4 and HEAD~3

Visual Example

Before:
  main: A---B
  feature1: A---B---C---D
  feature2: A---B---C---D---E---F

git rebase --onto main feature1 feature2

After:
  main: A---B
  feature1: A---B---C---D  (unchanged)
  feature2: A---B---E'---F'

Rebasing onto a Remote

git fetch origin
git rebase origin/main          # Rebase onto the fetched remote main
git pull --rebase               # Fetch + rebase in one step
git pull --rebase=interactive   # Fetch + interactive rebase

Autosquash

Automatically squash commits whose messages start with fixup! or squash!:

git commit --fixup=<sha>        # Create a "fixup! <original-message>" commit
git commit --squash=<sha>       # Create a "squash! <original-message>" commit
git rebase -i --autosquash HEAD~10  # Auto-arrange fixup!/squash! commits

Auto-enable autosquash:

git config --global rebase.autoSquash true

Auto-Stash During Rebase

git rebase --autostash main     # Stash dirty state, rebase, re-apply stash
git config --global rebase.autoStash true  # Always auto-stash

Rebase Preserving Merges

git rebase -p <branch>          # Preserve merge commits (--preserve-merges, deprecated)
git rebase --rebase-merges <branch>  # Modern replacement (Git ≥2.18)
git rebase -r <branch>          # Shorthand for --rebase-merges

Resolving Rebase Conflicts

git status                      # See which file has a conflict
# Edit the file and resolve conflict markers
git add <resolved-file>
git rebase --continue           # Move to the next commit
# or:
git rebase --skip               # Drop this commit's changes and continue
# or:
git rebase --abort              # Give up and return to pre-rebase state

During interactive rebase with edit:

# Git pauses at that commit in detached HEAD
git commit --amend              # Amend the commit (message or changes)
git rebase --continue           # Resume

exec Command

Run a command after each (or a specific) commit during interactive rebase:

# In the todo list:
pick abc1234 feat: add login
exec npm test
pick def5678 feat: add logout
exec npm test

Or run a command across all commits:

git rebase -i --exec "npm test" HEAD~10

Splitting a Commit

git rebase -i HEAD~3
# Mark the commit you want to split as "edit"
# Git pauses at that commit:
git reset HEAD^                 # Unstage all changes from this commit
git add -p                      # Stage first portion interactively
git commit -m "part one"
git add -p                      # Stage second portion
git commit -m "part two"
git rebase --continue

Safety Rules

Never rebase commits that have been pushed to a shared branch. Rebase rewrites commit SHAs; pushing rewritten commits forces everyone else to reconcile diverged history.

Safe to rebase: local-only commits, personal feature branches not shared with others.

If you've already pushed and must rebase anyway: coordinate with the team, then git push --force-with-lease.

Configuring Rebase Defaults

git config --global pull.rebase true          # Always rebase on pull
git config --global rebase.autoSquash true    # Enable --autosquash by default
git config --global rebase.autoStash true     # Auto-stash dirty state
git config --global rebase.stat true          # Show diffstat after rebase
git config --global sequence.editor "code --wait"  # Editor for todo list

Checking for Rebase Conflicts Ahead of Time

git merge-base main HEAD        # Find the common ancestor SHA
git log main..HEAD              # Commits that will be replayed
git diff main...HEAD            # Changes introduced since branch point