git-revert-deshacer-cambios-publicos

Undoing Public Changes with Git Revert

  • 5 min

The git revert command is a command that cleanly undoes the modifications of a commit with a new commit.

In the previous post, we saw how to use git reset to clean up the history of our local Git. But reset can only be used if you haven’t shared your code.

But, what happens if you mess up, do a git push, your teammates pull the code, and then you realize the mistake?

But if by accident you broke the code, pushed it to the server, and your teammates had already pulled and integrated it, touching the histories would blow up with problems for everyone. You cannot delete that commit.

You must amend it. The only formula is to apply one more step where we will apply the inverse changes to fix the damage. That’s what git revert is for.

The Concept of the “Anti-Commit”

Git Revert does not delete anything. It creates a new commit that does exactly the opposite of the commit you want to eliminate.

If the original commit added a line, the revert deletes it. If it deleted a file, the revert creates it again.

Think of Git as an accounting ledger.

  • Commit A says: “Income 100€”.
  • Commit B says: “Expense 20€”.

If you want to cancel the 20€ expense but the ledger is already closed and audited, you cannot tear out the page (that would be doing a reset). What you do is add a new line that compensates for the error.

  • New Commit C: “Refund of 20€”.

That’s exactly what git revert does.

Reset vs Revert

This is the table you should keep in mind to choose between them:

Featuregit resetgit revert
What does it do?Moves the pointer back (deletes history)Creates a new commit (adds history)
SafetyDestructiveNon-destructive
Where to use it?Local / private branchesPublic / shared branches
Use caseI made a mistake on my machineI pushed a bug to production yesterday

How to use it

Let’s assume the history is this:

a1b2c3d (HEAD -› main) Add CSS styles (ERROR: breaks the layout) 98f1e2a Finished functionality

The commit a1b2c3d is a disaster and is already in production. To undo it:

git revert a1b2c3d
Copied!

When you execute it, the following will happen:

Git will calculate the inverse of the changes from that commit.

Your text editor will open asking for a message (by default: “Revert “Add CSS styles”…”).

You save and close.

Now your history looks like this:

f5g6h7j (HEAD -> main) Revert “Add CSS styles” a1b2c3d Add CSS styles 98f1e2a Finished functionality

The error is still in the history (commit a1b2c3d), but the current code no longer has it because commit f5g6h7j has undone it. History moves forward, code moves backward.

Reverting multiple commits

Sometimes the mistake wasn’t just the last commit, but the last three. You can revert a range using ..:

git revert HEAD~3..HEAD
Copied!

This will create 3 revert commits, one for each undone commit

If you prefer that Git doesn’t create 3 revert commits, but instead leaves the changes “staged” in your working area for you to make a single commit that undoes everything at once, use the --no-commit (or -n) option:

git revert -n HEAD~3..HEAD
git commit -m "Revert complete X functionality"

Copied!