Git ignore

Git 将工作副本中的每个文件视为三件事之一:

1. tracked - 之前已暂存或提交的文件;

2. untracked - 尚未暂存或提交的文件,或

3. ignored - 已明确告知 Git 要忽略的文件。

忽略的文件通常是构建工件和机器生成的文件,这些文件可以派生自您的存储库源代码或不应该提交。一些常见的示例包括:

  • 依赖关系缓存,例如 /node_modules/packages 的内容

  • 编译后的代码,例如 .o.pyc.class 文件

  • 构建输出目录,例如 /bin/out/target

  • 运行时生成的文件,例如 .log.lock 或者 .tmp

  • 隐藏的系统文件,例如 .DS_StoreThumbs.db

  • 个人集成开发环境配置文件,例如 .idea/workspace.xml

被忽略的文件会在名为 .gitignore 的特殊文件中进行跟踪,该文件在存储库的根目录中签入。没有明确的 git 忽略命令:而是 .gitignore当您有想要忽略的新文件时,必须手动编辑和提交文件。.gitignore 文件包含与存储库中的文件名匹配的模式,用于确定是否应忽略它们。

在本文档中,我们将介绍:

Git 忽略模式

.gitignore 使用通配符模式来匹配文件名。您可以使用各种符号来构造您的模式:

模式

示例匹配

解释*

**/logs

logs/debug.log

logs/monday/foo.bar

build/logs/debug.log

您可以在模式前面加上双星号,以匹配存储库中任何位置的目录。

**/logs/debug.log

logs/debug.log

build/logs/debug.log

但不是

logs/build/debug.log

您也可以使用双星号根据文件的名称和父项目录的名称来匹配文件。

*.log

debug.log

foo.log

.log

logs/debug.log

星号是匹配零个或多个字符的通配符。

*.log

!important.log

debug.log

但不是

logs/debug.log

在模式前加上感叹号会否定该模式。如果文件与模式匹配,但匹配文件后面定义的否定模式,则不会被忽略。

/debug.log

debug.log

但不是

logs/debug.log

在否定模式之后定义的模式将重新忽略任何先前否定的文件。

debug.log

debug.log

logs/debug.log

在前面加上斜杠只能匹配存储库根目录中的文件。

debug?.log

debug0.log

debugg.log

但不是

debug10.log

问号只匹配一个字符。

debug[0-9].log

debug0.log

debug1.log

但不是

debug10.log

方括号也可以用于匹配指定范围内的单个字符。

debug[01].log

debug0.log

debug1.log

但不是

debug2.log

debug01.log

方括号匹配指定集中的单个字符。

debug[!01].log

debug2.log

但不是

debug0.log

debug1.log

debug01.log

感叹号可用于匹配除指定集中的一个字符外的任何字符。

debug[a-z].log

debuga.log

debugb.log

但不是

debug1.log

范围可以是数字或字母。

日志

日志

logs/debug.log

logs/latest/foo.bar

build/logs

build/logs/debug.log

如果您不附加斜杠,则该模式将匹配具有该名称的文件和目录的内容。在左侧的示例匹配中,名为 logs 的目录和文件都被忽略

logs/

logs/debug.log

logs/latest/foo.bar

build/logs/foo.bar

build/logs/latest/debug.log

附加斜杠表示该模式是一个目录。存储库中与该名称匹配的任何目录的全部内容(包括其所有文件和子目录)都将被忽略

logs/

!logs/important.log

logs/debug.log

logs/important.log

等一下!左侧示例中难道不应该把 logs/important.log 排除掉吗?

并不是这样的!由于 Git 中一个与性能相关的特殊机制,对于因模式目录匹配而被忽略的文件,您无法对其执行排除操作。

logs/**/debug.log

logs/debug.log

logs/monday/debug.log

logs/monday/pm/debug.log

双星号匹配零个或多个目录。

logs/*day/debug.log

logs/monday/debug.log

logs/tuesday/debug.log

但不是

logs/latest/debug.log

通配符也可以在目录名中使用。

logs/debug.log

logs/debug.log

但不是

debug.log

build/logs/debug.log

在特定目录中指定文件的模式是相对于存储库根目录的。(如果您愿意,您可以在前面加一个斜杠,但它不会起任何特别的作用。)

** 这些解释假设您的 .gitignore 文件位于存储库的顶级目录中,就像惯例一样。如果您的存储库有多个 .gitignore 文件,只需将“存储库根”目录替换为包含 .gitignore 文件的目录即可(为了团队的理智,考虑统一他们)。*

除了这些字符外,您还可以使用 # 在 .gitignore 文件中添加注释:

# ignore all logs
*.log

您可以使用 \ 来逃避 .gitignore 模式字符,如果您有包含模式字符的文件或目录的话:

# ignore the file literally named foo[01].txt
foo\[01\].txt

分享了存储库中的 .gitignore 文件

Git 忽略规则通常在您的存储库根目录的 .gitignore 文件中定义。但是,您可以选择在存储库的不同目录中定义多个 .gitignore 文件。特定 .gitignore 文件中的每种模式都是相对于包含该文件的目录进行测试的。但是,惯例是在根目录中定义一个 .gitignore 文件,这也是最简单的方法。您的 .gitignore 文件已签入,它像存储库中的任何其他文件一样进行版本控制,并在推送时与队友共享。通常,您应该只在 .gitignore 中包含模式,这将使存储库的其他用户受益。

个人 Git 忽略规则

您还可以在 .git/info/exclude 的特殊文件中为特定存储库定义个人忽略模式。它们没有版本控制,也不会随您的存储库一起分发,因此是包含可能只会使您受益的模式的合适位置。例如,如果您有自定义的日志记录设置或在存储库工作目录中生成文件的特殊开发工具,则可以考虑将它们添加到 .git/info/exclude,以防止它们意外提交到您的存储库。

全局 Git 忽略规则

此外,您可以通过设置 Git core.excludesFile 属性为本地系统上的所有存储库定义全局 Git 忽略模式。您必须自己创建这个文件。如果您不确定要把您的全局 .gitignore 文件放在哪里,不妨试试您的主目录(而且以后可以轻松找到)。创建文件后,您需要使用 git config 配置其位置:

$ touch ~/.gitignore
$ git config --global core.excludesFile ~/.gitignore

您应该谨慎选择全局忽略哪些模式,因为不同的文件类型与不同的项目相关。特殊操作系统文件(例如 .DS_Storethumbs.db)或者某些开发人员工具创建的临时文件通常是全局忽略的候选文件。

忽略之前提交的文件

如果您想忽略过去提交的文件,则需要从存储库中删除该文件,然后为其添加 .gitignore 规则。在 git rm 中使用 --cached 选项意味着该文件将从您的存储库中删除,但会作为被忽略的文件保留在您的工作目录中。

$ echo debug.log >> .gitignore
  
$ git rm --cached debug.log
rm 'debug.log'
  
$ git commit -m "Start ignoring debug.log"

如果您想从存储库和本地文件系统中删除文件,可以省略 --cached 选项。

提交被忽略的文件

可以使用 git add 中的 -f(或 --force)选项强制将忽略的文件提交到存储库:

$ cat .gitignore
*.log
  
$ git add -f debug.log
  
$ git commit -m "Force adding debug.log"

如果您定义了一个通用模式(比如 *.log),但您想提交一个特定的文件,您可以考虑这样做。但是,更好的解决方案是定义一般规则的例外情况:

$ echo !debug.log >> .gitignore
  
$ cat .gitignore
*.log
!debug.log
  
$ git add debug.log
  
$ git commit -m "Adding debug.log"

对于队友来说,这种方法更明显,困惑也更少。

暂存被忽略的文件

git stash 是一项强大的 Git 功能,用于暂时搁置和还原本地变更,允许您稍后重新应用它们。正如您所预期的那样,默认情况下,git stash 会忽略被忽略的文件,只暂存对 Git 跟踪的文件的变更。但是,您也可以使用 --all 选项调用 git stash 来暂存对忽略和未跟踪文件的变更。

调试 .gitignore 文件

如果您有复杂的 .gitignore 模式,或分布在多个 .gitignore 文件上的模式,则可能很难跟踪特定文件被忽略的原因。您可以使用带有 -v(或 --verbose)选项的 git check-ignore 命令来确定哪种模式导致特定文件被忽略:

$ git check-ignore -v debug.log
.gitignore:3:*.log  debug.log

输出显示:

<file containing the pattern> : <line number of the pattern> : <pattern>    <file name>

如果您愿意,可以将多个文件名传递给 git check-ignore,而且名称本身甚至不必与存储库中存在的文件相对应。

为您推荐

Bitbucket 博客

DevOps 学习路径

了解有关 Git 的更多信息

在此中心查找更多 Git 指南和资源。