Skip to content

commit: preserve commit hash on a no-op amend#2334

Open
HaraldNordgren wants to merge 2 commits into
git:masterfrom
HaraldNordgren:amend-noop-keeps-commit
Open

commit: preserve commit hash on a no-op amend#2334
HaraldNordgren wants to merge 2 commits into
git:masterfrom
HaraldNordgren:amend-noop-keeps-commit

Conversation

@HaraldNordgren

@HaraldNordgren HaraldNordgren commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

git commit --amend --no-edit rewrote the commit and moved the branch
tip even when nothing changed, because the committer date was reset to
"now". Reuse the existing committer date so a no-op amend keeps the
commit hash and leaves the branch untouched.

A real change (tree, message, author, committer, or signing) still
rewrites as before.

cc: Johannes Sixt j6t@kdbg.org

@HaraldNordgren HaraldNordgren force-pushed the amend-noop-keeps-commit branch 4 times, most recently from e049e8d to faa4b57 Compare June 12, 2026 11:13
@HaraldNordgren HaraldNordgren changed the title commit: keep the commit on a no-op amend commit: keep the commit date on a no-op amend Jun 12, 2026
@HaraldNordgren HaraldNordgren changed the title commit: keep the commit date on a no-op amend commit: preserve commit hash on a no-op amend Jun 12, 2026
@HaraldNordgren HaraldNordgren force-pushed the amend-noop-keeps-commit branch 18 times, most recently from 90de46c to a8e5e5f Compare June 12, 2026 20:34
A later change adds a second caller that commits the index lock and dies
on failure, so wrap that into a helper to avoid duplicating its message.

No functional change intended.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
@HaraldNordgren HaraldNordgren force-pushed the amend-noop-keeps-commit branch 3 times, most recently from 74577b7 to 28ce025 Compare June 12, 2026 20:47
@HaraldNordgren HaraldNordgren force-pushed the amend-noop-keeps-commit branch 8 times, most recently from ca4bf1b to b932927 Compare June 13, 2026 08:03
"git commit --amend --no-edit" reset the committer date to "now" and
rewrote the commit even when nothing else changed, moving the branch tip
to a new hash for an effective no-op.

Build the amended commit reusing the existing committer date: if that
reproduces the current commit, leave the branch alone, report "nothing
to amend", and skip the reflog entry and the post-commit and post-rewrite
hooks.

Signing always rewrites the commit, since its signature cannot reproduce
the original, so it skips this detection.

Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
@HaraldNordgren HaraldNordgren force-pushed the amend-noop-keeps-commit branch from b932927 to 44be2f9 Compare June 13, 2026 08:10
@HaraldNordgren

Copy link
Copy Markdown
Contributor Author

/submit

@gitgitgadget-git

Copy link
Copy Markdown

Submitted as pull.2334.git.git.1781342189.gitgitgadget@gmail.com

To fetch this version into FETCH_HEAD:

git fetch https://github.com/gitgitgadget/git/ pr-git-2334/HaraldNordgren/amend-noop-keeps-commit-v1

To fetch this version to local tag pr-git-2334/HaraldNordgren/amend-noop-keeps-commit-v1:

git fetch --no-tags https://github.com/gitgitgadget/git/ tag pr-git-2334/HaraldNordgren/amend-noop-keeps-commit-v1

@gitgitgadget-git

Copy link
Copy Markdown

Johannes Sixt wrote on the Git mailing list (how to reply to this email):

Am 13.06.26 um 11:16 schrieb Harald Nordgren via GitGitGadget:
> git commit --amend --no-edit rewrote the commit and moved the branch tip
> even when nothing changed, because the committer date was reset to "now".
> Reuse the existing committer date so a no-op amend keeps the commit hash and
> leaves the branch untouched.

`git commit --amend --no-edit` is a way to set the committer timestamp
to the current time without changing other aspects of the commit. This
takes away this ability, doesn't it?

Is this keyed to --no-edit? Why is this mode special? Wouldn't it be an
identical case when the commit message is passed to the editor, but
comes back unchanged?

An invocation of `git commit` asks to "please make a new commit". But in
the suggested mode, no new commit is created. Shouldn't this then be
regarded as failure?

What happens with the current branch? Is it left unchanged (no ref
update occurs) or is it changed (a ref update occurs, but it happens to
be a no-op)? And does this then generate a reflog entry?

The updated documentation says about signed commits (note: I am totally
clueless about commit signing procedures):

> A commit that is being signed (`-S`, or `commit.gpgsign`)
> is always rewritten, since its signature cannot reproduce the original.

But if the commit doesn't change in any way, why should the signature be
invalidated, rewritten, or updated?

-- Hannes

@gitgitgadget-git

Copy link
Copy Markdown

User Johannes Sixt <j6t@kdbg.org> has been added to the cc: list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant