【入門編】GitHubのリポジトリ間でコードを「同期」させる:Git Subtreeとリモート連携の高度な自動化手法 – バージョン管理・CI/CD活用バイブル

こんにちは!日々の開発、本当にお疲れ様です。
新しいツールや技術に触れるときって、ワクワクする半面、「これ、本当に自分のプロジェクトの役に立つのかな?」と少し不安になりますよね。

今回は、複数のリポジトリ間でコードをスマートに共有・同期するための秘密兵器、「Git Subtree(サブツリー)」と、それをGitHub Actionsで完全に自動化するテクニックについてお話しします。

「共通のライブラリや設定ファイルを3つのリポジトリで使っているけれど、修正するたびにコピペしたり、Submoduleで地獄を見たりした……」そんな苦い経験はありませんか?

これをマスターすれば、コードの共有と同期に悩む時間は一切なくなります。一緒に優しく、確実にお仕事の効率を爆上げしていきましょう!

—

1. なぜ「Git Submodule」ではなく「Git Subtree」なのか?

複数のリポジトリでコードを共有する機能として、Gitにはもともと Git Submodule(サブモジュール) という機能があります。しかし、これがなかなか曲者です。

  • Submoduleの悲劇:

参照先のコミットハッシュがガチガチに固定されるため、親リポジトリ側で「ちょっとこのバグだけ直して親にすぐ反映したい」と思っても、HEADがデタッチしたり、更新を忘れて「あれ、動かない?」とチームメンバー全員が混乱する原因になります。

  • Subtreeの優しさ:

一方、今回紹介する Git Subtree は、「別リポジトリのコードを、自分のリポジトリの『ただのフォルダ』として取り込む」 技術です。
取り込んでしまえば、もう中身はあなたのプロジェクトの一部。普通のコードと同じように修正して、そのままコミット・プッシュできちゃいます。もちろん、本家(元リポジトリ)のアップデートを取り込むことも自由自在です。

初心者の方こそ、この直感的に扱えるGit Subtreeから入るのが圧倒的に幸せになれますよ。

—

2. 基礎のセットアップ:Git Subtreeを動かしてみよう

まずは、自分の手元(ローカル環境)で、別のリポジトリからコードを取り込む基本の動きを体験してみましょう。特別なインストールは不要です。お使いのGitに標準で備わっています。

前提シナリオ

  • 親リポジトリ(Main Repo): あなたが今作っているプロダクト。
  • 子リポジトリ(Sub Repo): 複数のプロジェクトで使い回したい共通コンポーネントや設定ファイル群。

ステップ1:子リポジトリを「サブツリー」として追加する

親リポジトリのルートディレクトリで、以下のコマンドを叩くだけです。これだけで、指定したフォルダに別リポジトリの全コードが降ってきます。

git subtree add –prefix=<取り込み先フォルダ名> <子リポジトリのURL> <ブランチ名> –squash
git subtree add –prefix=shared-components https://github.com/your-name/shared-lib.git main –squash

  • `–prefix`: 親リポジトリのどこに配置するかを指定します(例: `shared-components`)。
  • `–squash`: 子リポジトリの膨大なコミット履歴を親側に持ち込まず、1つの綺麗なコミットにまとめて取り込む魔法のオプションです。これをつけると履歴が汚れません。優しさですね!

これで、`shared-components` というフォルダが生まれ、中身のコードを自由に編集できるようになりました。

ステップ2:子リポジトリの最新変更を「取り込む(プルする)」

本家(子リポジトリ)側でコードがアップデートされたら、親リポジトリ側へは以下のコマンドで同期します。

git subtree pull –prefix=shared-components https://github.com/your-name/shared-lib.git main –squash

これだけで、最新の変更が手元のプロジェクトにマージされます。すごく直感的ですよね!

—

3. GitHub Actionsで「同期」を完全に自動化する

さて、ここからが本番です。
「手動で `git subtree pull` を打つのは面倒くさい!」
「本家リポジトリを更新した瞬間に、すべての派生リポジトリ(子を使う側)へ自動で反映させたい!」

これをGitHub Actionsの力で実現しましょう。今回は、「本家ライブラリが更新されたら、自動で宛先リポジトリにPull Requestを送る」または「直接プッシュする」ワークフローを構築します。

以下のYAMLファイルを、本家リポジトリの `.github/workflows/sync.yml` として配置してください。

name: Sync to Derivative Repositories

on:
push:
branches:

  • main # 本家のmainブランチが更新されたら発火

jobs:
sync:
runs-on: ubuntu-latest
steps:
# 1. 本家リポジトリのコードをチェックアウト

  • name: Checkout Source Repository

uses: actions/checkout@v4
with:
fetch-depth: 0 # 履歴全体を取得

# 2. 派生リポジトリへ変更を伝搬させる公式アクションを使用

  • name: Rsync / Push to Target Repo

uses: cpina/github-action-push-to-another-repository@main
env:
API_TOKEN_GITHUB: ${{ secrets.ACCESS_TOKEN }} # 権限を持ったPersonal Access Token
with:
source-file: “shared-code/” # 共有したいフォルダ
destination-repo-path: “shared-code/” # 派生側での配置先フォルダ
destination-repository: “your-name/derivative-project-repo” # 派生リポジトリ名
user-email: “bot@example.com”
commit-message: “chore: sync shared-components from upstream”
target-branch: main

このワークフローの優しさポイント

1. 完全自動化: あなたが本家リポジトリに `git push` をした瞬間、裏側でGitHubが勝手に派生リポジトリ側のコードを最新に書き換えてくれます。コピペ作業とはもうサヨナラです。
2. アクセストークン(Secrets): 別リポジトリを操作するため、あらかじめGitHubのSettingsで発行した `ACCESS_TOKEN` をRepository Secretsに登録しておくだけのセキュア設計です。

—

4. トラブルシューティング:初心者つまずきポイント

最後に、Git Subtreeを使い始めた開発者がよくハマる「優しくない罠」とその抜け出し方をこっそり共有しておきますね。

  • Q. マージコンフリクトが起きてしまったら?
  • A. 恐れることはありません。通常のGitのマージコンフリクトと全く同じです。衝突したファイルを開いて修正し、`git add` して `git commit` すれば何事もなかったかのように進められます。Subtreeだからといって特別なコマンドは必要ありません。
  • Q. フォルダ構成を途中で変えたくなったら?
  • A. `git mv` を使って普通にフォルダを移動し、いつも通りコミットすればGitが賢く追跡してくれます。

—

おわりに

いかがでしたでしょうか?
Git SubtreeとGitHub Actionsを組み合わせることで、「コードの共有」という多くの開発者が頭を悩ませるストレスが、驚くほどエレガントに解決できます。

「複数のリポジトリを管理するのが面倒で、ついコードをコピペしちゃっていた……」
そんな過去の自分とは今日でオサラバしましょう。

これをマスターすれば、あなたの毎日の開発作業が劇的に、そして圧倒的に楽になりますよ。ぜひ、次のプロジェクトの共通パーツ管理に取り入れてみてくださいね!

タイトルとURLをコピーしました