Undoing a Commit That Is Already In
Topic 18

Undoing a Commit That Is Already In

Undo

The commit is made. Possibly it is on GitHub. Possibly Theo already has it. And it was wrong.

Amending is off the table — that was the rule on the last page. What you want instead is git revert: a command that makes a new commit doing the exact opposite of the old one, leaving the history honest about what happened.

How revert works

Undo the change that commit made
git revert 7f4b2a9

Git works out what that commit did and creates a new commit doing the reverse. Lines it added are removed; lines it removed come back. Nothing is deleted from the history: the project gains a step rather than losing one.

Git opens an editor with a proposed message — usually Revert "Add the sightings list". Accept it or improve it; the way out of the editor is the same one from Chapter 2.

Both commits, side by side in the log
9a1c3e5 Revert "Redesign the home page"
7f4b2a9 Redesign the home page

Why adding beats removing

This is the part worth understanding, because it is the reason revert is the right tool for anything shared.

Suppose Theo already pulled the bad commit. If your fix were to remove it from the history, your copy of the project and his would now disagree about a commit he definitely has. Git has no good way to resolve that on its own, and the resulting mess is the subject of a whole section in Chapter 10.

A revert avoids all of it. Theo pulls once more, receives an ordinary new commit, and the undo applies to his copy exactly as it did to yours. Nothing disagrees with anything.

Revert adds a step; it does not remove one
a3f9c21Add the home page
7f4b2a9Redesign the home page
9a1c3e5Revert "Redesign…"

The mistake stays visible

Some people dislike this: the bad commit is still in the log, for anyone to see.

It is a feature. The history is a record of what happened, and what happened is that a change went in and was taken out again. Reading that later tells you something true and occasionally important — that this approach was tried, and that it did not work.

Reverting a revert

Perfectly ordinary, and it works exactly as you would expect. Revert the revert and the original change comes back, as another new commit. This is common when a change is pulled out to unblock something and put back a day later.

The other command, named honestly

You will see git reset --hard suggested for undoing commits. It is worth knowing what it is so that you can decline it.

git reset moves your branch to a different commit. With --hard it also overwrites your working directory to match, discarding uncommitted work in the process. Used deliberately on a local branch it is a real tool with real uses. Copied from a forum into a shared project, it is the origin of most "I lost a day of work" stories.

This book teaches revert for undoing commits and does not use reset anywhere. The full picture — what it does, when it is right — is one of the deep dive's chapters.

Common Confusions
  • "Revert deletes the bad commit." It adds an opposite one. Both stay in the log, and that is exactly what makes it safe for work other people already have.
  • "git reset --hard is just the quicker version of revert." It is a different operation that moves your branch and can discard uncommitted work at the same time. For a mistake that is already committed, revert is the tool.
  • "Reverting a revert is nonsense." It is a normal way to bring a change back, and it behaves exactly as you would guess.
  • "Revert undoes everything since that commit." It undoes the changes of the one commit you name. Everything committed after it stays exactly as it is.
Why It Matters
  • Revert is the only undo in this book that is safe on history other people already have, which makes it the one that matters from Chapter 7 onward.
  • Adding rather than removing keeps the log truthful, and a truthful log is what the blame-then-show loop in Chapter 3 depends on.
  • Knowing what reset --hard is protects you from the single most expensive piece of advice a beginner can copy from a forum.

Knowledge Check

What does git revert add to your history?

  • A new commit whose changes are the opposite of the one you named
  • A marker on the original commit showing that it has been cancelled
  • Nothing — it removes the named commit and rewrites the ones after it
  • A copy of the project as it was before the named commit was ever made

Why is revert the right tool once a commit has been pushed?

  • Because everyone else receives the undo as an ordinary new commit
  • Because pushed commits are locked by the server and cannot be modified
  • Because revert is faster than the alternatives when the history is long
  • Because it notifies collaborators that a change has been undone

You revert a commit that added a feature. Two days later the team wants it back. What now?

  • Revert the revert, which reinstates the change as yet another new commit
  • Nothing can be done, because the original commit's changes were deleted
  • The feature has to be written again from scratch and committed as new work
  • You must amend the revert commit to remove the changes it introduced

What does git reset --hard do that makes this book avoid it?

  • It moves your branch and overwrites the working directory, discarding uncommitted work
  • It permanently deletes commits from every copy of the repository at once
  • It rewrites every commit message in the history to match the new state
  • It uploads the change to the server before you have had a chance to review it

You got correct