移动包含子模块的Git工作副本

8
最近Git的一次更改改变了在使用子模块时处理.git目录的方式。现在不再是每个子模块都有一个.git目录,而是一切都在“根层级”.git目录中(对应于包括子模块的工作副本)。
然后,在每个子模块中,会创建一个文件来指向新位置的.git目录。
我的项目中,有以下.gitmodules文件:
[submodule "tests/shared-tests"]
        path = tests/shared-tests
        url = git://github.com/roboptim/roboptim-shared-tests.git
[submodule "cmake"]
        path = cmake
        url = git://github.com/jrl-umi3218/jrl-cmakemodules.git

当我执行 git clone --recursive 命令时,我会得到以下结果:
$ cat cmake/.git
gitdir: /home/moulard/profiles/default-x86_64-linux-ubuntu-12.04.1/src/unstable/roboptim/roboptim-core/.git/modules/cmake

我目前使用的是Git 1.8.1.5版本。

我的问题是:

  1. 为什么这种行为发生了变化?我没有看到任何明显的利益与这种新策略。
  2. 那么我该如何安全地移动工作副本呢?(如果我移动工作副本,我会收到一个错误消息,告诉我损坏的gitdir路径不再是Git仓库)

请注意,这不同于之前的问题移动包含子模块的git存储库的父目录,因为我确定这不是由于我的.gitmodules文件中存在绝对路径所导致的问题。

2个回答

10
.git/module 组织结构最早可以追溯到 git1.7.8 (2011年12月2日)

使用 "git submodule init" 命令来填充新的子模块目录时,为子模块创建了一个 $GIT_DIR meta 信息目录,在超级项目的 $GIT_DIR/modules/<name>/ 目录中,并通过 gitfile 机制进行引用。
这样就可以在超级项目中切换具有和不具有树形子模块的提交版本,而无需重新克隆。

然而,最近的错误修复已经包含在 1.8.2.11.8.3 (2013年4月22日) 中:

"git submodule update" 在递归到子子模块时未能累加前缀路径。

因此,升级到最新的 git 发布版本可能会解决此问题。


这里,OP Thomas Moulard评论中 提到了一种可能的解决方案(使用最新的 git 1.8.3,2013年4月22日):

$ git submodule deinit -f . 可以解决问题!
然后我可以运行 git submodule init 命令来修正路径

这解决了 (de)initialization 步骤 (.git/modules)

但它并没有解决 'add' 步骤,即将子模块的 url 记录在 .gitmodules 文件中:您仍需要手动从该文件中删除相关记录。


实际上我已经尝试了最新版本的Git和主分支的HEAD,但是到目前为止还没有成功,除非有我不知道的git命令... - Thomas Moulard
@ThomasMoulard,你的情况下最新的版本是1.8.3吗? - VonC
抱歉,我误读了上一个版本。我尝试了最新的真实版本1.8.2.1,1.8.3已经在“RelNotes”中了,但是这个版本还没有标签。无论哪种情况,即使是“master”分支的HEAD(提交118f60ee),也无法解决这个问题。 - Thomas Moulard
不幸的是,在我的情况下:git rm -rf cmake 会产生以下结果:fatal: Not a git repository: /home/moulard/profiles/default-x86_64-linux-ubuntu-12.04.1/src/unstable/roboptim/roboptim-core/.git/modules/cmake(而且该目录仍然存在)。基本上,除非我手动编辑文件以修复路径,否则 git 完全无法使用。 - Thomas Moulard
在父存储库工作副本的根级别。[而且它是git rm而不是简单的rm] - Thomas Moulard
显示剩余6条评论

1
我把工作副本移动到其他地方后,成功地通过以下方式修复了它:
  • 更新superproject/path/to/submodule/.git文件中的gitdir:路径
  • 更新superproject/.git/modules/path/to/submodule/config文件中的worktree=路径

我不知道为什么git在那里使用绝对路径!

(已测试于 git 2.0.1.563)


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