我正在尝试将我的Zend Framework 2供应商目录中的目录(及其内容)供应商列入白名单。
/ vendor中的原始.gitignore文件如下所示:
# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
现在我想将目录SupplierName列入白名单,我认为这应该不会太难。我有read the docs on gitignore并尝试了以下配置:
首先尝试,在评论后面添加!SupplierName,说明我必须在此处添加白名单路径。
# Add here the vendor path to be whitelisted
!SupplierName
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
之后我执行了git status
,但没有显示vendor / SupplierName目录。 git add vendor/SupplierName
显示以下消息:
您的.gitignore文件会忽略以下路径:vendor / SupplierName
第二次尝试
# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!SupplierName
!.gitignore
*
之后我执行了git status
,但没有显示vendor / SupplierName目录。 git add vendor/SupplierName
显示以下消息:
您的.gitignore文件会忽略以下路径:vendor / SupplierName
第三次尝试
# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
!SupplierName
之后我执行了git status
,但没有显示vendor / SupplierName目录。 git add vendor/SupplierName
似乎有效。但是现在,当我想添加Module.php文件(以及一些其他文件,子目录等)时,会发生以下情况。 git add vendor/SupplierName/Module.php
- >
您的.gitignore文件会忽略以下路径:vendor / SupplierName / Module.php
# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
*
!.gitignore
!SupplierName
!SupplierName/
!SupplierName/*
允许我直接在vendor / SupplierName中添加文件,但git add vendor/SupplierName/config/module.config.php
仍会导致
您的.gitignore文件会忽略以下路径:vendor / SupplierName / config / module.config.php
我一直在寻找有关递归白名单的问题,因为这似乎是问题,但没有出现。
答案 0 :(得分:35)
您可以使用2个.gitignore
文件来获得所需的结果:
# vendor/.gitignore
*
!.gitignore
!SupplierName/
!SupplierName/*
# vendor/SupplierName/.gitignore
!*
我使用测试仓库对此进行了测试,似乎对我在vendor/SupplierName
目录下的多个级别添加文件起作用。
$ git add .
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: vendor/.gitignore
# new file: vendor/SupplierName/.gitignore
# new file: vendor/SupplierName/a
# new file: vendor/SupplierName/b
# new file: vendor/SupplierName/c
# new file: vendor/SupplierName/d
# new file: vendor/SupplierName/dir1/d
# new file: vendor/SupplierName/dir1/dir4/dir5/dir6/dir7/dir8/dir9/dir10/somefile
# new file: vendor/SupplierName/dir1/dir4/f1
# new file: vendor/SupplierName/dir1/dir4/f2
# new file: vendor/SupplierName/dir1/dir4/f3
# new file: vendor/SupplierName/dir1/dir4/f4
# new file: vendor/SupplierName/dir1/e
# new file: vendor/SupplierName/dir1/f
# new file: vendor/SupplierName/dir3/dir6/f5
# new file: vendor/SupplierName/dir3/dir6/f6
# new file: vendor/SupplierName/dir3/dir6/f7
# new file: vendor/SupplierName/dir3/dir7/f8
# new file: vendor/SupplierName/e
#
答案 1 :(得分:13)
您也可以只使用一个.gitignore
文件(在项目根目录中)实现此目的:
/*
!/.gitignore
!/vendor
/vendor/*
!/vendor/SupplierName
答案 2 :(得分:5)
发现了一篇有趣的文章:https://jasonstitt.com/gitignore-whitelisting-patterns
Jason Stitt的所有学分。文本从上面的网站复制:
忽略所有内容,然后添加特定的子树
# Ignore everything * # But descend into directories !*/ # Recursively allow files under subtree !/subtree/** # You can be specific with these rules !/some/other/deep/path/** !.gitignore
!*/
规则取消忽略所有目录。但是Git不跟踪目录,只跟踪文件,所以!*/
本身只会跟踪 允许下降到完整目录树;它实际上不允许 回购的任何东西。有了这个规则,你只需要一个 规则使用**
递归通配符以包含子树。如果您未使用
!*/
,则需要其他规则才能取消忽略 / subtree /及其子目录。不是每个人都喜欢
!*/
,因为这意味着如果有其他规则 允许在某个您不想要的目录中找到的文件名模式 在repo中,目录本身不会被阻止。你需要使用 文件的特定规则包含在此文件中。忽略根目录,然后添加整个子树
# Ignore everything in the root /* # Un-ignore all of subtree !/subtree/ !.gitignore
这种模式比前一种模式稍微粗糙一些。
/*
规则只会忽略回购根目录中的项目 目录结构,所以只要你将目录列入白名单,全部 即使不使用,也允许目录的内容*
或**
通配符。忽略目录中的所有内容,但保留空目录
* !.gitignore
Git不希望在repo中包含空目录,因为它 跟踪文件。将隐藏文件(例如.gitignore)放入 目录,它将被保存。但要保持目录为空,甚至 如果你有文件用于测试/开发目的,它就是一个 除了.gitignore文件本身之外,最好忽略所有内容。
答案 3 :(得分:2)
从CVS转到Git时,我遇到了类似的问题。
与CVS不同,Git不会查看目录,而是关注文件。
例如你不能忽略目录“a”,但你不能忽略目录“a”中的所有文件,如下所示:!a / *
子目录也是如此。
如果目录“a”有一个子目录“b”而你忽略“!a / *”那么你仍然可以获得“a / b”中的所有文件。
所以你必须忽略那个“!a / b / *”等等你要列入白名单的所有子目录。
您只需要一个.gitignore文件。
所以你最终得到的结果是:
# ignore everything
*
# except for .gitignore files in the current directory
!.gitignore
# and all files in directory a
!a/*
#and all files in subdirectory b
!a/b/*
有了这个,您仍然可以从/ c和/ b / c获取文件。我不确定是否存在递归子目录的解决方法。
答案 4 :(得分:2)
首先应将所有内容都包含在黑名单中,然后在白名单中创建每个目录和子目录。
例如,我只想将DIR /opt/source/
,DIR /opt/nginx/
和FILE /home/test/.opt/hello.txt
放入白名单,可以像这样编写.gitignore
文件以使其正常工作:
/*
!/.gitignore
!/opt
/opt/*
!/opt/source/
!/opt/nginx/
!/home
/home/*
!/home/test
/home/test/*
!/home/test/.opt
/home/test/.opt/*
!/home/test/.opt/hello.txt
答案 5 :(得分:0)
我创建了一个简单的JS片段,该片段可以在Node中运行以生成白名单规则,因为我发现手动编写规则有些混乱,并且如果以后忘记手动编写规则,我希望能够修改规则
event.source
答案 6 :(得分:0)
这与@Simon Lang的第一种技术(归功于Jason Stitt)有关,但适用于多种情况。
假设您希望在项目根目录中只有一个.gitignore,并假设您忽略项目的某些子目录的大部分内容,但只允许一小部分。例如,假设您的存储库包含一个具有第三方依赖关系的/vendor/
目录,您选择保留该目录在很大程度上保持完整,但是您将对其进行一些较小的调整,以使git能够跟踪它们,也许可以帮助您当不可避免的新版本出现时,返回移植。
然后您可以在根.gitignore
文件中执行以下操作:
# ignore all files and folders in `/vendor/` and in its descendants
/vendor/**
# negated pattern to un-exclude all *folders* at any depth relative to `vendor/`
# as always git will ultimately ignore the folders for which you don't
# subsequently un-exclude any *files*.
!/vendor/**/
# negated pattern to un-exclude all files and folders at any depth below the deep
# path that contains files you want in git
!/vendor/supplier/version/module/component/src/**
每个双星号实例都是至关重要的。例如,尾随vendor/**
匹配内部的所有内容– vendor
中的所有文件和目录都具有无限的深度,因此排除了其所有后代。
在*.exe
或*
这样的“普通”通配符gitignore规则中,由于路径不受限制,因此全局元字符匹配会发现任何目录中的任何文件。不受限制的路径在这里繁重,而不是通配符扩展。一旦您尝试将忽略的范围限制到根目录的子目录中,该繁重的文件就消失了,您立即会陷入*
无法进入树的状态。
Simon的答案通过使初始排除路径的尖端不受约束而起作用。最初,它将排除包含.gitignore文件的目录中的每个文件(任何深度)。通过使用**
进行/
的globstar匹配,Mine使您可以灵活地将此排除所有方法应用于子目录。通过拥有多个.gitignore文件,并在位于/vendor/.gitignore
的.gitignore文件中使用Simon的技术,可以达到相同的效果,但这需要维护。
我不知道使用**
会对性能产生什么影响,就像我在这里所做的那样。通过比较看起来像.p的.gitignore的性能,可以证明这一点
*
!*/
!a/b/c/d/**
到一个看起来像这样的人
/**
!**/
!a/b/c/d/**
在具有大量文件的树中。我相信会包含和排除相同的内容,但是幕后的实现和性能可能会有所不同。