Memilih antara Proyek tunggal atau banyak dalam repositori git?

223

Dalam gitlingkungan, tempat kami memodulasi sebagian besar proyek, kami menghadapi satu proyek per repositori atau beberapa proyek per masalah desain repositori . Mari pertimbangkan proyek termodulasi:

myProject/
   +-- gui
   +-- core
   +-- api
   +-- implA
   +-- implB

Hari ini kami memiliki satu proyek per repositori . Ini memberi kebebasan untuk

  • release komponen individual
  • tag komponen individual

Tapi itu juga rumit untuk branchkomponen karena sering bercabang apimembutuhkan cabang yang setara core, dan mungkin komponen lainnya.

Mengingat kami ingin releasemasing - masing komponen dapatkah kami masih mendapatkan fleksibilitas yang sama dengan memanfaatkan beberapa proyek per desain repositori .

Pengalaman apa yang ada dan bagaimana / mengapa Anda mengatasi masalah ini?

Johan Sjöberg
sumber
1
Saya memiliki masalah yang sangat mirip saat ini. Saya perlu merilis versi proyek yang berbeda sehingga mereka harus berada di repositori yang berbeda. Ini adalah mimpi buruk untuk dikelola. Akan lebih bagus jika ada cara untuk hanya cabang sub direktori.
Andrew T Finnell
1
Setiap modul harus memiliki nomor versi terpisah. Dan kami menggunakan git-describe.
linquize
Saya terkejut melihat bahwa Bit ( bitsrc.io ) dan Lerna ( github.com/lerna/lerna ) tidak disebutkan! Anda dapat mempelajari lebih lanjut di sini: hackernoon.com/...
Yoni

Jawaban:

199

Ada tiga kelemahan utama one project per repository, cara Anda menggambarkannya di atas. Ini kurang benar jika mereka benar-benar proyek yang berbeda, tetapi dari suara itu berubah menjadi satu sering memerlukan perubahan yang lain, yang benar-benar dapat membesar-besarkan masalah ini:

  1. Lebih sulit ditemukan ketika bug diperkenalkan. Alat seperti git bisectmenjadi jauh lebih sulit digunakan ketika Anda memecah repositori Anda menjadi sub-repositori. Mungkin saja, tidak semudah itu, yang berarti perburuan serangga di saat krisis jauh lebih sulit.
  2. Melacak seluruh riwayat fitur jauh lebih sulit. Perintah traverse history seperti git loghanya tidak menampilkan histori bermakna dengan struktur repositori yang retak. Anda bisa mendapatkan beberapa hasil yang bermanfaat dengan submodula atau subtree, atau melalui metode skrip lainnya, tapi itu tidak sama dengan mengetik tig --grep=<caseID>atau git log --grep=<caseID>dan memindai semua komit yang Anda pedulikan. Sejarah Anda menjadi lebih sulit untuk dipahami, yang membuatnya kurang berguna ketika Anda benar-benar membutuhkannya.
  3. Pengembang baru menghabiskan lebih banyak waktu mempelajari struktur Kontrol Versi sebelum mereka dapat mulai coding. Setiap pekerjaan baru membutuhkan prosedur pengambilan, tetapi membuat repositori proyek berarti membuat mereka harus mengambil struktur VC sebagai tambahan arsitektur kode. Dalam pengalaman saya, ini sangat sulit bagi pengembang baru untuk git yang datang dari toko-toko tradisional yang lebih terpusat yang menggunakan repositori tunggal.

Pada akhirnya, ini merupakan perhitungan biaya peluang. Di satu mantan majikan, kami memiliki aplikasi utama kami dibagi menjadi 35 sub-repositori yang berbeda. Di atas mereka, kami menggunakan serangkaian skrip yang rumit untuk mencari sejarah, memastikan status (yaitu cabang-cabang produksi vs pengembangan) sama di seluruh mereka, dan menyebarkannya secara individu atau secara massal.

Itu terlalu banyak; setidaknya terlalu banyak untuk kita. Overhead manajemen membuat fitur kami kurang gesit, membuat penyebaran jauh lebih sulit, membuat mengajar para pengembang baru membutuhkan waktu terlalu banyak, dan pada akhirnya, kami hampir tidak bisa mengingat mengapa kami meretakkan repositori di tempat pertama. Suatu hari musim semi yang indah, saya menghabiskan $ 10 untuk satu sore waktu komputasi cluster di EC2. Aku menggerakkan repo itu kembali bersama dengan beberapa lusin git filter-branchtelepon. Kami tidak pernah melihat ke belakang.

Christopher
sumber
7
Di luar topik, ada beberapa hal yang lebih menyenangkan sebagai manajer repositori daripada membeli waktu pada sistem yang dapat dilakukan dalam dua jam apa yang tidak bisa dilakukan laptop Anda dalam 20, dengan harga kurang dari harga makan siang. Terkadang saya sangat menyukai internet.
Christopher
2
Bagaimana Anda akan merilis masing-masing proyek sebagai rilis terpisah? Atau apakah Anda tidak perlu melakukan itu? Itulah masalah yang saya miliki. Dengan jika Anda perlu membuat V1 dari Proyek A, dan V2 dari Proyek B.
Andrew T Finnell
5
Untuk bergerak di antara "satu proyek per repo" dan "beberapa repo" pertimbangkan git-subtree (penjelasan yang baik di stackoverflow.com/a/17864475/15585 )
deterb
1
Saya menulis sebuah skrip untuk mengotomatisasi ini untuk kasus penggunaan umum: github.com/Oakleon/git-join-repos
chrishiestand
Apa itu "struktur VC?"
Robert Harvey
60

Christopher melakukan pekerjaan yang sangat baik untuk menyebutkan kekurangan dari model satu proyek per repositori. Saya ingin membahas beberapa alasan mengapa Anda mungkin mempertimbangkan pendekatan multi-repositori. Dalam banyak lingkungan tempat saya bekerja, pendekatan multi-repositori telah menjadi solusi yang masuk akal, tetapi keputusan tentang berapa banyak repositori yang harus dimiliki, dan di mana membuat pemotongan tidak selalu merupakan cara yang mudah untuk dibuat.

Dalam posisi saya saat ini, saya memigrasi repositori CVS repositori tunggal dengan lebih dari sepuluh tahun sejarah ke sejumlah repositori git. Sejak keputusan awal itu, jumlah repositori telah bertambah (melalui aksi-aksi tim lain), sampai pada titik di mana saya menduga kita memiliki lebih banyak daripada yang akan optimal. Beberapa karyawan baru menyarankan penggabungan repositori tetapi saya telah membantahnya. Proyek Wayland memiliki pengalaman serupa. Dalam sebuah ceramah yang saya lihat baru-baru ini, mereka, pada satu titik, memiliki lebih dari 200 repositori git, yang mana pemimpinnya meminta maaf. Melihat situs web mereka , saya melihat sekarang mereka berada di 5, yang tampaknya masuk akal. Penting untuk mengamati bahwa bergabung dan membagi repositori adalah tugas yang dapat dikelola, dan boleh-boleh saja bereksperimen (sesuai alasan).

Jadi kapan Anda mungkin menginginkan beberapa repositori?

  1. Repositori tunggal akan terlalu besar untuk menjadi efisien.
  2. Gudang Anda secara longgar digabungkan, atau dipisahkan.
  3. Pengembang biasanya hanya membutuhkan satu, atau sebagian kecil dari repositori Anda untuk berkembang.
  4. Anda biasanya ingin mengembangkan repositori secara independen, dan hanya perlu menyinkronkannya sesekali.
  5. Anda ingin mendorong lebih banyak modularitas.
  6. Tim yang berbeda bekerja pada repositori yang berbeda.

Poin 2 dan 3 hanya signifikan jika poin 1 berlaku. Dengan membagi repositori kami, saya secara signifikan mengurangi keterlambatan yang diderita oleh kolega di luar kantor kami, mengurangi konsumsi disk, dan meningkatkan lalu lintas jaringan.

4 dan 5 lebih halus. Ketika Anda membagi repo katakanlah klien dan server, ini membuatnya lebih mahal untuk mengoordinasikan perubahan antara klien dan kode server. Ini bisa menjadi positif, karena mendorong antarmuka dipisahkan antara keduanya.

Bahkan dengan kerugian dari proyek multi-repositori, banyak pekerjaan terhormat dilakukan seperti itu - wayland dan dorongan muncul di benak. Saya tidak percaya konsensus mengenai praktik terbaik telah berkembang, dan beberapa penilaian diperlukan. Alat untuk bekerja dengan banyak repositori (git-subtree, git-submodule dan lainnya) masih sedang dikembangkan dan dicoba. Saran saya adalah bereksperimen dan bersikap pragmatis.

Spacemoose
sumber
7
Jawaban ini akan lebih membantu dengan referensi untuk mendukung klaim: "bergabung dan membagi repositori adalah tugas yang dapat dikelola."
Wildcard
3
Beberapa repo juga dapat bekerja melawan modularitas karena membuatnya lebih sulit untuk mengubah kode bersama. Ketergantungan lintas repo membuat integrasi lebih sulit, dapat memecahkan kode lebih mudah (bahkan jika Anda memiliki alat yang baik untuk memeriksa ini) dan ancaman melanggar kode repo menghambat antarmuka refactoring, yang merupakan salah satu alat paling ampuh untuk membuat berbagai hal lebih modular.
Curt J. Sampson
Segala sesuatu tentang MicroServices dan desain DDD berlaku di sini. Anda harus meminimalkan kode bersama.
Arwin
49

Ketika kita menggunakan GitHub, kita sebenarnya memiliki beberapa proyek dalam satu repo tetapi memastikan bahwa proyek / modul tersebut benar-benar dimodulasi (kita menggunakan -api dan konvensi-inti + Maven + statis dan pengecekan runtime dan bahkan mungkin pergi ke OSGi satu hari untuk boot) .

Apa yang dihematnya? Kita tidak perlu mengeluarkan beberapa Permintaan Tarik jika kita mengubah sesuatu yang kecil di banyak proyek. Masalah dan Wiki tetap tersentralisasi dll.

Kami masih memperlakukan setiap modul / proyek sebagai proyek independen yang tepat dan membangun serta mengintegrasikannya secara terpisah di server CI kami dll.

Martijn Verburg
sumber
1
Sangat menarik. Saya menduga ini adalah model umum di github. Jika Anda menghadapi rilis komponen individual, apakah Anda menggunakan sesuatu seperti submodulesatau melepaskan / menandai seluruh repositori?
Johan Sjöberg
submodules jika kita harus tetapi untuk sekarang kita versi dari induknya ke bawah.
Martijn Verburg
Di perusahaan saya saat ini, kami menggunakan strategi yang sama, dan mengemas metadata tentang komit terbaru dalam proyek ke dalam berbagai file manifes artefak (yaitu hasil git log -1 -- <project_dir>). Benar-benar hebat. Jawaban ini layak mendapatkan lebih banyak suara.
Christopher
22

Bagi saya, perbedaan utama dalam menggunakan satu atau lebih dari satu repositori adalah jawaban atas pertanyaan-pertanyaan berikut:

  • Apakah beberapa bagian dikembangkan oleh tim yang sama, memiliki siklus rilis yang sama, pelanggan yang sama? Lalu ada sedikit alasan untuk membagi satu repositori.
  • Apakah beberapa bagian sangat tergantung satu sama lain? Jadi memisahkan model, pengontrol dan UI (bahkan ketika mereka adalah bagian yang berbeda) tidak terlalu masuk akal, karena ketergantungan yang tinggi pada satu sama lain. Tetapi jika 2 bagian hanya memiliki ketergantungan kecil, yang diimplementasikan oleh antarmuka yang stabil yang hanya diubah setiap beberapa tahun, maka akan lebih bijaksana untuk membagi 2 bagian dalam 2 repositori.

Sama seperti contoh, saya punya aplikasi kecil (hanya klien), yang memeriksa "kualitas" repositori Subversion. Ada implementasi inti, yang bisa dimulai dari baris perintah, dan bekerja dengan baik dengan Java 6. Tapi saya sudah mulai mengimplementasikan UI, yang menggunakan JavaFX sebagai bagian dari Java 8. Jadi saya telah membagi 2, dan menciptakan repositori kedua (dengan proses pembuatan kedua), dengan jadwal yang berbeda, ...

Saya suka jawaban di atas (memilih mereka), tapi saya pikir itu bukan keseluruhan kisah nyata. Jadi saya ingin menambahkan argumen untuk membagi repositori juga. Jadi jawaban sebenarnya (kapan harus berpisah) mungkin di suatu tempat di tengah ...

mliebelt
sumber
0

Dari contoh Anda, repositori harus diatur dalam hal seberapa saling tergantung mereka. Semua alasan tentang merancang MicroServices dan Domain Driven Design berlaku di sini: dalam beberapa kasus kode duplikat dapat diterima, bekerja dengan antarmuka, jangan merusak kompatibilitas kecuali Anda benar-benar harus, dll.

Sekarang dalam pandangan saya UI harus independen dari backend. Jadi repositori proyek UI biasanya harus berisi kode UI dan Pengontrol Klien. Pengontrol Klien akan terhubung dengan Pengontrol Layanan secara abstrak. Mereka akan menggunakan abstraksi klien layanan / api yang diversi secara terpisah dari layanan, sehingga layanan dapat diperbarui tanpa memutus klien (mungkin ada beberapa klien berbeda).

Jadi layanan itu sendiri harus menjadi repositori sendiri. Dalam pandangan saya, layanan ini hanyalah pembungkus dari beberapa logika bisnis single-point-of-thruth. Jadi logika bisnis biasanya harus terpisah dari teknologi layanan yang menyelenggarakannya. Di sisi lain, implementasi repositori biasanya sangat terhubung dengan logika bisnis, sehingga ini dapat diintegrasikan dalam repositori yang sama. Tetapi bahkan di sana jarak tempuh Anda mungkin berbeda.

Tentu saja, proyek sederhana yang tidak mungkin banyak berubah dalam hal teknologi atau mendukung banyak tumpukan, di mana semua UI dapat di-host dari sumber yang sama dengan layanan backend dan backend biasanya hanya digunakan oleh klien yang sama, dapat memperoleh manfaat dari lebih banyak repositori yang terintegrasi secara ketat.

Dalam hal ini Anda mungkin akan baik-baik saja dengan hanya memiliki vertikal penuh dalam satu repositori, dan fokus hanya pada memastikan domain fungsional Anda berdiri sendiri dengan benar dalam repositori mereka sendiri. Anda kemudian masih memiliki sebagian besar keuntungan dari repositori yang lebih kecil, dan sedikit overhead.

Arwin
sumber