如何在Git中忽略目录中的文件?

573

如何正确地在.gitignore文件中忽略一个目录中的文件?

应该这样写:

config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*
或者
/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*


5
.gitignore 是否区分忽略文件和目录?例如,datadata/ 是不是有不同的含义? - Charlie Parker
9
@CharlieParker 的意思是:data 会忽略匹配的文件和目录,而 data/ 只会忽略匹配的目录。 - jox
永远记住,如果你已经暂存或提交了你想要忽略的文件,那么就没有办法忽略它 :( 这是我的两分钱建议,因为我曾经认为我的模式有误,并浪费了四分之一小时。 - Adam
@Adam 正确,您需要更新 .gitignore 文件,然后取消暂存 / git rm --cached 文件。 - Chris McKnight
10个回答

399

模式格式

  • 一个空行不匹配任何文件,因此它可以作为可读性的分隔符。

  • #开头的行作为注释。

  • 一个可选前缀! 反转模式;任何由先前模式排除的匹配文件将再次包含。如果反向模式匹配,则将覆盖低优先级模式源。

  • 如果模式以斜杠结尾,则将其删除以便于以下描述,但它只会与目录匹配。换句话说,foo/将匹配目录foo及其下面的路径,但不会匹配常规文件或符号链接foo(这与git中pathspec通常工作方式一致)。

  • 如果模式不包含斜杠/,则git将其视为shell glob模式,并针对相对于.gitignore文件的路径名检查匹配项(如果不是来自.gitignore文件,则相对于工作树顶层)。

  • 否则,git将该模式视为适合用fnmatch(3)消费的shell glob:模式中的通配符不会与路径名中的/相匹配。例如,Documentation/*.html匹配Documentation/git.html但不匹配Documentation/ppc/ppc.htmltools/perf/Documentation/perf.html

  • 前导斜杠匹配路径名开头。例如,/*.c匹配cat-file.c但不匹配mozilla-sha1/sha1.c

更多信息请参见

git help gitignore

man gitignore


2
我该如何将.gitignore文件放置在顶层,并使其适用于其下的任何文件夹?谢谢。 - Royi
119
这段话的意思是,原来的回答没有回答问题,只是简单概述了一下,而且关于目录而不是文件,所以加粗的部分只有通过某些心理活动才能与问题关联起来。@Jefromi的回答更为直接。 - Bob Stein
我已经阅读了@Jefromi的答案,它更好 - 只要您也阅读了@jox的警告 - 而@Luke Hutton的答案可能更有用,例如忽略IDE项目文件。 - WillC
这非常有帮助!但是你所说的“glob”是什么意思? - retrovius
2
这实际上是从Git文档中复制粘贴的。 - mcont
1
不确定(本质上)复制粘贴“man”页面或官方文档是否是适合在SO上的最佳格式... - SO_fix_the_vote_sorting_bug

188

应该选择前者。除了文件夹结构之外,也要根据扩展名来进行筛选。

例如,我的 C# 开发忽略文件示例:

#OS junk files
[Tt]humbs.db
*.DS_Store

#Visual Studio files
*.[Oo]bj
*.user
*.aps
*.pch
*.vspscc
*.vssscc
*_i.c
*_p.c
*.ncb
*.suo
*.tlb
*.tlh
*.bak
*.[Cc]ache
*.ilk
*.log
*.lib
*.sbr
*.sdf
ipch/
obj/
[Bb]in
[Dd]ebug*/
[Rr]elease*/
Ankh.NoLoad

#Tooling
_ReSharper*/
*.resharper
[Tt]est[Rr]esult*

#Project files
[Bb]uild/

#Subversion files
.svn

# Office Temp Files
~$*

更新

我想从下面的评论中提供一个更新。虽然不能直接回答提问者的问题,但是可以参考以下更多有关 .gitignore 语法的示例。

社区维基(不断更新):

.gitignore for Visual Studio Projects and Solutions

这里可以找到更多使用特定语言的示例(感谢Chris McKnight的评论):

https://github.com/github/gitignore


5
@Stallman,“range”就是这个意思。因此,它将匹配“*.Obj”和“*.obj”。 - Sam R.

151

如果路径中包含斜杠,则认为它们相对于包含.gitignore文件的目录 - 通常是存储库的顶部,但您也可以将其放置在子目录中。

因此,在您提供的所有示例中,路径都包含斜杠,因此这两个版本是相同的。唯一需要添加前导斜杠的时间是当路径中没有斜杠时。例如,要仅在存储库的顶级忽略foo,请使用/foo。仅编写foo会忽略存储库中任何名称为foo的内容。

您的通配符也是多余的。如果要忽略整个目录,请直接命名它:

lib/model/om
你只有打算随后取消忽略目录中的某些内容,才需要像你这样使用通配符:
lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo

9
这个问题需要比被接受的答案更好的解释。 - eerrzz

79

一个前导斜杠表示该忽略条目仅适用于.gitignore文件所在的目录。指定*.o将忽略此目录和所有子目录中的所有 .o 文件,而 /*.o 仅会在该目录中忽略它们,同样地 ,/foo/*.o 仅在/foo/*.o中忽略它们。


36

如果您想在顶层放置一个 .gitignore 文件并使其适用于下面的任何文件夹,请使用 /**/

例如,如果要忽略 /src/main/ 文件夹及其子文件夹中的所有 *.map 文件,请使用以下内容:

/src/main/**/*.map

我需要做这件事,不确定您为什么需要 两个 **。一个对我来说已经足够了。 - Novocaine
8
匹配也包括子目录中的文件。 - petrsyn
感谢@petrsyn的信息。 - Novocaine

33

问题中的两个示例都非常糟糕,可能导致数据丢失!

我的建议是:除非你有充分的理由,否则不要在.gitignore文件中将/*附加到目录中!

一个充分的理由可以是像Jefromi所写的那样:"如果您打算随后取消忽略目录中的某些内容"

否则不应该这样做的原因是,将/*附加到目录会在一方面正确地忽略目录中的所有内容,但另一方面会产生危险的副作用:

如果您在存储库中执行git stash -u(暂时stash已跟踪和未跟踪文件)或git clean -df(删除未跟踪但保留已忽略的文件),所有使用附加的/* 忽略的目录将被不可逆转地删除

背景知识

我必须通过艰苦的方式学习这一点。我们团队中的某些人正在向我们的.gitignore文件中的某些目录附加/*。随着时间的推移,我遇到了某些目录突然消失的情况。那是我们应用程序需要的本地数据的几千兆字节的目录。没有人能够解释这个问题,我总是不得不重新下载所有数据。过了一段时间,我有了一个想法,它可能与git stash有关。有一天我想清理我的本地repo(同时保留ignored文件),我使用git clean -df,我的数据再次丢失了。这次我受够了,调查了这个问题。最后我发现原因是附加的/*

我认为可以通过以下事实来解释:即directory/*确实忽略目录中的所有内容,但不包括目录本身。因此,在删除东西时,它既不被视为已跟踪,也不被视为已忽略。尽管git statusgit status--ignored在这个问题上有稍微不同的看法。

如何复制

以下是如何复制这种行为。我目前正在使用Git 2.8.4。

在本地git存储库中创建一个名为localdata/的目录,并在其中放置一个虚拟文件(important.dat),然后将其内容添加到.gitignore文件中,使其被忽略(/localdata/*)。当执行上述两个命令中的任意一个时,该目录将会意外地丢失。

mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file

如果你在这里运行git status --ignored,你会得到以下结果:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

  untracked-file

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

  localdata/

现在,可以执行以下操作:

git stash -u
git stash pop
或者
git clean -df

在两种情况下,据称被忽略的目录localdata都会消失!

我不确定这是否可以视为一个错误,但我想至少这是一个没有人需要的功能。

我将向git开发列表报告并看看他们对此的看法。


16

它会是:

config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om

或者甚至可能:

config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om

如果filterform是lib目录中唯一有需要忽略的base子目录的文件夹(将其视为使用通配符可以做什么的示例)。


15

第一点。这些文件路径是相对于您的 .gitignore 文件所在的位置。


2
这仅适用于包含斜杠的模式。像“mydir”这样的单个目录名称也将忽略位于任何深度的子文件夹中的目录(和文件)。只有在前面加上斜杠才会使它相对于您的.gitignore文件所在的位置。 - jox

4

我在维护一个基于GUI和CLI的服务,可以让您非常容易地生成.gitignore模板,网址是https://www.gitignore.io

您可以在搜索框中输入所需的模板,或安装命令行别名并运行

$ gi swift,osx


1

一个示例.gitignore文件可能如下所示,适用于Android Studio项目

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties


#Eclipse
*.pydevproject
.project
.metadata
bin/**
tmp/**
tmp/**/*
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
YourProjetcName/.gradle/
YourProjetcName/app/build/
*/YourProjetcName/.gradle/
*/YourProjetcName/app/build/

# External tool builders
.externalToolBuilders/

# Locally stored "Eclipse launch configurations"
*.launch

# CDT-specific
.cproject

# PDT-specific
.buildpath

# Proguard folder generated by Eclipse
proguard/

# Intellij project files
*.iml
*.ipr
*.iws
.idea/
/build
build/
*/build/
*/*/build/
*/*/*/build/
*.bin
*.lock
YourProjetcName/app/build/
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
.gradle/
app/build/
*app/build/

# Local configuration file (sdk path, etc)
local.properties
/YourProjetcName/build/intermediates/lint-cache/api-versions-6-23.1.bin
appcompat_v7_23_1_1.xml
projectFilesBackup
build.gradle
YourProjetcName.iml
YourProjetcName.iml
gradlew
gradlew.bat
local.properties
settings.gradle
.gradle
.idea
android
build
gradle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接