How to change a Git commit message
Fixing the last commit message is one command. Fixing an older one rewrites every commit after it, which is fine while nothing has been pushed and a problem the moment it has.
The most recent commit
$ git commit --amend -m "add c, properly"
before : 7c7ccf0 add c 7b6de0a add b ec8533e frist commit
after : 697735c add c, properly 7b6de0a add b ec8533e frist commit
Note the hash: 7c7ccf0 became 697735c.
--amend
does not edit anything — a commit is immutable, so git builds a replacement and
moves the branch to it. The old one is orphaned.
Leave off -m and your editor opens with the existing message, which is easier
for anything longer than a line.
An older commit
$ git rebase -i HEAD~3
That opens a list of commits. Change pick to reword on the one you want,
save, and git stops to let you retype the message.
Two details the answers often leave out.
The count includes the commit you are targeting. HEAD~3 means “replay the
last three”, so to reach the third-oldest you need at least HEAD~3.
For the very first commit there is nothing to count back to:
$ git rebase -i HEAD~3 # on a repo with exactly three commits
fatal: invalid upstream 'HEAD~3'
The root commit has no parent. Use --root instead:
$ git rebase -i --root
How far the rewrite reaches
This is the part worth measuring. Rewording the oldest of three commits:
the reworded commit : ec8533e -> 3a1977b
newest commit hash : 7c7ccf0 -> d943e4e
Every commit after it changed too. That is not a side effect — a commit identifies its parent by hash, so changing a commit necessarily changes every descendant. Rewording one message rebuilt the entire branch above it.
While the commits are yours alone, that costs nothing. Once they are pushed, everyone else has the old chain, and your next push is rejected unless you force it — at which point their history and yours disagree.
Knowing what is safe
$ git log --oneline @{upstream}..HEAD
That lists commits you have and the remote does not — exactly the set you can rewrite freely. If it errors, that is informative too:
fatal: no upstream configured for branch 'main'
No upstream means nothing has been pushed from this branch, so everything on it is fair game.
If the commits are pushed and shared, the honest options are to leave the
message alone, or to agree the force-push with whoever else has the branch
first. --force-with-lease is the safer spelling, since it refuses when the
remote has moved since you last fetched.
What a message should look like
subject: Short summary under 50 chars
body : A longer explanation, wrapped, after a blank line.
git treats the first line as the subject and everything after a blank line as
the body. That convention is why git log --oneline is readable at all, and why
-m "..." -m "..." gives you the two parts without opening an editor.
About Netcup (advertisement)
The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).