将包含子模块的子目录拆分到单独的git存储库中

uno*_*ode 6 git git-filter-branch

作为之前已经提出的问题detach-subdirectory的一个子集,并考虑到这样一个事实,即尽管有很多关于拆分和合并git存储库的过程的问题,但是当子模块存在时,我找不到触及拆分主题的问题.当下.

所以在以下场景中:

.git/
.gitmodules
folder/
    data/
    content/
        other_data/
        submoduleA/
        submoduleB/
Run Code Online (Sandbox Code Playgroud)

我想获得两个具有以下结构的存储库:

.git/
data/
Run Code Online (Sandbox Code Playgroud)

.git/
.gitmodules
content/
    other_data/
    submoduleA/
    submoduleB/
Run Code Online (Sandbox Code Playgroud)

第一种情况不是问题,可以使用detach-subdirectory中描述的方法轻松解决.

第二个不是那么多.子模块的存在以及.gitmodules包含完整路径folder/content/submoduleAfolder/content/submoduleB导致部分历史记录不一致的事实,因为.gitmodules引用了一个不存在的目录结构(一旦使用了filter-branch).

所以我想知道是否有办法做到这一点,而不会导致不一致的历史记录.

小智 6

我有与Unode完全相同的问题,并设法使用以下过程解决它:

git clone git@github.com:kdeldycke/kev-code.git
cd kev-code
git filter-branch --tree-filter "test -f ./.gitmodules && mv ./.gitmodules ./cool-cavemen/gitmodules || echo 'No .gitmodules file found'" -- --all
git filter-branch --force --prune-empty --subdirectory-filter cool-cavemen --tag-name-filter cat -- --all init..HEAD
git filter-branch --force --tree-filter "test -f ./gitmodules && mv ./gitmodules ./.gitmodules || echo 'No gitmodules file found'" -- --all
git filter-branch --force --tree-filter "test -f ./.gitmodules && sed -i 's/cool-cavemen\///g' ./.gitmodules || echo 'No .gitmodules file found'" -- --all
git remote rm origin
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
git remote add origin git@github.com:kdeldycke/cool-cavemen.git
git push -u origin master --force --tags
Run Code Online (Sandbox Code Playgroud)

如您所见,诀窍是暂时重命名该.gitmodules文件并用于sed重写其内容.您可以在我的博客上获取此过程的所有详细信息和上下文.


Von*_*onC 2

我怀疑(未测试)第二个git filter-branch将有机会修改.gitmodules新存储库的每次提交的内容。

但事实上,git submodule split2009 年初就有人在讨论一项命令

建议用途:

git submodule split [--url submodule_repo_url] submodule_dir \
    [alternate_dir...]
Run Code Online (Sandbox Code Playgroud)

替换submodule_dir为新创建的子模块,保留submodule_dir.
此命令还会重写当前存储库历史记录中的每个提交,以包含正确的修订版本sumodule_dir和适当的.gitmodules条目。

但是,我在最新的“What's Cooking”中没有看到它。
提议的补丁中的脚本可以让您了解更新文件所需的树重写类型.gitmodules