Repository adalah satuan keputusan yang lebih besar daripada branch, dan dua strategi menatanya membagi dunia pengembangan perangkat lunak: monorepo yang menampung banyak proyek dalam satu repository, dan polyrepo yang memberi setiap proyek repository sendiri. Topik ini membandingkan keduanya, menunjukkan alat Git yang membuat monorepo tetap terkendali, dan merangkum faktor yang menentukan pilihan pada skala besar.
Dua strategi dan sifat aslinya#
Monorepo menyimpan banyak proyek, pustaka, dan alat dalam satu repository dengan satu riwayat. Keuntungan terbesarnya adalah keterlihatan: perubahan yang menyentuh dua proyek sekaligus direkam sebagai satu commit, sehingga keduanya selalu serasi dan tidak ada versi yang tertinggal. Refaktor lintas batas, pembaruan pustaka bersama, dan penelusuran penyebab berjalan pada satu riwayat yang sama.
Polyrepo memberi setiap proyek repository sendiri dengan riwayat, akses, dan siklus rilisnya sendiri. Keuntungan terbesarnya adalah batas yang tegas: hak akses, pemicu CI, dan tanggung jawab rilis mengikuti repository, sehingga proyek kecil tidak mengangkat beban proyek besar. Hargaannya ada pada rujukan antar proyek, yang harus diselenggarakan melalui nomor versi dan pembaruan sadar, sebagaimana dipakai manajer paket.
| Aspek | Monorepo | Polyrepo |
|---|---|---|
| Perubahan lintas proyek | satu commit atomik | beberapa commit dan rilis |
| Hak akses | satu repository untuk semua | terpisah per proyek |
| Pemicu CI | perlu penyaringan jalur | otomatis per repository |
| Riwayat | satu dan utuh | terpisah per proyek |
Alat Git yang menjaga monorepo tetap terkendali#
Keberatan yang paling sering terhadap monorepo adalah ukurannya, dan Git menjawabnya dengan alat penyaringan yang bekerja pada tingkat jalur. Riwayat satu layanan diperiksa tanpa membaca riwayat lainnya, dan perbandingan antar commit dapat dibatasi pada jalur tertentu.
Siapkan repository berisi dua layanan dengan commit yang berselang-seling, lalu bandingkan pembacaan riwayatnya.
# tanggal commit ditetapkan agar keluaran contoh dapat direproduksi secara persis
export GIT_AUTHOR_DATE="2026-11-01T09:00:00+07:00"
export GIT_COMMITTER_DATE="2026-11-01T09:00:00+07:00"rm -rf /tmp/lab-mono
mkdir -p /tmp/lab-mono/layanan-catatan /tmp/lab-mono/layanan-laporan
cd /tmp/lab-mono
git init -b main
git config user.name "Budi"
git config user.email "[email protected]"
printf "API catatan.\n" > layanan-catatan/api.md
git add layanan-catatan
git commit -m "Layanan catatan: API pertama"
printf "API laporan.\n" > layanan-laporan/api.md
git add layanan-laporan
git commit -m "Layanan laporan: API pertama"
printf "API catatan.\nHapus catatan.\n" > layanan-catatan/api.md
git commit -am "Layanan catatan: hapus catatan"
git log --oneline -- layanan-catatanInitialized empty Git repository in /tmp/lab-mono/.git/
[main (root-commit) cdf97e7] Layanan catatan: API pertama
1 file changed, 1 insertion(+)
create mode 100644 layanan-catatan/api.md
[main 683e386] Layanan laporan: API pertama
1 file changed, 1 insertion(+)
create mode 100644 layanan-laporan/api.md
[main fb9d260] Layanan catatan: hapus catatan
1 file changed, 1 insertion(+)
fb9d260 Layanan catatan: hapus catatan
cdf97e7 Layanan catatan: API pertamaPembacaan riwayat dengan jalur layanan menghasilkan dua commit milik layanan itu saja, meskipun riwayat penuhnya berisi tiga. Filter jalur yang sama bekerja pada git diff, dan itulah mekanisme yang dipakai CI monorepo untuk menjalankan pengujian hanya pada layanan yang berubah.
Untuk working directory, proyek yang sangat besar dapat memakai sparse-checkout, yaitu opsi yang mengambil hanya subset folder ke disk, dan penyetelannya berjalan pada tingkat repository tanpa mengubah riwayat. Alat pelengkap seperti ini berlapis di atas Git, dan pemakaiannya tumbuh seiring besarnya monorepo.
Faktor yang menentukan pilihan#
Kebutuhan yang paling menentukan adalah keterkaitan proyek-proyeknya. Proyek yang saling bergantung erat dan berubah bersama lebih nyaman pada monorepo, karena sinkronisasinya gratis, sedangkan proyek yang berdiri sendiri dengan siklus rilis berbeda lebih nyaman pada polyrepo, karena batasnya jadi kebijakan yang ditegakkan alat, bukan kesepakatan yang dijaga manusia.
Faktor kedua adalah organisasi akses dan ukuran tim. Monorepo menyatukan hak akses, dan pemisahannya pada tingkat folder memerlukan alat tambahan, sedangkan polyrepo memisahkan sejak awal. Faktor ketiga adalah beban alat: monorepo menuntut CI yang bisa menyaring, alat pembangun yang tahu bagian mana yang berubah, dan kebiasaan riwayat yang disaring jalur, sedangkan polyrepo menuntut disiplin versi antar repository.
Banyak organisasi nyata memakai campuran keduanya, misalnya monorepo untuk produk utama dan polyrepo untuk perkakas internal. Keputusan ini juga tidak bersifat kekal, dan perpindahan yang disengaja memakai mekanisme riwayat yang dijaga agar penelusuran tidak putus.
Ringkasan#
- Monorepo menyatukan banyak proyek dalam satu riwayat dengan commit lintas proyek yang atomik, sedangkan polyrepo memberi batas tegas per repository.
- Riwayat monorepo disaring dengan jalur pada
git logdangit diff, dan itulah mekanisme CI untuk menguji layanan yang berubah. - Sparse-checkout membatasi isi working directory pada subset folder untuk repository yang sangat besar.
- Pilihan strateginya mengikuti keterkaitan proyek, organisasi akses, dan kemauan memelihara alat pelengkapnya.
Referensi#
- git-log — Git Documentation — rujukan filter jalur pada pembacaan riwayat.
- git-sparse-checkout — Git Documentation — rujukan pembatasan isi working directory.