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, .git
sebagian 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-found
atau git-fsck --lost-found
dan 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/HEAD
file, yang terlihat seperti ini jika Anda berada di master
cabang.
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 update
in 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-submodule
tetapi 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 heads
disebut tips
dan branches
yang bookmarks
bukan dalam terminologi lincah.