与“ git子模块吸收gitdirs”相反/相反?

gen*_*ult 7 git git-submodules

我该怎么做git submodule absorbgitdirs呢?即将子模块的.git信息移出目录superproject/.git/modules/<module>并移回superproject/path/to/<module>/.git目录?

我还是想<module>成为的一个子模块superproject,我只是不想<module>.git目录信息superprojects'的.git/modules目录。

Meh*_*dad 8

我写了一个脚本来执行此操作。将其添加到您的~/.gitconfig

[alias]
    extract-submodules = "!gitextractsubmodules() { set -e && { if [ 0 -lt \"$#\" ]; then printf \"%s\\n\" \"$@\"; else git ls-files --stage | sed -n \"s/^160000 [a-fA-F0-9]\\+ [0-9]\\+\\s*//p\"; fi; } | { local path && while read -r path; do if [ -f \"${path}/.git\" ]; then local git_dir && git_dir=\"$(git -C \"${path}\" rev-parse --absolute-git-dir)\" && if [ -d \"${git_dir}\" ]; then printf \"%s\t%s\n\" \"${git_dir}\" \"${path}/.git\" && mv --no-target-directory --backup=simple -- \"${git_dir}\" \"${path}/.git\" && git --work-tree=\"${path}\" --git-dir=\"${path}/.git\" config --local --path --unset core.worktree && rm -f -- \"${path}/.git~\" && if 1>&- command -v attrib.exe; then MSYS2_ARG_CONV_EXCL=\"*\" attrib.exe \"+H\" \"/D\" \"${path}/.git\"; fi; fi; fi; done; }; } && gitextractsubmodules"
Run Code Online (Sandbox Code Playgroud)

然后运行:

git extract-submodules [<path>...]
Run Code Online (Sandbox Code Playgroud)

如果您在不指定任何子模块的情况下运行它,它将提取所有子模块。


如果你想看看代码在做什么,只需更改

&& gitextractsubmodules
Run Code Online (Sandbox Code Playgroud)

最后到

&& type gitextractsubmodules
Run Code Online (Sandbox Code Playgroud)

然后运行不带参数的命令以使 Bash 漂亮地打印函数体。

  • 我已将此单行代码清理为人类可读的 posix 脚本,并添加了对嵌套子模块的支持。https://gist.github.com/Jamesits/64f9daf3f9467a8aee9a1a5c6e970ea3 (2认同)

Von*_*onC 5

请注意,这将使superproject / path / to //成为嵌套的Git存储库,其SHA1仍将由父项目记录。

要保持完全相同的状态,您可以复制superproject/.git/modules/<module>并重命名为superproject/path/to/<module>,然后重命名<module>/<module><module>/.git

然后,您可以使用git submodule deinit删除子模块:

mv asubmodule asubmodule_tmp
git submodule deinit -f -- a/submodule    
rm -rf .git/modules/a/submodule

# if you want to leave it in your working tree
git rm --cached asubmodule
mv asubmodule_tmp asubmodule
Run Code Online (Sandbox Code Playgroud)

我仍然想成为superprojec的子模块

然后它的.git文件夹将在superproject/.git/modules/<module>

子模块absorbgitdirs没有任何选择:

如果子模块的git目录位于子模块内部,请将子模块的git目录移动到其superprojects $GIT_DIR/modules路径中,然后通过设置core.worktree并添加一个.git指向超级项目git中嵌入的git目录的文件来连接git目录及其工作目录目录。

我看不到git config任何可能移动的配置$GIT_DI R/modules

absorbgitdirs是在Git 2.12的commit f6f8586中引入的(2016年第四季度)。
它的测试表明它希望使用GIT_DIR/modules

较旧的Git( 2011年10月Git 1.7.8之前.git直接位于submodule文件夹内。

  • @genpfault 是的:旧版本的 Git 将 .git 直接放在子模块文件夹中。 (2认同)
  • @CBBailey:另一种情况发生在构建脚本向 Git 查询版本控制标签(例如“gitdescribe”)时,但它们不可用,因为父 gitdir 不可用(例如在单独的 Docker 上下文中构建)。 (2认同)
  • 另一个用例是,如果您使用 Docker 容器在子模块内使用 git 命令,则容器看不到超级项目并出错。:( (2认同)