Why does git checkout not delete new files?
Asked Answered
T

3

7

Suppose I create (but do not commit) a file file.txt, and then type git checkout HEAD or git checkout HEAD .. I thought git checkout basically overwrote your current working files with the snapshot at the commit you give it, so I would have thought this would delete file.txt. But it doesn't. Why?

Titty answered 27/8, 2018 at 17:0 Comment(11)
Well, because your assumption was wrong. git checkout does not affect untracked files.Germander
Git only manages tracked files, and it works fairly hard to avoid letting you lose data (which is critical).Sri
@SergioTulentsev I don't think that's really a good way to phrase it. "Untracked" just means "not in the staging area right now". git checkout will still modify files that differ from how they were in the last commit, even if you haven't staged those changes.Titty
@JackM no, that's not what "untracked" means in git.Germander
@SergioTulentsev It is according to the "Pro Git" book and this answer: "No! Tracked files are files that are in the index right now".Titty
@JackM the git book disagrees: "Tracked files are files that were in the last snapshot; they can be unmodified, modified, or staged. In short, tracked files are files that Git knows about. Untracked files are everything else — any files in your working directory that were not in your last snapshot and are not in your staging area."Germander
@JackM: hah, even simpler, create a new file and do git status. You'll see the new file in the "Untracked files" section.Germander
The Git book isn't really disagreeing: the index is normally populated via git checkout, so what's in the index right now are those that were in the snapshot. But if you change the index (with git rm --cached or git add, for instance), that changes the set of tracked files. Note also that git checkout <tree-ish> <paths> is a very different command from git checkout <branch>. Some (including myself) believe it should use a different spelling, i.e., not start with git checkout at all.Ianteen
@torek: yeah, I had a hard time explaining to my newbie friend why git checkout behaves so wildly differently :)Germander
"git checkout <tree-ish> <paths> is a very different command from git checkout <branch>" Oh, that's cool. I'll just be over here, crying.Titty
@JackM to remove untracked files you can use git clean, i've corrected my answer below.Reciprocity
R
9

git checkout doesn't overwrite your working copy by-design.

It works in the same way as git reset --hard but with the important difference - git checkout is working-directory safe, so it doesn't overwrite existing changes in your working directory. Actually, it’s a bit smarter — it tries to do a trivial merge in the working directory.

So, if you want to discard all of your changes and just get the snapshot from HEAD use git reset --hard HEAD or just git reset --hard instead.

But even git reset --hard doesn't remove your untracked files. To remove untracked files:

  • Run git clean --dry-run. It just tells you what will be removed. Do it because cleaning is a dangerous command.
  • Run git clean --force to eventually remove your untracked files.

You can find more details about git checkout and git reset here and about cleaning here.

Reciprocity answered 27/8, 2018 at 17:20 Comment(0)
S
2

file.txt, being untracked, is "invisible" to Git. If there is another file named file.txt in the commit you check out, it can be overwritten as a side effect of the check out, but Git won't go out of its way to removed untracked files.

Scholiast answered 27/8, 2018 at 17:3 Comment(6)
So if I delete or modify a file that was in the previous commit, and checkout to that commit, that file is reverted, but this only as a "side effect"?Titty
@JackM Actually, what you'll get in this case is checkout error. Git will force you to do something about the pending change, because it can't know what were your intentions here. Did you simply forget to commit?Germander
@SergioTulentsev That's not true. Git gives me no error, and reverts modified files to their previous state.Titty
@JackM: when doing git checkout . or git checkout <ref>? I was describing the latter.Germander
@SergioTulentsev git checkout HEAD . - if I just do git checkout HEAD it doesn't do anything, but it doesn't give me an obvious error either (it prints out a message about the modification to the file, though, which I guess is what you mean).Titty
@JackM: yep, that's precisely what I meant.Germander
C
0

Try

git clean -fd

This has been bothering me for a long time. Finally found that the command above will delete untracked files/folders.

BTW, you still need

git checkout -- .

to discard all local changes.

Chrysanthemum answered 28/6 at 1:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.