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

# Amending a Commit

Fixing the last commit's message or content; producing a new object because a commit is immutable, the reflog, and the limit of shared history.

The previous lesson undid changes that had not yet been committed. This lesson goes one
step further: it takes up what to do if a commit that has already been written is
missing something or has a mistake. The two most common cases are a mistyped message and
a file that was forgotten from the commit.

## Amending Does Not Actually Change Anything

A commit object is immutable. Its ID is the hash of its content; if the content changes,
the ID changes too, and a different object results. This is why the operation called
"amending a commit" does not edit the existing object: it creates a **new** commit
attached to the same parent, and moves the branch tip to that new commit. The old commit
stays in the object database but becomes unreachable from any ref.

The distinction matters in practice: fixing the past is rewriting the past.

## Fixing the Message

A usage section is added to `README.md` and committed; but the message has two typos:

```bash
git commit -m "READMEye kullanm bölümü ekle"
```

```
[main c190fa9] READMEye kullanm bölümü ekle
 1 file changed, 4 insertions(+)
```

```bash
git commit --amend -m "README'ye kullanım bölümü ekle"
```

```
[main d847955] README'ye kullanım bölümü ekle
 Date: Fri Mar 8 11:30:00 2024 +0300
 1 file changed, 4 insertions(+)
```

The ID went from `c190fa9` to `d847955`. Not a single byte of the content changed; the
only thing that changed was the message, and the message enters the ID computation too.

The `Date:` line in the output is printed to report that the commit's author date was
preserved.

That the only thing that changed is really the message can be tested by comparing tree
IDs:

```bash
git log -1 --format='%h %T' c190fa9
git log -1 --format='%h %T' d847955
```

```
c190fa9 4e359f7361da5c8654dce5682f26e5a79e43f5ca
d847955 4e359f7361da5c8654dce5682f26e5a79e43f5ca
```

The two commits point at the same tree. The project content is byte-identical, the
commit IDs are different: this is direct proof that the ID covers metadata as well as
content. The only thing newly written to the object database is the second commit
object; the blob and tree objects are shared.

## Author and Committer

The reason the commit object's two date fields are kept separate shows up here:

```bash
git log -1 --format='author   : %an %ad%ncommitter: %cn %cd' --date=iso
```

```
author   : Deniz Kaya 2024-03-08 11:30:00 +0300
committer: Deniz Kaya 2024-03-08 11:33:00 +0300
```

The **author** is the person who wrote the change, and the time that change was first
created. The **committer** is the person who put the commit into the object database,
and the time of that recording. Amending preserves the author field and updates the
committer field. Keeping the two fields separate ensures the source is not lost in cases
where a contribution is placed into history by someone else.

## Adding a Forgotten Change

`README.md` had been committed without the line describing the exit code. The missing
line is added, staged, and folded into the commit while keeping the message:

```bash
git add README.md
git commit --amend --no-edit
```

```
[main 18600c5] README'ye kullanım bölümü ekle
 Date: Fri Mar 8 11:30:00 2024 +0300
 1 file changed, 6 insertions(+)
```

`--no-edit` uses the existing message without opening the editor. The line count went
from four to six: the staging area's content formed the new commit's tree.

History shows a single commit:

```bash
git log --oneline -n 3
```

```
18600c5 README'ye kullanım bölümü ekle
bfe57d3 Öbek ve dizi terimlerini ekle
cb8f7ee Yerel notları izlemeden çıkar
```

Three separate commit objects were written — `c190fa9`, `d847955`, `18600c5` — but only
the last one stands in history. The first two became unreachable.

## The Scope of Amending

`--amend` builds the new commit's tree from **the staging area's current state**. This is
as much a trap as a convenience: if the staging area holds files staged for other work,
they enter the amended commit too, and end up recorded in the wrong place in history.

When only the message needs fixing, the staging area needs to match the last commit. The
check is a single command:

```bash
git status --short
```

The output's first column should carry no mark. If it does, those entries will enter the
scope of the amend.

The same mechanism applies to the author field. The `--author` option sets the new
commit's author; a commit written while the configured identity was wrong is fixed this
way. The committer field is still taken from the configuration, so the two fields
diverge — this is the expected result of keeping the fields separate.

## What Happened to the Old Commits

Being unreachable is not the same as being gone:

```bash
git cat-file -t c190fa9
```

```
commit
```

The object is in place. The way to reach it is the **reflog**: a local log that records
what values `HEAD` and branch tips took on in the past.

```bash
git reflog -n 3
```

```
18600c5 HEAD@{0}: commit (amend): README'ye kullanım bölümü ekle
d847955 HEAD@{1}: commit (amend): README'ye kullanım bölümü ekle
c190fa9 HEAD@{2}: commit: READMEye kullanm bölümü ekle
```

The `HEAD@{n}` notation names the value of the `HEAD` ref `n` steps ago. The log is
local and is not shared; an amend made in one copy of the repository does not show up in
another copy's log.

Unreachable objects do not stay forever. **Garbage collection**, which runs during
repository maintenance, deletes objects unreachable from any ref and from the reflog. The
default retention period is long enough; but it is not correct to work under the
assumption that "an unreachable object is permanent." The recovery window is limited.

## Bringing Back a Lost Commit

The reflog is not just a record; it is a recovery tool. The way to make a commit that was
amended by mistake reachable again is to give it a name:

```bash
git branch recovery HEAD@{2}
git log --oneline -n 2 recovery
```

```
c190fa9 READMEye kullanm bölümü ekle
bfe57d3 Öbek ve dizi terimlerini ekle
```

The command runs silently and creates a ref named `recovery`. Because the object is now
reachable from a name, it falls outside the scope of garbage collection; once the
content has been inspected and whatever was needed has been taken, this name can be
deleted.

The same thing can be done with an ID: `c190fa9` from the reflog can be written directly.
The `HEAD@{n}` notation is preferred, because which step to go back to is read from the
sequence, not the ID.

The general rule here is this: a single name that can reach an object is enough to
protect it. Operations like amending and the resetting seen in the next lesson do not
delete objects; they only move the names pointing to them.

## The Limit of Amending

Amending applies only to the **last** commit, and is safe only on **unshared** commits.

The reason for the second condition is that the ID covers the chain of parents. When a
commit is amended, its ID changes; every commit after it is then forced to change its
parent field too, and their IDs change. History, from the amended point on, ends up made
entirely of new objects.

A copy that already has this history keeps holding on to its own old chain. The result
is two separate chains, in two copies, that contain the same changes but carry different
IDs; when someone tries to merge them, every commit appears twice. In a repository worked
on collaboratively, this is a situation to avoid.

The rule is simple: if a commit has been shared, it is not amended. Instead, a new
commit is written that reverses its effect — reverting, the subject of the next lesson.

Amending is also a narrow tool because it is limited to the last commit alone. When an
older commit needs fixing, history has to be rewritten from that point on; these
operations will be covered in the Advanced Git course.

## Summary

- A commit object is immutable; amending creates a new commit attached to the same
  parent and moves the branch tip to it.
- Because the ID covers the message too, fixing only the message still produces a new
  ID.
- The author field is preserved, the committer field is updated; keeping the two fields
  separate preserves the contribution's source.
- Old commits become unreachable but are not deleted; the reflog makes it possible to
  reach them. Garbage collection deletes unreachable objects after a certain period.
- Amending applies only to the last commit, and only to unshared history.

## Next Step

Amending targets the last commit and moves the branch tip to a new object. It is also
possible to move the branch tip further back — that is, to drop more than one commit from
history — and this operation has three different modes. The next lesson shows, one by
one, what these modes do to the working directory and the staging area.
