使.gitignore忽略除少数文件以外的所有内容


1696

我知道.gitignore文件会掩盖Git版本控制中的指定文件。我有一个项目(LaTeX),它在运行时会生成许多其他文件(.auth,.dvi,.pdf,日志等),但我不希望这些文件被跟踪。

我知道我可以(也许应该这样做)将所有这些文件放在项目的单独子文件夹中,因为这样我就可以忽略该文件夹了。

但是,是否有任何可行的方法将输出文件保留在项目树的根目录中,并使用.gitignore忽略除我正在使用Git跟踪的文件以外的所有内容?就像是

# Ignore everything
*

# But not these files...
script.pl
template.latex
# etc...

12
stackoverflow.com/q/9162919/321973重复(我知道这是较新的,但是答案更正确)。其实这个答案可能是最好的
托比亚斯Kienzler

Answers:


2435

!否定模式的可选前缀;先前模式排除的所有匹配文件将再次包含在内。如果否定的模式匹配,它将覆盖优先级较低的模式源。

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# ...even if they are in subdirectories
!*/

# if the files to be tracked are in subdirectories
!*/a/b/file1.txt
!*/a/b/c/*

14
看起来这也是“忽略”子文件夹,因此无论如何都找不到根目录以外的任何名为“ script.pl”的文件。我现在正在使用此文件(带有* .pl),尽管.gitignore文件下面的子目录中有很多子目录,所有* .pl文件都将被忽略
PandaWood

38
@PandaWood该问题在这里(stackoverflow.com)提出。它是由第一个匹配所有内容(包括目录)的表达式引起的,您永远不会对其求反。要解决此问题,请添加(!* /),它与当前目录中的所有子目录匹配(递归)。这对将特定文件列入白名单的父答案无济于事(如果它们在子目录中,则可能需要手动指定完整路径,或使用目录特定的.gitignore文件)。
simont

40
我无法使它正常工作。我忽略了一个文件夹(例如wp/),但是我不想忽略该文件夹中一些文件(例如wp/path/to/some/location/*)。我可以使它正常工作的唯一方法是执行git add -f wp/path/to/some/location/*
trusktr 2012年

13
@trusktr使用simont !*/例外
Tobias Kienzler 2012年

7
哎呀,最后一条规则:!*/使我徒劳地纠缠.gitignore文件以工作的所有尝试都与众不同。非常感谢你。
racl101 2015年

627

如果要忽略目录中除其中一个文件之外的全部内容,可以为文件路径中的每个目录编写一对规则。例如.gitignore忽略pippo文件夹,除了pippo / pluto / paperino.xml

.gitignore

pippo/*
!pippo/pluto
pippo/pluto/*
!pippo/pluto/paperino.xml

58
优秀的答案,但值得一提的任何人碰到这个未来晚些时候foofoo/*一样的。为此,您需要使用foo/*基本文件夹
thislooksfun

20
@Mayank Pippo在意大利语中是Goofy,而Paperino是Donald Duck,Pluto与英语相同。在过去,它们曾经是变量名的非常常见的三元组,用于对样本进行编程。很高兴再次阅读它们.. :)
Ghidello

如果您要“排除文件x以外的文件夹”,@ thislooksfun所说的内容很重要。
捷克学,

8
不适用于我:node_modules / *!node_modules / bootstrap
SuperUberDuper

1
@simple_human如果他忽略存储库根目录中的所有内容,或者如果他在提到的目录中有.gitignore文件需要关心,那将是正确的。
xZero

244

您想使用/*而不是**/在大多数情况下

使用*是有效的,但是它是递归的。从此以后,它就不再查找目录。人们建议!*/再次使用将目录列入白名单,但是最好将最高级别的文件夹列入黑名单/*

# Blacklist files/folders in same directory as the .gitignore file
/*

# Whitelist some files
!.gitignore
!README.md

# Ignore all files named .DS_Store or ending with .log
**/.DS_Store
**.log

# Whitelist folder/a/b1/ and folder/a/b2/
# trailing "/" is optional for folders, may match file though.
# "/" is NOT optional when followed by a *
!folder/
folder/*
!folder/a/
folder/a/*
!folder/a/b1/
!folder/a/b2/
!folder/a/file.txt

# Adding to the above, this also works...
!/folder/a/deeply
/folder/a/deeply/*
!/folder/a/deeply/nested
/folder/a/deeply/nested/*
!/folder/a/deeply/nested/subfolder

上面的代码会忽略所有的文件,除了.gitignoreREADME.mdfolder/a/file.txtfolder/a/b1/folder/a/b2/和包含在那些过去的两个文件夹的一切。(并且.DS_Store*.log文件将在那些文件夹中被忽略。)

很显然,我可以做如!/folder!/.gitignore过。

更多信息:http//git-scm.com/docs/gitignore


3
非常聪明,谢谢。IMO,对于包含最少规则的WordPress网站,这是最好的解决方法。另外,未经您的明确许可,不会删除或添加任何新的插件,主题或WP更新。当使用GitHub Desktop时,我发现.DS_Store文件不会被忽略,但是通过命令行这不是问题。为了解决这个问题,我必须**/.DS_Store遵循以下所有其他规则。
Jibran

7
我的内部语法荧光笔对您的帖子标题产生了奇怪的反应。
itsadok

3
格拉西亚斯!您也可以将文件夹中的文件列入白名单。./some/folder/file.txt
PodTech.io 2015年

太棒了,使用/ *代替*可以解决以上所有问题时我的所有问题。我现在唯一的问题是!/ folder和!/ folder / *有什么区别?如果使用不带*的!/ folder,据我所知,它仍然会拾取文件夹中所有文件的更改。
dallin '18

1
@dallin没有区别。一个将白名单添加到一个文件夹,另一个将白名单添加到该文件夹​​的子文件夹,这将执行相同的操作。唯一的问题是一个文件夹或文件的父或母,有白名单,可以列入白名单之前,所以你不能这样做/*,然后!/nested/folder/*(或同等!/nested/folder)没有做!/nested/!/nested第一!(可能/nested/*介于两者之间)。要记住的一个技巧是,如果您要将一个嵌套深度较大的子文件夹列入白名单,则需要将每个子文件夹中的子代全部加黑,并且这些黑名单将以“斜杠星号”结尾...
Ryan Taylor

75

更具体一点:

示例:忽略所有内容,webroot/cache但保留webroot/cache/.htaccess

注意cache文件夹后的斜杠(/):

失败

webroot/cache*
!webroot/cache/.htaccess

作品

webroot/cache/*
!webroot/cache/.htaccess

如果您使用的是VS Code,请注意将其应用于.gitkeep文件夹后不要误读文件颜色,因为文件夹名称将变为绿色,但.gitkeep文件将变为灰色,就像所有其他忽略的文件一样;.gitkeep看起来像被忽略了,但您应该看到右侧有一个“ U”,表明已检测到它
OzzyTheGiant


28

要忽略目录中的某些文件,必须以正确的顺序执行此操作:

例如,忽略文件夹“ application”中的所有内容,除了index.php和文件夹“ config”之外,请注意顺序

您必须否定要先想要的东西。

失败

application/*

!application/config/*

!application/index.php

作品

!application/config/*

!application/index.php

application/*


38
错误。您否定了“忽略一切”的要求。
卡洛斯

2
不要上当git status检查您的更改是否.gitignore按预期工作
PhilippeRathé13年

10
如果git status不是要告诉您它在看什么而忽略了什么,那么您如何知道它是否有效?
克里斯,

1
@kris首先清除git缓存。首先执行“ git rm --cached *”,然后执行“ git add --all”,然后执行“ git status”,将显示所有新的gitignore更改。
Mark McCorkle


16

要从.gitignore中排除文件夹,可以执行以下操作。

!app/

app/*
!app/bower_components/

app/bower_components/*
!app/bower_components/highcharts/

这会忽略的所有文件/子文件夹bower_components除外/highcharts


14

关于此还有很多类似的问题,因此我将发布我之前写的内容:

我在计算机上使用此方法的唯一方法是这样做:

# Ignore all directories, and all sub-directories, and it's contents:
*/*

#Now ignore all files in the current directory 
#(This fails to ignore files without a ".", for example 
#'file.txt' works, but 
#'file' doesn't):
*.*

#Only Include these specific directories and subdirectories and files if you wish:
!wordpress/somefile.jpg
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*

请注意,您必须显式允许要包含的每个级别的内容。因此,如果我在主题下有5个子目录,则仍然需要清楚地说明。

这是来自@Yarin在这里的评论:https : //stackoverflow.com/a/5250314/1696153

这些是有用的主题:

我也试过

*
*/*
**/**

**/wp-content/themes/**

要么 /wp-content/themes/**/*

这些都不对我有用。很多的跟踪和错误!


2
这是唯一包含某些文件扩展名的唯一方法。更好的是,它造就了出色的ASCII艺术:gist.github.com/Wolfgange3311999/91c671f5e4d3c56cf5a1
Matthew D. Scholefield


9

我尝试了上面给出的所有答案,但没有一个对我有用。阅读gitignore文档(在此处)后,我发现,如果您首先排除文件夹,则不会索引子文件夹中的文件名。因此,如果以后使用感叹号包含文件,则该文件不会在索引中找到,因此不会包含在您的git客户端中。

那就是找到解决方案的方法。我首先为文件夹树中的所有子文件夹添加了例外,以使其正常运行,这真是一件难事。之后,我能够将详细的配置压缩为以下配置,这与本文档有些矛盾。

工作.gitignore:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' subfolder
/Pro/3rdparty/*
!Pro/3rdparty/domain/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

结果,我在git客户端中看到,只有Pro / 3rdparty / domain / modulename /文件夹中的两个文件正在准备下一次提交,而这正是我在寻找的东西。

而且,如果您需要将同一文件夹的几个子文件夹列入白名单,则可以将感叹号标记行分组到exclude语句下,如下所示:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' & 'hosting' subfolders
/Pro/3rdparty/*
!Pro/3rdparty/domain/
!Pro/3rdparty/hosting/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

# Ignore the 'hosting' folder, except for the 'modulename' subfolder
Pro/3rdparty/hosting/*
!Pro/3rdparty/hosting/modulename/

否则它将无法按预期工作。


最后一个有效的答案。我想知道我何时才能了解.gitignore的实际工作原理
大卫

8

那就是对我有用的东西,我只想向回购提交一个Cordova插件:

...
plugins/*
!plugins/cordova-plugin-app-customization

8

我知道我参加晚会很晚,但这是我的答案。

正如@Joakim所说,要忽略文件,您可以使用以下内容。

# Ignore everything
*

# But not these files...
!.gitignore
!someFile.txt

但是,如果文件位于嵌套目录中,则手动编写规则会有点困难。

例如,如果我们要跳过git项目中的所有文件,而不是a.txt中的文件aDir/anotherDir/someOtherDir/aDir/bDir/cDir。然后,我们.gitignore将像这样

# Skip all files
*

# But not `aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt`
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

上面给定的.gitignore文件将跳过除目录之外的所有目录和文件!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

您可能已经注意到,很难定义这些规则。

为了解决这个问题,我创建了一个名为git-do-not-ignore的简单控制台应用程序,它将为您生成规则。我已经将项目的详细说明托管在github中

使用范例

java -jar git-do-not-ignore.jar "aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt"

输出量

!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

还有提供一个简单的Web版本在这里

谢谢。


7

我有来自凉亭的Jquery和Angular。Bower将它们安装在

/public_html/bower_components/jquery/dist/bunch-of-jquery-files
/public_html/bower_components/jquery/src/bunch-of-jquery-source-files
/public_html/bower_components/angular/angular-files

最小化的jquery在dist目录内部,angular在angular目录内部。我只需要将最小化的文件提交到github。一些篡改.gitignore,这是我设法想到的...

/public_html/bower_components/jquery/*
!public_html/bower_components/jquery/dist
/public_html/bower_components/jquery/dist/*
!public_html/bower_components/jquery/dist/jquery.min.js
/public_html/bower_components/angular/*
!public_html/bower_components/angular/angular.min.js

希望有人能发现这个有用。


7

这是我的方法:

# Ignore everything
*

# Whitelist anything that's a directory
!*/

# Whitelist some files
!.gitignore

# Whitelist this folder and everything inside of it
!wordpress/wp-content/themes/my-theme/**

# Ignore this folder inside that folder
wordpress/wp-content/themes/my-theme/node_modules

# Ignore this file recursively
**/.DS_Store

用于gig status -u递归地查看未跟踪目录中的单个文件- git status仅查看文件夹,这可能使您误以为它们中的所有内容都已被跟踪


5

如果您需要忽略除少数文件和少数文件夹以外的所有内容,则为简单的解决方案:

/*
!.gitignore
!showMe.txt
!my_visible_dir

魔术已经存在/*(如上所述),它会(而不是递归)忽略(根)文件夹中的所有内容。


4

我对单个文件的否定也遇到了一些问题。我能够提交它们,但是我的IDE(IntelliJ)总是抱怨被跟踪的忽略文件。

git ls-files -i --exclude-from .gitignore

显示了两个文件,我已经用这种方法排除了它们:

public/
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

最后,这对我有用:

public/*
!public/typo3conf/
public/typo3conf/*
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

关键是首先要否定文件夹 typo3conf/

同样,语句的顺序似乎无关紧要。相反,您需要显式地否定所有子文件夹,然后才能否定其中的单个文件。

文件夹!public/typo3conf/和文件夹内容public/typo3conf/*是.gitignore的两件事。

好线程!这个问题困扰了我一段时间;)


3

到目前为止,对我没有任何帮助,因为我试图从lib中添加一个jar。

这没有用:

build/*
!build/libs/*
!build/libs/
!build/libs/myjarfile.jar 

这工作:

build/*
!build/libs

3

我得到了这个工作

# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib

2

与OP有类似的问题,但前10名投票的答案均未奏效
我终于发现了以下内容

语法错误:

*
!bin/script.sh

正确的语法:

*
!bin
!bin/script.sh

来自gitignore手册页的解释:

可选的前缀“!” 否定了模式;先前模式排除的所有匹配文件将再次包含在内。如果排除了该文件的父目录,则无法重新包含该文件。由于性能原因,Git不会列出排除的目录,因此包含在文件上的任何模式无论在何处定义都无效。

扩展示例:

$树。

.
├── .gitignore
└── bin
    ├── ignore.txt
    └── sub
        └── folder
            └── path
                ├── other.sh
                └── script.sh

$ cat .gitignore

*
!.gitignore
!bin
!bin/sub
!bin/sub/folder
!bin/sub/folder/path
!bin/sub/folder/path/script.sh

$ git status-未跟踪文件-已忽略

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        bin/sub/folder/path/script.sh

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        bin/ignore.txt
        bin/sub/folder/path/other.sh

nothing added to commit but untracked files present (use "git add" to track)

1

要旨

# Ignore everything
*

# But not these files...
!script.pl
!template.latex

可能包括:

!.gitignore

参考

https://git-scm.com/docs/gitignore

可选前缀“ !”,用于否定模式;先前模式排除的所有匹配文件将再次包含在内。如果排除该文件的父目录,则无法重新包含该文件。由于性能原因,Git不会列出排除的目录,因此包含在文件上的任何模式无论在何处定义都无效。对于以文字“ ” 开头的模式(例如“ \”),请在第一个“ !” 前面加上反斜杠(“ ”)。!\!important!.txt

...

排除特定目录以外的所有内容的示例foo/bar(请注意/*-,不带斜杠,通配符还将排除内的所有内容foo/bar):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar

0

我似乎找到了对我有用的东西,没有其他人提到过。

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# And if you want to include a sub-directory and all sub-directory and files under it, but not all sub-directories
!subdir/
!subdir/**/*

基本上,这似乎使否定一个子目录无效,您必须有两个条目,一个用于子目录本身!subdir/,另一个用于扩展到其下的所有文件和文件夹。!subdir/**/*

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.