メインプロジェクト内のサブプロジェクトを管理するために、git-subtree拡張機能(https://github.com/apenwarr/git-subtree )を使用しています。サブプロジェクトに加えられた変更をメインプロジェクトから分割しようとすると失敗するという事実以外は、私が望んでいることを正確に実行しています。
たとえば、以前に私がやった
git subtree add -P Some/Sub/Dir --squash git@gitserver:lib.git master
メインプロジェクトのSome/Sub/Dirにライブラリコードを取り込みます。ここのすべてがうまくいったので、私は変更を中央のメインプロジェクトの裸のgitリポジトリにプッシュしました。次に、Some / Sub / Dirでローカルバージョンのライブラリに変更を加え、コミットしてから分割して、lib.gitリポジトリにプッシュすることにしました。
git subtree split -P Some/Sub/Dir -b some_branch
すべてが期待どおりに機能します。リポジトリのローカルコピーはもう必要ありません。削除しました。
中央リポジトリからリポジトリの新しいコピーを複製した後、Some / Sub / Dirのlibにいくつかの変更を加え、それらの変更を分割してlib.gitリポジトリにプッシュバックすることにしました。以前と同じサブツリー分割コマンドを使用しようとしましたが、今回は次の出力になります。
1/ 3 (0)
2/ 3 (1)
3/ 3 (1)
fatal: bad object d76a03f0ec7e20724bcfa253e6a03683211a7bb1
d76a03f0ec7e20724bcfa253e6a03683211a7bb1は、サブツリーを追加したときのものです。
commit 43b3eb7d69d5eb64241eddb12e5bd74fd0215083
Author: Ian Bond <ibond@onezero.com>
Date: Fri Apr 22 15:06:50 2011 -0400
Squashed 'Subtree/librepoLib/' content from commit d76a03f
git-subtree-dir: Subtree/librepoLib
git-subtree-split: d76a03f0ec7e20724bcfa253e6a03683211a7bb1
これは実際にはlib.gitリポジトリのコミットを指します。
私がつなぎ合わせることができたのは(そして私はgit noobなので、間違っているか、何かを見落としているか、ここで間違った用語を使用している可能性があります)、「git subtree add --squash」は、リモートのlib.gitレポジトリを現在のレポジトリに押し込み、別のコミットに押しつぶしてから、そのコミットを作業ブランチに追加します。lib.gitのコミット履歴は現在のリポジトリに残りますが、スカッシュコミットのテキスト以外では実際に参照されていないため、コミットがぶら下がっています。それらのぶら下がりコミットが残っている限り、git-subtreeはそれらを使用して分割を実行できますが、プッシュまたはプルにはぶら下がりオブジェクトが含まれていないため(または、gcを実行してぶら下がりオブジェクトを完全に削除した場合)、それらのぶら下がりコミットは失われ、 git-subtreeには、分割を実行するために必要な情報がありません。
私が抱えていた問題を完全に再現するスクリプトを追加しました。
私の質問は次のとおりです。
1)元のリポジトリにマージしたいサブツリーがあり、それらをリンクする履歴がなくなったという既存の状況を処理するにはどうすればよいですか。私の現在の考えは、次のようなことをすることです。
git subtree split -P Some/Sub/Dir 43b3eb7^.. --ignore-joins -b splitBranch
'git subtree add'以降のすべての履歴を分割し、元のリポジトリにマージして戻します(ありがたいことに、追加以降、変更はありません)。これが最善の方法ですか?マージを実行する方法に関する推奨事項はありますか?
2) git-subtreeを期待どおりに機能させるためにできることはありますか?'git subtree add'の--squashパラメーターを省略すると、すべてが機能すると思いますが、それにより、無関係な履歴の束がリポジトリに挿入されます。必要なコミットを維持する方法はありますか(できれば、ライブラリの履歴全体を維持することなく)?