Skip to content

Unstaging and Amending

Two common corrections happen at different boundaries. You may have selected the wrong content in the Index, or you may have just created a local commit with a wrong message or a forgotten file. These are different operations with different risks.

Terminal window
git restore --staged App/user.php

This updates the selected path in the Index from HEAD while leaving the Working Tree file unchanged. The edit therefore moves from “changes to be committed” to “changes not staged for commit.” It does not delete the edit and does not change the last commit.

Check the state before and after:

Terminal window
git status
git restore --staged App/user.php
git status

The absence of --staged changes the destination:

Terminal window
git restore App/user.php

Plain git restore copies the Index version into the Working Tree. Any newer unstaged content in that path is overwritten. For example, if the Index contains echo 1 and the Working Tree was later changed to echo 2, plain restore puts echo 1 back in the file and discards echo 2.

Always run git status and, when needed, git diff before a Working Tree restore. Uncommitted and unstaged content may be difficult or impossible to recover.

Commits are immutable objects. --amend does not open the latest commit and edit it in place. Git creates a replacement commit and moves the current branch to it:

before: A ← B ← master
after: A ← C ← master

C has the same parent as B, but uses the current Index, message, and commit metadata. Its SHA is different. The old B is no longer in the branch’s ordinary history, although its object may remain locally recoverable for a limited time through recovery tools covered later.

Change the latest commit message:

Terminal window
git commit --amend -m "Update user output"

If a file belongs to the same logical change but was omitted, stage it first:

Terminal window
git add Tests/UserTest.php
git diff --staged
git commit --amend --no-edit

The replacement commit records the complete current Index. --no-edit keeps the existing message; it does not preserve the old SHA. Review the selected content instead of assuming only the intended file is present.

Amending an unpublished local commit is normally manageable because only your branch depends on its SHA. After publication, teammates or automation may already reference the old SHA. Replacing it creates incompatible histories and normally requires a force update, so do not amend shared history casually.

This lesson does not perform or recommend a force push. Safe history-sharing and recovery policies are covered later.

  • Confusing restore --staged with deleting the Working Tree edit.
  • Running plain restore when the intention was only to unstage.
  • Thinking amend edits an existing commit without changing its SHA.
  • Forgetting that amend records the entire current Index.
  • Assuming the old commit remains a normal visible backup on the branch.
  • Amending a published commit after teammates depend on it.
  • Staging broadly with git add . without reviewing git diff --staged.
git restore --staged <path> → change Index; preserve Working Tree edit
git restore <path> → replace Working Tree path from Index
git commit --amend -m "message" → replacement commit with a new message
git commit --amend --no-edit → replacement commit; keep the message
amend → new commit object and new SHA
Where does an edit remain after git restore –staged file?

In the Working Tree. It is no longer selected in the Index.

Why does a message-only amend change the SHA?

The message is part of commit data. Amend creates a new commit object rather than editing the original object in place.

Why is amend risky after publication?

Other people and systems may already reference the old commit. Replacing it creates a different history with a different SHA.