2つのGitリポジトリを統合する

別々に作った2つの Git リポジトリを統合する方法。違う方法もあると思うけど、調べた結果この方法でできた、ってことで記録しておく。

前提として:

  • 既存の2つのリポジトリ、repo_arepo_b を、新しく作った repo_combined に統合する
  • いずれも Python のプロジェクトで、Poetry を使ってる

まずは新しいプロジェクトを作る。

takatoh@apostrophe:w$ poetry new repo_combined

ディレクトリに移動して、Git の初期化と最初のコミット。このコミットには Poetry がデフォルトで作ってくれるファイルしかない。

takatoh@apostrophe:w$ cd repo_combined
takatoh@apostrophe:repo_combined$ git init
Initialized empty Git repository in /home/takatoh/w/repo_combined/.git/
takatoh@apostrophe:repo_combined$ git add .
takatoh@apostrophe:repo_combined$ git commit -m "First commit."
takatoh@apostrophe:repo_combined$ git branch -M main

リポジトリ repo_a をリモートブランチに取り込む。

takatoh@apostrophe:repo_combined$ git remote add -f repo_a https://github.com/takatoh/repo_a.git

これで、repo_combined の中には main ブランチと、全く繋がりのない repo_a/main が存在する状態になる。で、その repo_a/mainmain にマージする。

takatoh@apostrophe:repo_combined$ git merge repo_a/main
fatal: refusing to merge unrelated histories

……が、失敗した。mainrepo_a/main は全く別もので繋がりがないのでマージできない。マージするには --allow-unrelated-histories オプションをつけてやる。

takatoh@apostrophe:repo_combined$ git merge --allow-unrelated-histories repo_a/main
CONFLICT (add/add): Merge conflict in pyproject.toml
Auto-merging pyproject.toml
Automatic merge failed; fix conflicts and then commit the result.

pyproject.toml にコンフリクトが発生したので、解消してやる。

takatoh@apostrophe:repo_combined$ code pyproject.toml
takatoh@apostrophe:repo_combined$ git add pyproject.toml
takatoh@apostrophe:repo_combined$ git commit -m "Merge repository 'repo_a/main'."

これで repo_a/main のマージが完了。根元が別のコミットツリーが合流するという、ちょっと不思議な感じのするツリーが出来上がる。

つぎは repo_b。これも同じようにすればいい。

takatoh@apostrophe:repo_combined$ git remote add -f repo_b https://github.com/takatoh/repo_b.git

リモートブランチ repo_b/main に取り込んだら、main にマージ(--allow-unrelated-histories をつけて)。

takatoh@apostrophe:repo_combined$ git merge --allow-unrelated-histories repo_b/main
CONFLICT (add/add): Merge conflict in pyproject.toml
Auto-merging pyproject.toml
CONFLICT (add/add): Merge conflict in poetry.lock
Auto-merging poetry.lock
CONFLICT (add/add): Merge conflict in .gitignore
Auto-merging .gitignore
Automatic merge failed; fix conflicts and then commit the result.

当然のようにコンフリクトが発生する(今度はファイル3つ)ので解消してやる。

poetry.lock のコンフリクトを解消するのは厄介だけど、そもそもこのファイルは人間が編集するようなものじゃないので、あとで poetry install で作り直せばすむ。ここでは内容の整合は無視して、とにかくコンフリクトを解消してやればいい。

takatoh@apostrophe:repo_combined$ git add .gitignore
takatoh@apostrophe:repo_combined$ git add pyproject.toml
takatoh@apostrophe:repo_combined$ git add poetry.lock
takatoh@apostrophe:repo_combined$ git commit -m "Merge repository 'repo_b/main'."

で、poetry.lock をいったん削除してから poetry install

takatoh@apostrophe:repo_combined$ git rm poetry.lock
rm 'poetry.lock'
takatoh@apostrophe:repo_combined$ poetry install
takatoh@apostrophe:repo_combined$ git add poetry.lock
takatoh@apostrophe:repo_combined$ git commit -m "poetry.lock: Re-generate."

これでめでたく完了。