0

I'm trying to run git ls-files and exclude a specific directory from it. Does the --exclude flag only exclude file patterns, and not directories?

git ls-files -x */util/*

arhak
  • 2,488
  • 1
  • 24
  • 38
user1795832
  • 2,080
  • 8
  • 29
  • 50

2 Answers2

1

As the documentation says, -x takes a pattern argument, so it only excludes patterns.

But Git only stores files: "directories" or "folders" only exist in the imagination—and, alas, reality—of your computer's operating system, not in Git. Git just has files named foo/util/bar or whatever. But that's fine: if your computer insists on storing a file named bar inside a directory/folder named util inside a directory/folder named foo when Git is storing a file named foo/util/bar, the pattern */util/* matches Git's file name.

Note that -x only excludes untracked files, so it only affects git ls-files invocations that print the names of files found in the work-tree, not those that print the names of files found in the index. Files stored in the index literally do have long names that may contain slashes, such as dir/sub/file.ext: the index has no ability to store directories / folders. (This is why Git cannot store an empty directory. Git builds new commits from whatever is in the index, and the index does not store directories, so Git cannot build a commit containing an empty directory.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • Ah, I missed the part about untracked files. So really, `-x` is useless unless you include untracked files via `-o`? – user1795832 Feb 26 '20 at 22:57
  • @user1795832: pretty much, yes. – torek Feb 26 '20 at 23:00
  • Thanks. So if I wanted to exclude files from `ls-files` that match a pattern, is that possible? Say I have two files, `foo/bar/util/baz/test.txt` and `foo/bar/util/qux/test.txt`, can I exclude them with a single exclusion pattern? – user1795832 Feb 26 '20 at 23:04
  • Well, `foo/bar/util/*/test.txt` would match both, but would also match `foo/bar/util/plugh/test.txt` as well. If that's what you want, that's good; if not, perhaps avoid the `*` glob match. Note also that you can use `**` to match zero or more component names here as (at least the documentation claims) the `-x` arguments are handled the same way as lines in `.gitignore` files. – torek Feb 26 '20 at 23:38
  • See https://stackoverflow.com/questions/36753573/how-do-i-exclude-files-from-git-ls-files for how to exclude files – user1795832 Feb 28 '20 at 17:41
  • @user1795832: ah, I missed the idea that you were no longer asking about the `-x` option. Yes, for that, you need to use *pathspecs* (as shown in the linked Q&A). – torek Feb 28 '20 at 19:48
1

To make exclusion patterns work on tracked files, ask for excluded-and-tracked files and invert your patterns.

So if you want to list everything that's tracked and outside the media directory,

git ls-files -ix\* -x'!media/*'

which defaults to listing tracked files and matches that sequence of patterns.

To filter both tracked and untracked, git ls-files -ocix\* -x'!media/*'

jthill
  • 55,082
  • 5
  • 77
  • 137