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.
1. Unstage without losing the edit
Section titled “1. Unstage without losing the edit”git restore --staged App/user.phpThis 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:
git statusgit restore --staged App/user.phpgit status2. Unstage is not discard
Section titled “2. Unstage is not discard”The absence of --staged changes the destination:
git restore App/user.phpPlain 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.
3. Amend replaces the latest commit
Section titled “3. Amend replaces the latest commit”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 ← masterafter: A ← C ← masterC 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:
git commit --amend -m "Update user output"4. Add a forgotten file
Section titled “4. Add a forgotten file”If a file belongs to the same logical change but was omitted, stage it first:
git add Tests/UserTest.phpgit diff --stagedgit commit --amend --no-editThe 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.
5. The publication boundary
Section titled “5. The publication boundary”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.
6. Common mistakes
Section titled “6. Common mistakes”- Confusing
restore --stagedwith deleting the Working Tree edit. - Running plain
restorewhen 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 reviewinggit diff --staged.
7. Summary
Section titled “7. Summary”git restore --staged <path> → change Index; preserve Working Tree editgit restore <path> → replace Working Tree path from Indexgit commit --amend -m "message" → replacement commit with a new messagegit commit --amend --no-edit → replacement commit; keep the messageamend → new commit object and new SHA8. Knowledge check
Section titled “8. Knowledge check”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.