如何重命名包含子目录中子模块的git repo(项目)

Jia*_* W. 19 git git-submodules

我从不期望重命名git repo,更具体地说,它是顶级文件夹保存项目,会非常困难.是的,项目包含一些子模块,但它是需要重命名的顶级文件夹,而不是子模块文件夹.Git似乎在其子模块机制中记录了一些奇怪的绝对路径.

让我们假设一下

  1. 你所有的项目都在/tmp.
  2. 你有一个proj_masterproj_mod.
  3. 您克隆porj_master,proj_ALL然后克隆prom_mod为其中的子模块.
  4. 你重命名proj_ALLproj_onebillion.然后黑魔法发生了.

以下步骤将重现我提到的问题.我使用的git版本是:

$ git --version
git version 1.7.9.5
Run Code Online (Sandbox Code Playgroud)
  1. 初始化proj_master.

    $ cd /tmp
    $ mkdir proj_master; cd proj_master
    $ git init .
    $ touch README
    $ git add .; git commit -m "hello proj_master"
    
    Run Code Online (Sandbox Code Playgroud)
  2. 初始化proj_mod.

    $ cd /tmp
    $ mkdir proj_mod; cd proj_mod
    $ git init .
    $ touch README
    $ git add .; git commit -m "hello proj_mod"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 克隆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.
    
    Run Code Online (Sandbox Code Playgroud)
  4. 重命名proj_ALLproj_onebillion.遇到致命错误.

    $ cd /tmp
    $ mv proj_ALL proj_onebillion
    $ cd proj_onebillion
    $ git status
    fatal: Not a git repository: /tmp/proj_ALL/.git/modules/mod
    
    Run Code Online (Sandbox Code Playgroud)

需要注意的一件事是.git子模块目录中的文件.

$ cat /tmp/proj_ALL/mod/.git 
gitdir: /tmp/proj_ALL/.git/modules/mod
Run Code Online (Sandbox Code Playgroud)

是的,绝对的道路.我第一次意识到git知道顶级repo文件夹范围之外的东西.

而已.我再重复一次,我重命名顶级项目文件夹,而不是子模块文件夹.我检查了schmuck的问题,它试图重命名子模块文件夹,因此对我的问题似乎没那么有帮助.

如果我错过了之前应该阅读的内容,我会道歉.对所有人来说,欢迎任何建议.

AD7*_*six 12

你有几个选择,他们最终是同一件事:

再次克隆

而不是重命名文件夹 - 只需再次克隆

$ cd /project/original
$ cd ..
$ mkdir moved
$ git init
$ git pull ../original master
$ git submodule init
$ git submodule update
Run Code Online (Sandbox Code Playgroud)

比较original/.git/configmoved/.git/config并解决任何显著差异(缺少分支机构需要在创建 -丢失的遥控器只需要添加到配置文件).

修复路径

您可以重命名项目文件夹,只需稍微调整即可.

  • 修复子模块.git文件引用.

即这些文件:

$ cd /project/moved
$ find -name .git -type f
Run Code Online (Sandbox Code Playgroud)

您需要做的就是编辑它们以指向正确的目录

  • 修复子模块.git配置文件

即这些文件:

$ cd /project/moved
$ find .git/modules/ -name config
Run Code Online (Sandbox Code Playgroud)

在这里,更新worktree设置:

[core]
    ...
    worktree = /original/path/submodule
Run Code Online (Sandbox Code Playgroud)

[core]
    ...
    worktree = /moved/path/submodule
Run Code Online (Sandbox Code Playgroud)

就是这样.

关于版本的说明

1.7.8为子模块引入了.git文件的使用并使用了绝对路径,这在1.7.10中得到了修复 - 因此该问题仅适用于使用git 1.7.8和1.7.9创建的git repos.


小智 5

将具有git子模块的项目从一个文件夹移动到另一个文件夹时,在同一台计算机上,有一些必须更新的硬编码链接.

首先,所有子模块都有一个.git文件,它存储了git配置文件夹的绝对路径(这些文件位于main的项目.git文件夹中,分组到modules文件夹中).要修复所有这些,请从主项目的根目录运行以下命令:

find . -name .git -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'
Run Code Online (Sandbox Code Playgroud)

其次,git子模块的配置文件有一行保存工作目录,也是绝对的.要一次更新所有引用,请从主项目的根目录运行以下命令:

find . -name config -print0 -type f | xargs -0 sed -i 's|<OLD PATH>|<NEW PATH>|g'
Run Code Online (Sandbox Code Playgroud)

假设你的操作系统是某种形式的*nix,并且你已经安装了sed软件包.