Binari dalam kontrol sumber

30

Saat mengembangkan untuk perangkat yang disematkan dan dunia ganjil lainnya, sangat mungkin proses build Anda akan menyertakan beberapa binari berpemilik, menggunakan versi yang sangat spesifik. Jadi pertanyaannya adalah, apakah mereka bagian dari kontrol sumber Anda? Kantor saya berjalan dengan aturan "memeriksa dari kontrol sumber mencakup semua yang Anda butuhkan untuk mengkompilasi kode" dan ini telah menyebabkan beberapa argumen serius.

Argumen utama yang saya lihat menentang ini adalah membengkaknya sumber kontrol DB, kurangnya file biner yang berbeda ( lihat pertanyaan sebelumnya pada subjek) . Ini bertentangan dengan kemampuan untuk memeriksa, membangun, mengetahui bahwa Anda memiliki lingkungan yang tepat yang diinginkan pengembang sebelumnya dan tanpa memburu file yang sesuai (dengan versi spesifik tidak kurang!)

Daniel Goldberg
sumber
3
Atau, Anda dapat menulis skrip bash / python / perl / bat ke checkout dan mengunduh semua komponen dependen lainnya dalam satu langkah. Namun, saya tetap merekomendasikan memeriksa binari ke dalam kontrol versi Anda, hanya demi menjaga revisi. Satu-satunya file yang tidak boleh diperiksa ke dalam repositori adalah file yang dapat dengan mudah dibuat ulang dari file yang dikontrol versi. Ruang disk murah, dan seharusnya tidak menjadi pertimbangan utama.
Lie Ryan

Jawaban:

28

Gagasan VERSION CONTROL (misnomer: source control) adalah untuk memungkinkan Anda memutar kembali sejarah, memulihkan efek perubahan, melihat perubahan, dan mengapa dibuat. Ini adalah serangkaian persyaratan, beberapa di antaranya memerlukan binary thingies, beberapa di antaranya tidak.

Contoh: Untuk pekerjaan firmware bawaan, Anda biasanya akan memiliki toolchain lengkap: baik kompiler berpemilik yang menghabiskan banyak uang, atau beberapa versi gcc. Agar pengiriman dapat dieksekusi, Anda memerlukan toolchain serta sumbernya.

Memeriksa toolchains ke dalam kontrol versi memang menyebalkan, utilitas yang berbeda itu mengerikan (jika sama sekali), tetapi tidak ada alternatif. Jika Anda ingin toolchain dilestarikan untuk orang yang datang untuk melihat kode Anda dalam waktu 5 tahun untuk mencari tahu apa yang dilakukannya, maka Anda tidak punya pilihan: Anda HARUS memiliki toolchain di bawah kontrol versi juga.

Saya telah menemukan selama bertahun-tahun bahwa metode paling sederhana untuk melakukan ini adalah dengan membuat gambar ZIP atau ISO dari CD instalasi dan memeriksanya. Komentar checkin harus berupa nomor versi pembuat khusus toolchain. Jika gcc atau serupa, bundel semua yang Anda gunakan menjadi ZIP besar dan lakukan hal yang sama.

Kasus paling ekstrim yang saya lakukan adalah Windows XP Embedded di mana "toolchain" adalah Windows XP VM yang berjalan, yang termasuk (saat itu) SQL Server dan setumpuk file konfigurasi bersama dengan ratusan dan ratusan file tambalan. Menginstal keseluruhan dan memperbaruinya biasanya memakan waktu sekitar 2-3 hari. Menjaga agar anak cucu berarti memeriksa SELURUH VM ke dalam kontrol versi. Melihat disk virtual terdiri dari sekitar 6 x 2GB gambar, sebenarnya berjalan cukup baik. Kedengarannya di atas, tetapi itu membuat hidup sangat mudah bagi orang yang datang setelah saya dan harus menggunakannya - 5 tahun kemudian.

Ringkasan: Kontrol versi adalah alat. Gunakan untuk menjadi efektif, jangan terpaku pada hal-hal seperti arti kata-kata, dan jangan menyebutnya "kontrol sumber" karena lebih besar dari itu.

dengan cepat_now
sumber
1
Dan kapan VM perlu diperbarui balon repo Anda hingga 12 GB? Bahkan jika Anda memiliki perbedaan biner yang baik, Anda masih berbicara repo 10GB +
TheLQ
3
Ya tidak. Jika Anda menggunakan VMWare, Anda dapat menggunakan snapshot disk. Ini menyimpan gambar disk awal asli dan menambahkan file baru yang hanya mengandung delta, yang cukup kecil. Anda hanya perlu ingat untuk memeriksa file yang baru dibuat. Terakhir saya melihat ini, pembaruan menambahkan sekitar 250 ribu - pakan ayam. Selain itu, khawatir tentang ukuran repo tidak ada artinya - disk murah.
cepat_now
Bagaimana dengan kapan rantai alat tertanam Anda tergantung pada lisensi jaringan :)
Dan
18

Neal Ford berpendapat dalam The Productive Programmer bahwa Anda harus menjaga binari dalam kendali sumber:

Mengapa menyimpan binari? Proyek saat ini bergantung pada petak alat eksternal dan perpustakaan. Katakanlah Anda menggunakan salah satu kerangka logging populer (seperti Log4J atau Log4Net). Jika Anda tidak membuat biner untuk pustaka logging tersebut sebagai bagian dari proses build Anda, Anda harus menyimpannya dalam kontrol versi. Itu memungkinkan Anda untuk terus membangun perangkat lunak Anda, bahkan jika kerangka kerja atau pustaka yang bersangkutan hilang (atau, lebih mungkin, memperkenalkan perubahan besar pada versi baru). Selalu jaga seluruh jagad yang diperlukan untuk membangun perangkat lunak Anda dalam kontrol versi(minus sistem operasi, dan bahkan itu dimungkinkan dengan virtualisasi; lihat “Menggunakan Virtualisasi,” nanti dalam bab ini). Anda dapat mengoptimalkan penahan binari dengan mempertahankannya di kontrol versi dan di drive jaringan bersama. Dengan begitu, Anda tidak harus berurusan dengan mereka setiap jam, tetapi mereka selamat jika Anda perlu membangun kembali sesuatu setahun kemudian. Anda tidak pernah tahu apakah Anda perlu membangun kembali sesuatu. Anda membangunnya sampai berfungsi, lalu lupakan. Sangat panik untuk menyadari bahwa Anda perlu membangun kembali sesuatu dari dua tahun lalu dan tidak memiliki semua bagian.

Saya sangat setuju; sementara ini bisa dibilang menumbangkan VCS untuk tugas yang tidak dirancang untuk (menjaga biner), saya pikir manfaatnya lebih besar daripada potensi kelemahannya. Tetapi, seperti yang dicatat penulis nanti, terkadang menyimpan binari di VCS mungkin bukan solusi yang praktis, sehingga opsi lain harus dipertimbangkan - seperti menyimpannya di drive jaringan yang dipetakan.

Jika binari tidak terlalu besar, saya pasti akan menyimpannya di VCS. Ini tampaknya lebih benar dalam kasus Anda, karena binari mungkin kecil, dan Anda bekerja dengan versi yang sangat spesifik. Mereka mungkin juga sulit ditemukan, karena berbagai alasan (penulis menutup situs web mereka, atau versi yang Anda butuhkan tidak lagi tercantum untuk diunduh). Meskipun tidak mungkin, Anda tidak pernah tahu apa yang akan terjadi dalam beberapa tahun.

Saya berharap saya membaca buku ini beberapa tahun yang lalu, ketika saya mengerjakan sebuah game menggunakan perpustakaan grafis (yang merupakan file dll); Saya mengganggu pengembangan untuk sementara waktu, dan ketika saya ingin melanjutkan saya tidak dapat menemukan dll lagi karena proyek itu mati.

Mihai Rotaru
sumber
2
Ya, ini terlalu sering terjadi. Saya memiliki proyek hobi di mana saya mengandalkan generator scanner yang ditinggalkan oleh penulisnya 3-4 tahun yang lalu. Untungnya itu selalu di bawah kendali versi.
Christian Klauser
9

Pada prinsipnya, saya menghargai kamp "periksa semua yang Anda butuhkan untuk membangun menjadi kontrol sumber", tetapi manajemen ketergantungan telah berkembang sedikit dalam beberapa tahun terakhir, dengan alat-alat seperti Maven, Ivy dan NuGet.

Juga, dalam praktiknya, saya menemukan memeriksa dalam biner untuk menciptakan sejumlah efek samping yang tidak menyenangkan. Git / Mercurial tidak benar-benar disetel untuk itu, misalnya, dan Subversion dan Perforce dapat membuat Anda gila ketika menggabungkan cabang yang berisi binari.

Dengan solusi manajemen dependensi, Anda menentukan dalam file yang dikendalikan sumber di proyek Anda yang nama paket dan versi mana proyek Anda bergantung. Hampir semua alat manajemen dependensi memungkinkan Anda untuk membuat repositori pribadi dari dependensi Anda, mengikuti semacam konvensi versi dan penamaan; ketika Anda membangun, alat manajemen ketergantungan akan menyelesaikan semua sumber terbuka dan dependensi milik Anda dari daftar sumber yang disetujui, kemudian memasukkannya ke dalam cache lokal Anda. Lain kali Anda membangun dengan dependensi versi yang sama, semuanya sudah ada dan berjalan lebih cepat.

Repositori pribadi Anda kemudian dapat didukung dengan alat cadangan sistem file konvensional.

Ini menghindari perlambatan yang saya alami ketika satu ton binari ditarik dari pohon sumber, dan mencegah repositori Anda dari memiliki banyak file yang sulit untuk di-diff. Hanya ada satu lokasi untuk ketergantungan apa pun, berdasarkan nama dan nomor versi, sehingga tidak ada konflik gabungan yang harus dihadapi, dan cache sistem file lokal berarti Anda tidak harus berurusan dengan biaya mengevaluasi apakah salinan lokal Anda telah berubah saat Anda menarik pembaruan.

Jason True
sumber
8

Kontrol sumber adalah untuk sumber. Sumber adalah apa yang tidak dapat Anda bangun dari hal lain. Beberapa file yang memenuhi syarat sebagai sumber adalah binari.

VCS saya memiliki banyak binari yang diperiksa, tetapi masing-masing adalah unit pelepasan dari beberapa produk yang tidak saya tulis dan tidak saya pertahankan. Ini mungkin sesuatu seperti GNU ccRTP, yang dirilis sebagai tarball terkompresi. Tarball itu adalah sumber saya, dan diperiksa bersama dengan infrastruktur apa pun yang saya perlukan untuk mengubahnya menjadi produk jadi (Makefile dan spesifikasi RPM dalam kasus saya) dalam satu langkah otomatis. Ketika ada versi baru ccRTP, saya memperlakukan tarball baru sebagai sumber yang diubah: itu masuk ke salinan check-out, dibangun, diuji dan berkomitmen kembali ke VCS. Saya telah melakukan hal yang sama dengan produk komersial yang tidak dikirimkan dengan sumber (kompiler, perpustakaan, dll.) Dan bekerja dengan cara yang sama. Alih-alih membongkar-configure-kompilasi-paket, itu hanya membongkar-paket. Perangkat lunak yang melakukan pembangunan malam tidakmake dan dapatkan produk jadi.

Sebagian besar VCSes memiliki fitur yang membuat sumber yang dapat dibaca manusia lebih mudah untuk ditangani dan lebih efisien untuk disimpan, tetapi untuk mengatakan bahwa mereka tidak cocok untuk binari tidak benar-benar benar jika biner dimasukkan kembali keluar tanpa gangguan. Bagaimana VCS berurusan dengan binari secara internal bergantung sepenuhnya pada apakah pengarangnya berpikir untuk hanya menyimpan perbedaan layak dilakukan. Secara pribadi, saya pikir menyimpan salinan lengkap dari distribusi ccRTP pada 600K pop lebih dari dibuat untuk kemampuan untuk menandai versi itu bersama dengan semua sumber saya yang lain.

Blrfl
sumber
4

Ini mengingatkan saya pada masalah "jars in repository" yang beberapa waktu lalu Java miliki. Orang-orang yang membangun aplikasi java digunakan untuk mendorong dependensi mereka (file jar biner) ke dalam repositori. Semua orang senang dengan ini, karena kami Anda akan memiliki sistem "satu klik" membangun dan ruang disk murah, jadi siapa yang peduli. Kemudian datang Maven dan Anda bisa menyingkirkan semua biner biner itu dan dengan repositori hanya-cache lokal masih mempertahankan build bullet-prof. Masih Anda memiliki sistem build "satu klik", tetapi kontrol sumber tidak harus mengacak file biner yang tidak masuk akal di sana.

Jadi ya, Anda bisa mendapatkan file biner dari kontrol sumber, tetapi ini akan mengharuskan Anda untuk men-tweak sistem build, untuk membuatnya pada waktu build. Tanpa perangkat lunak khusus (seperti Maven) ini mungkin banyak upaya untuk mengeluarkannya.

Jacek Prucia
sumber
1
Saya khawatir mempersulit proses pembuatan, sebagian besar karena sebagian besar tim adalah ahli matematika dan bukan penggemar proses.
Daniel Goldberg
3

Kontrol sumber Anda menahan sumber untuk apa yang Anda lakukan. Jika gumpalan biner yang diberikan dapat direkonstruksi dari sumber itu bukan sumber dan tidak boleh masuk dalam repositori kode sumber. Hanya gumpalan yang tidak dapat diolah kembali yang harus di kontrol sumber.

Anda biasanya memiliki lain repositori folder jaringan gumpalan biner Anda telah membangun melalui waktu satu sumber. Ini dapat digunakan untuk pelanggan atau digunakan dalam proyek (bukan membangun semuanya dari awal setiap waktu).

Jadi, letakkan di dalam jika itu adalah sumber. Jangan jika tidak.


sumber
Siapa yang akan mengunduh ini ??
Itu bukan saya, tapi saya curiga siapa pun yang tidak setuju dengan jawaban kedua.
Joel Coehoorn
@ JoelCoehoorn, menarik, karena memang itulah repositori Maven.
2

Tujuannya adalah untuk bisa mendapatkan kode terbaru dan membangunnya tanpa harus menginstal / mensetup apa pun (jadi, build "satu klik").

Di banyak tempat saya pernah, itu berarti memeriksa binari dependensi. Di yang lain, ini berarti skrip build mengunduh dan mendapatkan dependensi secara otomatis.

Lihat posting blog ini oleh Derek Greer tentang masalah ini.

Oded
sumber
2

Saya bekerja di sebuah proyek dengan dua tahap pembangunan yang berbeda

  • "program utama build" hanya membutuhkan beberapa binari, dibandingkan dengan ribuan file teks kode sumber, sehingga binari diperiksa ke dalam repositori. Ini berfungsi dengan baik.

  • installer installer memerlukan banyak komponen pihak ketiga (beberapa di antaranya hanya disalin ke CD instalasi, seperti Adobe Reader). Kami tidak memasukkannya ke dalam repositori. Sebagai gantinya, komponen-komponen itu berada di drive jaringan (bahkan versi yang lebih lama), dan skrip build menyalinnya ke tempat yang tepat. Tentu saja, untuk memiliki bangunan yang dapat direproduksi, siapa pun harus berhati-hati untuk tidak mengubah folder tempat komponen pihak ketiga disimpan.

Kedua strategi berfungsi dengan baik dan memenuhi persyaratan "memeriksa dari kendali sumber mencakup semua yang Anda perlukan untuk mengkompilasi kode".

Doc Brown
sumber
1

Anda perlu menyimpan semua yang Anda perlukan untuk membangun kembali versi produk tertentu di masa mendatang.

Namun Anda tidak harus menyimpan semuanya di Kontrol Sumber.

Satu perusahaan menyimpan rak server yang dibekukan (karena OS hanya berjalan pada perangkat keras tertentu, dan toolchain hanya berjalan pada OS itu, dan sumbernya tergantung pada toolchain itu). Tidak dapat memeriksanya ke Kontrol Sumber.

Jika Anda perlu membagi persyaratan untuk bangunan, maka Anda memiliki masalah akuntansi menjaga dua sistem kontrol versi disinkronkan. mis. kotak perangkat keras dalam lemari ini, atau VM atau binari dalam volume cadangan yang diawetkan ini, ikuti revisi Kode Sumber SVN ini, dll.

hotpaw2
sumber
0

Sangat kacau untuk check-in biner ke SCM di pikiran saya. Saya telah menjalankan proyek yang sangat kompleks, yang memiliki banyak ketergantungan pada perpustakaan bagian ketiga. Prinsip-prinsip yang kami adopsi:

  1. Semua kode sumber dikelola dengan SCM
  2. Semua dependensi dikelola dengan Ivy, yang memiliki integrasi gerhana besar.

Ini bekerja dengan cukup baik. Kami memiliki file konfigurasi tentang versi setiap perpustakaan eksternal yang dapat dikompilasi dengan kode sumber. File konfigurasi ini diperiksa ke dalam SCM, sehingga berevolusi ketika kode sumber berevolusi. Dengan menerapkan pendekatan ini, kita dapat benar-benar mereproduksi build tanpa mengacaukan versi pustaka eksternal.

James Gan
sumber
0

Secara pribadi, secara filosofis, saya cenderung membiarkan kontrol sumber memeriksa pointer ke file biner besar (sumber daya biner kecil ok), dan bukan isi file. Pointer ini akan berisi hash dari isi file biner.

File biner itu sendiri tidak akan dikelola oleh kontrol sumber. Ini akan disimpan di semacam perpustakaan di mana ia dapat diambil menggunakan pointer, atau hash secara khusus.

Git LFS dan git lampiran melakukan itu, tetapi mereka juga mencoba untuk mengelola file biner sampai batas tertentu, saya tidak ingin mereka melakukan itu. Saya ingin Git hanya menyimpan checksum, dan memberi tahu saya apakah file biner saya telah berubah atau tidak - tetapi saya tidak ingin Git mencoba mengelolanya dan menyimpannya. Saya ingin melakukan ini sendiri.

Saya pikir git dapat menangani file biner berukuran kecil dan menengah, tetapi saya tidak yakin itu adalah alat yang tepat untuk mengelola file biner besar.

Rolf
sumber