1 ポイント 投稿者 GN⁺ 4 시간 전 | 1件のコメント | WhatsAppで共有
  • Copybara は Google 内部で使われているツールで、複数のリポジトリ間でソースコードを変換・移動し、confidential リポジトリと public リポジトリを同期する用途で使われる
  • 1つのリポジトリを 権威あるリポジトリ として選び、単一の信頼できる情報源を維持しつつ、どのリポジトリからでもコントリビューションを受け付けられ、どのリポジトリからでもリリースを作成できる
  • 主なユースケースは反復的なコード移動で、confidential リポジトリから public リポジトリへ一部のコードを持ち出したり、public リポジトリの変更を authoritative リポジトリへ取り込んだりする流れをサポートする
  • Copybara は状態を別サーバーではなく対象リポジトリの コミットメッセージラベル に保存する stateless 方式のため、複数のユーザーやサービスが同じ設定とリポジトリで同じ結果を得られる
  • 現在サポートされているリポジトリ種別は Git で、Mercurial の読み取りは実験的機能。拡張可能な構造により、カスタムの origin と destination を追加できる

Copybara が解決する問題

  • Copybara はリポジトリ間でのソースコードの移動と変換のためのツール
  • ソースコードを複数のリポジトリに存在させる必要がある場合があり、Copybara はそのようなリポジトリ間でコードを変換・移動できるようにする
  • 代表的なケースは、confidential リポジトリpublic リポジトリ を同期して維持するプロジェクト
  • 最も一般的な使い方は、あるリポジトリから別のリポジトリへコードを繰り返し移すこと
  • 新しいリポジトリへコードを一度だけ移す用途にも使える

権威リポジトリとコントリビューションの流れ

  • Copybara では、リポジトリの1つを authoritative repository として選ぶ必要がある
    • 常に1つの source of truth が存在するようにするための条件
  • コントリビューションはどのリポジトリからでも可能
  • リリースもどのリポジトリからでも作成できる
  • 非権威リポジトリで変更が発生した場合、Copybara がその変更を変換して権威リポジトリの適切な場所へ移動できる
    • 例としては、public リポジトリの contributor が作成した変更
    • マージコンフリクトは、権威リポジトリ内で古い変更を処理する場合と同じ方法で扱う

使用例

  • Copybara の使用例には次のものが含まれる
    • confidential リポジトリのコードの一部を public リポジトリへ持ち出す
    • public リポジトリのコードを confidential リポジトリへ取り込む
    • non-authoritative リポジトリの変更を authoritative リポジトリへ取り込む
  • 例の設定では core.workflow で origin と destination を定義する
    • origin は git.github_originhttps://github.com/google/copybara.gitmaster を使う
    • destination は git.destinationfile:///tmp/foo を使う
    • destination_filesthird_party/copybara/** を対象とし、README_INTERNAL.txt は除外する
    • core.replacecore.move で BUILD ファイルのパス置換とディレクトリ移動を行う
  • 実行例は、bare Git リポジトリを作成した後に copybara copy.bara.sky を実行する方式

状態保存方式とリポジトリ対応

  • Copybara の主な特徴の1つは stateless な構造であること
  • より正確には、状態は対象リポジトリに保存される
    • 保存場所はコミットメッセージの ラベル
  • この方式により、複数のユーザーやサービスが同じ設定とリポジトリの組み合わせを使って同じ結果を得られる
  • 現在サポートされているリポジトリ種別は Git
  • Mercurial リポジトリからの読み取り機能は利用できるが、まだ 実験的
  • 拡張可能なアーキテクチャにより、ほぼすべてのユースケースに合う bespoke な origin と destination を追加できる
  • 他のリポジトリ種別の正式サポートは今後追加される予定

インストールとビルド

  • 始める最も簡単な方法は、事前ビルド済みバイナリを含む週次の snapshot release を使うこと
  • 未リリース版を使うには HEAD からビルドする必要がある
    • JDK 11 のインストールが必要
    • Bazel のインストールが必要
    • git clone https://github.com/google/copybara.git でソースをクローン
    • bazel build //java/com/google/copybara でビルド
    • 実行可能な uberjar は bazel build //java/com/google/copybara:copybara_deploy.jar で生成
    • テストは bazel test //... で実行可能
  • 一部のテストでは Mercurial や Quilt のような基盤ツールのインストールが必要
    • Pull Request が該当モジュールに関連しない場合は、そのテストをスキップしてもよい
    • CI はすべてのテストを実行する
  • Arch Linux では aur/copybara-git パッケージを利用できる

Bazel で事前ビルド済み Copybara を使う

  • 週次 snapshot release を Bazel で利用できる
  • Copybara は class file version 65.0 で提供されるため、Java Runtime 21 以上で実行する必要がある
    • .bazelrcrun --java_runtime_version=remotejdk_21 を追加する必要がある
  • http_jar で release artifact をダウンロードする
    • WORKSPACE では load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") を使う
    • MODULE.bazel では http_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") を使う
  • WORKSPACE または MODULE.bazel[version] の箇所を埋め、copybara_deploy.jar を指定する
  • BUILD ファイルでは java_binary を宣言し、com.google.copybara.Main を main class として使う
  • 実行例は bazel run //tools:copybara -- migrate copy.bara.sky

外部 Bazel リポジトリとしてソースをビルド

  • Copybara 依存関係のための便利なマクロが提供されている
  • WORKSPACEhttp_archive を追加し、{{ sha256sum }}{{ commit }} の値を埋める
  • その後、次のマクロをロードして呼び出す
    • copybara_repositories()
    • copybara_maven_repositories()
    • copybara_go_repositories()
  • ワークスペース内で bazel run @com_github_google_copybara//java/com/google/copybara -- <args...> によりビルドと実行ができる

Docker の使用

  • Docker で Copybara をビルド・実行する方法は現在 実験的
  • ビルドは docker build --rm -t copybara . で行う
  • 実行は対象コードのルートで docker run -it -v "$(pwd)":/usr/src/app copybara help の形で行う
  • コンテナ実行引数の代わりに環境変数を使える
    • COPYBARA_SUBCOMMAND=migrate: 実行コマンドを変更、デフォルトは migrate
    • COPYBARA_CONFIG=copy.bara.sky: 設定ファイルのパスを指定、デフォルトはルートの copy.bara.sky
    • COPYBARA_WORKFLOW=default: 実行する workflow を指定、デフォルトは default
    • COPYBARA_SOURCEREF='': sourceref を指定、デフォルト値なし
    • COPYBARA_OPTIONS='': Copybara オプションを指定、デフォルト値なし
  • Git 設定と SSH 認証情報は Docker コンテナに共有できる
    • 例として ~/.gitconfig~/.sshSSH_AUTH_SOCK をコンテナにマウントする方法がある

ドキュメントと問い合わせ

1件のコメント

 
GN⁺ 4 시간 전
Hacker Newsのコメント
  • ちょうど自分がゲーム開発スタジオで使うために作った Perforce対応パッチをオープンソースとして公開した直後にこの記事が出たので面白かった
    Copybaraの主な用途がGoogle内部のコード配布であり、そのコードがPerforceに関連するPiperにあることを考えると、Perforce対応がなく、Git対応だけが実質的にあるのはかなり意外だった
    PRを作る前にGit履歴を見たところ、Gerrit Change-IDの表示が多かったので、どこか自分がアクセスできないGerritコードレビューシステムがあり、自分のPRはアップストリームされないのではないかと心配にもなった
    Perforce向けのGerrit/Rietveldがない点も残念だが、すべてを望むことはできない
    https://github.com/google/copybara/pull/347

    • Gerrit/Rietveldに Perforce対応がない理由の一つは、GoogleがPiperに保存されたコード変更にそれらのツールを使っていないから。代わりに Critique を使っている
      https://abseil.io/resources/swe-book/html/ch19.html
      https://read.engineerscodex.com/p/how-google-takes-the-pain-...
      外部ツールでCritiqueほど良いものはまだ見つけられておらず、GitHubの貧弱なPRレビュー機能が多くの人に受け入れられているのは驚き。似たレベルのツールを知っている人がいれば聞いてみたい
      数年前にGoogleを離れるときにかなり入念に探し、https://codeapprove.com/が最も近かったが、それでも欠けている部分は多かった
    • PiperはPerforceのフォークではない。PerforceとAPI互換ではあるが、完全に別の実装
    • そのリポジトリはPRを受け付けている。ただし内部でマージしたあと、再び外部へエクスポートする方式
      内部モノレポに置かれているgVisorやBazelのようなオープンソースプロジェクトも、多少の違いはあるが、おおむね似た運用になっている
  • この領域の別の興味深いツールとして、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
    この分野にほかのツールはまだあるだろうか?

  • 複数のリポジトリで少しだけコードを共有したいが、ライブラリとして切り出して参照を張り、バージョンリリースを発行し、依存するリポジトリを更新する手間をかけるほどの価値はない場合にも、これは便利なのだろうか?
    例えば、共通のドメインモデルが入っているフォルダを、1つの主リポジトリからほかのリポジトリへ単に 同期する、といった使い方ができるのか気になる
    Go流に「依存関係を大量に持つより、少しコピーするほうがよい」という哲学に近い用途

    • 主に外部の オープンソースプロジェクトを内部モノレポと同期するために使われる。方針上、ビルド成果物よりソースコードの取り込みが求められるが、例外を認めてもらうことはできる
      一部のプロジェクトはモノレポで開発され、Copybaraで外部にエクスポートされる
      うちのチームでは内部的にStarlarkルールセットのバージョン管理にも使っている
    • 内部に モノレポがあり、その一部を世の中にオープンソースとして公開したいときに使うツール。とはいえコードは引き続きモノレポ内に置いておく必要があるので、これが解決策になる
      公開リポジトリを社内の非公開リポジトリの依存関係にすると、開発面ではかなり面倒になる。そうした依存関係がツリー状に増えていくと、本当に頭痛の種になる
    • Copybaraでそういうこともできるが、その使い方だと苛立たしく退屈なものになりがち。ライブラリを切り出したり、いくつかのファイルを別リポジトリへ押し込んだりする問題より、さらに面倒かもしれない
  • かなり長く使ってきており、主に大きなプロジェクト内で作ったツールが単独リリースできるほど大きくなったときに使っている
    コードをエクスポートして再び取り込む双方向デプロイ全体を行えるほど強力だが、それは面倒すぎるので避けている
    私はたいてい、元のリポジトリからフォルダを1つ切り出しつつ履歴は保持する、単純な一回限りのエクスポートに使っている。その後の開発は新しいリポジトリへ移す
    新しいプロジェクト構造がまったく違っていても Git blame が動くので満足している

    • その一方向パターンこそ、実際に Google 内部でも使われているやり方。モノレポから GitHub へ外向きに同期する
      双方向は厄介になる。パスの再マッピング、ファイルの除外、ヘッダー削除のような変換は一方向なら簡単だが、常にきれいに逆変換できるとは限らないからだ
      両側がどちらも分岐すると、Copybara のベースライン追跡はややこしい結果を出し始める。意味的には同じコミットでも、変換後には互いに異なる SHA が生成されるためだ
      知っておくべき点は、履歴の「保持」は本当の移植ではなく、書き換えられたコミットをチェリーピックする方式だということ。ファイル内容と作者情報は引き継がれるので Git blame は動くが、SHA は新しく生成される
      Copybara は元の SHA をコミットメッセージのトレーラー GitOrigin-RevId に入れておくので、後でリポジトリ間のコミットを照合する必要があるときに便利
  • 52年を超える進歩とは :-)
    2026年7月: Google copybara は、2つの本番リポジトリ間でコードを移動できるようにしてくれる
    1974年3月: IBM COPY は、2つの本番パーティションデータセット間でコードを移動できるようにしてくれた。OS/MVT および OS/VS2 TSO Data Utilities COPY, FORMAT, LIST, MERGE User's Guide and Reference https://www.computinghistory.org.uk/downloads/8987

  • Dagster では、公開用リポジトリがより大きな内部モノレポの中に存在できるようにハブ・アンド・スポークモデルを構成するために Copybara を使っており、動作はしたが、かなり多くの回り道的な処理が必要だった
    https://dagster.io/blog/monorepos-the-hub-and-spoke-model-an...

  • 除外や変換なしにリポジトリ同期だけが必要なら、あえて使わないと思う。今は合っているかもしれないが、kaniko や多くの Google 製品・ツールのようにアーカイブ化されたり終了したりすると困る可能性がある
    GitLab には、GitLab から GitHub や他の Git プロバイダー/サーバーへミラーリングする非常に単純な方法がある

    • Copybara が終了する可能性は本当に低いと思う。私の知る限り、google3 と大規模オープンソースプロジェクトの保守・ベンダリング方式においてかなり中核的なツール
    • その通り。Copybara は、一方向または双方向で変換を行うためのツールに近い
      たとえば外部の bzl を内部の Blaze BUILD 互換の形に変えたり、外部 import と内部の third_party 式 import の間で変換したりする作業だ
      純粋なミラーなら Copybara は重すぎる
  • いいね。私も約5年前に、ネストした Git リポジトリとスクリプトで似たようなものを作り、非公開・公開リポジトリを一緒に扱う目的を達成した
    私のシェルスクリプトは、当然ながらGoogle 規模ではなかった

    • 私も似たようなものだった。最初は git subtree のラッパーだと思ったが、見てみるとはるかに多くのことをしているようだ
      たとえば同期中にコミット作者のメールアドレスを変更する機能もある