我认为这可以解决问题:
*
!/dir1/
!/dir2/
!/file1
!/file2
但令我惊讶的是,事实并非如此。如果我在星号之前添加斜杠,它似乎有效。但我真的不明白为什么在这次改变之前它不起作用。有人能指出吗?
答案 0 :(得分:4)
要在!
中使用否定模式.gitignore
,请记住2条规则。
规则1.文件和目录在模式中分开处理。要包含一个目录并不意味着它的子文件/目录也包括在内。
即。目标是排除除/dir1
内的所有文件/目录以外的所有文件/目录。以下不起作用。
# CANNOT work
*
!/dir1/
为什么呢?原因只是第一条规则。虽然目录dir1
再次包含在内,但并非所有子文件/目录都包含在内。并且只包含没有子节点的目录对git没什么意义,因为git不会跟踪空文件夹。
作为比较,以下工作。
# works
/*
!/dir1/
为什么呢?因为/*
仅直接匹配根目录下的文件/目录,但不会忽略子目录下的任何文件/目录,例如dir1
。在!/dir1/
包含dir1
之后,其所有子文件/目录都会自然恢复。
有人可能会问,如果是这样,为什么以下内容不起作用,因为!/dir1/**
将包含dir1
的所有子文件/目录?
# CANNOT work
*
!/dir1/**
原因在于规则2。
规则2.如果仍然忽略其父目录,则不会包含文件/目录。对于此规则,请先阅读my answer to a SO question。
这就是为什么之前的模式无法发挥作用的原因。如果我们添加另一个否定模式以首先包含父目录dir1
,它就可以工作。
# works
*
!/dir1/
!/dir1/**
在理解了2条规则后,OP案例的解决方案非常简单。
以下作品。
/*
!/dir1/
!/dir2/
!/file1
!/file2
以下也有效。
*
!/dir1/
!/dir1/**
!/dir2/
!/dir2/**
!/file1
!/file2
简化如下。
*
!*/
!/dir1/**
!/dir2/**
!/file1
!/file2