Git子模块提交冲突问题


纸上得来终觉浅,绝知此事要躬行。

Git子模块提交冲突问题


  • 今天更新项目的时候,使用 git submodule 进行 update 的时候,出现下面的错误信息。通过字面上面的意思,说是主项目中记录的 submoduleHEAD 超前,导致找不到指定的 commit 信息。
# 子模块更新报错
$ git submodule update
Submodule path 'project1': checked out 'f0246e6589fcb0f80e62f99c5ac39cfb397aff9d'

Another git process seems to be running in this repository, e.g.
an editor opened by 'git commit'. Please make sure all processes
are terminated then try again. If it still fails, a git process
may have crashed in this repository earlier:
remove the file manually to continue.
error: Server does not allow request for unadvertised object 760fdec22c33e28eac20de661e4e6ce0e24c8549
Fetched in submodule path 'project2', but it did not contain 760fdec22c33e28eac20de661e4e6ce0e24c8549. Direct fetching of that commit failed.
  • 很奇怪,自己什么都没有做,而且使用的 CI 自动进行环境更新的。理论上来说,不应该出错才对。查了网上的一些文章,发现下面的这个解释还是比较可行的。

  • 现有 main 主仓库,里面有子模块对应的 sub 仓库。用户修改了 sub 中的文件,但没有提交到 sub 的远程库,然后把 main 提交到了远程库。现在,另外一个人尝试把 main 拉去下来并同步 sub 中的修改时,由于 sub 的改动并未 push 到其对应的远程库,但 update 命令尝试从 sub 的远程库 pull 对应的改动,因此也就不存在,就会报错。

  • 所以如果你在 main 仓库中修改了 sub 子模块,记得一定要先 push sub 中的修改,再 push main 中的修改,否则别人 update 的时候会报错哦!


  • [1] 小明初始化 mainsub 项目仓库
# 初始化main仓库
$ mkdir /data/main; cd main; git init
Initialized empty Git repository in ~/main/.git/

$ touch README.md && git add .
$ git commit -m "add README"
$ git remote add origin [email protected]:escape/main.git
$ git push -u origin master
# 初始化sub仓库
$ mkdir /data/sub; cd ../sub; git init
Initialized empty Git repository in ~/sub/.git/

$ touch README.md && git add .
$ git commit -m "add README"
$ git remote add origin [email protected]:escape/sub.git
$ git push -u origin master
  • [2] 小明在 main 仓库中添加 sub 仓库作为子模块
$ cd /data/main
$ git submodule add [email protected]:escape/sub.git sub
Cloning into '~/main/sub'...
done.

$ git commit -am "Added submodule sub"
[master (root-commit) 74f4d5f] Added submodule sub
 2 files changed, 4 insertions(+)
 create mode 100644 .gitmodules
 create mode 160000 sub
  • [3] 小明在 main 主仓库中修改了 sub 仓库的内容
$ cd /data/main/sub
$ echo "Monkey patch" >> README.md

$ git commit -am "Local hotfix"
[master b84f2c0] Local hotfix
 1 file changed, 1 insertion(+)

$ cd ..
$ git status
    # xxxxx
    modified:   sub (new commits)

$ git commit -am "add some files sub-module"
[master a4e419f] add some files sub-module
 1 file changed, 1 insertion(+), 1 deletion(-)
  • [4] 小明把 main 仓库提交到了远程服务器上
$ git push
  • [5] 小黄 clonemain 仓库的代码
# 拉主仓库
$ git clone [email protected]:escape/main.git

# 拉子模块
$ cd main
$ git submodule init
Submodule 'sub' ([email protected]:elixiao/sub) registered for path 'sub'
$ git submodule update
报了上面的错 ❌❌❌
  • [6] 小明把 main 仓库中对子模块 sub 的修改提交到远程仓库
$ cd /data/main/sub
$ git push
  • [7] 小黄再 clone 下来的 main 仓库 update 即可修复
$ cd /data/main
$ git submodule update
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From 115.28.xx.17:elixiao/sub
   dc3bc98..16f38a2  master     -> origin/master
Submodule path 'sub': checked out '16f38a223583f6771843c2a3333377e7219119a2'

  • 今天还发现有一种情况也会导致出现上述的报错(主项目中记录的 submoduleHEAD 超前,导致找不到指定的 commit 信息),还是提交代码的时候姿势不对,解决方案如下所示。
# 使用如下命令合并子模块到最新版
$ git submodule update --remote --merge <sub_module>

# 提交对应的修改
$ git add .
$ git commit -m "Update submodule to xxx."

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !