サブモジュールでサブディレクトリを別のGitリポジトリに分割する
-
25-09-2019 - |
質問
質問のサブセットとして デタッチサブディレクトリ すでに作成されており、GITリポジトリの分割とマージのプロセスについて多くの質問がなされたとしても、サブモジュールが存在するときに分割の主題に触れるものを見つけることができなかったという事実を考慮してください。
したがって、次のシナリオでは:
.git/
.gitmodules
folder/
data/
content/
other_data/
submoduleA/
submoduleB/
次の構造で2つのリポジトリを取得したいと思います。
.git/
data/
と
.git/
.gitmodules
content/
other_data/
submoduleA/
submoduleB/
最初のケースは問題ではなく、で説明されている方法で簡単に解決できます デタッチサブディレクトリ.
2番目はそれほどではありません。サブモジュールの存在と、.gitmodulesにのフルパスが含まれているという事実 folder/content/submoduleA
と folder/content/submoduleB
.gitmodulesは存在しないディレクトリ構造を指すため、履歴の一部は一貫性がありません(フィルターブランチが使用されると)。
ですから、一貫性のない歴史を引き起こすことなく、これを行う方法があるかどうかを知りたいと思います。
解決
私はその秒であると疑っています(テストされていません) git filter-branch
変更する機会があります .gitmodules
新しいリポジトリの各コミットのコンテンツ。
しかし、実際には git submodule split
コマンドは2009年初頭に議論されました.
提案された使用法:
git submodule split [--url submodule_repo_url] submodule_dir \
[alternate_dir...]
交換
submodule_dir
新しく作成されたサブモジュールで、のすべての歴史を維持しますsubmodule_dir
.
また、このコマンドは、現在のリポジトリの履歴における各コミットを書き直して、の正しい改訂を含めるようにしますsumodule_dir
そして適切です.gitmodules
エントリ。
しかし、私はそれを見ていません 最新の料理は何ですか.
提案されたパッチのスクリプトは、更新するために必要なツリーの書き換えのアイデアを提供できます .gitmodules
ただし、ファイル。
他のヒント
私は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
ご覧のとおり、トリックは一時的に名前を変更することです .gitmodules
ファイルと使用 sed
そのコンテンツを書き換える。すべての詳細を取得できます 私のブログでのこの手順のコンテキスト.
ケビンの答えについて詳しく説明するために:外にサブモジュールが存在しなかったと仮定する cool/cavemen
- デタッチされているフォルダー(それ以外の場合は、それらの追加セクションを削除するために.gitmodulesのより精巧な編集が必要です)、これを達成できます 多くの より速く、anを使用して1つのステップで 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
追加の利点として、if cool/cavemen
すべての改訂または支店には存在しませんでした。 cool/cavemen
見られます。
これがケースの場合は、変更されていない参照を削除するために以下を実行することをお勧めします。
$ 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