Google Copybara: Memindahkan Kode Antar-Repositori
(github.com/google)- Copybara adalah alat yang digunakan secara internal di Google untuk mentransformasi dan memindahkan source code antar berbagai repositori, dan dipakai dalam kasus sinkronisasi antara repositori confidential dan repositori public
- Satu repositori dipilih sebagai repositori otoritatif untuk menjaga satu sumber kebenaran, tetapi kontribusi bisa diterima dari repositori mana pun dan rilis juga bisa dibuat dari repositori mana pun
- Kasus penggunaan utamanya adalah pemindahan kode berulang, mendukung alur seperti membawa sebagian kode dari repositori confidential ke repositori public atau membawa perubahan dari repositori public ke repositori authoritative
- Copybara menggunakan pendekatan stateless dengan menyimpan status bukan di server terpisah, melainkan di label pesan commit pada repositori tujuan, sehingga banyak pengguna atau layanan bisa memperoleh hasil yang sama dari konfigurasi dan repositori yang sama
- Jenis repositori yang saat ini didukung adalah Git; pembacaan Mercurial masih merupakan fitur eksperimental, dan strukturnya yang dapat diperluas memungkinkan penambahan origin dan destination kustom
Masalah yang Diselesaikan Copybara
- Copybara adalah alat untuk memindahkan dan mentransformasi source code antar repositori
- Ada situasi ketika source code perlu berada di beberapa repositori, dan Copybara memungkinkan kode ditransformasi dan dipindahkan di antara repositori tersebut
- Contoh yang representatif adalah proyek yang menjaga sinkronisasi antara repositori confidential dan repositori public
- Cara penggunaan yang paling umum adalah memindahkan kode secara berulang dari satu repositori ke repositori lain
- Alat ini juga bisa digunakan untuk memindahkan kode satu kali saja ke repositori baru
Repositori Otoritatif dan Alur Kontribusi
- Copybara mengharuskan salah satu repositori dipilih sebagai authoritative repository
- Ini adalah syarat agar selalu ada satu source of truth
- Kontribusi bisa dilakukan dari repositori mana pun
- Rilis juga bisa dibuat dari repositori mana pun
- Jika perubahan terjadi di repositori non-otoritatif, Copybara dapat mentransformasi perubahan tersebut dan memindahkannya ke lokasi yang tepat di repositori otoritatif
- Contohnya adalah perubahan yang dibuat oleh kontributor di repositori public
- Konflik merge ditangani dengan cara yang sama seperti menangani perubahan lama di dalam repositori otoritatif
Contoh Penggunaan
- Contoh penggunaan Copybara mencakup hal-hal berikut
- membawa sebagian kode dari repositori confidential ke repositori public
- membawa kode dari repositori public ke repositori confidential
- membawa perubahan dari repositori non-otoritatif ke repositori authoritative
- Contoh konfigurasi mendefinisikan origin dan destination dengan
core.workflow- origin menggunakan
git.github_origindenganmasterdarihttps://github.com/google/copybara.git - destination menggunakan
git.destinationdenganfile:///tmp/foo destination_filesmenargetkanthird_party/copybara/**dan mengecualikanREADME_INTERNAL.txtcore.replacedancore.movedigunakan untuk mengganti path file BUILD dan memindahkan direktori
- origin menggunakan
- Contoh eksekusinya adalah membuat bare Git repository lalu menjalankan
copybara copy.bara.sky
Cara Penyimpanan Status dan Dukungan Repositori
- Salah satu karakteristik utama Copybara adalah arsitekturnya yang stateless
- Lebih tepatnya, status disimpan di repositori tujuan
- Lokasi penyimpanannya adalah label pada pesan commit
- Dengan cara ini, banyak pengguna atau layanan bisa mendapatkan hasil yang sama dengan menggunakan kombinasi konfigurasi dan repositori yang sama
- Jenis repositori yang saat ini didukung adalah Git
- Kemampuan membaca dari repositori Mercurial dimungkinkan, tetapi masih eksperimental
- Melalui arsitektur yang dapat diperluas, origin dan destination bespoke dapat ditambahkan untuk menyesuaikan hampir semua kasus penggunaan
- Dukungan resmi untuk jenis repositori lain akan ditambahkan di masa mendatang
Instalasi dan Build
- Cara termudah untuk memulai adalah menggunakan snapshot release mingguan yang menyertakan binary yang sudah dibangun sebelumnya
- Rilis dibuat secara otomatis
- Tidak ada pengujian manual, kompatibilitas versi, atau jaminan akurasi
- Rilis dapat dipilih di
https://github.com/google/copybara/releases
- Untuk menggunakan versi yang belum dirilis, Anda perlu build dari HEAD
- perlu memasang JDK 11
- perlu memasang Bazel
- kloning source dengan
git clone https://github.com/google/copybara.git - build dengan
bazel build //java/com/google/copybara - uberjar yang dapat dieksekusi dibuat dengan
bazel build //java/com/google/copybara:copybara_deploy.jar - pengujian dapat dijalankan dengan
bazel test //...
- Beberapa pengujian memerlukan pemasangan alat dasar seperti Mercurial dan Quilt
- Jika Pull Request tidak terkait dengan modul tersebut, pengujian itu boleh dilewati
- CI akan menjalankan semua pengujian
- Di Arch Linux, paket
aur/copybara-gitdapat digunakan
Menggunakan Copybara Pra-build di Bazel
- Snapshot release mingguan dapat digunakan di Bazel
- Copybara disediakan dengan class file version 65.0, sehingga harus dijalankan di Java Runtime 21 atau lebih baru
- perlu menambahkan
run --java_runtime_version=remotejdk_21ke.bazelrc
- perlu menambahkan
- Gunakan
http_jaruntuk mengunduh artifact rilis- di
WORKSPACE, gunakanload("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") - di
MODULE.bazel, gunakanhttp_jar = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar")
- di
- Isi placeholder
[version]diWORKSPACEatauMODULE.bazeluntuk menentukancopybara_deploy.jar - Di file BUILD, deklarasikan
java_binarydan gunakancom.google.copybara.Mainsebagai main class - Contoh eksekusinya adalah
bazel run //tools:copybara -- migrate copy.bara.sky
Build Source sebagai Repositori Bazel Eksternal
- Tersedia macro kemudahan untuk dependensi Copybara
- Tambahkan
http_archivekeWORKSPACEdan isi nilai{{ sha256sum }}serta{{ commit }} - Setelah itu, load dan panggil macro berikut
copybara_repositories()copybara_maven_repositories()copybara_go_repositories()
- Di dalam workspace, Anda dapat build dan menjalankannya dengan
bazel run @com_github_google_copybara//java/com/google/copybara -- <args...>
Menggunakan Docker
- Cara build dan menjalankan Copybara dengan Docker saat ini masih eksperimental
- Build dilakukan dengan
docker build --rm -t copybara . - Menjalankannya dilakukan dari root kode target dengan bentuk
docker run -it -v "$(pwd)":/usr/src/app copybara help - Variabel lingkungan dapat digunakan sebagai pengganti argumen saat menjalankan container
COPYBARA_SUBCOMMAND=migrate: mengubah perintah eksekusi, default-nyamigrateCOPYBARA_CONFIG=copy.bara.sky: menentukan path file konfigurasi, default-nyacopy.bara.skydi rootCOPYBARA_WORKFLOW=default: menentukan workflow yang akan dijalankan, default-nyadefaultCOPYBARA_SOURCEREF='': menentukan sourceref, tidak ada nilai defaultCOPYBARA_OPTIONS='': menentukan opsi Copybara, tidak ada nilai default
- Konfigurasi Git dan kredensial SSH dapat dibagikan ke container Docker
- Contohnya adalah me-mount
~/.gitconfig,~/.ssh, danSSH_AUTH_SOCKke dalam container
- Contohnya adalah me-mount
Dokumentasi dan Pertanyaan
- Dokumentasi masih dalam proses pengerjaan
- Materi yang tersedia adalah sebagai berikut
- Pertanyaan dapat diajukan melalui mailing list
- Untuk melihat error pengujian Bazel tanpa
catpada file log, Anda dapat menambahkantest --test_output=streamedke~/.bazelrc
1 komentar
Komentar Hacker News
Menarik karena tulisan ini muncul tepat setelah saya merilis sebagai open source patch dukungan Perforce yang saya buat untuk dipakai di studio pengembangan game
Mengingat kegunaan utama Copybara adalah distribusi kode internal Google, dan kode itu berada di Piper yang terkait dengan Perforce, cukup mengejutkan bahwa tidak ada dukungan Perforce dan hanya dukungan Git yang berarti
Sebelum membuat PR, saya melihat riwayat Git dan ada banyak tanda Gerrit Change-ID, jadi saya sempat khawatir ada sistem code review Gerrit di suatu tempat yang tidak bisa saya akses dan PR saya mungkin tidak akan di-upstream
Sayang juga tidak ada Gerrit/Rietveld untuk Perforce, tetapi tentu tidak bisa mengharapkan semuanya
https://github.com/google/copybara/pull/347
https://abseil.io/resources/swe-book/html/ch19.html
https://read.engineerscodex.com/p/how-google-takes-the-pain-...
Saya belum menemukan alat eksternal yang sebagus Critique, dan saya heran alat review PR GitHub yang miskin fitur itu bisa diterima oleh kebanyakan orang. Kalau ada yang tahu alat dengan level serupa, saya ingin mendengarnya
Beberapa tahun lalu saat meninggalkan Google, saya mencarinya cukup teliti dan https://codeapprove.com/ adalah yang paling mendekati, tetapi masih banyak bagian yang kurang
Proyek open source seperti gVisor atau Bazel yang hidup di monorepo internal juga dioperasikan kurang lebih serupa, meski ada sedikit perbedaan
Sebagai alat menarik lain di area ini, Rust memakai alat bernama Josh untuk sinkronisasi commit
https://josh-project.dev
Ada juga artikel blog dari pihak Rust
https://blog.rust-lang.org/inside-rust/2026/06/04/how-josh-h...
Meta dulu memiliki alat open source bernama fbshipit, tetapi menurut repositori publiknya alat itu tidak lagi digunakan
https://github.com/facebookarchive/fbshipit
Apakah ada alat lain di bidang ini?
Kemudian digabungkan ke Git itu sendiri
https://manpages.debian.org/testing/git-man/git-subtree.1.en...
https://docs.github.com/en/get-started/using-git/about-git-s...
Apakah ini juga praktis ketika beberapa repositori ingin berbagi sedikit kode, tetapi upaya memisahkannya menjadi library, membuat referensi, menerbitkan rilis versi, dan memperbarui repositori yang bergantung padanya tidak sepadan?
Misalnya, saya penasaran apakah ini bisa dipakai untuk sekadar menyinkronkan sebuah folder berisi model domain bersama dari satu repositori utama ke repositori-repositori lain
Penggunaannya lebih dekat dengan filosofi ala Go, “lebih baik sedikit menyalin daripada menumpuk banyak dependensi”
Beberapa proyek dikembangkan di monorepo dan diekspor ke luar dengan Copybara
Tim kami juga memakainya secara internal untuk pengelolaan versi kumpulan aturan Starlark
Menjadikan repositori publik sebagai dependensi repositori privat perusahaan cukup merepotkan dari sisi pengembangan. Kalau dependensi seperti itu bertambah seperti pohon, benar-benar bikin pusing
Sudah cukup lama saya memakainya, terutama saat sebuah alat yang dibuat di dalam proyek besar sudah berkembang cukup besar untuk dirilis secara mandiri.
Cukup kuat untuk menangani seluruh deployment dua arah—mengekspor kode lalu mengimpornya kembali—tetapi itu terlalu merepotkan, jadi saya menghindarinya.
Saya biasanya memakainya untuk ekspor satu kali yang sederhana: memisahkan satu folder dari repositori asal sambil tetap mempertahankan riwayat. Setelah itu pengembangan dipindahkan ke repositori baru.
Saya puas karena
Git blametetap berfungsi meskipun struktur proyek barunya benar-benar berbeda.Dua arah cenderung berantakan, karena transformasi seperti pemetaan ulang path, pengecualian file, atau penghapusan header mudah dilakukan ke satu arah, tetapi tidak selalu bisa dibalik dengan bersih.
Jika kedua sisi sama-sama bercabang, pelacakan baseline Copybara mulai menghasilkan hasil yang membingungkan. Penyebabnya, commit yang secara semantik sama pun setelah transformasi akan menghasilkan SHA yang berbeda.
Hal yang perlu diketahui: “mempertahankan” riwayat di sini bukan migrasi riwayat yang sebenarnya, melainkan cherry-pick commit yang sudah ditulis ulang. Isi file dan informasi penulis ikut terbawa, jadi
Git blameberfungsi, tetapi SHA baru akan dibuat.Copybara menyimpan SHA asli di trailer pesan commit
GitOrigin-RevId, sehingga berguna saat nanti perlu mencocokkan commit antar-repositori.Kemajuan lebih dari 52 tahun, ya :-)
Juli 2026: Google copybara memungkinkan pemindahan kode di antara dua repositori produksi.
Maret 1974: IBM COPY memungkinkan pemindahan kode di antara dua production partitioned data set. OS/MVT dan OS/VS2 TSO Data Utilities COPY, FORMAT, LIST, MERGE User's Guide and Reference https://www.computinghistory.org.uk/downloads/8987
Di Dagster, kami memakai Copybara untuk menyusun model hub-and-spoke agar repositori publik bisa tinggal di dalam monorepo internal yang lebih besar. Itu berhasil, tetapi membutuhkan cukup banyak penanganan tidak langsung.
https://dagster.io/blog/monorepos-the-hub-and-spoke-model-an...
Kalau yang dibutuhkan hanya sinkronisasi repositori tanpa pengecualian atau transformasi, saya rasa saya tidak akan memakainya. Untuk saat ini mungkin cocok, tetapi bisa menyulitkan jika nanti diarsipkan atau dihentikan seperti kaniko atau banyak produk/alat Google lainnya.
GitLab punya cara yang sangat sederhana untuk melakukan mirroring dari GitLab ke GitHub atau penyedia/server Git lain.
Misalnya mengubah
bzleksternal menjadi bentuk yang kompatibel dengan BlazeBUILDinternal, atau mengubah antara import eksternal dan import gayathird_partyinternal.Untuk mirror murni, Copybara terlalu berat.
Bagus. Saya juga sekitar 5 tahun lalu membuat sesuatu yang mirip dengan repositori Git bersarang dan skrip, untuk mencapai tujuan mengelola repositori privat dan publik bersama-sama.
Tentu saja skrip shell saya bukan pada skala Google.
git subtree, tetapi setelah dilihat sepertinya melakukan jauh lebih banyak hal.Misalnya ada juga fitur untuk mengubah email penulis commit saat sinkronisasi.