Lesson 4 of 6 in Undoing Things
Undoing in public
Story: HQ already has a copy of this timeline. Whatever you fix, fix it in the open.
Amend and reset rewrite history: they take commits off your branch. That's fine for commits only you have. But once you've shared a commit, by pushing it or by letting a teammate pull it, other people's work is built on it. Take it off your branch and your history no longer matches theirs.
git revert undoes a commit without rewriting anything. It makes a new commit that does the opposite of the one you name. Lines the old commit added are removed, lines it removed come back, and files it created are deleted.
git revert HEAD
git writes the new commit's message for you: Revert "Add the banner", a blank line, and a line saying which commit it undoes. Like git commit --amend without -m, git revert opens that message in the edit pane first. Save it as it is, or change it, and git makes the commit.
To keep git's message without opening the edit pane, add --no-edit:
git revert --no-edit HEAD
Either way, git log --oneline then shows the bad commit and the commit that cancels it:
99af3e7 (HEAD -> main) Revert "Add the banner"
0067ace Add the banner
984ebf9 Style the heading
a0ec373 Add the home page
No commit left main. Your branch only moved forward, so everyone who pulls gets the revert as an ordinary new commit, and nothing breaks for them.
Revert any commit
Revert isn't limited to the last commit. Name any commit, and git undoes just that one. The commits after it stay as they are:
git revert HEAD~2
HEAD~2 is two commits before the one you're on. git log --oneline lists the commits newest first, which helps you count.
Every revert is a new commit, so the counting changes after each one. After git revert HEAD, the commit that was HEAD~1 is now HEAD~2. Check git log --oneline before each revert.
Undoing several commits
To undo several commits, revert them one at a time, newest first.
The order matters when a later commit changed the same lines as an earlier one. Revert the earlier one first, and git can't put its lines back, because they've changed since. It stops with a conflict.
If that happens, git revert --abort gives the revert up: your branch, the index and your files go back to how they were before git revert. git's message suggests it too, and git status says a revert is in progress until you abort it.
Reset or revert?
| Compared | git reset |
git revert |
|---|---|---|
| What it does | moves your branch back, so commits leave it | adds a new commit that undoes one |
| History | rewritten | kept, and only grows |
| Use it for | commits only you have | commits others may already have |
A simple rule: if you've pushed it, revert it.
One thing you may see elsewhere: reverting a merge commit needs an extra option, -m, to say which side of the merge to keep. This course doesn't cover it.
New commands
git revertgit revert --no-editgit revert --abort
Explainer: Revert undoes a commit with a new one
Graph as text
project: your repo, you are here
- HEAD → main at ff2859b "Revert "Add a pop-up""
Branches and tags
- main at ff2859b "Revert "Add a pop-up""
Commits, newest first
- ff2859b "Revert "Add a pop-up""; parent e0d92b8; refs: HEAD → main
- e0d92b8 "Revert "Add the banner""; parent 5504731
- 5504731 "Add the banner"; parent 8946bf5
- 8946bf5 "Fix the bread price"; parent f599422
- f599422 "Add a pop-up"; parent 2a3cb2b
- 2a3cb2b "Write the menu"; no parent
Challenge 1 of 3
Story: HQ already has this record, banner and all. Cancel it out in the open.
Everyone on your team already has the commits on main. The last one, Add the banner, is a mistake. Undo it with a new commit, so that no commit leaves main's history.
Unlocks after Branching & Merging.
Terminal
Unlocks after Branching & Merging.
This Lesson can be played once Branching & Merging is complete. Its text and Explainer are open to everyone.