Apa yang dimaksud dengan "bercabang gratis" di Git?

27

Apa yang dimaksud dengan "bercabang gratis" di Git?

Saya sering mendengar ini setiap kali Git disebutkan dibandingkan dengan sistem kontrol versi lainnya.

Saya belum memiliki kesempatan (?) Untuk berurusan dengan orang lain ( SVN , dll.), Jadi bagaimana percabangan "mahal" pada orang lain?

laggingreflex
sumber

Jawaban:

28

Klaim bahwa "bercabang adalah gratis di git" adalah penyederhanaan fakta karena itu tidak "bebas" per se. Mencari di bawah tenda klaim yang lebih tepat akan mengatakan bahwa percabangan itu redonkulously murah , karena cabang pada dasarnya referensi untuk melakukan . Saya mendefinisikan "murahnya" di sini sebagai lebih murah, lebih murah.

Mari kita gali mengapa Git sangat "murah" dengan memeriksa jenis overhead apa yang dimilikinya:

Bagaimana cabang diimplementasikan di git?

Repositori git, .gitsebagian besar terdiri dari direktori dengan file yang berisi metadata yang digunakan git. Setiap kali Anda membuat cabang di git, dengan misalnya git branch {name_of_branch}, beberapa hal terjadi:

  • Referensi dibuat ke cabang lokal di: .git/refs/heads/{name_of_branch}
  • Log riwayat dibuat untuk cabang lokal di: .git/logs/refs/heads/{name_of_branch}

Pada dasarnya itu, beberapa file teks dibuat. Jika Anda membuka referensi sebagai file teks, isinya akan menjadi id-sha dari commit yang ditunjuk oleh cabang. Perhatikan bahwa bercabang tidak mengharuskan Anda untuk membuat komitmen karena mereka jenis objek lain. Baik cabang maupun komit adalah "warga negara kelas satu" dalam git dan salah satu caranya adalah dengan memikirkan hubungan cabang-untuk-komitmen sebagai agregasi daripada komposisi. Jika Anda menghapus cabang, komit akan tetap ada sebagai "menggantung". Jika Anda secara tidak sengaja menghapus cabang, Anda selalu dapat mencoba menemukan komit dengan git-lost-foundatau git-fsck --lost-founddan membuat cabang pada sha-id yang Anda temukan tergantung menggantung (dan selama git belum melakukan pengumpulan sampah apa pun).

Jadi bagaimana cara git melacak cabang mana yang sedang Anda kerjakan? Jawabannya ada pada .git/HEADfile, yang terlihat seperti ini jika Anda berada di mastercabang.

ref: refs/heads/master

Berpindah cabang hanya mengubah referensi di .git/HEAD file, dan kemudian mulai mengubah konten ruang kerja Anda dengan yang didefinisikan dalam komit.

Bagaimana hal ini dibandingkan dalam sistem kontrol versi lain?

Dalam Subversion , cabang adalah direktori virtual dalam repositori . Jadi cara termudah untuk bercabang adalah melakukannya dari jarak jauh, dengan satu garis svn copy {trunk-url} {branch-url} -m "Branched it!". Apa yang akan dilakukan SVN adalah sebagai berikut:

  • Salin direktori sumber, mis trunk , ke ke direktori target,
  • Komit perubahan untuk menyelesaikan tindakan salin.

Anda akan ingin melakukan tindakan ini dari jarak jauh di server, karena membuat salinan itu secara lokal adalah operasi linear, dengan file yang disalin dan disinkronkan. Ini adalah operasi yang sangat lambat , sedangkan melakukannya di server adalah operasi waktu yang konstan. Perhatikan bahwa bahkan ketika melakukan cabang pada server, subversi memerlukan komit ketika bercabang sementara git tidak, yang merupakan perbedaan utama. Itu adalah salah satu jenis overhead yang membuat SVN sedikit lebih murah daripada Git.

Perintah untuk berpindah cabang di SVN , yaitu svn switch, sebenarnya adalah svn updatein disguise. Berkat konsep direktori virtual, perintahnya sedikit lebih fleksibel di svn daripada di git. Sub direktori di ruang kerja Anda dapat diubah untuk mencerminkan url repositori lain. Hal terdekat adalah menggunakan git-submoduletetapi menggunakan itu secara semantik sangat berbeda dari percabangan. Sayangnya ini juga merupakan keputusan desain yang membuat pengalihan SVN sedikit lebih lambat daripada di Git karena harus memeriksa setiap direktori ruang kerja yang dicerminkan oleh remote-url-nya. Dalam pengalaman saya, Git lebih cepat untuk berganti cabang daripada SVN.

Percabangan SVN datang dengan biaya karena menyalin file dan selalu harus tersedia untuk umum. Di git, seperti yang dijelaskan di atas, cabang adalah "hanya referensi" dan dapat disimpan dalam repositori lokal Anda dan dipublikasikan sesuai kebijaksanaan Anda. Namun dalam pengalaman saya, SVN masih jauh lebih murah dan lebih berkinerja daripada misalnya ClearCase.

Sangat disayangkan bahwa SVN tidak terdesentralisasi. Anda dapat memiliki beberapa repositori yang dicerminkan ke beberapa repo sumber tetapi menyinkronkan perubahan yang berbeda beberapa repositori SVN tidak dimungkinkan karena SVN tidak memiliki pengidentifikasi unik untuk komit (git memiliki pengidentifikasi hash yang didasarkan pada isi komit). Alasan mengapa saya secara pribadi mulai menggunakan git melalui SVN adalah karena memulai repositori jauh lebih mudah dan lebih murah di git . Secara konseptual dalam hal manajemen konfigurasi perangkat lunak, setiap salinan proyek yang berbeda (klon, garpu, ruang kerja atau apa pun) adalah "cabang", dan mengingat terminologi ini membuat salinan baru di SVN tidak semurah Git, di mana yang terakhir memiliki cabang "built-in".

Sebagai contoh lain, di Mercurial , bercabang dimulai sedikit berbeda sebagai DVCS dan membuat / menghancurkan cabang bernama diperlukan komitmen terpisah. Pengembang Mercurial dilaksanakan nanti dalam pengembangan bookmark model percabangan yang sama meniru git sekalipun headsdisebut tipsdan branchesyang bookmarksbukan dalam terminologi lincah.

Spoike
sumber
Wow. Terima kasih banyak atas penjelasan "mahal".
laggingreflex
2
Dari sumber Anda sendiri: This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.- Membuat cabang itu sepele di SVN, kecuali jika Anda secara eksplisit membuat salinan setiap file.
Bobson
@ Bobson Saya sedang berpikir tentang menulis ulang bit pada percabangan, karena saya melakukan banyak handwaving mengenai hal itu, tetapi poin saya masih teguh bahwa sebuah komit diperlukan untuk membuat cabang sementara di Git tidak. Dalam pengalaman saya yang sederhana, saya masih merasa bahwa beralih cabang di SVN lebih lambat daripada di Git tapi saya tidak bisa menunjukkan alasan spesifik mengapa.
Spoike
2
@Spoike - Beralih, tentu saja. Dan sebuah komit pasti diperlukan. Saya melakukan edit untuk memperjelas bagian yang bermasalah. Jangan ragu untuk mengembalikannya jika Anda mau.
Bobson
10

Di Git, cabang hanya merujuk pada komit ke repo lokal. Menciptakannya sangat murah, tidak ada jaringan sama sekali. Tidak cukup gratis (Anda harus mengetik perintah), tetapi sangat dekat.

Bercabang tidak terlalu mahal di SVN - itu hanya salinan, yang merupakan komit yang sangat murah. SVN memang memiliki model repositori pusat, jadi ini adalah akses jaringan, tetapi bukan yang mengerikan.

Di CVS yang terhormat, di sisi lain, percabangan SANGAT mahal. Pada dasarnya, cabang CVS melibatkan penambahan tag, tetapi dalam CVS itu berarti bahwa SETIAP FILE TERPENGARUH harus dimodifikasi. Setiap file ditulis ulang untuk memasukkan tag baru. Itu sangat mahal. Dan jika repositori Anda besar, itu juga sangat lambat. Bahkan, jika Anda sedang mengerjakan proyek besar, itu cukup lambat sehingga beberapa orang cenderung menghindari membuat cabang jika mereka bisa.

Michael Kohne
sumber
4
Dengan Git, bahkan kurang dari komit - cabang hanyalah label. Dan SVN terdengar semahal CVS, karena keduanya menyalin semua file.
Izkata
8
@Izkata: jika kita melihat dari sudut pandang pengguna - ya, semua file disalin, dari sudut pandang implementasi (dan kinerja) - tidak, hanya catatan tentang salinan yang ditambahkan.
maxim1000
@Izkata terlalu banyak untuk dikomentari - lihat jawaban saya.
gbjbaanb
6
@Izkata SVN membuat pointer dan referensi, itu tidak menyalin segalanya.
Aaron McIver
2
Cabang Git bukan komit, itu hanya referensi ke komit yang dapat dipindahkan secara bebas ke komit lainnya. Pikirkan repo Git hanya sebagai pohon komitmen, dan cabang-cabang sebagai catatan tempel yang dapat dengan bebas dipindahkan ke berbagai komitmen pada pohon itu.
40XUserNotFound
5

Percabangan SVN sebebas Git. Hanya sedikit data housekeeping yang menyebutkan dari mana cabang dimulai, tidak ada perubahan pada file yang disimpan. 'Salin' di SVN seperti menambahkan symlink ke direktori Unix. Perhatikan bahwa cabang SVN tidak akan memerlukan perjalanan jaringan sampai Anda melakukan perubahan copy pekerjaan Anda (tetapi tidak ada banyak gunanya memiliki SCM jika Anda tidak melakukan off-lokal di beberapa titik).

Perhatikan bahwa cabang Git juga akan melibatkan beberapa housekeeping - seperti menambahkan tag itu secara internal - yang harus disimpan di suatu tempat ketika Anda melakukan. Sama sekali bukan masalah besar, oleh karena itu disebut 'gratis'.

gbjbaanb
sumber
5

Ini 'gratis' (dalam konteks ini 'bebas' benar-benar berarti cepat dan mudah dan tidak memakan tempat) karena dalam beberapa sistem kontrol versi yang lebih lama, sebuah cabang adalah salinan lengkap kode pada saat itu, sehingga cabang-cabang mengambil banyak ruang dan mudah untuk berakhir dengan banyak versi yang berbeda dari perangkat lunak, yang kemudian mengambil manajemen. Di yang lain itu bukan salinan lengkap dari kode tetapi setiap file masih perlu dimodifikasi untuk sebuah tag jadi lambat dan menyakitkan ('mahal').

Cabang-cabang git pada dasarnya adalah label yang menunjukkan komit dan karenanya menghindari masalah di atas.

Michael Durrant
sumber
1

Aspek lain dari "gratis / murah / mahal" adalah berkaitan dengan berapa biaya dalam hal sumber daya pengembang untuk menangani konsekuensi hilir dari percabangan; yaitu proses menggabungkan perubahan dari cabang.

Dan di sini, menggabungkan cabang dalam sistem DVCS seperti Git dan Mercurial lebih mudah daripada di sistem yang lebih lama ... karena sistem DVCS melakukan pekerjaan yang jauh lebih baik untuk melacak sejarah versi dalam grafik; yaitu di mana cabang sebelumnya penggabungan telah terjadi. Ini membuat penggabungan menjadi lebih akurat, mengurangi konflik yang tidak perlu dan ... menjadikan penggabungan secara subyektif "lebih mudah" atau "kurang menakutkan" bagi pengembang yang terlibat.

Stephen C
sumber