私のプロジェクトにはいくつかの依存関係があります。 ほとんどの依存関係はgitリポジトリにあります。 プロジェクト自体もギタに住んでいます。
使用しているライブラリの1つは頻繁に更新されます。 私たちは開発バージョンに座っており、多くの場合、プロジェクトが必要とするコードに起因すると考えています。 つまり、このライブラリのメインリポジトリの編集をすばやくスキップする必要があります。多くの理由でフォークを作成および維持する必要はありません。
以前は、プロジェクトフォルダに依存関係をコピーし、VERSION.TXTファイルとそのバージョンをそれぞれに追加しました。 しかし、サードパーティのコードの現在のバージョンで作業する必要がある場合、これは不便です。 はい、そしてgitがあるときに手でファイルをコピーするのはなんとなく馬鹿げています。 もっと現代的な解決策を見つけたいです。
サードパーティのリポジトリを操作するためのgitの最も宣伝されているファッショナブルな機能は、 gitサブモジュール (「サブモジュール」)です。 当然、まず第一に、私は彼女を見始めました。
その前に、私はすでに「ホーム」プロジェクトのサブモジュールで作業しようとしました。 1人がリポジトリを慎重に使用する限り、特別な問題はありません。 いずれにせよ、コードを手でコピーするよりも著しく便利です。
しかし、自分の経験をより深刻なワークフローに移行しようとするとすぐに、すべてがそれほど単純ではないことが判明しました。
これは私たちが直面しているものです:
- メインリポジトリで作業する各人は、サブモジュールの取得元のリポジトリにアクセスできる必要があります。
- 一般的な場合、1つのコマンドで完全な作業コピーを取得することはできません。 git checkoutの後、git submodule update --initを実行する必要があります。
- 同じことがgitの他のコマンドにも当てはまります。 たとえば、git archiveはサブモジュールを無視します-1つのコマンドでプロジェクト全体をアーカイブにパックすることはできなくなりました。
- 最上位プロジェクトからは、サブモジュール内に変更は表示されず、逆も同様です。 プロジェクトの作業コピーの完全な状態を確認するには、各サブモジュールと親プロジェクトに対して個別に要求する必要があります。 サブモジュールがなければ、作業コピー内の任意の場所でgit statusを言うだけで十分です。
- サブモジュールのルートディレクトリを別のもの(たとえば、別のサブモジュール)に置き換えた後、すべての作業コピーで古いバージョンを手動で削除する必要があります。
- git submoduleコマンドは、標準オプション--git-dirおよび--work-treeを理解しません。 作業コピーのルートからのみ実行できます。 これにより、自動化が困難になります。
サブモジュールは放棄されなければなりませんでした。
しかし、銀の裏地はありません。 知識のある人々 は 、長い間(1.5.2の前でさえも) gitに代替ソリューション- サブツリーマージ戦略 (「サブツリー」) があることを提案しました。
アイデアは、外部プロジェクトからコミット履歴を取得し、内部プロジェクトのサブディレクトリにリダイレクトすることです。 この場合、外部ブランチを操作するための標準のgitメカニズムが使用されます。
ドキュメントの例:Bprojectリポジトリのmasterブランチ(/ path / to / Bにある)からdir-B /サブディレクトリのプロジェクトにコードを追加します。
$ git remote add -f Bproject /path/to/B
$ git merge -s ours --no-commit Bproject/master
$ git read-tree --prefix=dir-B/ -u Bproject/master
$ git commit -m "Merge B project as our subdirectory"
git remote addの-fスイッチに注意する必要があります。 彼はgitにこのリモートをすぐに取得するように指示します。
さらに、Bprojectへの変更はgit pullコマンドによってプルされ、目的のブランチとマージ戦略が明示的に示されます。
$ git pull -s subtree Bproject master
対応するリモートサブツリーが作業コピーに追加されない場合、変更のプル元のブランチの名前はメインリポジトリの履歴に表示されません。
この問題は純粋に表面的なものであり、作業には影響しません。 このリモートを作業コピーに追加することで処理されます。
$ git remote add -f Bproject /path/to/B
将来、新しいブランチが表示された場合、リモートで変更をプルアップできます。
$ git fetch Bproject
さらにいくつかの欠点があります。
- 通常のブランチマージの場合と同様に、コミットログでは、サブツリーの履歴がメインプロジェクトの履歴と混合されます。
- サブツリープロジェクトへの変更の送信は、サブモジュールの場合よりもはるかに困難です。 しかし、これはこのプロジェクトの別のクローンに変更を加えることで簡単に回避できます。
サブツリーでの作業は、サブモジュールでの作業よりもはるかに便利です。 ユーザーを再トレーニングする必要はありません。自動化する方が簡単です。 サブツリーは保守が簡単です。 お勧めです。
ところで、Githubにはサブツリーを使用した作業の開発を目的としたプロジェクトgit-subtreeがあります。
追加の読み物: