代码之家  ›  专栏  ›  技术社区  ›  unode

将带有子模块的子目录拆分为单独的git存储库

  •  6
  • unode  · 技术社区  · 14 年前

    detach-subdirectory

    所以在下面的场景中:

    .git/
    .gitmodules
    folder/
        data/
        content/
            other_data/
            submoduleA/
            submoduleB/
    

    .git/
    data/
    

    .git/
    .gitmodules
    content/
        other_data/
        submoduleA/
        submoduleB/
    

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

    第二个不是那么多。子模块的存在以及.gitmodules包含 folder/content/submoduleA folder/content/submoduleB 导致部分历史不一致,因为.gitmodules引用了不存在的目录结构(一旦使用了筛选器分支)。

    所以我想知道,是否有一种方法可以做到这一点,而不会造成前后矛盾的历史。

    3 回复  |  直到 7 年前
        1
  •  1
  •   VonC    14 年前

    我怀疑(没有测试)那一秒 git filter-branch 会有机会修改 .gitmodules

    但事实上 git submodule split command was in discussion early 2009 .

    git submodule split [--url submodule_repo_url] submodule_dir \
        [alternate_dir...]
    

    替换 submodule_dir 使用新创建的子模块,保留 子模块\u目录
    sumodule_dir 以及适当的 .git模块 条目。

    不过,我在报纸上看不到 latest what's cooking .
    .git模块 不过要归档。

        2
  •  6
  •   user487610 user487610    13 年前

    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
    

    如您所见,诀窍是临时重命名 .gitmodules sed 重写它的内容。你可以得到所有的细节和 context of this procedure on my blog .

        3
  •  0
  •   Levi Haskell    9 年前

    cool/cavemen 要分离的文件夹(否则需要对.gitmodules进行更详细的编辑以删除这些额外的部分)可以实现这一点 使用 index-filter :

    $ git filter-branch --subdirectory-filter cool/cavemen --index-filter $'
    hash=$(git rev-parse --verify $GIT_COMMIT:.gitmodules 2>/dev/null) &&
     git update-index --add --cacheinfo 100644 $(git cat-file -p $hash |
     sed \'s/cool\\/cavemen\\///g\' | git hash-object -w --stdin) .gitmodules ||
    true' --tag-name-filter cat --prune-empty -- --all
    

    酷/穴居人 酷/穴居人 将被查看。

    $ git for-each-ref --format='%(refname)' | 
     grep -vF "$(git for-each-ref --format='%(refname)' refs/original |
     sed 's/refs\/original\///g')" | xargs -n 1 git update-ref -d