你在 .gitignore 文件中忽略一个 git 子模块,还是将其提交到仓库中?

134

我已经在project_dir/vendor/submodule_one下添加了一个子模块,现在每次运行git status都会出现modified: vendor/submodule_one (new commits)

我的问题是最好的处理方式是什么? 我是否应该将vendor/submodule_one文件夹添加到我的.gitignore中,因为我的主要项目不应该知道我的子模块的具体信息?

还是当我更改和提交子模块的更改时,我需要在我的主项目中进行提交?

刚开始使用子模块,似乎找不到除了设置之外的更多信息。


你好,你找到相同问题的答案了吗?我也处于类似的情况。 - L.Learner
3个回答

107
不,您无需将子模块添加到.gitignore中:父级将从您的子模块中看到一个gitlink(一个特殊条目,mode 160000)。
这意味着:直接在子模块中进行的任何更改都需要在父目录中跟随提交。 这样,父目录将记录子模块状态的正确提交:该提交是上述"gitlink"。 您可以在 "git submodule update (true nature of submodules)" 中了解更多关于此策略的信息。 子模块背后的主要思想是基于组件的方法,其中您引用其他存储库的特定提交。但是,如果您更改这些子模块中的任何内容,则还需要在父存储库中更新这些引用。
请注意,从Git 2.13(2017年第二季度)开始,虽然不会忽略gitlink,但您仍然可以使用以下方法忽略子模块:
git config submodule.<name>.active false

请查看 "忽略git子模块的新提交" 以获取更多信息。


注意:从Git 2.15.x/2.16(2018年第一季度)开始,忽略子模块更加精确。"git status --ignored --untracked"不会停在嵌套在被忽略的目录中的另一个项目的工作树上,并列出该项目中的文件,而只显示被忽略的目录本身。请参见 commit fadb482 (2017年10月25日) by Johannes Schindelin (dscho)(由Junio C Hamano -- gitster --合并于commit da7996a,2017年11月6日)

状态:不要被排除目录中的子模块搞混

我们将exclude标志详细传递给treat_directory()函数,以便在递归时指示其中的文件被排除而不是未跟踪。

但我们还没有以同样的方式处理子模块。

因此,在被Git忽略的tracked/中有一个名为submodule的子模块时,git status --ignored --untracked会在"Untracked files"部分显示该子模块。

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    tracked/submodule/

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

    tracked/submodule/initial.t

相反,我们希望它在“忽略的文件”部分中显示子模块:
On branch master
Ignored files:
  (use "git add -f <file>..." to include in what will be committed)

    tracked/submodule/

19
这个答案让人感到困惑,因为问题的标题询问是否应该忽略子模块文件夹,而你在问题的正文中回答了一个与此无关的问题。 - SgtPooki
1
我认为现在它更有意义了,并且提供了一些非常有用的深入信息。太棒了,谢谢你的更新 :) - SgtPooki
.gitignore的参数:为什么要在提交时检查.gitsubmodules文件,而其中包含的url可能会包含带有用户名参数的用户特定git url? - djangofan
1
@djangofan 这个问题(以及我的回答)是关于忽略子模块文件夹本身(由gitlink表示的那个)。而不是忽略.gitmodules文件。确实,这个文件(.gitmodules)可能包含凭据,但如果仅用于克隆公共存储库,则不必包含它们。此外,它们可以被缓存,即使在Windows上,也可以使用类似于“Git Credential Manager for Windows”(https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases/tag/v1.1.0)的凭据助手。因此,在`.gitmodules`中拥有凭据并不是一个致命错误。 - VonC

19

由于某种原因,submodule.module-name.active 对我不起作用。

这就是为什么我使用了 submodule.module-name.ignore

git config submodule.<your module path>.ignore all

https://git-scm.com/docs/gitmodules - 这里可以找到参数可能取值的描述。

对我来说,这适用于(新提交)和(修改内容)的消息。


1
但是运行 git add . 仍会提交子模块。 - towry

8
补充已有答案,我发现将Git子模块文件夹添加到.gitignore中实际上会导致问题 - 特别是在尝试创建项目的新克隆时。具体来说,运行正常的子模块克隆命令会导致子模块文件夹为空:
git submodule init
git submodule update
git pull --recurse-submodules

只有当我们试图重新运行时

git submodule add <Git repo> <submodule folder>

基于输出结果,问题显而易见:

The following path is ignored by one of your .gitignore files:
<submodule folder>
Use -f if you really want to add it.

我没有添加-f参数,而是将Git子模块文件夹从.gitignore中删除,并重新运行了子模块 clone 命令 - 现在成功创建了该文件夹。 我认为这可能存在一个 bug,其中某个子模块 clone 命令会尊重.gitignore文件,但不会相应地警告跳过一个子模块。


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