github で特定のディレクトリ(またはファイル)について、そのコミット履歴を保持したまま、別のリポジトリの新しいフォルダ(サブディレクトリ)に取り込む方法をここにメモします。
履歴を保持して取り込む主な方法
「git subtree」の使用を検討しました。
Git Subtree を利用する方法
git subtree は、リポジトリBをリポジトリAの特定のサブディレクトリ(新しいフォルダ)として取り込み、その履歴を保持します。Submodule と異なり、リポジトリAの通常のコミットとして扱えるため、管理が比較的容易です。
手順
リモートの追加: リポジトリAに、リポジトリBを新しいリモートとして追加します。
# リポジトリAのローカルディレクトリで実行 git remote add repo-b [リポジトリBのURL]
Subtreeの追加: リポジトリBの内容を、リポジトリA内の新しいフォルダ(例: new_folder)に履歴付きで追加します。
git subtree add --prefix=new_folder repo-b main
- --prefix=new_folder: リポジトリA内に作成する新しいフォルダ名
- repo-b: 手順1で追加したリモート名
- main: リポジトリBのブランチ名
これで、「A/new_folder/」以下にBのファイルが、Bの履歴を保持した状態で組み込まれます。
Git Filter-Repo で履歴を切り出す方法
リポジトリBの特定のフォルダの履歴だけを抽出して、独立した履歴としてリポジトリAにマージする方法です。これは、リポジトリB全体ではなく、その中の特定のフォルダだけをAに取り込みたい場合に有効です。
手順
- リポジトリBをクローンし、git filter-repo(または古いgit filter-branch)コマンドを使用して、目的のフォルダ以外の履歴をすべて破棄し、残ったフォルダをリポジトリのルートに移動させます。
- 履歴を切り出した新しいリポジトリ(B')を、リポジトリAにリモートとして追加し、取り込みたいフォルダにマージ(またはgit read-tree)します。
これは手順が複雑で、git filter-repoのインストールも必要ですが、Bの不要な履歴を取り込まないようにリポジトリを整理できます。