【问题标题】:Force Git submodules to always stay current强制 Git 子模块始终保持最新状态
【发布时间】:2026-02-06 04:30:01
【问题描述】:

我喜欢 git 子模块。另外,我讨厌 git 子模块。我喜欢它们的是它如何使您能够清晰地划分依赖关系等。我明白让它们指向回购上的特定提交的意义,我确实这样做了。但就我而言,我正在构建一个将在另一个项目中使用的库,所以我想将它保存在那个单独的仓库中。

但是,当我每天都在这个库上工作时,烦恼就来了,我必须经常使用我的库切换回应用程序来提交指针更新。

那么,当我不断更新和添加到这个库时,是否有可能让一个 git 子模块始终位于它指向的 repo 的头部?

【问题讨论】:

标签: git git-submodules


【解决方案1】:

更新:从 git 1.8.2 开始,似乎有一个解决方案。请参阅VonC's answer down below。原始答案留给 git


不,这是设计使然。如果有办法将子模块指向其他存储库的“当前头”,那么就不可能从主存储库检索历史版本(例如标记版本)。它不知道要签出哪个版本的子模块。

话虽如此,您可能对git subtree 脚本感兴趣。这提供了一种处理子模块的不同方式,可能与您的工作流程更兼容。最近的post on HN让我想起了这一点。

【讨论】:

  • 是的,我明白了,我的意思是我希望我的父仓库在子模块中本地提交更改时自动更新子模块指针。如果我有具有子模块 X 的项目 A,当我在处理项目 A 时进入子模块 X 时,我必须不断地进行 2 次提交,一次在子模块中,然后再次在父模块中。如果您正在处理一个变化不大的子模块,这没什么大不了的,但是当您不断地来回走动时,这真的很烦人....似乎我应该能够让我的本地仓库同时提交
  • 翻译:告诉我的本地仓库在我提交对子模块的更改时自动提交子模块指针更新...
  • 我想您可以编写一个在提交到子模块时使用的脚本,该脚本会自动在父模块中进行相应的提交。或者,您可以编写一个在父模块工作目录中运行的脚本,该脚本会自动对自上次父项目提交以来已更新的任何子模块进行提交。
  • @Ben:我已经更新了我的答案,提供了更多可能有用的信息。
  • 从 Git 1.8.2(2013 年 3 月)起不再适用。 github.com/git/git/blob/master/Documentation/RelNotes/1.8.2.txt 。 Git 为子模块添加了指向远程分支尖端的功能。
【解决方案2】:

暂时没有这样的事情。为了使代码保持最新,我使用以下命令:

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

【讨论】:

    【解决方案3】:

    正如我在“git submodule tracking latest”中提到的,你可以从 git 1.8.2(2013 年 3 月)开始创建一个子模块来跟踪分支的 HEAD:

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

    子模块 SHA1 仍作为 gitlink (special entry in the index)

    记录在父 repo 中

    但是git submodule update --remote 会将该条目更新为与子模块远程 repo 分支的 HEAD 匹配的 SHA1。

    如果您有一个现有的子模块,you can make it follow a branch 与:

    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/master master
    
    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    

    【讨论】:

    • 每次我运行git submodule update --remote 子模块回到提交并丢失了 HEAD 引用
    • git submodule foreach git pull它不会发生。
    • @MarceloFilho 考虑到子模块不会签出分支,这并不奇怪。如果它被配置为跟随一个远程分支,那么git submodule update --remote --recursive 是唯一需要的命令。检查您的 .gitmodules 以查看该/那些子模块是否遵循分支。
    • 是的,我的.gitmodules 将子模块指向一个分支(主),但指向一个本地分支:master = master
    • @marc 和更新遥控器不起作用?你用的是什么版本的git?
    【解决方案4】:

    为什么不在子模块目录中进行更改,它本身就是一个 git 存储库?这样,您的应用将始终拥有更新的库。

    注意事项:

    1. 您仍然需要在应用程序仓库中提交子模块更改,以将更改放入版本控制(针对应用程序)。

    2. 如果使用此库的应用程序不止一个,那么这将不起作用,因为在任何给定时间只有一个应用程序是最新的。

    【讨论】:

    • “你为什么不在子模块目录中进行更改”,因为它是分离的,并且它可能已经在前面,所以你会引入冲突,这个人总是希望得到子模块的 HEAD 版本坚持特定的提交