Hello all, in https://github.com/Kentzo/git-archive-all/issues/87 I reported a problem which turns out to be more likely a problem in git. The documentation of `gitattributes` says: > The rules [mostly follow .gitignore], with a few exceptions: > * [...] > * patterns that match a directory do not recursively match paths > inside that directory (so using the trailing-slash path/ syntax > is pointless in an attributes file; use path/** instead) This means to me, that patterns may match _directories_ instead of the files in them. So, if I have a /.gitattributes file like this: > LICENSES/ export-ignore I expect the whole directory /LICENSES/ to be matched, so a tool like `git-archive` skips it when creating an archive. However, if I have a /.gitattributes file like this: > LICENSES/** export-ignore I expect the directory itself not to be matched, but all files inside it, so a tool like `git-archive` adds an empty /LICENSES/ directory to the archive. `git-archive` actually behaves like this. However, `git-check-attr` does not behave like this. In the second example, it will list `export-ignore` matching on every file inside /LICENSES/. But in the first example, it will list `export-ignore` matching nowhere. This leads to the problem where `git-archive-all` wrongly exports the whole /LICENSES/ directory. The documentation for `gitattributes` says for `export-ignore`: > `export-ignore` > Files and directories with the attribute `export-ignore` > won’t be added to archive files. For most other attributes it does not include directories, because they do not make sense for directories. --- I think the solution is like this: 1. Change the documentation of `gitattributes` to: > The rules [mostly follow .gitignore], with a few exceptions: > * [...] > * patterns that match a directory do not recursively match paths > inside that directory. (Since most attributes are only useful for > files, the path/ syntax is probably incorrect; use path/** instead.) 2. Change git-check-attr to make patterns like path/ match directories. At least, for attributes like `export-ignore` this should be changed, but I think the correct solution is to change it for all attributes. --- Below is a shell script to reproduce the problem. ``` mkdir test_attributes cd test_attributes git init -b master mkdir include dont-include-1 dont-include-2 dont-include-3 touch include/a.txt dont-include-1/b.txt dont-include-2/c.txt dont-include-3/ d.txt echo dont-include-1/ export-ignore >>.gitattributes echo dont-include-2/** export-ignore >> .gitattributes echo dont-include-3 export-ignore >>.gitattributes git add -A git commit -m "Test gitattributes" git archive --output ../test_attributes.zip HEAD zipinfo ../test_attributes.zip git check-attr export-ignore * */* ``` This is the output which I get with git version 2.33.0.752.gd22421fcc6: > $ git archive --output ../test_attributes.zip HEAD > $ zipinfo ../test_attributes.zip > Archive: ../test_attributes.zip > Zip file size: 584 bytes, number of entries: 4 > -rw---- 0.0 fat 94 tx defN 21-Sep-23 16:37 .gitattributes > drwx--- 0.0 fat 0 bx stor 21-Sep-23 16:37 dont-include-2/ > drwx--- 0.0 fat 0 bx stor 21-Sep-23 16:37 include/ > -rw---- 0.0 fat 0 tx stor 21-Sep-23 16:37 include/a.txt > 4 files, 94 bytes uncompressed, 46 bytes compressed: 51.1% > > $ git check-attr export-ignore * */* > dont-include-1: export-ignore: unspecified > dont-include-2: export-ignore: unspecified > dont-include-3: export-ignore: set > include: export-ignore: unspecified > dont-include-1/b.txt: export-ignore: unspecified > dont-include-2/c.txt: export-ignore: set > dont-include-3/d.txt: export-ignore: unspecified > include/a.txt: export-ignore: unspecified Note how `dont-include-2/** export-ignore` caused an empty directory to be created. This is problematic for my workflow. `dont-include-3 export-ignore` yields the desired results here, but I think it is not always an alternative, since the missing trailing slash makes the rule apply to files too. For example in this repository structure: > - a/ > - dont-include-3/ > - a.txt > - b/ > - dont-include-3/ > - b.txt > - dont-include-3 I could not use the glob syntax `**/dont-include-3 export-ignore` to skip only the two _directories_ with a.txt and b.txt, because the _file_ dont-include-3 would also be skipped. --- I am generally available for submitting patches to fix this issue. Let me know what you think. :) Cheers, David