---
title: Reverting
source: 'https://academia.sh/en/courses/introduction-to-version-control/reverting'
course: 'Introduction to Version Control'
language: en
updated: '2026-08-17T18:10:48+00:00'
license: 'CC BY-SA 4.0'
---

# Reverting

A new commit that reverses another's effect; undoing without disturbing history, verifying with the tree ID, reverting without committing, and reverting a revert.

Reset and amending both work by rewriting history; this is why they cannot be used on
shared commits. If a shared commit is wrong, only one path remains: leave the past as it
is, and write a **new** commit that reverses the mistake's effect. This operation is
called **reverting**.

## The Mistake

The search script's output is meant to be limited to just the Turkish column, and
`grep`'s output is passed through a filter:

```sh
if ! grep -i -- "$1" terimler.txt | cut -d '|' -f 1; then
    echo "eşleşme yok: $1" >&2
    exit 2
fi
```

```bash
git commit -m "Arama çıktısını yalnızca Türkçe sütuna indir"
```

```
[main ad60f31] Arama çıktısını yalnızca Türkçe sütuna indir
 1 file changed, 1 insertion(+), 1 deletion(-)
```

The change produces the intended output but carries a hidden flaw: the shell takes the
pipeline's exit code from the last command. Because `cut` always finishes successfully,
the condition comes out false even when `grep` finds no match:

```bash
./ara.sh yokboyle
echo "exit code: $?"
```

```
exit code: 0
```

The script printed no no-match notice and exited with code zero; yet there is no match,
and the exit code should be 2. The flaw is not in the output itself but in the error
reporting; this is why it is prone to going unnoticed.

The commit has been shared, and it cannot be dropped from history.

## Reverting

```bash
git revert --no-edit ad60f31
```

```
[main a58791f] Revert "Arama çıktısını yalnızca Türkçe sütuna indir"
 Date: Mon Mar 11 10:12:00 2024 +0300
 1 file changed, 1 insertion(+), 1 deletion(-)
```

`--no-edit` accepts the prepared message without opening the editor. The script works
correctly again:

```bash
./ara.sh yokboyle
```

```
eşleşme yok: yokboyle
```

```bash
git log --oneline -n 4
```

```
a58791f Revert "Arama çıktısını yalnızca Türkçe sütuna indir"
ad60f31 Arama çıktısını yalnızca Türkçe sütuna indir
18600c5 README'ye kullanım bölümü ekle
bfe57d3 Öbek ve dizi terimlerini ekle
```

The faulty commit stands in history. Alongside it, a commit that reverses its effect has
been added.

## The Content of a Revert Commit

```bash
git show HEAD
```

```
commit a58791f8f8b5325563397d592015cb2009b5e567
Author: Deniz Kaya <deniz@ornek.test>
Date:   Mon Mar 11 10:12:00 2024 +0300

    Revert "Arama çıktısını yalnızca Türkçe sütuna indir"

    This reverts commit ad60f311bd296f370a18d98a40173d878160d809.

diff --git a/ara.sh b/ara.sh
index 64b5b70..582ddde 100755
--- a/ara.sh
+++ b/ara.sh
@@ -6,7 +6,7 @@ if [ $# -ne 1 ]; then
     exit 1
 fi
 
-if ! grep -i -- "$1" terimler.txt | cut -d '|' -f 1; then
+if ! grep -i -- "$1" terimler.txt; then
     echo "eşleşme yok: $1" >&2
     exit 2
 fi
```

The diff is the reverse of the reverted commit's diff: the deleted line has been added,
the added line has been deleted. The automatically generated message writes the
reverted commit's full ID into the body; thanks to this line, what a revert undoes can be
read straight from history.

## Verifying the Result

Whether the revert really returned things to the previous state can be tested with
certainty by comparing tree IDs:

```bash
git log --format='%h %T %s' -n 4
```

```
a58791f ac0eb40463f387ce1cb40623aa9c16a9a7ed229f Revert "Arama çıktısını yalnızca Türkçe sütuna indir"
ad60f31 9ab09543909d738602a2a947e858b1457972ef28 Arama çıktısını yalnızca Türkçe sütuna indir
18600c5 ac0eb40463f387ce1cb40623aa9c16a9a7ed229f README'ye kullanım bölümü ekle
bfe57d3 c6ec3cea3b8943f818cd8bb423c65f0cb5c553ea Öbek ve dizi terimlerini ekle
```

The revert commit's tree, `ac0eb40`, is the same as the tree of `18600c5`, the commit
before the faulty one. Two different commits point at the same tree: the project content
has returned to its old state, byte for byte. This equality check, which
content-addressed storage provides, removes the need to compare diffs by eye.

## Why Reverting Does Not Disturb History

Reverting only adds: it touches no existing object, it changes no ID. Copies that
already have this history keep the chain they hold and take on just one new commit on
top. The incompatibility that arises with reset does not occur here.

The cost is that the mistake stays visible in history. This is not a flaw; it is, most
of the time, the desired behavior: when a faulty change went in, and when and why it was
undone, ends up on record.

## Reverting Without Committing

The result of a revert can be inspected without committing it directly:

```bash
git revert -n bfe57d3
git status --short
```

```
M  terimler.txt
```

```bash
git diff --staged
```

```
diff --git a/terimler.txt b/terimler.txt
index a5350ef..17af3b8 100644
--- a/terimler.txt
+++ b/terimler.txt
@@ -5,5 +5,3 @@ ağaç | tree
 karma tablosu | hash table
 bağlı liste | linked list
 küme | set
-öbek | heap
-dizi | array
```

The `-n` option puts the change in the staging area but does not commit it. This is
used to combine multiple commits into a single revert commit, or to inspect the result
before committing it. The operation can be canceled:

```bash
git revert --abort
```

The command returns the working directory and the staging area to their state before
the revert began.

In the example, the reverted commit was not history's most recent one. A revert can be
applied to any commit; what is computed is that commit's diff, reversed, applied to the
current content. If the commits in between touched the same lines, the application
fails and a conflict is reported. Resolving conflicts is the subject of the Branching
and Collaboration course.

## Reverting a Revert

A revert is a commit too; it can be reverted. This is the way to reapply a change that
was undone:

```bash
git revert --no-edit a58791f
```

```
[main 464855e] Reapply "Arama çıktısını yalnızca Türkçe sütuna indir"
 Date: Mon Mar 11 15:00:00 2024 +0300
 1 file changed, 1 insertion(+), 1 deletion(-)
```

This time the message starts with `Reapply`, not `Revert`: reverting a revert is, in
essence, reapplying.

```bash
git log --format='%h %T %s' -n 4
```

```
464855e 9ab09543909d738602a2a947e858b1457972ef28 Reapply "Arama çıktısını yalnızca Türkçe sütuna indir"
a58791f ac0eb40463f387ce1cb40623aa9c16a9a7ed229f Revert "Arama çıktısını yalnızca Türkçe sütuna indir"
ad60f31 9ab09543909d738602a2a947e858b1457972ef28 Arama çıktısını yalnızca Türkçe sütuna indir
18600c5 ac0eb40463f387ce1cb40623aa9c16a9a7ed229f README'ye kullanım bölümü ekle
```

Four commits alternate back and forth between two trees. This last step was not kept in
the example repository's history — the flawed change was not reapplied; the revert was
left standing.

## Reverting or Resetting

| Criterion | Reverting | Resetting |
|---|---|---|
| History | Preserved, a new commit is added | Rewritten |
| On a shared commit | Suitable | Not suitable |
| Visibility of the mistake | Stays on record | Erased |
| Which commit it applies to | Any commit | Backward from the branch tip |

There is a single criterion: if the commit has been shared, revert; if not, either can
be used.

## Summary

- Reverting creates a new commit that applies the reverse of another commit's diff.
- History is preserved; no object changes, only a new commit is added.
- A revert commit's tree is the same as the tree before the reverted commit; this
  equality is a verification tool.
- The `-n` option puts the result in the staging area without committing it; `--abort`
  cancels the operation.
- A revert can be reverted too; the result is the change being reapplied.

## Next Step

The tools covered so far were about completed changes. So what happens when there is
unfinished work and it becomes necessary to switch to something else? Committing is
premature, and undoing is a loss. The next lesson takes up the stash, which sets
unfinished work aside temporarily, and what that storage corresponds to in the object
model.
