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

时间:2012-05-19 16:11:18

标签: git git-submodules

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

我们假设

  1. 您的所有项目都位于/tmp
  2. 您有一个proj_masterproj_mod
  3. 您将porj_master克隆为proj_ALL,然后将prom_mod克隆为其中的子模块。
  4. 您将proj_ALL重命名为proj_onebillion。然后发生黑魔法。
  5. 以下步骤将重现我提到的问题。我使用的git版本是:

    $ git --version
    git version 1.7.9.5
    

    1. 初始化proj_master

      $ cd /tmp
      $ mkdir proj_master; cd proj_master
      $ git init .
      $ touch README
      $ git add .; git commit -m "hello proj_master"
      
    2. 初始化proj_mod

      $ cd /tmp
      $ mkdir proj_mod; cd proj_mod
      $ git init .
      $ touch README
      $ git add .; git commit -m "hello proj_mod"
      
    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.
      
    4. 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
      

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

      $ cat /tmp/proj_ALL/mod/.git 
      gitdir: /tmp/proj_ALL/.git/modules/mod
      

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

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

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

4 个答案:

答案 0 :(得分:12)

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

再次克隆

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

$ cd /project/original
$ cd ..
$ mkdir moved
$ git init
$ git pull ../original master
$ git submodule init
$ git submodule update

original/.git/configmoved/.git/config进行比较并解决任何重大差异(missing branches need creating - 丢失的遥控器只需要添加到配置文件中)。

修复路径

您可以重命名项目文件夹,只需要稍微调整一下。

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

即。这些文件:

$ cd /project/moved
$ find -name .git -type f

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

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

即。这些文件:

$ 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