I Have Not Committed Yet
Topic 15

I Have Not Committed Yet

Undo

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:

Always the first command in an accident
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:

See exactly what you are about to discard
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

Put one file back to its last committed state
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:

Discard every unstaged change here 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.

Two undos that look similar and are not
git restore <file>
throws away an unstaged change — permanent, no recovery, no confirmation
git stash
puts the same change aside — recoverable, and the safer choice when you are unsure

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.

Common Confusions
  • "restore is 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 restore and git reset do the same thing." restore works on files; reset moves 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.
Why It Matters
  • 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 status before 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 status to see where the change is, then git diff to 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 recovered
  • git restore with an option that keeps a backup copy of the change
  • git 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