有没有一种方法告诉git只包括某些文件,而不是忽略某些文件?

我的程序通常会生成巨大的输出文件(~1 GB),我不想将这些文件备份到git存储库中。所以我们不能

git add .

我得做点什么

git add *.c *.cc *.f *.F *.C *.h *.cu

这有点麻烦…

我相信我可以编写一个快速perl脚本,将目录内容ls到.gitignore,然后根据.gitinclude(或一些类似的名称)文件删除文件,但这似乎有点太笨拙了。有没有更好的办法?

101421 次浏览

我自己没有必要尝试这个,但从我对解冻的阅读来看,它看起来像一个负模式会做你想要的。你可以在.gitignore中使用后面的负项来覆盖条目。因此你可以这样做:

*.c
!frob_*.c
!custom.c

要让它忽略所有。c文件,除了custom.c和任何以"frob_"开头的文件

在你的存储库中创建.gitignore文件,你想只跟踪c文件,忽略所有其他文件,然后添加以下行....

*
!*.c

'*'将忽略所有文件

和!将否定文件被忽略....所以这里我们要求git不要忽略c文件....

实现这一目标的最佳解决方案

在存储库root中创建.gitignore文件,如果你只想包含.c文件,那么你需要在.gitignore文件中添加以下行

*.*
!*.c

这将递归包括所有.c文件从目录和子目录。

使用

*
!*.c

不会在所有版本的git上工作。

测试

Git 2.12.2.windows.2

虽然姗姗来迟,但我的解决方案是为源文件提供一个目录,为可执行文件和程序输出提供一个不同的目录,就像这样:

+ .git
|    (...)
+ bin
|    my_exe.exe
|    my_output.txt
+ src
some_file.c
some_file.h

... 然后只将src/中的东西添加到我的存储库中,并完全忽略bin/

如果你需要忽略文件,而不是目录中的特定文件,下面是我是如何做到的:

# Ignore everything under "directory"
directory/*
# But don't ignore "another_directory"
!directory/another_directory
# But ignore everything under "another_directory"
directory/another_directory/*
# But don't ignore "file_to_be_staged.txt"
!directory/another_directory/file_to_be_staged.txt

如果你只是试图包含点文件,这对我来说是可行的…

!.*

我已经看到了很多关于开头“忽略一切”的建议。规则,在这里在SO和其他网站,但我发现他们中的大多数有自己的恼人的使用问题。这就产生了像可分配的.gitinclude.NETGH页面托管git-do-not-ignore这样的项目,它们都只是帮助减少维护的繁琐。

这些(以及许多其他博客文章)都建议从简单的*开始,毫不夸张地说,忽略当前根目录下的所有文件和文件夹。

此后,包括文件是“;作为简单的”;作为路径前缀的!,例如!.gitignore,以确保我们的repo不会忽略它自己的.gitignore规则文件。

这样做的缺点是,当Git遇到一个被忽略的文件夹时,出于性能原因,它不会检查它的内容。尝试忽略嵌套路径中的文件非常麻烦:

# ...when ignoring all files and folders in the current root
*


!custom_path                       # allow Git to look inside this folder
custom_path/*                      # but ignore everything it contains
!custom_path/extras                # allow Git to look inside this folder
custom_path/extras/*               # but ignore everything it contains
!custom_path/extras/path_to_keep   # allow Git to see the file or folder you want to commit

因此,为了提供另一种想法,我刚刚在我的Windows用户配置文件文件夹的根目录下配置了一个.gitignore文件,以**/*开始,而不是常见的**.*

此后,我想显式包含的每个路径只需要一个条目每棵树将前面的例子简化如下:

# ...when ignoring all files recursively from the current root
**/*


!custom_path                       # allow Git to look inside this folder
!custom_path/extras                # allow Git to look inside this folder
!custom_path/extras/path_to_keep   # allow Git to see the file or folder you want to commit

这并不完全是巨大的的区别,但它足以使文件更容易阅读和维护,特别是在试图“取消忽略”时。一个嵌套了5层的文件…