2

This is what I did:

$ git status
# I see some files *and* directories (some tracked, some not) which I really wanted to discard
$ git clean -xd

And I am surprised to see that git removes some other directories, which were not shown in git status. After an initial schock (this was my /etc in one of my production hosts) I realize that they were not listed by git because they were empty directories (so not a big deal, just mkdir them - hoping to get permissions right). Which is fine, but:

Why on earth does git not consider empty directories when doing git status, but does consider them when doing git clean? This is very annoying (and dangerous)!

blueFast
  • 41,341
  • 63
  • 198
  • 344
  • git only tracks file. If you want to track a folder, putting a `.gitignore` file in the folder is a common way to achieve it. Git clean returns the repository to the state known to git (files only). – Holloway Feb 17 '15 at 15:57
  • Closely related: http://stackoverflow.com/questions/115983/how-can-i-add-an-empty-directory-to-a-git-repository – Sascha Wolf Feb 17 '15 at 16:02
  • Might even be a "hidden" duplicate. – Sascha Wolf Feb 17 '15 at 16:03
  • If you truly want to see what `git clean` removes, run it with the `-n` (`--dry-run`) option. See the [documentation](http://git-scm.com/docs/git-clean). – Sascha Wolf Feb 17 '15 at 16:05
  • I am not asking how to add empty dirs (I already know that). I am just complaining (and hoping to be corrected) why are `git clean` and `git status` not consistent wrt empty directories – blueFast Feb 17 '15 at 16:08

1 Answers1

3

As you already seem to know: You can't add empty directories in git (If not see the FAQ).

git status effectivly tells you which changes you can add and commit. So, even if it would be possible for git status to display empty directories, this would be highly confusing for the user.

Why can I see this directory but not track it?


git clean on the other hand removes everything which isn't tracked. Using the -d option also tells clean to remove untracked directories.

But what defines an untracked directory?

As we learned, git doesn't track directories, it tracks files (or more specific file contents). In turn this means that an untracked director is nothing else but a directory which doesn't contain any tracked files. This applies for the build folder you ignore with multiple hundred of files, as it does for the empty tmp folder, you created earlier and forgot about.

If you want to make sure that git clean doesn't remove anything you want to keep, you should use the -n (--dry-run) option (which is described in the documentation). This tells you about all files git clean will remove.

To ensure that you don't forget -n (--dry-run) you can create an alias.

git config --global alias.status-clean "clean --dry-run"

Which you can now easily use like git status-clean -dx to display all files which would be removed by a git clean -dx call.


TL;DR: Don't use git status to see what git clean -d will remove. Use git clean -d --dry-run.

Sascha Wolf
  • 18,810
  • 4
  • 51
  • 73
  • Thanks, but not convinced. `git status` can already report non-trackable files (with `--ignored`), so it makes sense to have a `--all` flag, and `git status` could just have another section for "Empty non-trackable directories". Basically, the reporting tool (`git status`) and the acting tool (in this case `git clean`) are using a different set of files/directories, which is not cool at all. You would not be very happy if `ls` could not list empty directories but `rm` could very well delete them. Luckily there is the `ls -a` form. – blueFast Feb 18 '15 at 06:43
  • I do not like to use a tool which is intended for writing to the filesystem (`git clean`) to perform a reporting operation, simply because it is too easy to make a mistake and forget the `--dry-run` (ever done a `^R` to search for your last command?). Reporting with a *read-only* tool, acting with a *read-write* tool. But if they are not consistent ... – blueFast Feb 18 '15 at 06:44
  • I disagree strongly. You are comparing two completly different situations. `git status --ignored` doesn't report **non-trackable files** it reports **trackable files** which you **explicitly choose** not to track. An empty directory is **not trackable**. `git status` is the reporting too for everything which involves the **tracking** of files (`add`, `commit`, `diff` etc.); `git clean` on the other hand removes everything you **don't track**, be it **on purpose** or because git **can't track** it. You're expecting the wrong tool to do the job. – Sascha Wolf Feb 18 '15 at 07:27
  • Which is the corresponding reporting tool for git clean then? I mean, a read-only reporting tool, which can not wreak havoc if I forget a command-line flag? My point is that it *should* be `git status` – blueFast Feb 18 '15 at 07:31
  • As I said, `git status` is for **tracking** and `git clean` for **not tracking**. You can easily create an alias `git config --global alias.status-clean "clean --dry-run"` and use this. – Sascha Wolf Feb 18 '15 at 07:42