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

发布于 2024-12-21 06:19:15 字数 363 浏览 4 评论 0原文

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

What is the proper syntax for the .gitignore file to ignore files in a directory?

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

?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

风透绣罗衣 2024-12-28 06:19:15

模式格式

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

  • #开头的行作为注释。

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

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

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

  • 否则,git 将模式视为适合 fnmatch(3) 使用 FNM_PATHNAME 标志使用的 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

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 directory foo and paths underneath it, but will not match a regular file or a symbolic link foo (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 the FNM_PATHNAME flag: wildcards in the pattern will not match a / in the pathname. For example, Documentation/*.html matches Documentation/git.html but not Documentation/ppc/ppc.html or tools/perf/Documentation/perf.html.

  • A leading slash matches the beginning of the pathname. For example, /*.c matches cat-file.c but not mozilla-sha1/sha1.c.

You can find more here

git help gitignore
or
man gitignore

森罗 2024-12-28 06:19:15

是前者。也可以使用扩展名而不是文件夹结构。

即我的示例 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
~$*

更新

我想我应该从下面的评论中提供更新。虽然没有直接回答OP的问题,但请参阅以下内容以获取 .gitignore 语法的更多示例。

社区 wiki(不断更新):

.gitignore 用于 Visual Studio 项目和解决方案

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

https://github.com/github/gitignore

It would be the former. Go by extensions as well instead of folder structure.

I.e. my example C# development ignore file:

#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.

Community wiki (constantly being updated):

.gitignore for Visual Studio Projects and Solutions

More examples with specific language use can be found here (thanks to Chris McKnight's comment):

https://github.com/github/gitignore

靖瑶 2024-12-28 06:19:15

包含斜杠的路径被视为相对于包含 .gitignore 文件的目录 - 通常是存储库的顶层,尽管您也可以将它们放在子目录中。

因此,由于在您给出的所有示例中,路径都包含斜杠,因此两个版本是相同的。唯一需要添加前导斜杠的情况是当路径中没有斜杠时。例如,要仅忽略存储库顶层的 foo,请使用 /foo。简单地编写 foo 将忽略存储库中任何位置名为 foo 的任何内容。

你的通配符也是多余的。如果您想忽略整个目录,只需将其命名:

lib/model/om

按照现有方式使用通配符的唯一原因是您打算随后取消忽略目录中的某些内容:

lib/model/om/*      # ignore everything in the directory
!lib/model/om/foo   # except foo

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.

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't one 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.

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

前导斜杠表示忽略条目仅对 .gitignore 文件所在的目录有效。指定 *.o 将忽略此目录和所有子目录中的所有 .o 文件,而 /*.o 将仅忽略该目录中的它们,而 /foo/*.o 只会忽略 /foo/*.o 中的它们。

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.

梦在深巷 2024-12-28 06:19:15

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

例如,要忽略 /src/main/ 文件夹和子文件夹中的所有 *.map 文件,请使用:

/src/main/**/*.map

If you want to put a .gitignore file at the top level and make it work for any folder below it use /**/.

E.g. to ignore all *.map files in a /src/main/ folder and sub-folders use:

/src/main/**/*.map
悸初 2024-12-28 06:19:15

问题中的两个例子实际上都是非常糟糕的例子,可能会导致数据丢失!

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

一个很好的理由是 Jefromi 所写的:”如果您打算随后取消忽略目录中的某些内容”

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

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

一些背景知识

我必须通过艰苦的方式才能了解 。我团队中的某人将 /* 附加到 .gitignore 中的某些目录。随着时间的推移,我有时会遇到某些目录突然消失的情况。我们的应用程序所需的包含千兆字节本地数据的目录。没有人能解释它,我总是不得不重新下载所有数据。一段时间后,我意识到这可能与 git stash 有关。有一天,我想清理我的本地存储库(同时保留被忽略的文件),并且我正在使用 git clean -df ,但我的数据再次消失了。这次我受够了并调查了这个问题。我终于想到原因是附加的/*

我认为这可以通过以下事实来解释: directory/* 确实忽略目录的所有内容,但不忽略目录本身。因此,当内容被删除时,它既不会被视为已跟踪,也不会被忽略。尽管 git status 和 git status --ignored 给出的图片略有不同。

如何重现

以下是如何重现该行为。我目前使用的是 Git 2.8.4。

将在本地 git 存储库中创建一个名为 localdata/ 的目录,其中包含一个虚拟文件 (important.dat),并且通过放置 / 来忽略内容。 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

如果您在此处执行 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 开发列表,看看他们对此有何看法。

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!

A good reason would be for example what Jefromi wrote: "if you intend to subsequently un-ignore something in the directory".

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!

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

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.

How to reproduce

Here is how to reproduce the behaviour. I'm currently using 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.

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:

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!

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.

飘逸的'云 2024-12-28 06:19:15

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 子目录的目录被忽略(将其视为可以使用星号做什么的示例)。

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 basesubdirectory that needs to be ignored (see it as an example of what you can do with the asterics).

以往的大感动 2024-12-28 06:19:15

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

The first one. Those file paths are relative from where your .gitignore file is.

情深如许 2024-12-28 06:19:15

我正在维护一个基于 GUI 和 CLI 的服务,允许您在 https 上轻松生成 .gitignore 模板://www.gitignore.io

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

$ gi swift,osx

I'm maintaining a GUI and CLI based service that allows you to generate .gitignore templates very easily at 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

流星番茄 2024-12-28 06:19:15

对于 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

A sample .gitignore file can look like one below for a Android Studio project

# 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文