Second thing --amend can do: fold a forgotten file into the
last commit. You commit README.md, glance at your file list, and
realise you were supposed to include NOTES.md in the same
commit. Rather than making a second commit called "actually add
NOTES too", you can just add it retroactively.
The two step recipe
Stage the missing file, then amend:
git add NOTES.md
git commit --amend --no-edit
The --no-edit flag tells Git "keep the previous message; don't
open an editor." Without it, Git would pop open your editor with
the existing message pre-filled, in case you want to change both
the files and the message at once.
After the amend, git log --oneline still shows one commit with
the original message, but git show HEAD --stat shows both files
in the change list. From the outside, it looks like you committed
them both together the first time.
The same rewrite rules apply
Just like amending a message, folding in a file creates a new commit with a different SHA. The old commit is unreachable from your branch, and the branch label has moved to the new one. If this is a local unshared commit, no one will notice or care. If you've already pushed, force-pushing to update the remote is the only way, and now anyone who pulled the old version is in an awkward state.
The heuristic: use --amend freely on your last commit until
the moment you push. After push, treat the commit as sealed.
When you'd use --amend without --no-edit
You dropped --no-edit when you want to change both the files and
the message. Some examples:
- You forgot a file AND the message was vague. Fix both together.
- You realise the commit's scope changed after you added a file and want a message that reflects the new scope.
Same command, minus the flag:
git add SOMETHING.md
git commit --amend
Editor opens with the old message. Edit it, save, done.
Removing a file from the last commit
The reverse also works. If you accidentally committed something that shouldn't be in the commit:
git rm --cached path/to/wrong-file.txt
git commit --amend --no-edit
Same shape. git rm --cached stages the removal (of the tracked
version) without deleting the file from disk. Then amend folds
the removal into the last commit. Now the file is untracked again
and no longer part of that commit's snapshot.
What amend can't do
--amend only touches the most recent commit. It's a one-step
tool. If you want to change something further back in history,
you need git rebase -i, which is more powerful and more
finicky. We'll cover a light use of that in the squashing lesson.
For deeper rewrites (edit an old commit, split a commit, drop a
commit), the same interactive-rebase machinery is what you reach
for.