この質問は、ここで提起された多くの質問と似ていますが、不快なほど異なります。
かつてsvnリポジトリだったgitリポジトリがあります(以前はcvsリポジトリでした)。1999年頃までさかのぼるデータが含まれています。
この 1 つのリポジトリを複数の異なるリポジトリに分割し、この豊富な履歴をすべて保存する時が来ました。ただし、リポジトリの構造は頻繁に変更されています。現在のすべてのプロジェクトは、基本プロジェクトから派生し、それがいくつかのプロジェクトに成長し、2 つのプロジェクトに縮小され、その後再び成長しました。コードは移動されましたが、複製されることはありませんでした。現在、いくつかの成熟したプロジェクトの 1 つで最終的な安息の地を見つけています。
これにより、履歴を保存したい場合、リポジトリの分割が非常に難しくなります。git-filter-branch を使用することは正しいアプローチのように思えますが、これらはすべて、リポジトリの一部をハッキングして履歴を切り捨てているようです。
EDIT ADDED明確にするために、ここに小さな例を示します。私はリポジトリのルートにいるふりをしています。リポジトリが次のようになっているとします。
foo/
bar/
file.txt
baz/
の内容を編集するとしfile.txt
ます。次に、名前を に変更しnewfile.txt
ます。その後、再度内容を編集します。次に、このファイルを との間で移動しbar/
ますbaz/
。私のリポジトリは次のようになります。
foo/
bar/
baz/
newfile.txt
baz/
では、独自のリポジトリに分割したいとしましょう。git filter-branch を使用するか、git subtree split を使用するとnewfile.txt
、それが内部にbar/
あり、名前が付けられたときのすべてのコミット メッセージと履歴が失われfile.txt
ます。
歴史的なリビジョンをチェックアウトするのは気が狂っているかもしれないことは理解しています。呼び出されたものを参照../bar/
するか、存在しない無効なディレクトリを参照して見事に失敗する可能性があります。特定のリビジョンでファイルの内容を見ることができる限り、私は気にしません。
編集終了
私がやりたいことには2つの道があるようです:
リポジトリをN回複製し、そのリポジトリに必要なフォルダーを保存し(git rm-ing他のフォルダーを介して)、最終的にHEADにあるファイルを参照しないリビジョンを何らかの方法でハックします。古いリビジョンをチェックアウトしても意味のあるコードベースが提供されないという点で、これにはいくつかのマイナスの副作用があることを認識しています-気にしません。これを行うには、HEAD に存在するすべてのファイルから派生するすべてのパスを取得する方法を見つける必要があります。これは、醜いスクリプトで行うことができます。
各インデックス中にリポジトリがどのように見えるかについて、ある種の履歴インデックスを作成します。ツリー フィルターを使用して、それぞれのリビジョンで一致しないファイルを切り取ります。次に、HEAD 内のファイルに表示されないファイルまたはその派生ファイルを削除します。
HEAD に表示されないすべてのファイルを見つけて、それらに関連する履歴を削除することは可能ですか? 長い間削除されていたファイルを復活させることは気にしません。これが私の問題の核心にあるようです。
代替ソリューションも高く評価されます。私は比較的 git に慣れていないので、明らかな何かが欠けている可能性があります。