22

我已经将一个 Git 存储库(包含几个子模块)移动到本地磁盘上的另一个目录。任何 git 命令都会产生错误:

fatal: Not a git repository: <absolute path to .git/modules/*>

该错误源于在不同位置编码的文件的绝对路径[1]。两个问题:

  • 是否有用于修复这些路径的 Git 命令,即,使它们相对?[2]
  • 有没有办法确保未来的 Git 存储库只使用相对路径?[3]

谢谢!


笔记

  1. 我注意到对于所有子模块,该.git文件包含:

    gitdir: <absolute path to repository>
    

    core.worktree每个子模块 ( ) 中的参数.git/modules/*/config设置为该子模块的绝对路径。

  2. 我不是在寻找 shell 命令,而是在寻找原生 Git 方法。

  3. 我不确定绝对路径是否是使用较旧版本的 Git 创建的,而较新版本的 Git 则采用了相对路径。

4

4 回答 4

7

我写了一个将任何 .git gitdir 文件更改为相对路径的 oneliner(需要 bash 和 coreutils):

find -type f -name .git -exec bash -c 'f="{}"; cd $(dirname $f); echo "gitdir: $(realpath --relative-to=. $(cut -d" " -f2 .git))" > .git' \;

如果你不喜欢这里有 git 子模块:

git submodule foreach --recursive '[[ -f .git ]] && echo "gitdir: $(realpath --relative-to=. $(cut -d" " -f2 .git))" > .git'
于 2016-07-20T19:49:29.727 回答
4

@r3dey3 适用于 Windows 的解决方案:

git submodule foreach --recursive '[[ -f .git ]] && chmod +w .git && echo "gitdir: $(realpath --relative-to=. "$(cygpath -u "$(cut -d" " -f2 .git)")")" > .git'

在这里我补充说:

  • chmod +w .git删除只读属性
  • cygpath -u调用将 Windows 路径转换为 ​​Unix 路径
于 2016-12-02T12:54:56.463 回答
0

我遇到了同样的问题。

这是我编写的一个小脚本的要点,可能会有所帮助。

通过将路径转换为相对形式并不能真正解决问题,但它会在相关位置进行快速搜索和替换,从而使您可以修复所有问题。如果您正在处理一组复杂的子模块,其中可能有很多需要修复的路径,则特别方便。

请注意,我自己在 OS X 10.8 上使用过这个脚本,但我不能 100% 确定它在所有情况下都有效,所以要小心并采取明智的预防措施!

https://gist.github.com/3394771

于 2012-08-19T13:48:20.247 回答
0

以下命令将所有子模块的路径转换为相对路径(即使gitdir子模块.git文件中的值错误或为空,它也可以使用,因此即使将存储库移动到新位置也可以使用该命令):

for module in $(dirname $(find .git/modules -type f -name description)); do
    git="$(echo $module | cut -d/ -f2- | perl -pe "s|modules/||g")/.git"
    if [[ -e $git ]]; then
        echo "gitdir: $(realpath --relative-to=$(dirname $git) $module)" > $git
    fi
done

它需要从存储库根目录(.git 目录所在的位置)执行。

我使用 PyTorch 存储库对其进行了测试,该存储库不仅具有子模块,甚至还有子模块的子模块,并且按预期工作。为了确保它在不写入文件的情况下检测到正确的路径,您可以通过替换>.(或其他没有特殊含义的符号)来执行“试运行”。如果一切正常,则使用>实际编写更改。

于 2021-02-23T18:44:28.437 回答