How to amend a Git commit (message, contents, author, date — and when not to)

· Category: Git

Short answer

git commit --amend rewrites the most recent commit. The most common uses:

git commit --amend -m "Fix login redirect bug"     # change the message
git add forgotten.js && git commit --amend --no-edit   # add files, keep the message
git commit --amend --author "Jane Doe <[email protected]>"   # fix the author
git commit --amend --date "2026-06-14T09:00:00"    # change the timestamp

--amend always produces a new commit SHA. That's safe before you push. After pushing it requires force-push, which means the rule is: only amend commits that are still local, or commits on a branch that's solely yours. For commits on shared branches, use git revert instead.

What --amend actually does

There's no "edit a commit in place" operation in Git. --amend is shorthand for:

  1. Take the parent of the current HEAD (let's call it P).
  2. Combine the index and the existing commit's tree.
  3. Create a new commit with parent P, the merged tree, and the (new or kept) message.
  4. Move HEAD to the new commit.

The original commit is now unreferenced. It stays in the reflog for ~90 days, then is garbage-collected. Since --amend creates a new commit object, the SHA is different — that's why pushing is rejected if the original was already on a remote.

Reference: git-commit(1) — --amend.

Steps for each scenario

Fix the commit message only

git commit --amend                        # opens $EDITOR
# or, in one shot:
git commit --amend -m "Add login form validation"

Use the editor form (no -m) when the message has multiple lines and you want a body — -m only handles the subject line cleanly.

Add forgotten files to the last commit

git add src/login/validate.js tests/login.test.js
git commit --amend --no-edit

--no-edit reuses the existing message verbatim. Without it, --amend opens the editor and (annoyingly) re-asks you to confirm the message.

Remove a file you accidentally committed

# Unstage the file in the index, then amend
git reset HEAD^ -- secrets.env             # remove from the index, keep on disk
git commit --amend --no-edit
echo "secrets.env" >> .gitignore
git add .gitignore
git commit --amend --no-edit

If the file contained credentials and you've already pushed, amend isn't enough — the file is in the previous (now orphaned) commit and reachable via reflog and on the remote until garbage collection. Treat the credentials as compromised, rotate them, then rewrite history with git-filter-repo and force-push.

Fix the author

You committed with the wrong identity (work email on personal repo, or vice versa):

git config user.email "[email protected]"        # set the right local config
git commit --amend --reset-author --no-edit         # rewrite author from current config

--reset-author updates both author and timestamp from the current config. To set author manually:

git commit --amend --author "Jane Doe <[email protected]>" --no-edit

For broader cleanup (more than the last commit), see how to configure Git user name and email and the git filter-repo recipe documented there.

Backdate or fix the date

# Override author date only (committer date stays "now")
git commit --amend --date "2026-06-14T09:00:00" --no-edit

# Override both:
GIT_COMMITTER_DATE="2026-06-14T09:00:00" git commit --amend --date "2026-06-14T09:00:00" --no-edit

This matters when CI looks at commit timestamps for build reproducibility, or when you're transplanting a commit between branches and want to preserve when it was actually written.

Change the parent (rare)

You can't change the parent with --amend, but git rebase --onto will reattach the commit to a different base while preserving the diff. See how to rebase in Git.

After amend: pushing

If the original commit was never pushed, just git push normally. If it was pushed, you'll get:

! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind

Force-push, but use the safe variant:

git push --force-with-lease origin main

--force-with-lease only succeeds if the remote tip is what you last fetched, meaning nobody else has pushed in the meantime. --force blindly overwrites and is the wrong tool except in the case where you genuinely want that behavior. Reference: git-push(1) — --force-with-lease.

Amending older commits (use rebase --interactive)

--amend only works on the most recent commit. For older ones:

git rebase -i HEAD~5
# pick   abc1234  Older commit
# edit   def5678  This is the one to fix
# pick   ...

# Git stops at def5678. Edit, then:
git add changes
git commit --amend --no-edit
git rebase --continue

Or use the modern shorthand: git commit --fixup=<sha> creates a fixup! commit, then git rebase -i --autosquash <base> automatically reorders and squashes it into the original. See how to squash commits in Git.

Common issues

git push rejected after amend. Either the commit was pushed (use git push --force-with-lease) or the remote moved (run git fetch, then either rebase or merge before retrying).

The original message disappeared. git reflog show HEAD lists every prior HEAD including the pre-amend commit. git show HEAD@{1} shows the old commit; git reset --hard HEAD@{1} restores it. Reflog covers you for ~90 days.

Committer is right but author is still wrong. Author and committer are different fields. --amend doesn't change author unless you pass --reset-author or --author. Run git log -1 --format=fuller to see both.

Pre-commit hook ran twice. --amend re-runs hooks by default. If the hook is slow and you're certain the change is trivial, git commit --amend --no-verify skips them. Don't habitually use --no-verify — that's how secrets get committed.

I amended a merge commit and lost the second parent. --amend on a merge commit drops the merge unless you pass the merge parents back in. Easier: don't amend merge commits. If you need a different message on a merge, redo the merge: git reset --hard HEAD~1 && git merge --no-ff -m "new message" feature/x.

Tips

  • git commit --amend --no-edit is the move you want 80% of the time — most amends are "I forgot a file, keep the message".
  • For a chain of related fixups, git commit --fixup=<sha> + git rebase -i --autosquash is much faster than amending repeatedly.
  • Pair --amend with git status before pushing — confirm the resulting commit looks right via git show HEAD once before git push --force-with-lease.
  • Amending preserves the original commit in the reflog. If you panic, git reflog is your safety net — see how to use git reflog to recover lost commits.