2217

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

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

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

# Ignore everything
*

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

27 回答 27

3057

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

# 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/*
于 2009-06-12T15:07:38.680 回答
837

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

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

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

pippo/*
!pippo/pluto/paperino.xml

它不起作用,因为plutoGit 不存在中间文件夹,因此paperino.xml找不到存在的地方。

于 2013-05-01T12:31:26.253 回答
310

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

使用*是有效的,但它以递归方式工作。从那时起,它不会查看目录。人们建议!*/再次使用将目录列入白名单,但实际上最好将最高级别的文件夹列入黑名单/*

# 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

上面的代码将忽略除.gitignore, README.md,folder/a/file.txt和最后两个文件夹中包含的所有文件之外folder/a/b1/的所有文件。folder/a/b2/(并且.DS_Store这些*.log文件夹中的文件将被忽略。)

显然我可以做例如!/folder!/.gitignore太。

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

于 2015-04-29T00:31:53.600 回答
89

更具体一点:

示例:忽略webroot/cache- 但保留webroot/cache/.htaccess.

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

失败

webroot/cache*
!webroot/cache/.htaccess

作品

webroot/cache/*
!webroot/cache/.htaccess
于 2013-08-13T13:23:16.840 回答
69
# ignore these
*
# except foo
!foo
于 2009-06-12T15:06:18.857 回答
36

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

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

你必须首先否定你想要的。

失败

application/*

!application/config/*

!application/index.php

作品

!application/config/*

!application/index.php

application/*

于 2012-08-09T08:39:07.397 回答
34

Let's toolify!

As @Joakim said, to ignore a file, you can use something like below.

# Ignore everything
*

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

but if the file is in nested directories, it's a little difficult to write those rules.

For example, if we want to skip all files but not a.txt, located in aDir/anotherDir/someOtherDir/aDir/bDir/cDir. Then, our .gitignore will be something like this

# 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

This is quite hard to write by hand.

To solve this hurdle, I've created a web app named git-do-not-ignore which will generate the rules for you.

Tool

Demo

Sample Input

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

Sample Output

!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
于 2019-02-25T15:58:09.357 回答
30

有与 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

$ 猫 .gitignore

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

$ git status --untracked-files --ignored

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)
于 2020-05-02T07:54:27.180 回答
23

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

/data/*
!/data/README.md

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

!/data/output/
/data/output/*
!/data/output/README.md
于 2021-01-29T23:17:07.840 回答
22

您可以使用git config status.showUntrackedFiles no并且所有未跟踪的文件都将对您隐藏。详情请参阅man git-config

于 2009-06-12T15:20:38.073 回答
19

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

!app/

app/*
!app/bower_components/

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

这将忽略bower_components/highcharts.

于 2016-11-10T14:21:51.590 回答
16

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

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

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

这些都不适合我。很多线索和错误!

于 2015-04-29T23:40:05.403 回答
12

我是这样做的:

# 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您只会看到文件夹,这可能会让您误以为其中的所有内容都已被跟踪

于 2019-06-12T22:39:37.400 回答
11

我的子文件夹有问题。

不工作:

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

作品:

/custom/config/*
!/custom/config/foo.yml.dist
于 2018-06-06T06:43:02.463 回答
10

我尝试了上面给出的所有答案,但没有一个对我有用。阅读 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/

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

于 2018-09-12T12:55:53.677 回答
9

That's what have worked for me, I wanted to commit only one Cordova plugin to the repo:

...
plugins/*
!plugins/cordova-plugin-app-customization
于 2016-04-30T18:58:21.687 回答
8

我有来自凉亭的 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

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

于 2015-01-27T20:57:04.933 回答
7

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

/*
!.gitignore
!showMe.txt
!my_visible_dir

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

于 2018-05-31T11:24:07.450 回答
7

我解决这个问题的最简单方法是强制添加文件。即使它被掩埋或嵌套在 git 忽略的子目录树中,它也会在 git 中进行说明。

例如:

x64 文件夹不包含在 .gitignore 中:

x64/

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

git add -f x64/Release/myFile.py

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

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

等等。

于 2020-11-16T00:56:30.893 回答
7

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

# ignore all files that have an extension
**/*.*

# except for these extensions
!**/*.extension1
!**/*.extension2

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

**/EXTENSIONLESSFILETOIGNORE
于 2021-11-05T11:58:54.213 回答
5

我得到了这个工作

# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib
于 2018-09-10T06:39:31.247 回答
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 来说是两个不同的东西。

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

于 2018-07-12T15:51:47.133 回答
4

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

这没有用:

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

这有效:

build/*
!build/libs
于 2018-05-15T16:17:33.483 回答
3

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

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

于 2019-06-08T09:30:50.433 回答
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
于 2020-01-13T21:42:22.107 回答
0

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

唯一聪明但非常奇怪的选择是使用git add --force. 当您不单独处理 gitted repo 时,某些时候肯定会失败。

所以我写了一个小 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 行子目录项,第一行带有! prefix,第二行带有/* postfix
  • 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

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

享受!

于 2022-02-05T16:41:19.580 回答
-1

我知道这是一篇旧帖子,但我现在正面临同样的“问题”,我刚刚在官方 Git Google Group 上发布了一个建议,以实现类似 .gitaccept 文件的内容:对话

我们使用的 .gitignore 与@Joakim Elofsson 发布的内容和@Mohit 非常相似。

于 2022-02-28T16:26:08.367 回答