在计算忽略文件时,Git 可以忽略嵌套的 .gitignore 文件吗?

11

我希望能够将一些被许多代码库忽略的文件追踪到单个代码库中。

这里是一个示例布局:

.
+-- .git
+-- .idea
|-- .gitignore
|-- proj1
|   +-- .git
|   |-- .gitignore
|   |-- foo
|   |   |-- foo.iml
|   |-- bar.c
|   |-- proj1.iml
|-- proj2
    +-- .git
    |-- .gitignore
    +-- bar
    |-- foo.c
    |-- proj2.iml

我想要:

  • 根级别的仓库包括所有*.iml文件,而每个子仓库单独忽略它们
  • 所有仓库都是独立的(项目不依赖于根,可以分别操作)
  • 保留此文件夹结构

有什么解决方案吗?

3个回答

6
问题的标题和详细描述似乎在询问略有不同的问题...
关于问题的标题:要排除嵌套的.gitignore文件,但不包括根目录中的.gitignore本身,请在根目录的.gitignore文件中添加以下行:
*/**/.gitignore

(这只会忽略那些嵌套至少一个文件夹级别的 .gitignore 文件)

或者,如果您只想忽略直接子文件夹中的 .gitignore 文件,但仍然希望包括所有间接的(即第二级、第三级...)子文件夹中的 .gitignore 文件,请使用:

*/.gitignore

1
请澄清一下,这是配置文件本身的跟踪,还是忽略其中的规则?后者是指问题中的“忽略”。 - OrangeDog
@StopHarmingMonica 这个配置跟踪嵌套的.gitignore文件。如果存在这些文件,则其中的规则仍将适用。您可以在本地指定忽略规则(它们将再次被本地识别),但是这些文件不会被跟踪。 - raner
2
жҲ‘жғізҹҘйҒ“еҰӮдҪ•еҝҪз•Ҙ规еҲҷпјҢиҖҢдёҚд»…д»…жҳҜ.gitignoreзҡ„и·ҹиёӘгҖӮжҲ‘еҸӘеёҢжңӣGitиҜҶеҲ«ж №зӣ®еҪ•.gitignoreзҡ„规еҲҷгҖӮ - redanimalwar

2
译文如下:

技巧是:父仓库会忽略嵌套仓库的全部内容。

在 OP 的问题中,由于 proj1proj2 中存在 .git 子文件夹,所以根级别的仓库不会跟踪任何 *.iml 文件。

但是,假设 proj1/2 的内容实际上是由父仓库跟踪的(git subtreegit subrepo),那么 .gitignore 模式应用规则 是很清楚的:

模式从与路径相同的目录中的 .gitignore 文件中读取,或者从任何父目录(直到工作树的顶层)中读取,高级别文件中的模式被低级别文件中的模式覆盖,直到包含该文件的目录为止

所以:

我只希望 Git 识别根目录下 .gitignore 文件中的规则。
这意味着需要一个 Git 包装脚本,它应该:
- 删除 projx/.gitignore 文件 - 添加所有文件 - 恢复被删除的 .gitignore 文件。
原文已经是英文了,这里给一个汉语翻译:

在评论中 OP 补充道:

你能设置 Git 自动运行“包装脚本”吗?

可以:你只需为 git 定义一个别名(即使在 Windows 上也可以使用 doskey),然后调用自己的脚本。

如果我能够自动运行一个在提交时重命名 .gitignore 的包装脚本,那么就能解决我目前遇到的问题了。

你需要一个 pre-commit hook,它会首先 修改索引,通过为嵌套的 .gitignore 注册空 blob 来实现(意味着它们没有被删除,只是变为空)。 这里有示例

一个 post-commit hook 可以恢复这些 .gitignore 的内容。


我刚在git手册中读到,你可以使用$GIT_DIR/info/exclude,但我不喜欢这个解决方案,因为即使这个repo是我的个人repo,但如果我理解正确的话,它实际上会起作用,因为我的.git文件只是一个包含gitDir: /path/to/git/files/的文件,我已经将git文件移出了文件夹,特别是因为嵌套的原因。我还没有尝试过,但它肯定听起来比这个方法更好。你能设置git自动运行一个“包装脚本”吗? - redanimalwar
最近我有一个仓库,在合并时自动运行npm命令。如果我能在提交时自动运行一个包装脚本来重命名.gitignore,那么就可以解决我目前遇到的问题。 - redanimalwar
@redanimalwar 我已经编辑了答案来回答你的评论/问题。 - VonC

0

只需将较低级别的gitignore添加到顶层gitignore文件中:

*/**/.gitignore

这将跟踪除顶级gitignore文件中标记的文件以外的所有文件。

另一个值得研究的解决方案可能是Git子树或Git子模块。


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