Gitのサブツリーのマージについて
複数のプロジェクトを単一のリポジトリで管理する必要がある場合、サブツリーマージを使ってすべての参照を扱うことができます。
通常、サブツリーのマージはリポジトリ内にリポジトリを格納するために使われます。 「サブリポジトリ」はメインのリポジトリのフォルダー内に格納されます。
サブツリーマージは、例で説明するのが最も分かりやすいでしょう。 以下のように進めます:
- プロジェクトを表す
test
という空のリポジトリの作成。 Spoon-Knife
というもう1つのリポジトリをサブツリーとしてマージ。test
プロジェクトは、そのサブプロジェクトを同じリポジトリの一部であるかのように使う。Spoon-Knife
からの更新をtest
プロジェクトにフェッチする。
サブツリーマージのための空のリポジトリのセットアップ
-
ターミナルターミナルGit Bashターミナル を開いてください。
-
新しいディレクトリを作成し、そこに移動します。
$ mkdir test
$ cd test
-
新しい Git リポジトリを初期化します。
$ git init > Initialized empty Git repository in /Users/octocat/tmp/test/.git/
-
新しいファイルを作成してコミットします。
$ touch .gitignore $ git add .gitignore $ git commit -m "initial commit" > [master (root-commit) 3146c2a] initial commit > 0 files changed, 0 insertions(+), 0 deletions(-) > create mode 100644 .gitignore
サブツリーとして新しいリポジトリを追加
-
関心のある別個のプロジェクトを指す新しいリモート URL を追加します。
$ git remote add -f spoon-knife git@github.com:octocat/Spoon-Knife.git > Updating spoon-knife > warning: no common commits > remote: Counting objects: 1732, done. > remote: Compressing objects: 100% (750/750), done. > remote: Total 1732 (delta 1086), reused 1558 (delta 967) > Receiving objects: 100% (1732/1732), 528.19 KiB | 621 KiB/s, done. > Resolving deltas: 100% (1086/1086), done. > From git://github.com/octocat/Spoon-Knife > * [new branch] master -> Spoon-Knife/master
-
Spoon-Knife
プロジェクトをローカルの Git プロジェクトにマージします。 こうしてもローカルではファイルはまったく変更されませんが、Git は次のステップに備えることになります。Git 2.9 以降を使っている場合:
$ git merge -s ours --no-commit --allow-unrelated-histories spoon-knife/master > Automatic merge went well; stopped before committing as requested
Git 2.8 以前を使っている場合:
$ git merge -s ours --no-commit spoon-knife/master
> Automatic merge went well; stopped before committing as requested
-
spoon-knife というディレクトリを新たに作成し、
Spoon-Knife
プロジェクトの Git の履歴をそこへコピーします。$ git read-tree --prefix=spoon-knife/ -u spoon-knife/master
-
変更をコミットして安全にします。
$ git commit -m "Subtree merged in spoon-knife" > [master fe0ca25] Subtree merged in spoon-knife
ここでは 1 つのサブプロジェクトを追加しただけですが、Git リポジトリには好きな数のサブプロジェクトを取り込むことができます。
参考: 将来このリポジトリのクローンを新しく作成した場合、追加したリモートは作成されません。 それらは git remote add
コマンドを使って再度追加しなければなりません。
更新および変更との同期
サブプロジェクトが追加された場合、それは上流の変更と自動的には同期されません。 サブプロジェクトは、以下のコマンドで更新しなければなりません。
$ git pull -s subtree remotename branchname
上の例では、以下のようになるでしょう:
$ git pull -s subtree spoon-knife master