Home > Blockchain >  .gitignore double star not working recursively from intermediate directories?
.gitignore double star not working recursively from intermediate directories?

Time:12-15

Using git version 2.34.0.windows.1

I have a /.gitignore file at the root of my repository with the usual suspects of extension ignores in it (it's not really relevant here).

Halfway up the tree (/a/b/c/.gitignore), I have another file, where I wanted to say "recursively below this directory, ignore any directory called devl, except for one particular file extension directly inside". So I put the following rules:

devl/**
!devl/*.dat

Unfortunately, it appears this does not work -- git still reports the file /a/b/c/d/devl/test/foo.bar as untracked, not ignored. (It does not ignore anything at all in the devl directory tree.)

I was able to work around this by using the following rules instead, but as far as I can tell from the documentation, the above should have been legal and working as well:

/**/devl/**
!/**/devl/*.dat

Why is this? Is it a bug or a misunderstanding?

CodePudding user response:

Unfortunately, you didn't read the documentation carefully enough...

If there is a separator at the beginning or middle (or both) of the pattern, then the pattern is relative to the directory level of the particular .gitignore file itself. Otherwise the pattern may also match at any level below the .gitignore level.

Your first pattern devl/** has a / at the middle, so it's relative to the directory /a/b/c/.

Therefore, /a/b/c/devl/test/foo.bar should be excluded, while /a/b/c/d/devl/test/foo.bar should not.


The second pattern !devl/*.dat won't work as you expected, either, because:

It is not possible to re-include a file if a parent directory of that file is excluded.

In your case, it's impossible to re-include a/b/c/devl/test.dat since a/b/c/devl is excluded.

CodePudding user response:

Maybe these two things could help: Cache and Order.

Remove the cache of all or of specific file(s).

git rm -r --cached .
git rm -r --cached <your_file_name.ext>

Change order

Each line in a gitignore file specifies a pattern. When deciding whether to ignore a path, Git normally checks gitignore patterns from multiple sources, with the following order of precedence, from highest to lowest (within one level of precedence, the last matching pattern decides the outcome):

This line is important: the last matching pattern decides the outcome

CodePudding user response:

This works:

**/dev1/**
!**/dev1/*.dat

(Gotta go take care of the kids. back later)

CodePudding user response:

I would make sure to not ignore folders, before not ignoring a file.

If a folder is ignored, no amount of !myFile inside that folder would work.

So for your second nested .gitignore, try:

**/devl/
!**/devl/**/         <=== Important
!**/devl/*.dat

That being said, this should be tried with Git for Windows 2.34.1 (Nov. 2021), which includes a regression fix for 2.34.0

See commit 33c5d6c (19 Nov 2021) by Derrick Stolee (derrickstolee).
(Merged by Junio C Hamano -- gitster -- in commit 1bf2673, 22 Nov 2021)

dir: revert "dir: select directories correctly"

Reported-by: Danial Alihosseini
Signed-off-by: Derrick Stolee

This reverts commit f6526728f950cacfd5b5e42bcc65f2c47f3da654.

The change in f652672 ("dir: select directories correctly", 2021-09-24, Git v2.34.0-rc0 -- merge listed in batch #13) caused a regression in directory-based matches with non-cone-mode patterns, especially for .gitignore patterns. A test is included to prevent this regression in the future.

The commit ed495847 ("dir: fix pattern matching on dirs", 2021-09-24, Git v2.34.0-rc0 -- merge listed in batch #13) was reverted in 5ceb663 ("dir: fix directory-matching bug", 2021-11-02, Git v2.34.0-rc1 -- merge) for similar reasons. Neither commit changed tests, and tests added later in the series continue to pass when these commits are reverted.

CodePudding user response:

Try the following:

**/devl/*
!**/devl/*.dat

It worked for me and found the answer from exclamation mark in .gitignore doesn't work. The first line ignores everything inside devl and in the second line it is excluding .dat files.

CodePudding user response:

This appears to be a bug in git; I have posted a report to their issue tracker.

  • Related