Kemungkinan Gandakan:
Saya pecandu Subversion, mengapa saya harus mempertimbangkan atau tidak mempertimbangkan Mercurial atau Git atau DVCS lainnya?
Sesekali, Anda mendengar seseorang mengatakan bahwa kontrol versi terdistribusi (Git, HG) secara inheren lebih baik daripada kontrol versi terpusat (seperti SVN) karena penggabungan sulit dan menyakitkan di SVN. Masalahnya adalah, saya tidak pernah memiliki masalah dengan penggabungan dalam SVN, dan karena Anda hanya pernah mendengar klaim yang dibuat oleh pendukung DVCS, dan bukan oleh pengguna SVN yang sebenarnya, cenderung mengingatkan saya pada iklan-iklan yang menjengkelkan di TV di mana mereka Cobalah untuk menjual sesuatu yang tidak Anda butuhkan dengan membuat aktor yang kikuk berpura-pura bahwa barang yang sudah Anda miliki dan berfungsi dengan baik sangat sulit digunakan.
Dan use case yang selalu diangkat adalah menggabungkan kembali cabang, yang sekali lagi mengingatkan saya pada iklan produk strawman; jika Anda tahu apa yang Anda lakukan, Anda seharusnya tidak (dan seharusnya tidak perlu) menggabungkan kembali cabang di tempat pertama. (Tentu saja sulit dilakukan ketika Anda melakukan sesuatu yang pada dasarnya salah dan konyol!)
Jadi, mendiskontokan kasus penggunaan strawman yang konyol, apa yang ada dalam penggabungan SVN yang secara inheren lebih sulit daripada penggabungan dalam sistem DVCS?
Jawaban:
Itu karena svn tidak memiliki struktur data yang tepat untuk secara akurat menentukan leluhur bersama terbaru dari dua cabang. Itu bukan masalah besar untuk cabang yang hanya digabung satu kali, tetapi dapat menyebabkan banyak konflik penggabungan yang salah dalam situasi di mana beberapa cabang digabung beberapa kali.
Saya tidak mengikuti svn dengan sangat cermat, tetapi pemahaman saya adalah masalah teknis tertentu telah diperbaiki dalam versi terbaru. Namun, itu tidak diperbaiki cukup awal untuk menghilangkan mitos, dan orang-orang yang mencoba DVCS untuk penggabungan telah terjebak dengan itu karena alasan lain.
sumber
Dan di situlah letak sumber kebingungan Anda dan seluruh masalah secara umum.
Anda mengatakan bahwa menggabungkan cabang adalah "secara fundamental salah dan konyol". Nah, itulah masalahnya: Anda memikirkan cabang sebagai hal yang tidak boleh digabungkan. Mengapa? Karena Anda adalah pengguna SVN yang tahu bahwa menggabungkan cabang itu sulit . Karena itu, Anda tidak pernah melakukannya, dan Anda mendorong orang lain untuk tidak melakukannya. Anda telah dilatih untuk menghindari penggabungan; Anda telah mengembangkan teknik yang Anda gunakan untuk menghindari penggabungan.
Saya pengguna Mercurial. Bahkan pada proyek saya sendiri, di mana saya satu-satunya pengembang, saya menggabungkan cabang sepanjang waktu . Saya memiliki cabang rilis, yang saya perbaiki. Yah, saya menggabungkan itu kembali ke jalur utama sehingga perbaikannya ada di sana.
Jika saya menggunakan SVN, saya akan mengadopsi struktur basis kode yang sama sekali berbeda. Mengapa? Karena SVN membuat penggabungan menjadi sulit, dan karenanya Anda mengembangkan idiom dan teknik untuk menghindari melakukan penggabungan yang rumit.
DVCS membuat penggabungan yang kompleks menjadi mudah karena merupakan kondisi default . Semuanya adalah cabang, kurang lebih, dalam DVCS. Jadi seluruh strukturnya dibangun dari bawah ke atas untuk mempermudah penggabungan. Ini memungkinkan Anda untuk mengembangkan alur kerja yang menggunakan penggabungan setiap hari, daripada alur kerja SVN di mana Anda tidak pernah menggunakan penggabungan.
Fakta sederhananya adalah ini: Anda harus mendekati DVCS dengan cara yang berbeda dari SVN. Anda harus menggunakan idiom yang tepat untuk berbagai jenis sistem kontrol versi yang sangat berbeda ini. Di SVN, Anda mengadopsi idiom yang tidak melibatkan penggabungan karena penggabungan itu sulit. Di DVCS, Anda mengadopsi idiom yang sering menggunakan penggabungan karena itu bukan masalah besar.
Alat yang tepat untuk pekerjaan yang tepat.
Masalahnya, alur kerja yang berfokus pada penggabungan jauh lebih bagus dan lebih mudah digunakan daripada alur kerja gaya SVN di mana Anda tidak menggabungkan hal-hal. Lebih mudah untuk melihat ketika sesuatu dari cabang rilis dibawa ke cabang dev. Lebih mudah untuk melihat berbagai interaksi antar cabang. Sangat mudah untuk membuat cabang uji untuk berbagai hal, lalu memotongnya jika tes tidak berhasil. Dan seterusnya.
Sungguh, Joel menjelaskan ini jauh lebih baik daripada yang saya bisa . Anda harus membaca itu dengan baik.
sumber
Tidak ada yang terlalu sulit tentang penggabungan SVN ... lagi ... jika Anda mengikuti filosofi yang benar
Apa yang saya lihat di sebagian besar jawaban lain tampaknya berasal dari orang yang belum pernah menggunakan SVN untuk sementara waktu. Seperti seseorang dengan akurat menyebutkan: "itu tidak diperbaiki cukup awal untuk menghilangkan mitos".
Dari pengalaman saya saat ini menggunakan SVN 1.6 hingga 1.8 pada proyek lawas yang saya warisi baru-baru ini, SVN telah jauh menuju membuat penggabungan hal yang jauh lebih mudah. Ini bukan sangat mudah, dan saya pikir itu tidak mudah membuat pengguna menyimpang dari penggunaan yang dimaksudkan.
Sementara saya mengenal SVN dengan sangat baik dan juga telah mencoba Mercurial untuk proyek-proyek pribadi sementara itu, saya belum pernah melakukan banyak percabangan di SVN sebelum proyek ini. Ada sedikit trial and error dan saya mendapat banyak konflik penggabungan yang tidak terduga ketika saya mulai.
Pada akhirnya, saya menyadari bahwa setiap kali saya mendapatkannya (atau masalah lain), itu karena saya tidak melakukan hal-hal dengan benar (alias "jalan SVN" - bisa dibilang, cara kontrol versi yang tepat). Saya percaya di sinilah letak masalahnya: Anda tidak dapat melakukan apa pun yang Anda inginkan dengan cara yang tidak terorganisir dan berharap SVN bekerja dengan sempurna, terutama dengan penggabungan. Penggabungan membutuhkan disiplin yang ketat dari pengguna sebelum mereka menunjukkan kekuatan mereka yang sebenarnya.
Berikut adalah hal-hal yang saya perhatikan adalah rekomendasi kuat, jika bukan persyaratan, untuk penggunaan gabungan yang bersih:
Jika Anda tidak mengikuti hal di atas, kemungkinan besar Anda akan mengalami konflik. Mereka selalu dipecahkan, tetapi tidak terlalu menyenangkan untuk menghabiskan waktu.
Oh, satu hal lagi tentang menggabungkan di mana, dari semua yang telah saya baca dan coba, SVN benar-benar menyebalkan: menghapus / memindahkan / mengganti nama file / folder. Rupanya , SVN masih tidak dapat menangani file yang diganti namanya, dihapus atau dipindahkan dalam satu cabang, dan versi aslinya diubah di cabang lain ... dan kemudian menggabungkan ini bersama-sama. Itu tidak akan tahu ke mana file itu pergi dengan satu cara, dan akan "melupakan" perubahan dengan cara lain. Satu perubahan jelas tidak dapat dipecahkan (Anda menghapus atau mengubah file, tidak dapat melakukan keduanya), tetapi menerapkan perubahan pada file yang dipindahkan / diubah namanya harus berfungsi dan tidak. Semoga ini segera diperbaiki.
Jadi, secara keseluruhan, apakah penggabungan SVN mudah? Saya rasa tidak. Tidak dengan cara yang riang, pasti. Apakah itu buruk ? Saya kira tidak. Itu hanya meludahi wajah Anda ketika Anda menggunakannya dengan cara yang salah dan tidak cukup berpikir tentang apa yang Anda lakukan.
Berdasarkan hal ini, saya dapat melihat mengapa orang mungkin lebih suka Mercurial (misalnya) karena sedikit lebih lunak tentang hal-hal ini dari pengalaman saya dan semuanya otomatis dari awal (setidaknya dari versi awal saya mulai dengan). SVN telah sedikit mengejar, jadi tidak layak untuk banyak bashing lagi.
sumber
Model data internal secara fundamental berbeda.
Pada dasarnya, di SVN, ketika Anda melihat sejarah cabang, Anda hanya melihat apa yang terjadi di cabang itu. Jadi, ketika Anda menggabungkan dari cabang
B
ke cabangA
, sejarah cabangA
akan berisi satu komit besar yang berisi semua perubahan yang dibuat secara eksplisitB
sejak bercabang.Di versi SVN pertama, jika Anda harus menggabungkan cabang
B
menjadi cabangA
sekali lagi, Anda harus secara manual menentukan rentang revisi cabang manaB
yang ingin Anda gabungkan untuk menghindari penggabungan revisi yang sama dua kali. Pengembang yang pintar tentu saja akan menggunakan pesan komit seperti 'Digabung dalam B: 1234'.SVN 1.5 "memperbaiki" ini. Tetapi itu tidak mengubah bagaimana penggabungan diterapkan secara fundamental. Itu hanya menambahkan beberapa metadata tambahan ke cabang
A
, membiarkan SVN tahu bahwa revisi 1234 telah digabungkan, memungkinkan SVN untuk secara otomatis memilih rentang revisi yang benar.Tetapi solusi ini pada dasarnya merupakan solusi untuk model data yang pada dasarnya tidak mendukung melacak apa yang telah digabungkan.
Menggabungkan dua cabang adalah contoh yang relatif sederhana. Tetapi pencitraan skenario yang lebih kompleks ini
A
daritrunk
, dan buat beberapa komitmen di siniB
dariA
dan buat beberapa komitmen di sinitrunk
danA
B
ketrunk
A
keB
A
ketrunk
B
ketrunk
(ini tidak harus benar-benar melakukan apa-apa)Menangani ini dengan benar menggunakan model metadata menjadi sangat kompleks (saya tidak tahu apakah SVN memang menangani skenario ini dengan benar, dan saya tidak merasa cenderung untuk mengujinya).
Menangani skenario ini di git sangat sederhana.
Di git, setiap kali Anda melakukan, objek internal yang mewakili komit berisi referensi ke kepala sebelumnya. Ketika Anda menggabungkan cabang, komit berisi referensi ke kepala sebelumnya dari semua cabang yang digabung (Anda dapat menggabungkan lebih dari satu cabang sekaligus dalam git)
Oleh karena itu, ketika Anda memeriksa sejarah satu commit di git, Anda bisa melihat semua histori, Anda bisa melihat kapan itu bercabang, kapan itu digabung, dan Anda bisa melihat sejarah kedua cabang antara percabangan dan penggabungan.
Jadi ketika menggabungkan cabang yang telah sebagian digabung, sangat mudah untuk menentukan apa yang sudah digabung, dan apa yang belum.
Saya tidak punya pengalaman dengan Mercurial, tetapi saya curiga cara kerjanya mirip dengan git.
Jadi pada dasarnya, untuk SVN, itu adalah tujuan desain untuk membuat percabangan murah. Tetapi dalam git, itu adalah tujuan desain untuk membuat penggabungan menjadi murah.
Terakhir, terakhir kali saya menggunakan SVN, itu tidak dapat menangani penggabungan, di mana file diubah namanya di satu cabang, dan dimodifikasi di yang lain.
sumber
Saya telah melakukan sedikit penggabungan SVN - termasuk memiliki pengembangan yang berjalan lama dan melepaskan cabang. Pada umumnya saya selamat. Penggabungan selalu sulit, tetapi dengan DCVS, sisi buruknya tidak buruk - semuanya bersifat lokal, jadi perbarui saja revisi yang dikenal baik dan teruskan. Sedangkan dengan banyak SVN terjadi di sisi server sehingga pemulihan jelek - biasanya itu melibatkan memusnahkan salinan lokal kemudian memeriksa cabang bersih baru untuk mencobanya lagi. Tidak buruk dalam kasus saya - koneksi gigabit ke kotak SVN membantu. Tetapi kami memiliki beberapa kontraktor yang memiliki banyak masalah dengan ini karena mereka pada koneksi yang lambat sehingga semuanya butuh waktu lama, termasuk penggabungan.
sumber
Di sinilah letak salah satu hal yang sangat menyenangkan tentang git. Itu tidak mewarisi tentang DVCS, itu hanya sesuatu yang unggul di git. Anda dapat menggabungkan revisi spesifik dari cabang mana saja ke cabang lain. Pada dasarnya hanya mengambil diff dan menerapkannya ke cabang lain, tetapi melakukan pelacakan dan jauh lebih otomatis.
Jadi, jika Anda memiliki branch 2.0 dan branch 3.0 dan menemukan bug di 2.0, Anda dapat memperbaikinya di 2.0 dan mengambil serangkaian revisi yang menyelesaikannya dan menggabungkan hanya revisi-revisi tersebut ke dalam cabang 3.0. Saya tidak percaya SVN punya cara untuk melakukan ini selain mengambil secara manual untuk setiap revisi dan menerapkannya
Tentu saja, algoritma auto-merge juga tampaknya berfungsi jauh lebih halus dan git dibangun dari bawah ke atas pada model "make a branch for all things", sehingga percabangan benar-benar halus dan mudah di dalamnya. Rasanya alami untuk bercabang sering dengan betapa ringan cabang-cabangnya
sumber