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

我知道.gitignore文件隐藏了Git版本控制中的指定文件。

我如何告诉.gitignore忽略除我使用Git跟踪的文件之外的所有内容?类似:

# Ignore everything:*
# Do not ignore these files:script.pltemplate.latex
765367 次浏览
# ignore these*# except foo!foo

一个可选的前缀!,它否定了模式;任何匹配的文件都被排除在外先前的模式将再次包含。如果否定的模式匹配,这将覆盖较低优先级模式源。

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

您可以使用git config status.showUntrackedFiles no,所有未跟踪的文件都将对您隐藏。有关详细信息,请参阅man git-config

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

例如,忽略文件夹“应用程序”中的所有内容,除了index.php和文件夹“config”注意秩序

你必须先否定你想要的。

失败

application/*

!application/config/*

!application/index.php

工作

!application/config/*

!application/index.php

application/*

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

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

请注意,如果你只是在上面写了:

pippo/*!pippo/pluto/paperino.xml

它不起作用,因为中间的pluto文件夹对Git来说不存在,所以paperino.xml找不到存在的地方。

再具体一点:

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

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

失败

webroot/cache*!webroot/cache/.htaccess

工作

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

我有JQuery和Angular从bhouse。鲍尔安装了它们

/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目录中。我只需要将最小化的文件提交到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

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

在大多数情况下,您希望使用/*而不是**/

使用*是有效的,但它是递归工作的。从那时起它不会查看目录。人们建议使用!*/再次包含目录,但实际上最好用/*封锁最高级别的文件夹

# Blocklist files/folders in same directory as the .gitignore file/*
# Includelist some files!.gitignore!README.md
# Ignore all files named .DS_Store or ending with .log**/.DS_Store**.log
# Includelist 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

关于这个问题有很多类似的问题,所以我将发布我之前写的内容:

我让它在我的机器上工作的唯一方法是这样做:

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

这些对我也不管用。很多线索和错误!

这就是我的工作,我想只提交一个科尔多瓦插件到存储库:

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

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

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

这将忽略bower_components中除/highcharts之外的所有文件/子文件夹。

到目前为止,没有什么对我有用,因为我试图从lib中添加一个罐子。

这并没有奏效:

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

这奏效了:

build/*!build/libs

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

/*!.gitignore!showMe.txt!my_visible_dir

神奇的是在/*(如上所述)它忽略(root)文件夹中的所有内容,但不是递归的。

我有一个问题与子文件夹。

不工作:

/custom/*!/custom/config/foo.yml.dist

作品:

/custom/config/*!/custom/config/foo.yml.dist

我在否定单个文件方面也遇到了一些问题。我能够提交它们,但我的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来说是两个不同的东西。

很棒的帖子!这个问题困扰了我一段时间;)

我把这个修好了

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

我尝试了上面给出的所有答案,但没有一个对我有效。阅读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' subfolderPro/3rdparty/domain/*!Pro/3rdparty/domain/modulename/

因此,我在我的git客户端中看到,只有Pro/3rdpart/domename/文件夹中的两个文件正在进行下一次提交,这正是我所寻找的。

如果您需要将同一文件夹的多个子文件夹列入白名单,请将排除语句下方的感叹号行分组,如下所示:

# 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' subfolderPro/3rdparty/domain/*!Pro/3rdparty/domain/modulename/
# Ignore the 'hosting' folder, except for the 'modulename' subfolderPro/3rdparty/hosting/*!Pro/3rdparty/hosting/modulename/

否则它不会像预期的那样工作。

让我们toolify!

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

# Ignore everything*
# But not these files...!.gitignore!someFile.txt

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

例如,如果我们想跳过所有文件,但不是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

这很难用手写。

为了解决这个障碍,我创建了一个名为注意事项git不要忽略规则的Web应用程序,它将为您生成规则。

工具

Demo

样本输入

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

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

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

我是这样做的:

# 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 folderwordpress/wp-content/themes/my-theme/node_modules
# Ignore this file recursively**/.DS_Store

使用gig status -u递归查看未跟踪目录中的单个文件-使用git status,您只能看到文件夹,这可能会欺骗您认为其中的所有内容都被跟踪

要点

# 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

与OP类似,但前10名投票的答案都没有奏效
终于发现了

语法错误:

*!bin/script.sh

正确语法:

*!bin!bin/script.sh

来自gitignore手册页的解释

一个可选的前缀“!”否定模式;任何被先前模式排除的匹配文件都将再次包含在内。如果排除了该文件的父目录,则无法重新包含该文件。出于性能原因,Git没有列出排除的目录,因此包含文件上的任何模式都没有影响,无论它们在哪里定义。

这意味着上面的“错误语法”是错误的,因为bin/script.sh不能被重新包含,因为bin/被忽略了。仅此而已。

扩展示例:

$树。

.├── .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状态--未跟踪的文件--忽略

On branch master
No commits yet
Untracked files:(use "git add <file>..." to include in what will be committed).gitignorebin/sub/folder/path/script.sh
Ignored files:(use "git add -f <file>..." to include in what will be committed)bin/ignore.txtbin/sub/folder/path/other.sh
nothing added to commit but untracked files present (use "git add" to track)

我最简单的方法是强制添加一个文件。即使它被埋在或嵌套在git忽略的子目录树中,它也会在git中占主导地位。

例如:

x64文件夹在. gitignore中被排除在外:

x64/

但是您想包含位于x64/Release/目录中的文件myFile.py。然后你必须:

git add -f x64/Release/myFile.py

您可以对匹配模式的多个文件执行此操作,例如。

git add -f x64/Release/myFile*.py

诸如此类。

这就是我保持文件夹结构而忽略其他所有内容的方式。您必须在每个目录(或. git保持)中拥有一个README.md文件。

/data/*!/data/README.md
!/data/input//data/input/*!/data/input/README.md
!/data/output//data/output/*!/data/output/README.md

这里有很多复杂的答案…这里有一些我在上面看不到的非常简单的东西,在许多情况下都能很好地工作:

# ignore all files that have an extension**/*.*
# except for these extensions!**/*.extension1!**/*.extension2

这不会忽略任何无扩展名文件,但如果您有一堆具有相同或相似名称的文件,您可以为这些文件添加排除项

**/EXTENSIONLESSFILETOIGNORE

在使用git 16年(2005年)之后,当排除一个文件位于目录层次结构的深处时,没有简单明了的方法来处理它,这是一场灾难,否则应该被忽略。相反,我们需要诉诸疯狂的事情,比如反复挖掘结构,以正确的顺序排除和包含目录。一年中不可能记住这4次你需要做的事情。

唯一聪明但非常奇怪的替代方案是使用git add --force。当您不单独处理被删除的存储库时,某些东西在某些时候肯定会失败。

所以我写了一个小bash函数来修复这个问题,以便轻松复制粘贴。让我先解释一下一个衬线:

f=0; y='';for x in $(echo "uploads/rubbish/stuff/KEEP_ME/a.py" | tr '\/' '\n'); do y="$y/$x"; if [ $(($f)) -eq 0 ]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo;
# output:!uploads/uploads/*!uploads/rubbish/uploads/rubbish/*!uploads/rubbish/stuff/uploads/rubbish/stuff/*!uploads/rubbish/stuff/KEEP_ME/uploads/rubbish/stuff/KEEP_ME/*!uploads/rubbish/stuff/KEEP_ME/a.py

特性介绍

  • 有一个if语句来调整第一项没有得到/
  • tr '\/' '\n'-将标准POSIX路径中的/转换为\n(以获取列表)
  • y="$y/$x"-在前一个目录之后添加下一个副标题(在列表中)。
  • echo -e '!'"$y/\n$y/*"-
    打印2行子目录项,第一行使用!前缀,第二行使用/*后缀
  • sed '$d'-删除最后一行
  • sed -z 's/..$//'-删除最后一行中的最后2个字符/*

然后我们创建函数:

function gitkeep () { f=0; y='';for x in $(echo "$1" | tr '\/' '\n'); do y="$y/$x"; if [[ f -eq 0 ]]; then y="$x"; f=1; fi; echo -e '!'"$y/\n$y/*"; done | sed '$d' |sed -z 's/..$//'; echo; }
# gitkeep "uploads/rubbish/stuff/KEEP_ME/a"
!uploads/uploads/*!uploads/rubbish/uploads/rubbish/*!uploads/rubbish/stuff/uploads/rubbish/stuff/*!uploads/rubbish/stuff/KEEP_ME/uploads/rubbish/stuff/KEEP_ME/*!uploads/rubbish/stuff/KEEP_ME/a

在这里,我将算术#0语句简化为if [[ f -eq 0 ]];

好好享受!

不确定是否已经指出了这一点,但我无法使用我希望gitignore忽略的文件夹前面的!忽略被忽略文件夹中的子文件夹。

但是,我发现被忽略的文件夹在其路径中没有*。我的. gitignore如下所示:

/folder/!/folder/subfolder

子文件夹仍被忽略,但在文件夹后添加*使其工作方式如下

/folder/*!/folder/subfolder