Git で特定のブランチを別リポジトリとして分割する
本ドキュメントはミラーです。最新の情報は以下Qiitaのドキュメントをご確認ください。:
TL;DR
- Gitで複数のプロジェクトが1つのリポジトリに混在しブランチ=プロジェクトという扱いとなってしまった場合に、履歴を残した状態でブランチを別のリポジトリに分割する方法を記載します。
前提
- リモートリポジトリへの変更の反映は行われていること。
環境
- Windows 10 Pro x64 1909 (OS ビルド 18363.1139)
- git version 2.28.0.windows.1
- Azure DevOps Server 2019 Update1
構成
名称 | 値 |
---|---|
分割元リポジトリ | repoA |
分割元ブランチ | repoA-branchB |
分割元サブフォルダ | repoA-branchB-folderC |
分割先リポジトリ | repoB |
変更前
repoA <--> http://hogehoge/repoA.git
├─master
└─remotes/origin
├─branchB
│ └─folderC
│ ├─subfolderD
│ ├─subfolderE
│ └─subfolderF
└─master
変更後
branchA
のfolderB
をrepoBとして分割する。
分割元
repoA <--> http://hogehoge/repoA.git
├─master
└─remotes/origin
└─master
分割先
repoB <--> http://hogehoge/repoB.git
└─master
├─subfolderD
├─subfolderE
└─subfolderF
手順
-
コマンドプロンプト、またはGit Bashを開きます。
-
作業フォルダを新しいリポジトリを作成したい場所に移動します。
-
分割したいフォルダのあるリポジトリをクローンします。
git clone https://hogehoge/repoA
-
作業フォルダをクローンしたリポジトリに移動します。
cd repoA
-
ブランチを切り替えます。
git checkout branchB
-
現在のブランチが切り替わっていることを確認します。
git branch > * branchB > master
💡 特定のブランチを分割するためブランチを移動しています。
-
作業フォルダをリポジトリの親フォルダに移動します。
cd ..\
-
ローカルでリポジトリをクローンします。
git clone repoA repoB
-
作業フォルダをクローンしたリポジトリに移動します。
cd repoB
-
ローカルブランチが切り替えたブランチのみになっていることを確認します。
git branch > * branchB
💡 ブランチを切り替えてからローカルでリポジトリをクローンすることで、切り替えたブランチのみとなります。
-
分割したいフォルダが一つのフォルダにまとまっていない場合は、
git mv
コマンドで移動してフォルダにまとめます。💡 エクスプローラーで移動してもリポジトリには移動としては記録されません(削除と追加となります)ので、
git mv
コマンドを使用する必要があります。 -
リポジトリのファイルからサブフォルダを抽出するには、以下の情報を指定して git filter-branch を実行します。
例文git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME HEAD
💡
FOLDER-NAME
: 別のリポジトリの作成元にしたいプロジェクト内のフォルダです。
💡--prune-empty
があると、コメントのみの空commitを消去してくれます。実施git filter-branch --prune-empty --subdirectory-filter folderC HEAD
-
repoAのルートに配置された必要な
.gitignore
があった場合にはリポジトリに追加します。git add .gitignore git commit -a -m "任意のコメント"
-
リモートリポジトリ上で新しいリポジトリを作成し、リモートリポジトリ URLをコピーします。
💡 Azure DevOps (Server) の手順
チームプロジェクト内に複数のリポジトリを作成することが可能です。
💡 GitHubの手順 -
リポジトリの既存のリモート名を確認します。
git remote -v > https://hogehoge/repoA (fetch) > https://hogehoge/repoA (push)
-
既存のリモート名および新しいリモートリポジトリ URL を使って、新しいリポジトリの新しいリモート URL をセットアップします。
git remote set-url origin https://hogehoge/repoB
-
リモートURLが変更されたことを確認します。
git remote -v > https://hogehoge/repoB (fetch) > https://hogehoge/repoB (push)
-
ブランチ名を変更します。
git branch -m branchB master
-
ブランチを確認します。
git branch > * master
-
リポジトリをリモートリポジトリにプッシュします。
git push -u origin --all
-
ローカルの
remotes/origin
内の不要なブランチを消すため、フォルダを消して再取得します。git branch -a > * master > remotes/origin/HEAD -> origin/branchB > remotes/origin/branchB > remotes/origin/master
cd ..\
エクスプローラーからrepoBフォルダを削除します。
💡 誤操作を避けるため、CUIコマンドは記載していません。git clone git clone https://hogehoge/repoB
cd repoB
git branch -a > * master > remotes/origin/HEAD -> origin/master > remotes/origin/master
-
リモートリポジトリから分割済みのブランチ「branchB」を削除します。
⚡ ブランチ削除時は慎重に作業してください!
Discussion