世界を動かす技術を、日本語で。

Google Copybara: リポジトリ間でのコード移動

2026年7月1日原文(github.com)

概要

  • Copybara はGoogleが開発した、複数リポジトリ間でコードを変換・移動するツール
  • 権威リポジトリ を指定し、片方を「真実のソース」として同期管理
  • Git リポジトリに対応し、Mercurialは実験的サポート
  • stateless設計 で複数ユーザーやサービスで同じ設定・結果を共有可能
  • 導入・ビルド方法 やDocker利用法など多様な運用に対応

Copybaraの概要と主な用途

  • Copybara は、ソースコードを複数のリポジトリ間で変換・移動するためのツール
  • Google社内で利用されているが、 OSS としても公開
  • 秘密リポジトリと公開リポジトリの 同期管理 用途が一般的
  • どちらか一方を 権威リポジトリ(source of truth) として指定
  • どちらのリポジトリからも コントリビュート やリリース作成が可能
  • 主な用途
    • 秘密リポジトリから公開リポジトリへの 部分的コード移行
    • 公開リポジトリから秘密リポジトリへの インポート
    • 非権威リポジトリでの変更を権威リポジトリへ 反映
  • マージコンフリクト は通常のリポジトリ管理と同様に処理

Copybaraの特徴

  • stateless設計 で、状態管理はコミットメッセージのラベルとして保存
  • 複数ユーザーやCIサービスで同じ設定・リポジトリを利用可能
  • 現時点で対応しているリポジトリ
    • Git (完全対応)
    • Mercurial (実験的サポート)
  • 拡張性の高いアーキテクチャ で、今後他のリポジトリタイプにも公式対応予定

基本的な設定例

  • 設定ファイル(例:copy.bara.sky)で ワークフロー や変換内容を定義
    • 例:origin(github)、destination(ローカルGit)、ファイル選択、変換処理(core.replace/core.move)など
  • 実行例
    • $ (mkdir /tmp/foo ; cd /tmp/foo ; git init --bare)
    • $ copybara copy.bara.sky

Copybaraの導入方法

  • 週次スナップショットリリース の利用が最も簡単
    • https://github.com/google/copybara/releases からバイナリ取得
  • ソースからのビルド 手順
    • JDK 11およびBazelのインストール
    • git clone https://github.com/google/copybara.git
    • bazel build //java/com/google/copybara
    • テスト実行(bazel test //...

システムパッケージ

  • Arch Linux: aur/copybara-git でインストール可能

Intellij + Bazelプラグイン利用

  • プロジェクト構成例
    • ディレクトリ指定:copybara/integrationjava/com/google/copybaraなど
    • ターゲット指定://java/com/google/copybara/... など

Bazelでの事前ビルドバイナリ利用

  • Java Runtime 21以上が必要
  • .bazelrcrun --java_runtime_version=remotejdk_21を追加
  • http_jarでリリースアーティファクトをダウンロード
  • BUILD.bazeljava_binaryとして宣言し、bazel runで実行

外部Bazelリポジトリとしてのビルド

  • WORKSPACEhttp_archiveでCopybaraを追加
  • 依存モジュールのマクロをロードし、bazel runで実行

DockerでのCopybara利用(実験的)

  • Dockerイメージのビルド
    • docker build --rm -t copybara .
  • コンテナ実行例
    • docker run -it -v "$(pwd)":/usr/src/app copybara help
  • 環境変数でサブコマンドや設定ファイルを指定可能
    • COPYBARA_SUBCOMMANDCOPYBARA_CONFIGCOPYBARA_WORKFLOWなど
  • Git設定・SSH認証情報の共有例
    • -v ~/.gitconfig:/root/.gitconfig:ro
    • -v ~/.ssh:/root/.ssh
    • -v ${SSH_AUTH_SOCK}:${SSH_AUTH_SOCK} -e SSH_AUTH_SOCK

ドキュメント・サポート

  • 公式ドキュメントやチュートリアル、リファレンスを順次整備中
  • 質問や問い合わせは 公式メーリングリスト
  • Bazelテストのログ出力を見やすくするには、~/.bazelrctest --test_output=streamedを追加

Copybara は、複数リポジトリ間でのコード同期や移行を効率化し、権威リポジトリ管理やCI/CDパイプラインへの統合も容易なツール。多様な運用形態に柔軟に対応し、拡張性も高い点が大きな特徴。

Hackerたちの意見

いいね、5年前に似たようなものを作ったことがあるよ。ネストしたGitリポジトリとスクリプトを使って、プライベートとパブリックのリポジトリを組み合わせる目的でね。でも、俺のシェルスクリプトはGoogleの規模には全然及ばなかったけど!

うん、同じく。git subtreeのラッパーかと思ったけど、もっと色々やってるみたいだね!例えば、同期中にコミットの著者メールアドレスを変更する機能とか。

この分野には他にも面白いツールがあるよ。RustはJoshっていうツールを使ってコミットを同期してるんだって。https://josh-project.dev Rustの人たちのブログ記事もあるよ: https://blog.rust-lang.org/inside-rust/2026/06/04/how-josh-h... Metaは以前、fbshipitっていうオープンソースツールを持ってたけど、オープンソースリポジトリによるともう使ってないみたい。https://github.com/facebookarchive/fbshipit 他にこの分野で面白いツールある?

git subtreeは元祖ツールだったよ:https://apenwarr.ca/log/20090430 それ以来、gitに統合されたんだ:https://manpages.debian.org/testing/git-man/git-subtree.1.en... https://docs.github.com/en/get-started/using-git/about-git-s...

使ったことがある人に聞きたいんだけど、複数のリポジトリで少しのコードを共有したいときに便利なのかな?ライブラリを抽出して参照したり、バージョン付きリリースを公開したり、依存リポジトリを更新したりする手間をかけるほどでもない場合に、1つのメインリポジトリからコードフォルダを「同期」する感じで使えるのかな?要するに、少しのコピーの方がたくさんの依存関係よりもいいっていうGoの哲学みたいな感じ?

主に外部のオープンソースプロジェクトをモノレポと同期させるために使われてるよ。ポリシーとしては、ビルドされたアーティファクトよりもソースコードのインポートを求めるんだ。ただし、例外もあるけどね。一部のプロジェクトはモノレポ内で開発されて、Copybaraを通じてエクスポートされることもある。うちのチームも内部でStarlarkルールセットのバージョン管理に使ってるよ。

内部にモノレポがあって、その一部をオープンソースとして公開したいときに使うんだ。まだモノレポ内に存在する必要があるから、これが解決策なんだよ。プライベートな企業リポジトリの依存関係としてパブリックリポジトリを持つのは、開発的には面倒くさいし、そんな依存関係のツリーを持つのは頭痛のタネだね。

Copybaraはそれができるけど、そう使うのは面倒で退屈だと思う。ライブラリを抽出したり、ファイルを別のリポジトリに押し込んだりするよりも、もっと面倒だよ。

Copybaraは、昨日でも設定しておくべきものの一つだよ。すごくうまく機能するし、モノレポでパブリックな部分とコラボレーションする際に、多くのチームが生産性を大幅に向上させてるのを見たことがある。内部モノレポを考えているなら、試してみる価値は絶対にあるよ。

面白いね。これってgitサブモジュールやサブツリーを使うのとどう違うのか知ってる人いる?それを使って、ウェブアプリの開発リポジトリに接続しつつ、ウェブサイトのアーティファクト用に別のリポジトリを作ったことがあるんだ。(両方とも変更可能で、変更を互いにマージできる状態。)ありがとう。

しばらくこれを使ってるけど、主に大きなプロジェクトの一部としてツールを作るときに使ってるんだ。ツールがリリースに値するくらい大きいときね。双方向のコードの輸出入をする全体のオペレーションもできるけど、そんなの面倒だからやりたくない。主にシンプルな「火をつけて忘れる」エクスポートに使ってる。元のリポジトリからフォルダを取り出して、履歴を保存する感じ。その後は新しいリポジトリで開発を進める。新しいプロジェクトのレイアウトは全然違っても、Git blameはちゃんと機能するから、それで満足してるよ。

一方向のパターンは、実際にGoogleが内部で使ってる方法でもあるよ。モノレポからGitHubに向けて同期してるんだ。双方向だとややこしくなる。変換(パスの再マッピング、ファイルの除外、ヘッダーの削除)は一方向では簡単に適用できるけど、必ずしもきれいに反転できるわけじゃないからね。両方の側が分岐してしまうと、Copybaraのベースライン追跡が混乱した結果を生むことになる。意味的に同等のコミットが変換後に異なるSHAを生成するから。一つ知っておくべきことは、履歴の「保存」は実際には書き換えたコミットのチェリーピックであって、本当の移植ではないってこと。Git blameはファイルの内容と著作権が引き継がれるから機能するけど、SHAは新しいものになる。Copybaraは元のSHAをコミットメッセージのトレーラー(GitOrigin-RevId)に埋め込むから、後でリポジトリ間でコミットを関連付ける必要があるときに役立つよ。

Hacker Newsで議論の続きを見る