我从不期望重命名git repo,更具体地说,是顶级文件夹保存项目,会非常困难。是的,项目包含一些子模块,但需要重命名的是顶级文件夹,而不是子模块文件夹。 Git似乎在其子模块机制中记录了一些奇怪的绝对路径。
我们假设
/tmp
。proj_master
和proj_mod
。porj_master
克隆为proj_ALL
,然后将prom_mod
克隆为其中的子模块。proj_ALL
重命名为proj_onebillion
。然后发生黑魔法。以下步骤将重现我提到的问题。我使用的git版本是:
$ git --version
git version 1.7.9.5
初始化proj_master
。
$ cd /tmp
$ mkdir proj_master; cd proj_master
$ git init .
$ touch README
$ git add .; git commit -m "hello proj_master"
初始化proj_mod
。
$ cd /tmp
$ mkdir proj_mod; cd proj_mod
$ git init .
$ touch README
$ git add .; git commit -m "hello proj_mod"
将proj_master
克隆为proj_ALL
并克隆proj_mod
作为子模块。
$ cd /tmp
$ git clone proj_master proj_ALL
$ cd proj_ALL
$ git submodule add /tmp/proj_mod ./mod
$ git add .; git commit -m "hello proj_ALL"
$ git status % Everything is OK.
将proj_ALL
重命名为proj_onebillion
。遇到致命的错误。
$ cd /tmp
$ mv proj_ALL proj_onebillion
$ cd proj_onebillion
$ git status
fatal: Not a git repository: /tmp/proj_ALL/.git/modules/mod
需要注意的一件事是子模块目录中的.git
文件。
$ cat /tmp/proj_ALL/mod/.git
gitdir: /tmp/proj_ALL/.git/modules/mod
是的,绝对的道路。我第一次意识到git知道顶级repo文件夹范围之外的东西。
就是这样。我再重复一次,我重命名顶级项目文件夹,而不是子模块文件夹。我检查了schmuck's question,它试图重命名子模块文件夹,因此对我的问题似乎没那么有帮助。
如果我错过了之前应该阅读的内容,我会道歉。对所有人来说,欢迎任何建议。
答案 0 :(得分:12)
你有几个选择,他们最终是同一件事:
再次克隆
而不是重命名文件夹 - 只需再次克隆
$ cd /project/original
$ cd ..
$ mkdir moved
$ git init
$ git pull ../original master
$ git submodule init
$ git submodule update
将original/.git/config
与moved/.git/config
进行比较并解决任何重大差异(missing branches need creating - 丢失的遥控器只需要添加到配置文件中)。
修复路径
您可以重命名项目文件夹,只需要稍微调整一下。
即。这些文件:
$ cd /project/moved
$ find -name .git -type f
您需要做的就是编辑它们以指向正确的目录
即。这些文件:
$ cd /project/moved
$ find .git/modules/ -name config
在此处,更新worktree
设置:
[core]
...
worktree = /original/path/submodule
要
[core]
...
worktree = /moved/path/submodule
就是这样。
关于版本的说明
1.7.8为子模块和used absolute paths引入了.git文件的使用,这已在1.7.10中修复 - 因此该问题仅适用于使用git 1.7.8和1.7创建的git repos。 9。
答案 1 :(得分:5)
将具有git子模块的项目从一个文件夹移动到另一个文件夹时,在同一台机器上,有一些必须更新的硬编码链接。
首先,所有子模块都有一个.git文件,它存储了git配置文件夹的绝对路径(这些文件位于main的项目.git文件夹中,分组到modules文件夹中)。要解决所有这些问题,请从主项目的根目录运行以下命令:
find . -name .git -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'
其次,git子模块的配置文件有一行保存工作目录,也是绝对的。要一次更新所有引用,请从主项目的根目录运行以下命令:
find . -name config -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'
假设您的操作系统是某种形式的* nix,并且您已安装了sed软件包。
答案 2 :(得分:4)
您还需要检查每个子模块的gitdir
。
它应该在子模块的文件夹.git
文件中。
答案 3 :(得分:1)
您需要实际修改两个文件
.git/modules/<path-to-submodule>/config
<path-to-submodule>/.git