如何忽略 Git 目录中的文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8527597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I ignore files in a directory in Git?
提问by Chris McKnight
What is the proper syntax for the .gitignore
file to ignore files in a directory?
.gitignore
文件忽略目录中文件的正确语法是什么?
Would it be
可不可能是
config/databases.yml
cache/*
log/*
data/sql/*
lib/filter/base/*
lib/form/base/*
lib/model/map/*
lib/model/om/*
or
或者
/config/databases.yml
/cache/*
/log/*
/data/sql/*
/lib/filter/base/*
/lib/form/base/*
/lib/model/map/*
/lib/model/om/*
?
?
采纳答案by Op De Cirkel
PATTERN FORMAT
花样格式
A blank line matches no files, so it can serve as a separator for readability.
A line starting with
#
serves as a comment.An optional prefix
!
which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.If the pattern ends with a slash, it is removed for the purpose of the following description, but it would only find a match with a directory. In other words,
foo/
will match a directoryfoo
and paths underneath it, but will not match a regular file or a symbolic linkfoo
(this is consistent with the way how pathspec works in general in git).If the pattern does not contain a slash
/
, git treats it as a shell glob pattern and checks for a match against the pathname relative to the location of the.gitignore
file (relative to the toplevel of the work tree if not from a.gitignore
file).Otherwise, git treats the pattern as a shell glob suitable for consumption by
fnmatch(3)
with theFNM_PATHNAME
flag: wildcards in the pattern will not match a/
in the pathname. For example,Documentation/*.html
matchesDocumentation/git.html
but notDocumentation/ppc/ppc.html
ortools/perf/Documentation/perf.html
.A leading slash matches the beginning of the pathname. For example,
/*.c
matchescat-file.c
but notmozilla-sha1/sha1.c
.
空行不匹配任何文件,因此它可以作为可读性的分隔符。
以 开头的行
#
用作注释。!
否定模式的可选前缀;任何被先前模式排除的匹配文件将再次包含在内。如果否定模式匹配,这将覆盖较低优先级的模式源。如果模式以斜杠结尾,则出于以下描述的目的将其删除,但它只会找到与目录的匹配项。换句话说,
foo/
将匹配目录foo
和其下的路径,但不会匹配常规文件或符号链接foo
(这与 pathspec 通常在 git 中的工作方式一致)。如果模式不包含 slash
/
,则 git 将其视为 shell glob 模式并检查与相对于.gitignore
文件位置的路径名的匹配项(如果不是来自.gitignore
文件,则相对于工作树的顶层)。否则,git 将模式视为适合
fnmatch(3)
使用FNM_PATHNAME
标志的 shell glob :模式中的通配符将与/
路径名中的 a 不匹配。例如,Documentation/*.html
匹配Documentation/git.html
但不匹配Documentation/ppc/ppc.html
或tools/perf/Documentation/perf.html
。前导斜杠与路径名的开头匹配。例如,
/*.c
匹配cat-file.c
但不匹配mozilla-sha1/sha1.c
。
You can find more here
你可以在这里找到更多
git help gitignore
orman gitignore
git help gitignore
或者man gitignore
回答by Luke Hutton
It would be the former. Go by extensions as well instead of folder structure.
应该是前者。也可以使用扩展名而不是文件夹结构。
I.e. my example C# development ignore file:
即我的示例 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
~$*
Update
更新
I thought I'd provide an update from the comments below. Although not directly answering the OP's question, see the following for more examples of .gitignore
syntax.
我想我会从下面的评论中提供更新。虽然没有直接回答 OP 的问题,但请参阅以下更多.gitignore
语法示例。
Community wiki (constantly being updated):
社区维基(不断更新):
.gitignore for Visual Studio Projects and Solutions
.gitignore 用于 Visual Studio 项目和解决方案
More examples with specific language use can be found here (thanks to Chris McKnight's comment):
可以在此处找到更多使用特定语言的示例(感谢 Chris McKnight 的评论):
回答by Cascabel
Paths which contain slashes are taken to be relative to the directory containing the .gitignore file - usually the top level of your repository, though you can also place them in subdirectories.
包含斜杠的路径相对于包含 .gitignore 文件的目录 - 通常是存储库的顶层,但您也可以将它们放在子目录中。
So, since in all of the examples you give, the paths contain slashes, the two versions are identical. The only time you need to put a leading slash is when there isn'tone in the path already. For example, to ignore foo only at the top level of the repository, use /foo
. Simply writing foo
would ignore anything called foo anywhere in the repository.
因此,由于在您提供的所有示例中,路径都包含斜杠,因此两个版本是相同的。只有当路径中没有斜线时才需要放置前导斜线。例如,要仅在存储库的顶层忽略 foo,请使用/foo
. 简单地编写foo
会忽略存储库中任何地方的任何名为 foo 的东西。
Your wildcards are also redundant. If you want to ignore an entire directory, simply name it:
您的通配符也是多余的。如果要忽略整个目录,只需将其命名为:
lib/model/om
The only reason to use wildcards the way you have is if you intend to subsequently un-ignore something in the directory:
以这种方式使用通配符的唯一原因是,如果您打算随后取消忽略目录中的某些内容:
lib/model/om/* # ignore everything in the directory
!lib/model/om/foo # except foo
回答by j?rgensen
A leading slash indicates that the ignore entry is only to be valid with respect to the directory in which the .gitignore file resides. Specifying *.o
would ignore all .o files in this directory and all subdirs, while /*.o
would just ignore them in that dir, while again, /foo/*.o
would only ignore them in /foo/*.o.
前导斜杠表示忽略条目仅对 .gitignore 文件所在的目录有效。指定*.o
将忽略此目录和所有子目录中的所有 .o 文件,而/*.o
只会忽略该目录中的它们,而同样,/foo/*.o
只会忽略 /foo/*.o 中的它们。
回答by petrsyn
If you want to put a .gitignore file at the top level and make it work for any folder below it use /**/
.
如果您想将 .gitignore 文件放在顶层并使其适用于它下面的任何文件夹,请使用 .gitignore 文件/**/
。
E.g. to ignore all *.map
files in a /src/main/
folder and sub-folders use:
例如要忽略*.map
文件/src/main/
夹和子文件夹中的所有文件,请使用:
/src/main/**/*.map
回答by jox
Both examples in the question are actually very bad examples that can lead to data loss!
问题中的两个示例实际上都是非常糟糕的示例,可能导致数据丢失!
My advice: never append /*
to directories in .gitignore files, unless you have a good reason!
我的建议:永远不要附加/*
到 .gitignore 文件中的目录,除非你有充分的理由!
A good reason would be for example what Jefromi wrote: "if you intend to subsequently un-ignore something in the directory".
一个很好的理由是例如 Jefromi 写道:“如果您打算随后取消忽略目录中的某些内容”。
The reason why it otherwise shouldn't be done is that appending /*
to directories does on the one hand work in the manner that it properly ignores all contents of the directory, but on the other hand it has a dangerous side effect:
不应该这样做的原因是,附加/*
到目录一方面以正确忽略目录的所有内容的方式工作,但另一方面它具有危险的副作用:
If you execute git stash -u
(to temporarily stash tracked and untracked files) or git clean -df
(to delete untracked but keep ignored files) in your repository, all directories that are ignored with an appended /*
will be irreversibly deleted!
如果您在您的存储库中执行git stash -u
(临时存储跟踪和未跟踪的文件)或git clean -df
(删除未跟踪但保留忽略的文件),所有被附加的目录/*
将被不可逆转地删除!
Some background
一些背景
I had to learn this the hard way. Somebody in my team was appending /*
to some directories in our .gitignore. Over the time I had occasions where certain directories would suddenly disappear. Directories with gigabytes of local data needed by our application. Nobody could explain it and I always hat to re-download all data. After a while I got a notion that it might have to do with git stash
. One day I wanted to clean my local repo (while keeping ignored files) and I was using git clean -df
and again my data was gone. This time I had enough and investigated the issue. I finally figured that the reason is the appended /*
.
我不得不以艰难的方式学习这一点。我团队中的/*
某个人正在向我们的 .gitignore 中的某些目录追加内容。随着时间的推移,我有时会突然消失某些目录。我们的应用程序所需的本地数据千兆字节的目录。没有人可以解释它,我总是讨厌重新下载所有数据。一段时间后,我意识到这可能与git stash
. 有一天我想清理我的本地存储库(同时保留被忽略的文件)并且我正在使用git clean -df
并且我的数据再次消失了。这次我受够了并调查了这个问题。我终于想通了原因是附加的/*
.
I assume it can be explained somehow by the fact that directory/*
does ignore all contents of the directory but not the directory itself. Thus it's neither considered tracked nor ignored when things get deleted. Even though git status
and git status --ignored
give a slightly different picture on it.
我认为可以通过directory/*
忽略目录的所有内容而不是目录本身的事实来以某种方式解释它。因此,当事物被删除时,它既不会被视为被跟踪,也不会被忽略。尽管git status
并git status --ignored
给出了略有不同的图片。
How to reproduce
如何繁殖
Here is how to reproduce the behaviour. I'm currently using Git 2.8.4.
这是重现该行为的方法。我目前正在使用 Git 2.8.4。
A directory called localdata/
with a dummy file in it (important.dat
) will be created in a local git repository and the contents will be ignored by putting /localdata/*
into the .gitignore
file. When one of the two mentioned git commands is executed now, the directory will be (unexpectedly) lost.
所谓的目录localdata/
,在它的虚拟文件(important.dat
)将在本地的Git仓库被创建和内容将通过将被忽略/localdata/*
到.gitignore
文件中。当现在执行提到的两个 git 命令之一时,目录将(意外地)丢失。
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
If you do a git status --ignored
here, you'll get:
如果你在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/
Now either do
现在要么做
git stash -u
git stash pop
or
或者
git clean -df
In both cases the allegedly ignored directory localdata
will be gone!
在这两种情况下,据称被忽略的目录localdata
都将消失!
Not sure if this can be considered a bug, but I guess it's at least a feature that nobody needs.
不确定这是否可以被视为错误,但我想它至少是一个没有人需要的功能。
I'll report that to the git development list and see what they think about it.
我会把这个报告给 git 开发列表,看看他们是怎么想的。
回答by aefxx
It would be:
这将是:
config/databases.yml
cache
log
data/sql
lib/filter/base
lib/form/base
lib/model/map
lib/model/om
or possibly even:
甚至可能:
config/databases.yml
cache
log
data/sql
lib/*/base
lib/model/map
lib/model/om
in case that filter
and form
are the only directories in lib that do have a base
subdirectory that needs to be ignored (see it as an example of what you can do with the asterics).
如果filter
并且form
是 lib 中唯一具有base
需要忽略的子目录的目录(将其视为您可以使用星号执行的操作的示例)。
回答by Unixmonkey
The first one. Those file paths are relative from where your .gitignore file is.
第一个。这些文件路径与 .gitignore 文件所在的位置相对。
回答by Joe
I'm maintaining a GUI and CLI based service that allows you to generate .gitignore
templates very easily at https://www.gitignore.io.
我正在维护一个基于 GUI 和 CLI 的服务,它允许您.gitignore
在https://www.gitignore.io 上非常轻松地生成模板。
You can either type the templates you want in the search field or install the command line alias and run
您可以在搜索字段中键入所需的模板,也可以安装命令行别名并运行
$ gi swift,osx
$ gi swift,osx
回答by Shirish Herwade
A sample .gitignorefile can look like one below for a Android Studio project
对于 Android Studio 项目,示例.gitignore文件可能如下所示
# 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