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
Amend replaces the commit, it doesn't edit it Before amend After amend B C main (HEAD) c3d4e5f B C' main (HEAD) 9f8e7d6 C unreachable — still in reflog Same parent B, brand-new SHA — the old commit is never edited in place.
git commit --amend never edits a commit in place: it creates C' with the same parent B and moves the branch pointer, while the original C survives, unreachable, in the reflog.

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"
Folding a forgotten file into the last commit commit c3d4e5f tree: retry.ts message unchanged ?? migration.sql untracked (git status) git add staged: migration.sql commit 9f8e7d6 retry.ts (unchanged) + migration.sql (new) --no-edit: message unchanged (replaces c3d4e5f) git commit --amend --no-edit folds the staged file into a new commit, message untouched.
An untracked file left out of the original commit gets staged with git add, then folded into a new commit via git commit --amend --no-edit — same message, one more file in the tree.

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>
--force vs --force-with-lease when the remote moved origin/main has teammate commit T git push --force T silently overwritten teammate's work is gone, no warning origin/main has teammate commit T --force-with-lease push rejected fetch and reconcile before retrying Same stale remote state, different outcome: --force overwrites blindly, --force-with-lease checks first.
Same setup, both lanes: origin/main carries a teammate's commit you haven't fetched. --force overwrites it with no check. --force-with-lease refuses the push and tells you to fetch first.

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 pull will either create a spurious merge commit or fail outright; the clean fix on their end is usually git fetch followed by git 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
git rebase -i HEAD~5: mark one commit edit, replay the rest pick a1b2c3d feat: add rate limiter edit b2c3d4e fix: correct retry backoffs pick c3d4e5f docs: update README pick d4e5f6a test: add retry unit tests pick e5f6a7b chore: bump lockfile After changing pick to edit and saving: a1b2c3d unchanged b2c3d4e HEAD detached amend f7a8b9c amended --continue c3d4e5f, d4e5f6a, e5f6a7b replayed → new SHAs Only the edited commit and everything after it get new SHAs — earlier commits are untouched.
Changing pick to edit pauses the rebase with HEAD detached at that commit. Amend it like any last commit, then git rebase --continue replays every later commit on top, giving each one a new SHA.

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.
Force-pushing an amended commit onto an open PR Before force-push After force-push review comment: "check retry cap" d4e5f6a review comment: "check retry cap" OUTDATED 9f8e7d6 PR stays open — same conversation thread, same checks, just a new diff
Force-pushing an amended commit updates the diff in place. The old review comment stays visible but gets marked "outdated," while the pull request itself, its thread, and its checks carry on unchanged.

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.

Confirm the amend changed exactly what you meant before-amend.txt retryDelay = 1000; - fixed backoff, 1s delay maxRetries = 3; onError(retry); after-amend.txt retryDelay = base * 2^n; + exponential backoff maxRetries = 3; onError(retry); amend Paste both into Diff Checker before you force-push — confirm the amend touched only what you intended.
before-amend.txt and after-amend.txt pasted side by side make the actual change from an amend obvious — here, a fixed 1s retry delay becomes exponential backoff, with everything else in the file untouched.

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 press c to commit, or use the dedicated amend keybinding (press A in 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.