I Have Not Committed Yet
The most common thing a beginner wants to undo is also the simplest: you changed a file, you do not want the change any more, and it has never been committed.
One command does it. It also comes with the only genuine warning in this chapter, so the warning goes first: this is the one undo in the book that destroys work permanently. There is no recovery afterwards, because there was never a recording to recover from.
Diagnose first
Before typing anything, ask Git where the change is:
git status
If the file appears under changes not staged for commit, it is in the working directory — the first of the three places. That is the situation this page covers.
Look before you throw it away
The second habit, and it takes four seconds:
git diff style.css
Roughly half the time this is where people discover that the change was the one they meant to keep, and that the thing they actually wanted to undo was somewhere else.
Throw it away
git restore style.css
The file returns to how it looked in the most recent commit. Git prints nothing, asks nothing, and offers no confirmation — the silence from Chapter 1 means it worked.
To discard everything in the current folder and below:
git restore .
That version is genuinely unforgiving. Read git status before you run it, every single time, because the list it prints is the list of things that are about to disappear.
The older spelling
Tutorials written before 2019 use git checkout -- style.css for this. It does the same job. git restore exists because checkout had been given too many unrelated responsibilities and had become genuinely confusing.
This book uses restore. Recognize checkout when you meet it, which you will, constantly.
What it does not touch
Two things it will not do. Name a file Git has never recorded — untracked, in the language of Chapter 2 — and the command does not quietly skip it: it stops with error: pathspec 'notes.txt' did not match any file(s) known to git and restores nothing at all, including any tracked file you named in the same breath. The untracked file's contents are safe, but only because nothing ran. And a change you have already staged is not affected either; that is the next topic.
Note that git restore . is different: a directory expands to the tracked files inside it, so it runs cleanly and leaves untracked files alone.
The safer alternative
If there is any chance you want the change back, do not discard it. git stash puts it in a drawer instead, and the drawer can be reopened. It is a full topic in the next chapter, and it is mentioned here so that "I might want this later" always has an answer that is not destruction.
Better still: commit it. A commit on a branch you later abandon costs nothing, and Chapter 6 makes that a normal thing to do rather than a mess.
- "
restoreis an undo, so it must be reversible." This one is not. Uncommitted work was never recorded, so there is nothing for Git to find. It is the strongest argument in this book for committing often. - "It deletes my file." It restores the file to its last committed state. It never deletes an untracked file — name one and the command refuses to run at all, which is a refusal rather than a silent skip.
- "
git restoreandgit resetdo the same thing."restoreworks on files;resetmoves the branch. They are different tools for different problems, and this book keeps them apart deliberately. - "Git will ask me to confirm before discarding something." It will not. Silence after the command is what success looks like, and by then the change is gone.
- Knowing which undo is destructive and which is not is the entire safety story of this chapter, and this is the destructive one.
- Diagnosing with
git statusbefore typing is what makes every other page in the chapter safe. It costs two seconds and it is the difference between fixing a problem and enlarging it. - The fact that uncommitted work is unrecoverable is why "commit often" is advice with teeth rather than a slogan.
Knowledge Check
You run git restore style.css on an unstaged change. Can you get that change back?
- No, since it was never recorded, so there is nothing at all for Git to recover here
- Yes, using
git reflog, which keeps a record of every discarded change - Yes, because Git keeps the previous contents of every file it has ever seen
- Only if the file had been staged at some point before the change was discarded
You name a file Git has never recorded in a git restore command. What happens?
- It stops with a pathspec error and restores nothing, not even the other files you named
- Nothing at all — Git skips that one quietly and restores the others you named
- It deletes the file, since Git treats anything untracked as unwanted clutter
- It records the file first, then restores it to that newly created state
What are the two habits this page recommends before discarding a change?
- Run
git statusto see where the change is, thengit diffto see what it is - Make a copy of the folder, then run the restore command on the original
- Commit everything first, so that the change is recorded before it is removed
- Close the editor, so that unsaved changes cannot interfere with the command
You might want the change back later. What should you use instead?
git stash, which sets the change aside where it can be recoveredgit restorewith an option that keeps a backup copy of the changegit status, which preserves a snapshot of the current state before reporting- Nothing exists for that — Git only offers discarding or committing the change
You got correct