🔥

Git で特定のブランチを別リポジトリとして分割する

2020/11/12に公開

本ドキュメントはミラーです。最新の情報は以下Qiitaのドキュメントをご確認ください。:
https://qiita.com/tfukumori/items/6aae507833bbbd1fa4b6


TL;DR

  • Gitで複数のプロジェクトが1つのリポジトリに混在しブランチ=プロジェクトという扱いとなってしまった場合に、履歴を残した状態でブランチを別のリポジトリに分割する方法を記載します。

前提

  • リモートリポジトリへの変更の反映は行われていること。

環境

構成

名称
分割元リポジトリ repoA
分割元ブランチ repoA-branchB
分割元サブフォルダ repoA-branchB-folderC
分割先リポジトリ repoB

変更前

repoA  <--> http://hogehoge/repoA.git
├─master
└─remotes/origin
    ├─branchB
    │  └─folderC
    │      ├─subfolderD
    │      ├─subfolderE
    │      └─subfolderF
    └─master

変更後

branchAfolderBをrepoBとして分割する。

分割元

repoA  <--> http://hogehoge/repoA.git
├─master
└─remotes/origin
    └─master

分割先

repoB  <--> http://hogehoge/repoB.git
└─master
    ├─subfolderD
    ├─subfolderE
    └─subfolderF

手順

  1. コマンドプロンプト、またはGit Bashを開きます。

  2. 作業フォルダを新しいリポジトリを作成したい場所に移動します。

  3. 分割したいフォルダのあるリポジトリをクローンします。

    git clone https://hogehoge/repoA
    
  4. 作業フォルダをクローンしたリポジトリに移動します。

    cd repoA
    
  5. ブランチを切り替えます。

    git checkout branchB
    
  6. 現在のブランチが切り替わっていることを確認します。

    git branch
    > * branchB
    >   master
    

    💡 特定のブランチを分割するためブランチを移動しています。

  7. 作業フォルダをリポジトリの親フォルダに移動します。

    cd ..\
    
  8. ローカルでリポジトリをクローンします。

    git clone repoA repoB
    
  9. 作業フォルダをクローンしたリポジトリに移動します。

    cd repoB
    
  10. ローカルブランチが切り替えたブランチのみになっていることを確認します。

    git branch
    > * branchB
    

    💡 ブランチを切り替えてからローカルでリポジトリをクローンすることで、切り替えたブランチのみとなります。

  11. 分割したいフォルダが一つのフォルダにまとまっていない場合は、git mvコマンドで移動してフォルダにまとめます。

    覚えておくと便利なGitコマンド - Qiita

    💡 エクスプローラーで移動してもリポジトリには移動としては記録されません(削除と追加となります)ので、git mvコマンドを使用する必要があります。

  12. リポジトリのファイルからサブフォルダを抽出するには、以下の情報を指定して 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
    
  13. repoAのルートに配置された必要な.gitignoreがあった場合にはリポジトリに追加します。

    git add .gitignore
    git commit -a -m "任意のコメント"
    
  14. リモートリポジトリ上で新しいリポジトリを作成し、リモートリポジトリ URLをコピーします。

    💡 Azure DevOps (Server) の手順
     チームプロジェクト内に複数のリポジトリを作成することが可能です。
    💡 GitHubの手順

  15. リポジトリの既存のリモート名を確認します。

    git remote -v
    > https://hogehoge/repoA (fetch)
    > https://hogehoge/repoA (push)
    
  16. 既存のリモート名および新しいリモートリポジトリ URL を使って、新しいリポジトリの新しいリモート URL をセットアップします。

    git remote set-url origin https://hogehoge/repoB
    
  17. リモートURLが変更されたことを確認します。

    git remote -v
    > https://hogehoge/repoB (fetch)
    > https://hogehoge/repoB (push)
    
  18. ブランチ名を変更します。

    git branch -m branchB master
    
  19. ブランチを確認します。

    git branch
    > * master
    
  20. リポジトリをリモートリポジトリにプッシュします。

    git push -u origin --all
    
  21. ローカルの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
    
  22. リモートリポジトリから分割済みのブランチ「branchB」を削除します。

    ブランチ削除時は慎重に作業してください!

    💡 Azure DevOps (Server) の手順
     image.png
    💡 GitHubの手順
    💡 コマンドでの手順

参考資料

Discussion