Computing and the Command Line

Rebasing

Rebasing takes your branch's commits and replays them on top of another branch, giving a straight history instead of a merge commit. The new commits get new IDs, which is why the golden rule says never to rebase commits other people already have. Rebasing conflicts and --continue/--abort, tidying your own commits with interactive rebase (reword, squash, fixup, drop), and when to merge instead.

  • 5 min
  • 7 steps
  • 2 questions
  • Lesson 33 of 80

In this lesson

  1. What rebase does
  2. The golden rule
  3. Rebase conflicts
  4. Tidying commits: interactive rebase
  5. Merge or rebase?
  6. Your turn
  7. So

What rebase does

Merging combines two branches with a merge commit. Rebasing does something different: it takes the commits on your branch and replays them, one by one, on top of another branch, as if you’d started your work from there 1.

me@linuxbox:~/garden$ git log --oneline --graph --all
* 304505a (main) Add garlic
| * 61c9ab4 (HEAD -> compost) Add compost schedule
| * ca5bca4 Plan the compost bin
|/
*   51d3821 Merge branch 'spacing'
me@linuxbox:~/garden$ git rebase main
Successfully rebased and updated refs/heads/compost.
me@linuxbox:~/garden$ git log --oneline --graph --all
* 09e3458 (HEAD -> compost) Add compost schedule
* ce75ff3 Plan the compost bin
* 304505a (main) Add garlic
*   51d3821 Merge branch 'spacing'

The history is now a straight line, and merging compost into main is a simple fast-forward. The end result, the files, is the same as a merge; the history is cleaner 1.

Look at the IDs: ca5bca4 became ce75ff3, and 61c9ab4 became 09e3458. A commit’s ID is a checksum of everything in it, including its parent. Rebasing gives each commit a new parent, so rebasing doesn’t move commits; it makes new ones and abandons the old ones 1.

Before: main has gained commit 3045, Add garlic, since the compost branch split off at 51d3; compost has two commits, ca5b and 61c9. After git switch compost and git rebase main: the history is a straight line, 51d3, 3045, then new commits ce75 and 09e3 on compost, with new IDs; the old ca5b and 61c9 are abandoned. Right, the golden rule: never rebase commits that other people already have and may have built on. Rebase to tidy your own local work before sharing; merge once it's shared. git rebase -i main lets you reorder, squash, and reword your local commits.
Same changes, replayed on a new base, with new IDs. Credit: StudyCorner diagram · CC BY 4.0 · Source

Quick check

Why do rebased commits get new IDs?

The golden rule

That’s why rebasing comes with one rule, Pro Git’s single-line warning 1: never rebase commits that other people already have and may have built on.

If you rebase commits someone else already has, their copies and yours now hold different commits for the same work, and sorting that out is painful 1. So:

  • Rebase your own local work, before you share it, to tidy it up or bring it up to date with main.
  • Merge once work is shared.

For this course’s projects, which are yours alone, rebase freely. On shared branches, don’t.

Quick check

Which is safe?

Rebase conflicts

Replaying commits can hit the same conflicts a merge can, but one commit at a time. Git stops at the commit that conflicts 2:

  1. Fix the file, as in the last lesson, and git add it.
  2. git rebase --continue to carry on with the next commit.
  3. Or git rebase --abort to put everything back as it was before the rebase.

Tidying commits: interactive rebase

git rebase -i opens a list of your recent commits in your editor and lets you rewrite them before sharing 1 2:

me@linuxbox:~/garden$ git rebase -i main
pick ce75ff3 Plan the compost bin
pick 09e3458 Add compost schedule
pick 7a1b2c3 Fix typo in compost plan

Change the word at the start of a line to say what to do with that commit, then save and close:

Word Does
pick keep the commit as is
reword keep it, but edit its message
squash fold it into the commit above, combining messages
fixup fold it into the commit above, dropping its message
drop delete the commit

Reorder lines to reorder commits. The classic use: three messy commits (“WIP,” “fix,” “fix again”) become one clean one before you share the branch. The same golden rule applies, since every rewritten commit gets a new ID.

Merge or rebase?

Both are fine, and teams choose their own convention 1:

  • Merge keeps the true history: when things happened, in parallel.
  • Rebase gives a tidy, linear history that’s easier to read.

A common habit: rebase your private branch on main to bring it up to date and clean it up, then merge it into main.

Your turn

Exercises

  1. Make a branch with two commits; meanwhile, make a commit on main. Draw the graph, then rebase your branch onto main and draw it again. Which IDs changed?
  2. Merge the rebased branch into main. Was it a fast-forward?
  3. Make three small commits on a new branch, then use git rebase -i main to squash them into one, with a good message.
  4. Cause a conflict during a rebase, resolve it, and finish with git rebase --continue.
Answers
  1. Your branch’s two commits get new IDs; main’s commit keeps its ID. The graph becomes a straight line.
  2. Yes: after the rebase, main is directly behind your branch.
  3. Mark the second and third lines squash (or fixup), save, and write one combined message. git log --oneline then shows a single commit.
  4. Fix the file, git add, git rebase --continue. If several commits conflict, you may do this more than once.

So

Rebasing replays your commits on top of another branch, giving a straight history; each replayed commit is new, with a new ID. So rebase only work nobody else has: tidy and update your own branches, squash messy commits with git rebase -i, and merge once work is shared. In a conflict, fix, git add, git rebase --continue, or --abort.

Lesson complete

Nice work.

1day streak
0/1today's goal
–correct

Up next · 5 min

Clone, Fetch, Pull, Push

Next lesson
Sources for this lesson
  1. 1
    Scott Chacon, Ben Straub. Pro Git, 2nd edition. Apress; free online at git-scm.com. 2014. verifiedFree CC BY-NC-SA 3.0 book, maintained online. Ch. 1: version control; Git's 2005 origin when the Linux kernel lost free use of BitKeeper; snapshots, not differences (unchanged files stored once); nearly every operation local; integrity through 40-character SHA-1 checksums; the three states (modified, staged, committed) and three areas (working tree, staging area or index, .git directory); first-time setup with system/global/local config levels, user.name and user.email baked into commits, core.editor, git config --list --show-origin. Ch. 2: git init, status (and -s), add, diff and diff --staged, commit (-m, -a), .gitignore, log options, amending, undoing, remotes, tags, aliases. Ch. 3: branches as movable pointers, HEAD, merging and conflicts, remote branches, rebasing and its rule. Ch. 7: reset demystified, stashing, revision selection. Ch. 8: core.autocrlf true on Windows, input on Linux and macOS. Ch. 10: objects (blob, tree, commit) and references.
  2. 2
    git-rebase documentation. Git project (git-scm.com). verifiedReapply commits on top of another base tip. On a conflict, resolve it, git add, and git rebase --continue, or --abort to return to the original branch, or --skip. -i/--interactive opens a todo list where each commit can be pick, reword, edit, squash, fixup, or drop, and lines can be reordered.