19

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

让我们假设

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

以下步骤将重现我提到的问题。我使用的 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_masterproj_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_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
    

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

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

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

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

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

4

4 回答 4

12

你有几个选择,它们最终是一样的:

再次克隆

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

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

比较original/.git/configmoved/.git/config解决任何显着差异(缺少的分支需要创建- 缺少的遥控器只需要添加到配置文件中)。

修复路径

您可以重命名您的项目文件夹,它只需要稍作调整。

  • 修复您的子模块 .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 引入了对子模块使用 .git 文件并使用绝对路径,这在 1.7.10 中已修复 - 因此问题仅适用于使用 git 版本 1.7.8 和 1.7.9 创建的 git repos。

于 2012-05-19T17:00:32.337 回答
5

将具有 git 子模块的项目从一个文件夹移动到另一个文件夹时,在同一台机器上,有一些硬编码的链接需要更新。

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

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。

于 2013-07-02T16:18:34.230 回答
4

您还需要检查每个子模块的gitdir.

它应该在子模块的文件夹.git文件中。

于 2012-10-15T04:29:20.163 回答
1

您需要实际修改两个文件

.git/modules/<path-to-submodule>/config
<path-to-submodule>/.git
于 2014-05-06T14:38:00.060 回答