git commit amend is the command for fixing the commit you just made instead
of undoing it: a typo in the message, a forgotten file, a wrong author, or a change you meant
to squash in before it went any further. Unlike git reset, which moves the branch
pointer and can leave you recommitting from scratch, --amend replaces exactly one
commit — the most recent one — with a corrected version. This guide covers every scenario:
fixing the message alone, adding a forgotten file, amending an older commit buried a few
commits back, amending after you've already pushed or opened a pull request, and the specific
errors people hit along the way. If you want the broader "how do I undo this commit entirely"
decision tree instead, the git undo last commit
guide covers reset, revert, and reflog recovery side by side.
Quick Answer: The Commands You Probably Want
If you landed here mid-task, here are the seven commands that cover almost every "amend commit message" search. Full explanations, including the pushed-commit and older-commit cases, follow below.
| Situation | Command |
|---|---|
| Edit the last commit message | git commit --amend |
| Change the last commit message without an editor | git commit --amend -m "new message" |
| Add a forgotten file, keep the same message | git add file && git commit --amend --no-edit |
| Change a commit message after push | git commit --amend -m "new" && git push --force-with-lease |
| Change the commit message of an older commit | git rebase -i HEAD~n, mark it reword or edit |
| Amend without changing the message at all | git commit --amend --no-edit |
| Fix the author on the last commit | git commit --amend --author="Name <email>" |
The one rule that governs every row above: --amend only ever touches the single
most recent commit on your current branch. For anything further back, skip to the
interactive rebase section. For the official flag
reference, see the git-commit
documentation.
What Does git commit --amend Actually Do?
Git commit objects are immutable — nothing in git ever edits one in place. What
--amend actually does is build a brand-new commit that reuses the same parent as
your current HEAD, then combine the old commit's tree with whatever you've staged
since, apply the message you give it (or the old message, unchanged, if you don't), and point
your branch at that new commit instead. The old commit doesn't disappear instantly — it becomes
unreachable from any branch, but it still exists as an object and shows up in
git reflog until garbage collection eventually prunes it.
One naming note, because it sends a lot of people looking for a command that doesn't exist:
there is no standalone git amend, and nothing called
git change commit message or git modify commit message either. Amend
is a flag on git commit, and all of those phrasings resolve to the same two tools
— git commit --amend for the most recent commit,
git rebase -i for anything further back.
# Before: HEAD points at commit C (parent B)
# git commit --amend creates C', with the same parent B, and moves HEAD to C'
# C is now unreachable from any branch, but survives in the reflog
git log --oneline -1
# c3d4e5f (HEAD -> main) fix: correct retry backoff
git commit --amend -m "fix: correct retry backoff on 429 responses"
git log --oneline -1
# 9f8e7d6 (HEAD -> main) fix: correct retry backoff on 429 responses
That single fact — amend always produces a new SHA — explains almost every
edge case in this guide. A commit's hash is computed from its tree, parent, author, timestamp,
and message together, so changing any one of those, even just the message with
--no-edit left off, yields a different hash. There is no flag that amends a commit
and keeps its old SHA; if the SHA didn't change, nothing was amended. This is exactly why
amending a commit that's already on a remote requires a force-push afterward: the remote is
holding the old SHA, your local branch now has a different one, and a normal push gets rejected
because the histories no longer share a matching tip.
Git Amend Commit Message: Edit the Last Commit Message
The most common reason people run git commit --amend is a typo, a wrong ticket
number, or a message that just doesn't explain the change well enough. Two forms handle it,
depending on whether you want your editor or a one-liner:
# Opens your configured editor with the previous message pre-filled
git commit --amend
# Skip the editor, set the message directly
git commit --amend -m "fix: correct retry backoff on 429 responses"
Both forms replace the commit message on the most recent commit only, and neither one touches
the tree — the actual file changes in that commit stay exactly as they were unless you also
staged something new beforehand. Running git commit --amend with a completely
clean working tree and index is the safe, no-side-effects way to edit a commit message:
nothing about the code changes, only the message and the SHA.
Change the commit description, not just the subject line
A commit message has two parts: the subject line and the description (the body underneath it).
-m carries both if you pass the whole thing, newlines included, so you don't have
to open an editor just to revise a commit message that needs a real explanation rather than a
one-line summary:
# Multi-line message without an editor
git commit --amend -m "fix: correct retry backoff
Retries were using a fixed 1s delay instead of exponential backoff,
causing thundering-herd retries against a rate-limited endpoint." git commit --amend --no-edit: Change Files, Keep the Message
The inverse case is just as common: the message is fine, but you need to fold a small
correction into the commit without rewriting the text at all. --no-edit tells git
to reuse the existing commit message verbatim, which is what people mean when they search
"git commit no edit" or "git amend no edit."
# Stage a small fix, fold it into the last commit, keep the message
git add src/retry.ts
git commit --amend --no-edit
# git status before the amend still shows the staged file as "Changes to be committed"
# after the amend, it's part of the previous commit instead of a new one
This is the pattern for the extremely common "I ran the linter/tests and found one more small
thing right after committing" moment — rather than creating a second tiny commit just to fix
a missed semicolon or an unused import, you fold the fix back into the commit it belongs to.
--allow-empty-message is the rarer sibling flag, for the (uncommon, usually
scripted) case where you deliberately want a commit with no message text at all; most people
who search for it actually want --no-edit instead.
Adding a Forgotten File to the Last Commit
A close relative of the no-edit case: you committed, then immediately noticed a file you meant to include — a new test, a config file, a migration — sitting unstaged. The fix is the same two-step pattern, whether or not you also want to touch the message:
# Stage the forgotten file(s)
git add src/migrations/2026_07_28_add_retry_column.sql
# Fold it in, keep the same message
git commit --amend --no-edit
# Or fold it in AND update the commit message to mention it
git commit --amend -m "feat: add retry tracking column and migration" git status right after the original commit is the fastest way to catch this before
it becomes a problem — an untracked or modified file sitting there right after
git commit is the signal that you forgot to stage something. If the file is
already tracked and just had uncommitted edits, the same git add + amend sequence
applies; nothing changes about the mechanics whether the file is brand-new or previously
tracked.
Amend vs Reset vs Revert vs Rebase
These four commands all rewrite or undo history in some way, and picking the wrong one is the single biggest source of confusion in this space. The table below is the fast decision path; each command has its own dedicated deep dive if you need the full mechanics.
| Command | What it changes | Rewrites history? | Safe on a shared branch? | When to use |
|---|---|---|---|---|
commit --amend | Replaces the last commit with a new one (same parent) | Yes — new SHA | Only with a coordinated force-push | Fix a message, add a forgotten file, small content fix to the last commit |
reset --soft | Moves branch pointer only; changes land back as staged | Yes — commit(s) become unreachable | Only if unpushed | Undo the last commit(s) entirely, restage, recommit differently |
reset --hard | Moves pointer, index, and working tree; discards uncommitted work too | Yes — commit(s) become unreachable | Only if unpushed | Throw away the last commit(s) and any uncommitted changes on top |
revert | Adds a new commit that inverts an earlier one | No — appends, never removes | Yes | Undo a commit that's already been pushed or shared |
rebase -i | Rewrites a whole range of commits (reword, edit, squash, drop, reorder) | Yes — every rewritten commit gets a new SHA | Only with a coordinated force-push | Amend or restructure a commit that isn't the most recent one |
The distinction that trips people up most: --amend and reset --soft
can look interchangeable for "undo the last commit and fix it," but they leave you in different
states. Amend does the whole fix-and-recommit in one command. Reset --soft undoes the commit
and leaves the changes staged, so you decide separately what the next commit looks like — useful
if you want to split one commit into two, or combine it with more staged changes before
recommitting. The full --soft vs --mixed vs --hard
breakdown, including recovery via reflog, lives in the
git reset hard guide; reverting an already-pushed
commit, including reverting a merge or reverting a revert, is covered in the
git revert commit guide.
Change Commit Message After Push: Amend, Then Force-Push
Everything above assumes the commit is still local-only. Once it's been pushed, amending still works exactly the same way locally — the difference is entirely on the push side afterward.
# The commit is already on origin/main
git commit --amend -m "fix: correct retry backoff on 429 responses"
# A plain push is rejected: origin has a commit your branch no longer has
git push
# ! [rejected] main -> main (non-fast-forward)
# Force-push is required because the history diverged
git push --force-with-lease
This is the entire answer to "how to edit commit message after push": amend locally exactly as
you would for any unpushed commit, then force-push, because a normal push will always be
rejected once the SHA has changed underneath a commit the remote already has. The amend step
itself has zero extra risk — it's the same operation either way. The risk is entirely in the
force-push that follows, which is covered next. One thing worth ruling out first: if the push
fails with "repository not found" or an authentication error rather than a
non-fast-forward rejection, the amend isn't the problem at all — the remote
address is, and the git change remote URL
guide covers fixing that.
Force-Pushing an Amended Commit Safely
git push --force overwrites whatever is on the remote branch unconditionally, even
if someone else pushed to it after your last fetch — which means it can silently discard a
teammate's work you never saw. --force-with-lease is the standard safe
alternative: it refuses the push instead if the remote branch has moved since you last
fetched it, forcing you to pull and reconcile before overwriting anything.
# Standard safe force-push after amending
git push --force-with-lease
# Even stricter: also verify the specific branch ref you expect to overwrite
git push --force-with-lease=main:<expected-remote-sha> What actually breaks downstream when a force-push lands, beyond the history rewrite itself:
- CI/CD reruns. Most pipelines trigger on push, so an amended commit typically re-triggers the full check suite against the new SHA — expect build/test time to repeat, not skip.
- Teammates' local branches diverge. Anyone who already pulled the old commit
now has a branch that disagrees with the remote. Their next
git pullwill either create a spurious merge commit or fail outright; the clean fix on their end is usuallygit fetchfollowed bygit reset --hard origin/branch-name(assuming they have no local-only work worth keeping), which the git reset hard guide covers in detail. - PR review comments get orphaned. Covered in full in the amending an open pull request section below, but the short version: they survive, marked "outdated."
Never force-push a branch that other people are actively basing work on without telling them
first — the technical safety of --force-with-lease only protects against
overwriting pushes it can see; it does nothing about the coordination problem of rewriting
history everyone else's local clone still disagrees with.
Amend a Previous or Older Commit with Interactive Rebase
--amend only ever reaches the single most recent commit. When you need to edit a
previous commit three, five, or ten commits back, git rebase -i is the tool: it
lets you mark any commit in a range for either a message-only edit (reword) or a
full content edit (edit). People search this as "git amend previous commit," but
--amend genuinely cannot reach past HEAD.
# Start an interactive rebase covering the last 5 commits
git rebase -i HEAD~5 Git opens a todo list, oldest commit at the top, one line per commit:
pick a1b2c3d feat: add rate limiter
pick b2c3d4e fix: correct retry backoffs
pick c3d4e5f docs: update README
pick d4e5f6a test: add retry unit tests
pick e5f6a7b chore: bump lockfile reword: change the commit message of an older commit
Change pick to reword on the commit whose message you want to edit —
git will pause on that commit and open your editor for the new message, then continue the
rebase automatically. That single word is the whole answer to "how do I change the commit
message of an older commit." Change it to edit instead if you also need to change
the commit's content, not just its message:
# reword: message-only change, git handles the rest automatically
reword b2c3d4e fix: correct retry backoffs
# edit: pauses so you can amend content too
edit b2c3d4e fix: correct retry backoffs edit: change the content of a previous commit
With edit, save and close the todo list and git stops right after checking out
that commit, with HEAD detached at it. From there, the workflow is exactly
git commit --amend again — stage whatever needs to change, amend, then tell the
rebase to continue:
# git paused here, HEAD detached at the target commit
git add src/retry.ts
git commit --amend --no-edit
# Resume the rebase — git replays every commit after this one on top
git rebase --continue
This is the mechanism worth understanding: an interactive rebase doesn't move one commit in
place, it replays every commit after your edit point on top of the amended version,
one at a time, which is why every commit from your edit point forward gets a new SHA even if
you only touched one of them. Conflicts during replay are resolved the same way as any rebase
conflict — fix the files, git add, git rebase --continue — and
git rebase --abort at any point returns you exactly to where you started, before
the rebase began.
Amending a Commit on an Open Pull Request
Amending a commit that backs an open GitHub pull request works exactly like amending any pushed commit — amend, then force-push the branch the PR is tracking. What's worth knowing is what does and doesn't happen to the PR itself as a result.
# On the PR's feature branch
git commit --amend -m "fix: address review feedback on retry logic"
git push --force-with-lease The pull request updates in place: same PR number, same conversation thread, same title and description, new commit(s) in the diff. It does not close, reopen, or reset in any way. What specifically happens to what reviewers already left:
- Line-level review comments remain attached to the old commit and get marked "outdated" in GitHub's UI — the comment text and thread are preserved, but GitHub can no longer map the comment to a line in the new diff, so reviewers have to re-locate the relevant context manually.
- General PR-level comments are untouched — they're attached to the pull request itself, not to a specific commit. Approvals remain visible but may be auto-dismissed if your branch protection rules include "Dismiss stale pull request approvals when new commits are pushed" — see GitHub's protected branches documentation for the exact setting.
- Required status checks configured to run on push typically re-trigger against the new commit, which is usually the point — you amended specifically to address feedback, and you want CI to confirm the fix.
In practice, many teams prefer adding a new commit on top during active review — reviewers can
diff exactly what changed since their last look — and only squash or amend right before merge.
Amending mid-review is fine too, it's a workflow preference rather than a technical requirement,
but a heads-up comment on the PR ("force-pushed to fold in the review feedback") saves a
reviewer from wondering where their comment thread went. Once the PR merges, the feature
branch has done its job — deleting the local and
remote branch is the cleanup step that keeps git branch readable.
Author, Date, and Signature: --author, --date, -S
Beyond the message and the tree, --amend can also correct metadata on the last
commit — who it's attributed to, when it happened, and whether it carries a GPG signature.
# Fix a wrong author (e.g. committed under the wrong local git config)
git commit --amend --author="Jane Doe <jane@example.com>"
# Reset the author to whoever is running the amend right now
git commit --amend --reset-author
# Correct the commit's authored date (committer date updates to "now" regardless)
git commit --amend --date="2026-07-28T10:00:00"
# Add a GPG signature to a commit that was made without one
git commit --amend -S --no-edit
# Combine several: new author, keep the message
git commit --amend --author="Jane Doe <jane@example.com>" --no-edit --author is the fix for the common mistake of committing under a wrong or generic
local identity — a work laptop still configured with a personal email, or a pair-programming
session that only credited one person. --reset-author is the inverse: it drops
whatever author was recorded and replaces it with your current user.name and
user.email, useful after cherry-picking or amending someone else's commit onto
your own work. --date only changes the recorded authored date; the
committer date — a separate field git also tracks — always updates to the moment you
run the amend, regardless of what --date says. -S (or
--gpg-sign) adds a cryptographic signature to the amended commit, which matters if
your repository enforces signed commits — since amending changes the SHA, any existing
signature on the old commit is invalidated anyway and has to be reapplied.
Review the Diff Before You Rewrite History
Every amend replaces a commit with a new one, and once you've force-pushed, the old version is
gone from the remote and increasingly hard for teammates to recover. Before that push, it's
worth actually looking at what changed between the original commit and the amended one, rather
than trusting that --no-edit or a quick message tweak didn't accidentally pull in
something extra you staged by mistake. git show and git diff handle
this from the terminal — the git diff between
two files reference covers the commit-range and path syntax you need for it.
# Save the pre-amend content for comparison
git show HEAD > /tmp/before-amend.txt
git commit --amend --no-edit
# Save the post-amend content
git show HEAD > /tmp/after-amend.txt
Diff Checker, a free Chrome extension, is a plain fit for exactly this comparison: paste the
contents of before-amend.txt into one pane and after-amend.txt into
the other, and its Monaco-based editor shows the two side by side, or as a unified diff, with
no setup. It doesn't read a git repository or run git commands itself — it's just a fast,
fully local text-diffing surface, which is precisely enough to confirm that an amended commit
contains exactly the file changes you intended before you force-push it somewhere a teammate
can't easily get back the old version. The same paste-and-compare workflow works just as well
for a single file: grab the old and new version of whatever you amended and confirm the diff
matches your mental model before it leaves your machine.
Amending from a GUI: GitHub Desktop, GitKraken, Lazygit
The CLI commands above are universal, but plenty of people amend from a GUI client instead. The underlying operation is identical — a new commit replaces the old one — only the interface differs.
- GitHub Desktop — with nothing else staged, make your last commit's history entry active and use "Amend Last Commit" from the commit history context menu, which lets you edit the message and optionally add currently staged changes before confirming.
- GitKraken — right-click the top commit in the graph view and choose "Amend," or stage changes and check the "Amend Previous Commit" option next to the commit box before committing.
- Lazygit — stage the file(s) with
space, then presscto commit, or use the dedicated amend keybinding (pressAin the commits panel) to fold staged changes into the selected commit without leaving the terminal UI.
All three still produce a new SHA and still require a force-push if the commit was already
pushed — the GUI doesn't change git's underlying rules, it just wraps the same
--amend operation in a menu item, usually with a confirmation dialog in place of
typing the flag yourself.
Troubleshooting Common Amend Errors
A handful of error strings account for most of the confusion around amending. Here's what each one actually means and the fix.
git: 'amend' is not a git command. See 'git --help'. — you typed
git amend, git edit, or git rename commit; none of
those exist. The flag lives on git commit. If you reach for it often enough to
keep mistyping it, git config --global alias.amend 'commit --amend' makes
git amend a real command in your own config.
error: could not lock config file .git/config: Permission denied
(or an editor that refuses to open) — usually a broken core.editor config or a
permissions issue on the repository directory, not the amend itself. Check
git config core.editor and confirm you have write access to the
.git directory.
"Nothing to commit" or amend appears to do nothing — if you ran
git commit --amend with no staged changes and didn't alter the message either
(e.g. saved the editor without changes), git still creates a new commit object, but its tree,
author, and message are identical to the original, so it looks like nothing happened. It
technically has a new SHA if the timestamp changed, but functionally it's a no-op. Confirm with
git log --oneline -1 before and after if you need certainty.
! [rejected] main -> main (non-fast-forward) after amending a pushed
commit — expected behavior, not a bug. The remote has the pre-amend SHA, your local
branch has the post-amend SHA, and a normal push only allows fast-forward updates. The fix is
the force-push covered in the force-push section above, not
a plain retry.
"Your branch and 'origin/main' have diverged" after someone else force-pushed —
this means you're on the receiving end of someone else's amend or rebase. Do not merge or
rebase blindly; confirm with the person who force-pushed what happened, then typically
git fetch followed by git reset --hard origin/main to match, assuming
you have no local-only work worth preserving — check the
amend vs reset comparison above for exactly what
--hard discards before you run it.
Amending the wrong commit because you lost track of what "last" means — after
a rebase, cherry-pick, or branch switch, "the last commit" can be a different one than you
expect. Always run git log --oneline -1 or git show HEAD --stat
immediately before amending, to confirm you're about to replace the commit you actually mean
to.
Frequently Asked Questions
What does amend commit do?
git commit --amend replaces your most recent commit with a brand-new one
that has the same parent but a different tree, message, or both. It does not edit the old
commit object in place — git objects are immutable — it creates a new commit, points your
branch at it, and lets the old commit become unreachable (it still exists in the reflog
until garbage collection runs). Run it alone and it opens your editor on the previous
commit message so you can revise it; stage new changes first with git add and
they get folded into the amended commit alongside whatever was already there.
How do I change a git commit message after push?
Run git commit --amend to rewrite the message locally, then
git push --force-with-lease to update the remote. This works exactly like
amending an unpushed commit, with one extra risk: because the commit already exists on the
remote, a plain git push is rejected (the histories no longer match), and you
must force-push to overwrite it. --force-with-lease refuses the push if
someone else has pushed to that branch since your last fetch, which plain
--force does not check. Never do this on a branch other people have already
pulled without warning them first, since their local history will diverge from the
rewritten remote.
Does amending change the commit hash?
Yes, always. A commit's hash is computed from its content, parent, author, timestamp, and
message, so changing any one of those — even just the message, with --no-edit
left off and nothing else touched — produces a different SHA and therefore a different
commit object. There is no way to amend a commit and keep the same hash; if the hash is
identical, nothing was actually amended. This is why amending a commit that's already been
pushed or shared requires a force-push: the remote is holding a commit your local branch
no longer has.
How do I amend an older commit, not just the last one?
git commit --amend only ever reaches the most recent commit. To change the
commit message of an older commit, run git rebase -i HEAD~n with
n large enough to include your target, then change pick to
reword on that line — git pauses there, opens your editor for the new
message, and continues on its own. Use edit instead of reword
when the content has to change too: git stops with HEAD detached at that
commit, you stage the fix, run git commit --amend --no-edit, then
git rebase --continue. Every commit from your edit point forward gets a new
SHA, because rebase replays them all on top of the rewritten one.
Can I amend a commit that others have already pulled?
Technically yes, but this is the one case where amending causes real damage. Once you
amend and force-push, everyone who already pulled the old commit has a local branch that
disagrees with the remote, and their next git pull either creates a spurious
merge commit or fails outright. --force-with-lease protects you from
clobbering a push you haven't fetched yet, but it does nothing about clones that already
hold the old commit. On a shared branch, either warn everyone before you force-push so
they can reset to the new remote state, or leave the history alone and correct it with
git revert or a follow-up commit instead.