Lesson 1 of 5 in Rewriting History
Rebase
Story: Your timeline split off before the main one moved on. Set your events down after the newest ones instead.
You started a branch, made a few commits, and meanwhile main moved on. Before your work goes back into main, you want it to build on the newest main.
In Branching & Merging you'd merge. git merge main on your branch makes a merge commit that joins the two lines of history. A rebase is the other way to do it: it replays your commits on top of the newest main, as if you'd started your branch from there.
Replaying commits
You're on about, which branched off main before main's newest commit:
$ git rebase main
Successfully rebased and updated refs/heads/about.
Here's what git did:
- It found the commits that are on
aboutbut not onmain. In revision syntax, that'smain..about. - It started from
main's newest commit and replayed those commits on top of it, one at a time, oldest first. For each one, it applied the same change and committed it with the same message. - It moved
aboutto the last of the new commits.
main didn't move. A rebase only moves the branch you're on.
Copies, not moves
A commit never changes. Its id comes from its content and its parent, so a commit with a new parent is a new commit. The rebase made copies: the same changes and messages, with new ids.
The originals are still in the repository, but no branch has them any more, so the Live Graph shows them faded. The reflog remembers them. A branch's reflog records the whole rebase as one move, so right after it, about@{1} is where about was before. main..about@{1} names the originals. If a rebase went wrong, git reset --hard about@{1} puts the branch back, as you learned in Undoing Things. Check git reflog about first if you've done anything since.
A straight line
After the rebase, about starts from main's newest commit, so history is one straight line. main can catch up with a fast-forward:
git switch main
git merge about
There's no merge commit: main just moves up to about.
Merge or rebase?
Both bring the same work together, and the files come out the same. The difference is the history:
- A merge keeps history as it happened: two lines of work, and a merge commit where they meet.
- A rebase rewrites your branch so that its history reads as one straight line, as though you'd done the work after the latest
main.
Teams choose their own habit. Many rebase their own branches to keep history tidy, and merge when work is shared.
Only rebase what you haven't shared
A rebase replaces your commits with copies. That's fine while the commits are only in your repository. Once you've pushed them, someone else may have built on the originals. If you rebase then, your branch no longer contains the commits on origin, so your next push is refused, just as when a teammate got there first. And a plain git pull would merge the originals back in, next to their copies.
So rebase your own work before you push it. Rewriting shared branches, later in this Track, shows the careful way to replace a branch you've already pushed.
Rebasing onto origin/main
A good habit before you publish a new branch: fetch, then rebase onto origin/main, the newest main your repository has heard of.
git fetch
git rebase origin/main
git push -u origin about
Your branch then starts from your team's latest work, and it goes up as one straight line.
When there's nothing to do
If your branch already has every commit of main, git says so and changes nothing:
$ git rebase main
Current branch about is up to date.
A rebase won't start while you have uncommitted changes to tracked files:
$ git rebase main
error: cannot rebase: You have unstaged changes.
error: Please commit or stash them.
Commit them, or set them aside, first.
New commands
git rebase
Explainer: Rebasing replays your commits
Graph as text
project: your repo, you are here
- HEAD → main at 9750797 "Link the about page"
Branches and tags
- about at 9750797 "Link the about page"
- main at 9750797 "Link the about page"
Commits, newest first
- 9750797 "Link the about page"; parent 74f7253; refs: HEAD → main, about
- 74f7253 "Add an about page"; parent c8b7659
- c8b7659 "Describe the website"; parent a4b8d97
- a4b8d97 "Style the heading"; parent ab89288
- ab89288 "Add the home page"; parent 37d7cf7
- 37d7cf7 "Add a README"; no parent
Unreachable
- d1a89c0 "Link the about page"; parent d4b981e
- d4b981e "Add an about page"; parent a4b8d97
Challenge 1 of 3
Story: Your timeline split off a moment too early. Replay it after the newest event.
You're on about, a branch you started before main's newest commit, Describe the website. Rebase about onto main, so that its commit comes after Describe the website in one straight line. Leave main where it is.
Unlocks after Remotes & Collaboration and Undoing Things.
Terminal
Unlocks after Remotes & Collaboration and Undoing Things.
This Lesson can be played once Remotes & Collaboration and Undoing Things are complete. Its text and Explainer are open to everyone.