4

Based on this post and this post ,
git ls-files --others --exclude-standard can list all untracked files.
But I test it, cannot list empty folder(both tracked and not tracked).

For example,cannot list empty folder archiver folder as below:

.
├── admin.php
├── api
│   ├── index.htm
│   └── remote
│       └── mod
│           ├── index.htm
│           ├── mod_cron.php
│           └── mod_index.php
└── archiver folder

Then my question is: how to list all untracked files and empty folders?

gorn
  • 5,042
  • 7
  • 31
  • 46
kittygirl
  • 2,255
  • 5
  • 24
  • 52

3 Answers3

4

TL;DR: just look for empty directories. You can safely remove them—well, "safe" depends on your own software, but as far as Git is concerned, it's safe. (Watch out for missing files—see the definition of "missing" below—which may remove a directory that Git might want later, but that's sort of OK, because Git will just create it again.)

On a Unix / Linux system (edited to correct lost word in transcription):

find . -name .git -prune -o -type d -empty -print

(at the top level of the work-tree) will find the empty directories.

Long(ish)

Git is not interested in folders / directories. There's no such thing as an untracked folder in the same way that there's no such thing as a tracked folder: Git only cares about files. Specifically, a file is either in the index, or not in the index, and if it's not in the index, it's untracked.

When you use the various options to list untracked files (which tend to skip over ones that are untracked-and-ignored since you normally want that), Git will, sometimes, aggregate together all the files that are in some folder, notice that there are no tracked files in that folder, and report them using the aggregated notation. You can stop this with, e.g., git status --untracked-mode=all; then you'll get the individual file names.

Note that it's possible to have some file that is tracked, yet missing. For instance, suppose sub/README.txt is a tracked file, and actually exists. Then we run rm sub/README.txt. The file sub/README.txt remains in Git's index, and will be in the next commit, but it's missing. If that was the only file in sub in your work-tree, sub is now empty, and you can remove it with rmdir sub. Even though sub/README.txt remains missing (and sub is missing too!), that does not affect the next commit: it will still contain sub/README.txt, because that file is in the index. (Using git rm --cached sub/README.txt, you can remove it from the index too, if that's what you wanted.)

If and when Git goes to copy sub/README.txt back out of the index into the work-tree, Git will, at this point, discover that there is no sub. Git will merely shrug its metaphorical shoulders and create the directory sub, and then put sub/README.txt into it. So this is why Git is not interested in folders / directories: they're just boring and dull, required only when needed to hold files, created on demand.

If you want Git to create a directory, you need to store a file in it. Since programs managed by Git need to be able to ignore the file named .gitignore, this is a very good file name to stick into such a directory. You can write * into that file, and add it to your commits, so that Git will create the directory and write a .gitignore file there containing *, and will thus ignore all additional untracked files within that directory automatically.

Side note: In general, when Git pulls the last file out of some directory, it will remove the directory too, but occasionally I've seen it leave some behind. (Of course, it has to leave the directory behind if it still contains some untracked files. Note that git clean -fd will remove the empty directories, though it also removes the untracked files.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • For example, there's empty folder `upload_resource`,git ignore it but we need this empty folder.This empty folder must be in production server,then users can upload files to this folder. – kittygirl Jan 05 '19 at 02:52
  • If you want to use Git to store a directory tree that you will deploy on a server elsewhere, and a `.gitignore` file is not sufficient, then don't use Git as the deployment tool. Use something else that will put the right files into place *and* create the empty directories that you need. – torek Jan 05 '19 at 02:54
  • yes,I use `rsync` to deploy empty folders.But how to `list empty folders`? – kittygirl Jan 05 '19 at 02:55
  • Well, with `find`, use the `-empty` predicate. It is true for empty files as well, so `find . -name .git -prune -o -d -empty -print` will find actually-empty directories. – torek Jan 05 '19 at 03:00
  • Just create a file in the folder. I usually call it `.keep`. Then you can commit it. – erik258 Jan 05 '19 at 13:06
  • @kittygirl: what do you mean by "wrong result"? I get: `find --version` => `find (GNU findutils) 4.7.0-git`; `mkdir empty` and then the above `find` => `./empty`; `rmdir empty` and repeat the find, no output. ... Oh! Gah, I lost the `-type` in the transcription! – torek Jan 05 '19 at 15:08
  • @torek,now, your script has no any warning or error. – kittygirl Jan 06 '19 at 02:31
1
git ls-files --others --exclude-standard> not_tracked
find . -depth -empty -type d \( ! -regex '.*/\..*' \) >> not_tracked

Please check my answer,I spent 2 days for it.

kittygirl
  • 2,255
  • 5
  • 24
  • 52
0

The command git clean does exactly what you want.

Adar Arnon
  • 183
  • 1
  • 5