【Git】コミット履歴を保持したまま特定ディレクトリを独立リポジトリへ切り出す(分割)Gitコマンド完全ガイド
公開日: 2026年09月12日
1. 概要とユースケース
プロジェクトの成長や構成の見直しに伴い、単一のリポジトリ(モノレポ)で管理していた特定サービスや共通コンポーネント(例: 共通 Nginx リバースプロキシ、共有ライブラリ、API ゲートウェイなど)を、「独立した別の Git リポジトリとして切り出したい」 という場面があります。
しかし、単純にファイルを別のディレクトリへコピー&ペーストして新しく git init してしまうと、これまでの開発で積み重ねてきたコミット履歴(git log や git blame)がすべて失われてしまいます。
Git の標準機能である git subtree split を活用することで、特定ディレクトリに関係する過去のコミット履歴(コミットメッセージ、日時、変更差分)を 100% 保持したまま、新しい独立リポジトリへ安全に切り出す ことができます。
2. 切り出しの仕組みと全体の流れ
┌─────────────────────────────────────────────────────────────┐
│ 1. 元プロジェクトのリポジトリ │
│ │
│ Commit 1: プロジェクト初期化 │
│ ↓ │
│ Commit 2: nginx/ 初期設定追加 ───【抽出対象】 │
│ ↓ │
│ Commit 3: nginx/ SSL設定修正 ───【抽出対象】 │
│ ↓ │
│ Commit 4: アプリの新機能追加 │
└──────────────────────────────┬──────────────────────────────┘
│
│ git subtree split -P nginx -b nginx-standalone
▼
┌─────────────────────────────────────────────────────────────┐
│ 2. 一時ブランチ (nginx-standalone) │
│ │
│ ・nginx/ ディレクトリに関わるコミット履歴のみを自動フィルタリング │
│ ・nginx/ 配下のファイルがリポジトリルートになるよう再構築 │
└──────────────────────────────┬──────────────────────────────┘
│
│ 新リポジトリ側で実行:
│ git pull <元リポジトリ> nginx-standalone
▼
┌─────────────────────────────────────────────────────────────┐
│ 3. 新しい独立リポジトリ (reverse-proxy) │
│ │
│ Commit 1: nginx/ 初期設定追加 (旧 Commit 2) │
│ ↓ │
│ Commit 2: nginx/ SSL設定修正 (旧 Commit 3) │
│ │
│ ★ 過去のコミットログ、作成者情報、コミット日時が完全保持される │
└─────────────────────────────────────────────────────────────┘
3. ステップ別コマンド手順
以下のシナリオを例として手順を解説します:
- 元リポジトリ:
/path/to/main-project - 切り出したいディレクトリ:
nginx/ - 新リポジトリの作成先:
/path/to/reverse-proxy
Step 1: 元リポジトリで特定ディレクトリの履歴を抽出する
元リポジトリのディレクトリに移動し、git subtree split コマンドを実行して、対象ディレクトリ(-P)のコミット履歴だけを抽出した新しいブランチ(-b)を作成します。
cd /path/to/main-project
# nginx ディレクトリの履歴だけを抽出して「nginx-standalone」ブランチを作成
git subtree split -P nginx -b nginx-standalone
解説:
-P <ディレクトリ名>: 抽出対象のサブディレクトリパスを指定します。-b <ブランチ名>: 抽出した履歴を格納する新しいブランチ名を指定します。
Step 2: 抽出されたブランチのコミット履歴を確認する
意図したディレクトリに関する過去のコミット履歴だけが正しく抽出されているか確認します。
git log --oneline nginx-standalone
出力例のように、対象ディレクトリに関するコミットログがルート階層を基準として並んでいれば成功です。
Step 3: 新しいディレクトリを作成して Git リポジトリを初期化する
切り出し先となる新しいディレクトリを作成し、空の Git リポジトリを作成します。
# 新リポジトリ用のディレクトリを作成
mkdir -p /path/to/reverse-proxy
cd /path/to/reverse-proxy
# Git リポジトリの初期化
git init -b master
Step 4: 抽出したブランチの履歴を引き込む (pull)
元リポジトリのパスと抽出ブランチを指定して、コミット履歴を新リポジトリに取り込みます。
git pull /path/to/main-project nginx-standalone
取り込み完了後、ファイル一覧とコミット履歴を確認します:
# ファイルが展開されているか確認
ls -la
# 過去のコミット履歴がそのまま残っているか確認
git log --oneline
これで、過去のコミットログ・作成日時・変更履歴を完全維持した独立リポジトリが完成しました!
Step 5: 元リポジトリ側から不要ディレクトリを削除して整理する
新リポジトリへの移行が確認できたら、元リポジトリ側にある旧ディレクトリを削除し、変更をコミットします。
cd /path/to/main-project
# ディレクトリの削除
git rm -r nginx
# 変更をコミット
git commit -m "Nginx環境を独立リポジトリ(reverse-proxy)へ切り離し"
Step 6: 一時的に作成した抽出ブランチを削除する(後片付け)
Step 1 で作成した一時ブランチは役目を終えたため、安全に削除します。
git branch -D nginx-standalone
4. 注意点と運用のヒント
- Git 管理外ファイル(
.gitignore)のコピー漏れに注意- 設定ファイルや環境変数(
.env、API トークン、秘密鍵等)など、.gitignoreで Git 管理から除外されていた実ファイルはgit subtree splitでは移行されません。 - 新ディレクトリへ手動で
cp -aして権限(パーミッション)を維持して配置する必要があります。
- 設定ファイルや環境変数(
- サブモジュール(Git Submodule)との使い分け
- リポジトリ同士の親子関係を厳密に保ちたい場合は Submodule を検討しますが、特定モジュールを「完全に独立して各サービスから切り離して運用したい」場合は、本記事の完全分割(独立リポジトリ化)が最もシンプルでトラブルが少なくなります。
5. まとめ
| コマンド | 役割 |
|---|---|
git subtree split -P <dir> -b <branch> |
特定サブディレクトリのコミット履歴だけを抽出して新ブランチを作成 |
git pull <元リポジトリパス> <抽出ブランチ> |
抽出した履歴を新しい Git リポジトリに取り込み |
git branch -D <抽出ブランチ> |
作業完了後の一時ブランチを安全に削除 |
この手順を踏むことで、「これまでの試行錯誤の歴史」を一切犠牲にすることなく、ディレクトリの分割・リポジトリの独立化を美しく実現できます。