.gitignore和.gitkeep有什么区别?

2570

.gitignore.gitkeep之间有什么区别?它们是只是名称不同的相同物品,还是它们都有不同的功能?

我似乎找不到太多关于.gitkeep的文档。

7个回答

4471

.gitkeep没有文档说明,因为它不是Git的一个功能。

Git 不能添加完全空的目录。想要在Git中跟踪空目录的人们已经创建了一种约定,即在这些目录中放置名为.gitkeep的文件。该文件可以被任意命名;Git对此名称没有特殊含义。

另有一种竞争性的约定是在空目录中添加.gitignore文件来跟踪它们,但有些人认为这会引起混淆,因为目标是保留空目录,而不是忽略它们;.gitignore也用于列出Git在查找未跟踪文件时应忽略的文件。


548
把一个 README 文件放在空的子目录中,包含一些关于该子目录将要用于什么的信息,这难道不是更好的解决方案吗?拥有一个名为 .gitkeep 的文件,它实际上并不是 Git 的一部分,这似乎很令人困惑。 - tamouse
556
很多时候,空目录的路径(例如文件夹名称)已经足以表达其用途(比如:templates/cache、upload/thumbs等)。在这些情况下,在每个空目录中放置自述文件似乎是多余的。 - Halil Özgür
25
希望追踪空目录的人应在自述文件中说明需要创建该目录或使用其构建工具或其他需要该目录存在的工具来创建目录。 - user9903
53
@tamouse, @omouse: 一个包含两行内容的.gitignore文件:“*”和“!.gitignore”,已足够清晰地表达其意图。如果需要更多解释,请使用“#”语法在文件顶部添加注释。 - yurisich
84
值得注意的是,流行的Rails框架使用.keep文件代替.gitkeep来保留这些空文件夹,因为Git不是唯一不能跟踪空文件夹的源代码控制系统。更多细节请参见:https://github.com/rails/rails/issues/2800 - Claudio Floreani
显示剩余20条评论

468

.gitkeep只是一个占位符。它是一个虚拟文件,这样Git就不会忘记这个目录,因为Git只跟踪文件。


如果你想要一个空目录并确保它对Git“保持干净”,请创建一个包含以下行的.gitignore文件:

# .gitignore sample
# Ignore all files in this dir...
*

# ... except for this one.
!.gitignore

如果您希望Git仅显示一种类型的文件,以下是如何过滤除.gitignore和所有.txt文件之外的所有内容的示例:

# .gitignore to keep just .txt files
# Filter everything...
*

# ... except the .gitignore...
!.gitignore

# ... and all text files.
!*.txt

3
我很喜欢这个实践。如果这些目录中有源代码,就不需要使用.gitkeep文件了。通常这些文件夹是用来存放暂存、缓存和用户内容的,在测试期间这些内容也会被生成,因此你需要在.gitignore文件中将它们忽略掉。 - chrisan
1
为什么需要在 .gitignore 前面加上 !?这是为了转义点吗? - Will
10
不,!符号是否定其后面的部分,就像在编程中通常所做的那样。 - sjas
3
不必将.gitignore放入git ignore文件中,可以先添加该文件然后再编辑它,或者使用适当的内容进行强制添加("*"表示忽略所有内容,不填则只是确保文件夹存在)。更多例子请见 - AD7six
22
从您的链接中得知:由于git ignore文件已经在repo中了,所以不需要取消忽略它——它已经被追踪。如果没有,而且您没有强制添加,那么您可能会忘记它。对于一些小的情况,这没什么问题,但如果是一个大文件,您可能会很烦恼。使用!.gitignore可以避免自己被绊倒。我更喜欢这种方式,因为以前曾经吃过这种亏。 - sjas
显示剩余2条评论

150
.gitignore

.gitignore 是一个文本文件,里面列出的是你的目录中 git 不需要跟踪或不需要加入/更新到版本库中的文件列表。

.gitkeep

由于Git会从代码库中移除或不添加空目录,因此.gitkeep算是一种hack(我不认为它是Git的官方部分),用于保留空目录在代码库中。

只需执行touch /path/to/emptydirectory/.gitkeep即可添加此文件,Git现在将能够维护此目录在代码库中。


23
如果你不想每次都指定每个文件夹的完整路径,那么你可以拥有任意数量的.gitignore文件。 - sjas
1
我试图将空目录列表提及到.gitkeep文件中,但它不会跟踪空目录,只有存在.gitkeep文件的文件夹才会被跟踪。为什么会这样? - Pardeep Jain
3
.gitkeep 不像 .gitignore 那样工作,它不是一个要保留的目录列表。它只是一个空文件,存在于你想要保留的目录中。它可以使用任何名称命名,例如 .keep。因此,你可以有一个目录 /foo/bar,其中 gitkeep 文件将是 /foo/bar/.gitkeep。 - Jim Munro
1
@sjas,拥有多个.gitignore文件如何避免每次都需要指定完整路径到每个文件夹?我觉得我可能漏掉了一些显而易见的东西。 - Willwsharp
假设你有/abc/def/somefile。如果你的git在/abc/中,你需要忽略./dev/somefile。如果你把你的.gitignore放在/abc/def里面,那么你只需要忽略./somefile。 - Default

9

很多人更喜欢使用.keep,因为这种约定与 Git 没有关系。


18
可能的理由是,召开这次会议几乎是明确因为 Git。 - JDPeckham
2
@JDPeckham Perforce还需要存在的文件来跟踪一个文件夹。 - Polygnome

4

文件.gitignore用于告诉Git应该忽略哪些文件和文件夹。通常,这些文件是构建产物、临时文件或其他不属于代码库的文件类型。Git将忽略在.gitignore文件中匹配模式的任何目录或文件。

例如:

# Ignore .DS_Store files
.DS_Store

# Ignore build artifacts
build/

# Ignore log files
*.log

相反地,Git 中使用 .gitkeep 文件来维护一个本来是空的目录。Git 默认不跟踪空文件夹,因此如果您希望将其保留在存储库中,则必须向该目录添加一个 .gitkeep 文件。文件名比文件的实际内容更重要。 .gitkeep 文件示例
# This file is used to keep the directory empty in Git

总之,.gitignore 命令用于告诉 Git 忽略哪些文件和文件夹。如果要维护一个本来会是空的 Git 目录,请使用 .gitkeep。它们彼此独立,具有不同的功能。

2

这并不是回答原问题“.gitignore 与 .gitkeep 有什么区别?”,但在此发布以帮助人们以简单的方式跟踪空目录。要跟踪空目录并知道 .gitkeep 不是 Git 的官方部分,只需在其中添加一个空的(没有内容的).gitignore 文件。

例如,如果您有 /project/content/posts,有时 posts 目录可能为空,则创建空文件 /project/content/posts/.gitignore,无需内容即可跟踪该目录及其未来的文件。


11
我不同意。".gitkeep"不是Git的正式组成部分这一事实,绝对不是误用".gitignore"的理由。空的".gitignore"没有意义且令人困惑。而一个空的".gitkeep"则明确表示要在Git中保留该目录,是一个占位符。 - Phil
2
我相信那是你的观点,而不是所有人的观点。 - Sohel Ahmed Mesaniya
2
要明确一点,您的观点是认为将官方的.gitignore文件用途扩展为在为空时充当占位符是可以接受的(或者是一个好主意)?就像我说的,我非常不同意。也许您可以编辑您的答案来解释您的推理或支持您的观点?现在它是一个毫无根据的答案,完全值得我给它一个负评。 - Phil
1
啊,我意识到我已经陷入了一个惯例之争。我刚刚注意到了对被接受答案的评论。也许这里有两种惯例,每一种都有自己的追随者数量,因此受欢迎程度不同。我仍然想听听支持这种惯例的论点,因为也许我会改变我的想法。 - Phil
我的观点是,当我在网上搜索更多关于.gitkeep的信息时,我发现所有内容都来自社区,而没有来自官方的Git文档。我更喜欢首先遵循官方文档。 - Sohel Ahmed Mesaniya
4
我明白了。但是你能否在官方的Git文档中找到指示人们添加空的.gitignore文件的部分? - Phil

0
如果你想忽略子目录中的所有内容,但是保留子目录本身(以及其中的.gitkeep文件)添加到Git中,你需要将以下内容添加到.gitignore文件中:
build/*
!build/.gitkeep

这意味着忽略build目录下的所有内容,但是不要将.gitkeep包括在忽略模式中。

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