.gitignore目录及其内容上的白名单

.gitignore目录及其内容上的白名单,git,gitignore,Git,Gitignore,我正在尝试将Zend Framework 2供应商目录中的目录(及其内容)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/SupplierNa

我正在尝试将Zend Framework 2供应商目录中的目录(及其内容)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
#
/vendor中的原始.gitignore文件如下所示:

# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
现在我想把目录供应商的名字列入白名单,我想这应该不会太难。我已经尝试了以下配置:

第一次尝试,添加!供应商名称就在注释后面,该注释表示我必须在此处添加白名单路径

# Add here the vendor path to be whitelisted
!SupplierName
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
紧接着我执行了
git status
,它没有显示供应商/供应商名称目录
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
*
# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
!SupplierName
紧接着我执行了
git status
,它没有显示供应商/供应商名称目录
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
*
# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
!SupplierName
紧接着我执行了
git status
,它没有显示供应商/供应商名称目录
git添加供应商/供应商名称
似乎有效。但是现在,当我想添加Module.php文件(以及其他一些文件、子目录等)时,会发生以下情况
git添加vendor/SupplierName/Module.php
-->

以下路径被一个.gitignore文件忽略:vendor/SupplierName/Module.php

允许我直接在vendor/SupplierName中添加文件,但git add vendor/SupplierName/config/module.config.php仍然会导致

以下路径被.gitignore文件之一忽略:vendor/SupplierName/config/module.config.php


我一直在搜索有关递归白名单的问题,因为这似乎是问题所在,但什么也没有出现。

您可以使用2个
.gitignore
文件来实现所需的结果:

# vendor/.gitignore
*
!.gitignore
!SupplierName/
!SupplierName/*

# vendor/SupplierName/.gitignore
!*
我用一个测试repo对此进行了测试,似乎在
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
#
$git add。
$git状态
#论分行行长
#要提交的更改:
#(使用“git重置磁头…”取消分级)
#
#修改:vendor/.gitignore
#新文件:vendor/SupplierName/.gitinore
#新文件:供应商/供应商名称/a
#新文件:供应商/供应商名称/b
#新文件:供应商/供应商名称/c
#新文件:供应商/供应商名称/d
#新文件:供应商/供应商名称/dir1/d
#新文件:vendor/SupplierName/dir1/dir4/dir5/dir6/dir7/dir8/dir9/dir10/somefile
#新文件:供应商/供应商名称/dir1/dir4/f1
#新文件:供应商/供应商名称/dir1/dir4/f2
#新文件:供应商/供应商名称/dir1/dir4/f3
#新文件:供应商/供应商名称/dir1/dir4/f4
#新文件:供应商/供应商名称/dir1/e
#新文件:供应商/供应商名称/dir1/f
#新文件:供应商/供应商名称/dir3/dir6/f5
#新文件:供应商/供应商名称/dir3/dir6/f6
#新文件:供应商/供应商名称/dir3/dir6/f7
#新文件:供应商/供应商名称/dir3/dir7/f8
#新文件:供应商/供应商名称/e
#

从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/*

这样,您仍然可以从a/c和a/b/c获取文件。我不确定是否有向下递归子目录的解决方法。

您也可以只使用一个
.gitignore
文件(在项目根目录中)来实现这一点:


您应该首先将所有内容都包含在黑名单中,然后将每个目录和子目录都包含在白名单中。 例如,我只想将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

发现一篇有趣的文章:

全部归功于杰森·斯蒂特。文本从上述站点复制:

忽略所有内容,然后添加特定子树
*/规则取消忽略所有目录。但是Git不跟踪目录,只跟踪文件,所以
*/本身只会
允许下降到完整的目录树;它实际上不允许
回购协议中的任何内容。有了这个规则,你只需要一个
使用递归通配符来包含子树的规则

如果您没有使用
*/,则需要其他规则才能取消忽略
/子树/及其子目录

不是每个人都喜欢
*/因为它意味着如果任何其他规则
允许在不需要的目录中找到文件名模式
在repo中,目录本身不会被阻止。你需要使用
此文件包含的文件的特定规则

忽略根目录,然后添加整个子树 这个图案比前一个略粗一些。
/*
规则将只忽略回购协议根目录中的项目 目录结构,所以只要你列出一个目录,所有的 目录的内容也将被允许,即使不使用
*
***
通配符

忽略目录中的所有内容,但保留空目录 Git不希望在repo中包含空目录,因为它 跟踪文件。将隐藏文件(如.gitignore)放入
# Ignore everything in the root
/*
# Un-ignore all of subtree
!/subtree/
!.gitignore 
*
!.gitignore
'use strict';

// Generating a "whitelist" wherein you only want a specific folder to be
// affected requires following .gitignore-style rules.
// https://github.com/prettier/prettier/issues/3328
//
// Handcrafting these rules is hard to reason about and error-prone, so I'm
// going to generate them.
// See: https://github.com/prettier/prettier/issues/3328
// And: https://git-scm.com/docs/gitignore
//

const path = require('path');

const whitelistDir = '/themes/simple/src/';

function generateIgnoreRule(dir) {
    let output = '# Auto-generated by ' + path.basename(__filename) + '\n';
    output += '# Exclude everything except `' + dir + '`\n';
    // Add exclude everything rule
    output += '/*' + '\n';

    // Split by path
    const parts = dir.split('/');
    if (parts[0] === '') {
        // Remove first item if its blank
        parts.shift();
    }
    if (parts[parts.length - 1] === '') {
        // Remove last item if its blank
        parts.pop();
    }

    let totalPart = '';
    for (let part of parts) {
        totalPart += '/' + part;
        output += '!' + totalPart + '\n';
        if (part !== parts[parts.length - 1]) {
            output += totalPart + '/*' + '\n';
        }
    }
    return output;
}

console.log(generateIgnoreRule(whitelistDir));
console.log(
    '\nCopy the above rules out of the console output and paste into your .gitignore / .prettierignore'
);
# 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/**
*
!*/
!a/b/c/d/**
/**
!**/
!a/b/c/d/**