强制Git子模块始终保持最新状态

99

我喜欢使用git子模块,但也讨厌它们。我喜欢的是它能够帮助你清晰地划分依赖关系等内容。我理解让它们指向仓库上特定的提交点的意义。但在我的情况下,我正在构建一个将用于另一个项目的库,因此我希望将其保留在单独的仓库中。

然而,当我每天都在这个库上工作并且不断更新时,我必须不断切换到使用此库的应用程序以提交指针更新,这就很麻烦。

那么,在我不断更新和添加到此库时,是否可能让git子模块始终处于其所指向仓库的最新状态?


1
这个有帮助吗?https://dev59.com/pnI-5IYBdhLWcg3wlpeW - Aseem Kishore
4个回答

91

如我在 "git submodule tracking latest" 中提到的那样,自从 git 1.8.2(2013年3月)起,您可以使子模块跟踪分支的 HEAD:

git submodule add -b <branch> <repository> [<path>]

一个子模块 SHA1 仍然作为gitlink索引中的特殊条目)记录在父存储库中。

但是,git submodule update --remote 将更新该条目以匹配子模块远程存储库分支 HEAD 的 SHA1。

如果您有现有的子模块,您可以使用以下方法使其跟随一个分支

cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>

cd path/to/your/submodule
git checkout -b <branch> --track origin/<branch>
  # if the master branch already exist:
  git branch -u origin/<branch> <branch>

cd /path/to/your/parent/repo
git add path/to/your/submodule
git commit -m "Make submodule tracking <branch>"

2
每次我运行 git submodule update --remote 命令时,子模块都会回到之前的提交并且失去 HEAD 引用。 - Idemax
1
@MarceloFilho 这并不奇怪,因为子模块不会检出分支。如果它被配置为跟随远程分支,则 git submodule update --remote --recursive 是唯一必要的命令。检查你的 .gitmodules 文件以查看哪个/哪些子模块正在跟随分支。 - VonC
@marc 更新远程的操作不起作用了吗?你使用的Git版本是什么? - VonC
@mar 没错,这就是子模块应该工作的方式。它检出它的gitlink,而不是分支。 - VonC
3
@VonC,有没有关于让gitlink始终指向分支的HEAD而不是SHA1的计划或讨论,或者在.gitmodules中最好有一个选项,这样git status就不会担心(new commits)了?虽然update --remote更新它很好,但如果我们有选择不需要在主分支上提交子模块gitlinks的提交,那就更好了。 - Partly Cloudy
显示剩余4条评论

38

更新:截至git 1.8.2,似乎已经有解决方案。请参见VonC在下面的答案。原始答案保留给git < 1.8.2的用户。


不行,这是故意的。如果有一种方法可以将子模块指向其他存储库的“当前版本”,那么就无法从主存储库检索历史版本(例如已标记版本)。它将不知道要检出哪个子模块版本。
话虽如此,您可能会对git subtree脚本感兴趣。这提供了一种与您的工作流更兼容的处理子模块的不同方式。我刚在最近的post on HN中想起了这一点。

3
我理解您的意思,您希望在子模块有本地提交时,父仓库能自动更新子模块指针。以A项目为例,如果它有一个名为X的子模块,那么在处理A项目时,每次进入X子模块都需要进行两次提交,一次在子模块中,另一次在父项目中。如果您处理的子模块不怎么变化,这可能并不是很麻烦,但如果您需要频繁地来回切换,这会让人感到非常烦恼。因此,您觉得应该可以让本地仓库同时提交两个仓库,解决这个问题。 - Ben
1
告诉我的本地仓库,当我提交子模块的更改时,只需自动提交子模块指针更新。 - Ben
2
我想你可以编写一个脚本,当提交子模块时使用,它会自动在父模块中进行相应的提交。或者,你可以编写一个脚本,在父模块的工作目录中运行,自动为任何自上次父项目提交以来已更新的子模块进行提交。 - Greg Hewgill
@Ben:我已经更新了我的答案,并添加了更多可能有用的信息。 - Greg Hewgill
7
自 Git 1.8.2(2013年3月)起,这不再是真实情况。https://github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt 。Git添加了子模块指向远程分支tip的功能。 - wisbucky

0
为什么不在子模块目录内进行更改,它本身就是一个git仓库?这样,您的应用程序将始终具有更新的库。
注意事项:
  1. 您仍然需要提交应用程序仓库中的子模块更改,以将更改放入版本控制(针对应用程序)。
  2. 如果有多个应用程序正在使用此库,则此方法将无法正常工作,因为任何时候只有一个应用程序会是最新的。

1
为什么不在子模块目录内进行更改呢?因为它是分离的并且其源可能已经超前了,所以您会引入冲突。这些人希望始终获取子模块的 HEAD 版本,而不是固定在特定的提交上。 - Pawel Cioch

0

目前还没有这样的东西。为了保持代码最新,我使用以下命令:

第一次下载全部:git clone --recursive http://github.com/<your repo>
更新现有存储库中的更新:git submodule update --remote --recursive --merge


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