Git - 如何只包含整个工作树中的某些文件和目录?

时间:2013-06-06 06:59:14

标签: git

我正在为magento开发一个扩展程序。工作目录中有很多文件,但我只需要在git中包含我在扩展中添加的文件。如何为此案例定义.gitignore规则?

我试过了 - .gitignore

*
!/app/etc/modules/Some_Ext.xml
!/app/code/local/Some/Ext/
!/app/designer/...
... - etc.

但是当我尝试 git status 时,它只会显示 .gitignore

当我用某些dirs替换星号时,它不会改变任何东西。实现目标的正确方法是什么?

2 个答案:

答案 0 :(得分:10)

<强>更新

有一个更简单的解决方案:

*
!*/
!/app/etc/modules/Some_Ext.xml
!/app/code/local/Some/Ext/
!/app/designer/...
... - etc.

第二行将再次包含所有目录,然后以下模式才能生效。


嗯,已经探索过源代码,我发现'gitignore'机制在某种程度上非常棘手。

一些要点总结如下:

  1. 小心忽略目录。 Git以递归的方式搜索未跟踪的文件,忽略目录将导致git跳过该目录并自动忽略其下的所有文件/子目录,即使你有一个“not”-pattern。所以

    /app
    !/app/code/index.php
    

    不会保存index.php,它会与/app一起被忽略。

  2. 尽力而为,请改用*.xml/txt/conf/etc...。最好不要使用独立的*因为它会忽略任何目录,这可能不是你想要的。

  3. 没有优先级,但订单。对于目录或文件,git逐行匹配到.gitignore的路径,并使用最后匹配的模式。如果最后匹配的模式具有前导!,则git将包含文件/目录,否则将忽略它。

    所以

    *.xml
    !/app/etcmodules/Some_Ext.xml
    

    将保留Some_Ext.xml

    !/app/etcmodules/Some_Ext.xml
    *.xml
    

    将过滤掉它。

  4. 将git更新到1.8.2版本可能有所帮助。在1.8.2中,他们添加了一个命令git check-ignore来调试.gitignore配置。


  5. 我认为git add -A的工作流程可以解释更多。

    假设有一个这样的存储库。

    .
    ├── a.conf
    ├── b
    │   └── b.conf
    └── c
        └── c1
            └── c2
                └── c.conf
    

    .gitignore中,它是

    *.conf
    b/
    !b/b.conf
    !c/c1/c2/c.conf
    

    当我运行git add -A时,git将

    1. 扫描工作目录,发现有一个常规文件a.conf和两个目录bc
    2. 请注意文件a.conf*.conf中的.gitignore匹配,然后忽略它。
    3. b是一个目录,但被b/中的模式.gitignore排除,停止递归到b
    4. 因排除了b,因此从未扫描b/b.conf。 (虽然他未被排除在.gitignore的第三行)
    5. c是一个目录,看起来不错,包含它并继续递归。
    6. c/c1/c2/c.conf匹配两种模式,但最后一种决定了命运。由于最后匹配的模式!c/c1/c2/c.conf具有前导!c/c1/c2/c.conf将继续存在。
    7. 以下是我的计算机git add -A的结果(Mac版本为1.8.2的git)

      # On branch master
      #
      # Initial commit
      #
      # Changes to be committed:
      #   (use "git rm --cached <file>..." to unstage)
      #
      #       new file:   .gitignore
      #       new file:   c/c1/c2/c.conf
      

答案 1 :(得分:0)

您可以尝试将!/app/替换为!app/