3

I want a list of all the files in my working tree that would be tracked (e.g. would be added by git add -A if every single file in my working tree had been changed) based on the .gitignore files I have written.

theonlygusti
  • 11,032
  • 11
  • 64
  • 119
  • Incidentally, it's usually more interesting to query Git about one particular file, or some short list of particular files, for which one can use `git check-ignore -v`. – torek Dec 19 '18 at 22:01
  • @torek can't I get all files in working tree (`**` or something?) and put them as arguments to `git check-ignore -v`? – theonlygusti Dec 19 '18 at 22:07
  • Unfortunately, `git check-ignore` takes pathnames, not pathspecs. You can use `find -print` (or `-print0`) to find all path names (but be sure not to descend through `.git` itself) and use `xargs` to send those names to `git check-ignore`, but this will be significantly more work and slower than using `git ls-files` twice. On the other hand, if you need the ignored files' path-names as well as the non-ignored files' path-names, this may be the way to go. – torek Dec 19 '18 at 22:10

2 Answers2

3

One has to be careful here, as the git add -A flag has changed meanings between Git 1.x and Git 2.x. See Difference between "git add -A" and "git add ." and scroll down to this answer (or click this link) to see what I mean.

For Git 2.x, files that are already tracked—are already in the index—will continue to be in the index. Using -A will ignore any files that have gone missing from the work-tree. (For 1.x, using -A will remove from the index files that have gone missing from the work-tree.)

There are a couple of different things you can do at this point, depending on what you want as a result, largely centering around git ls-files, which:

  • reads the index, so it knows what's in there now
  • optionally reads the work-tree, so that it knows what's there as well
  • optionally reads a specified exclusion file, or the standard ones

The command can be limited to showing:

  • existing tracked files: -c or --cached
  • files that are tracked, yet have been modified in the work-tree: -m or --modified
  • files that are in the work-tree but not in the index (are untracked): -o or --others
  • files that are, or would be, ignored: -i or --ignored

One has to combine these options with --exclude-standard to get git ls-files to obey the same "drop the untracked files" rules as git add. So:

git ls-files --exclude-standard --other

will get you the set of files that are currently untracked, but would be added by git add -A. It won't get you the files that are currently tracked and would also be added by git add -A; to get those, use git ls-files --modified. (To assume that all the files would have been modified, use --cached—but this won't account for work-tree files that have gone missing. If you want to do that, it's considerably trickier, and your best bet is to use git diff, or one of its variants, to compare index and work-tree, using a diff-filter to detect deleted files.)

(Combine the two lists to get everything.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • But my files are tracked and unmodified. I just want something that reads `.gitignore` and prints all files that wouldn't be ignored. – theonlygusti Dec 19 '18 at 21:58
  • @theonlygusti: you can't get that in one command. You can get it in two, provided you're not interested in work-tree files that have gone missing. See the edit regarding getting a second list with `--cached`. – torek Dec 19 '18 at 21:59
  • You can combine options, `git ls-files -oc --exclude standard`, and I have`git config --global alias.ls "ls-files --exclude standard"` so for me OP's request is `git ls -oc`, to find tracked files that maybe should be ignored it's `git ls -ci`. – jthill Dec 24 '18 at 19:06
  • @jthill: interesting; I tried combining options and it did not behave the way I wanted for that test, but maybe only some combinations don't work the way I would have wanted? – torek Dec 24 '18 at 21:14
1
git ls-files --exclude-from .gitignore

would have been my best guess, but I tried it on a repo I have here, to no avail :-/ It seems it doesn't take my .gitignore into account.

Maybe not too far from something working?

Romain Valeri
  • 19,645
  • 3
  • 36
  • 61