.gitignore白名单目录及其内容

时间:2013-03-08 07:18:53

标签: git gitignore

我正在尝试将我的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

我一直在寻找有关递归白名单的问题,因为这似乎是问题,但没有出现。

7 个答案:

答案 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/**

在具有大量文件的树中。我相信会包含和排除相同的内容,但是幕后的实现和性能可能会有所不同。