Dari pemahaman saya, SVN adalah 'Mudah untuk cabang. Sulit untuk digabung '. Mengapa demikian? Apakah ada perbedaan bagaimana mereka bergabung?
Silakan lihat jawaban Stack Overflow saya untuk situasi yang sangat konkret di mana Mercurial (dan Git) bergabung tanpa masalah dan di mana Subversion menghadirkan konflik palsu kepada Anda. Situasinya adalah refactoring sederhana yang dilakukan pada cabang tempat Anda mengganti nama beberapa file.
Berkenaan dengan jawaban tammmer, maka ada sejumlah kesalahpahaman di sana:
Subversion, Mercurial, dan Git semua snapshot track-lebar proyek. Menyebutnya versi , revisi , atau perubahan tidak ada bedanya. Itu semua secara logis merupakan cuplikan atom dari sekumpulan file.
Ukuran komit Anda tidak membuat perbedaan dalam hal penggabungan. Ketiga sistem bergabung dengan algoritma gabungan tiga arah standar dan input untuk algoritma tersebut
Tidak masalah bagaimana dua versi cabang dibuat. Anda dapat menggunakan 1000 komit kecil sejak versi leluhur, atau Anda dapat menggunakan 1 komit. Yang penting adalah versi final file. (Ya, ini mengejutkan! Ya, banyak panduan DVCS yang salah ini.)
Dia juga memunculkan beberapa poin bagus tentang perbedaan:
Subversion memiliki beberapa "voodoo" di mana Anda dapat bergabung dari /trunk
, katakanlah /branches/foo
,. Mercurial dan Git tidak menggunakan model ini - cabang malah dimodelkan secara langsung dalam sejarah. Karenanya sejarah menjadi grafik asiklik yang terarah bukannya linier. Ini model yang jauh lebih sederhana daripada yang digunakan oleh Subversion dan ini memotong sejumlah kasus sudut.
Anda dapat dengan mudah menunda penggabungan atau bahkan membiarkan orang lain menanganinya. Jika hg merge
memberi Anda satu ton konflik, maka Anda dapat meminta rekan kerja hg pull
Anda dari Anda dan kemudian ia memiliki kondisi yang sama persis. Jadi dia bisa hg merge
dan mungkin dia lebih baik dalam menyelesaikan konflik daripada Anda.
Ini sangat sulit dengan Subversion di mana Anda harus memperbarui sebelum dapat melakukan. Anda tidak bisa mengabaikan perubahan di server dan terus melakukan di cabang anonim Anda sendiri. Secara umum, Subversion memaksa Anda untuk bermain-main dengan copy pekerjaan yang kotor ketika Anda svn update
. Ini agak berisiko karena Anda belum menyimpan perubahan Anda di tempat yang aman. Git dan Mercurial memungkinkan Anda melakukan komit terlebih dahulu, lalu memperbarui dan menggabungkan seperlunya.
Alasan sebenarnya Git dan Mercurial lebih baik dalam merger daripada Subversion adalah masalah implementasi. Ada perubahan nama konflik yang Subversion tidak bisa atasi bahkan berpikir sudah jelas apa jawaban yang benar. Mercurial dan Git menangani itu dengan mudah. Tetapi tidak ada alasan mengapa Subversion tidak dapat menangani hal itu juga - dipusatkan tentu bukan alasannya.
trunk
di SVN. Dengan DVCS Anda dapat melakukan tanpa berbagi, tetapi dalam SVN Andasvn commit
akan langsung mempengaruhi orang lain yang bekerja di cabang yang sama. Bahkan jika kami berdua bekerja di cabang di SVN, saya tidak bisa melakukan pekerjaan saya tanpa harus segera bergabung dengan pekerjaan Anda. Itu membuat komit agak menakutkan - yang merupakan properti menakutkan untuk sistem kontrol versi! :-)Masalah inti terletak pada cara sistem ini mewakili struktur direktori berversi.
Konsep dasar Subversion di mana seluruh sistem berputar adalah versi (atau, dalam bahasa svn, "revisi"): snapshot file pada titik tertentu. Selama sejarahnya benar-benar linier, semuanya baik-baik saja, tetapi jika Anda perlu menggabungkan perubahan dari dua jalur independen pengembangan, svn harus membandingkan versi saat ini dari keduanya, dan kemudian melakukan perbandingan tiga arah antara versi terakhir yang dibagikan dan dua versi kepala. Garis yang muncul berubah di salah satu kepala, tetapi tidak yang lain, dapat dengan mudah diselesaikan; garis yang menyimpang dengan cara yang sama persis di kedua kepala lebih sulit, tetapi biasanya bisa dilakukan; garis yang menyimpang dengan cara yang berbeda adalah apa yang membuat svn mengatakan, "Aku tidak tahu ini, manusia, tolong selesaikan ini untukku."
Sebaliknya, git dan track perubahan berubah daripada versi. Seluruh repositori adalah pohon perubahan, masing-masing tergantung pada orang tua, di mana orang tua perubahan dapat memiliki jumlah anak berapa pun, dan akar pohon mewakili direktori kosong. Dengan kata lain, git / hg mengatakan "pertama saya tidak punya apa-apa, lalu tambalan ini diterapkan, lalu tambalan itu, dll.". Ketika Anda perlu menggabungkan dua baris pengembangan, git / hg tidak hanya tahu seperti apa masing-masing kepala saat ini, dan seperti apa versi umum terakhirnya, tetapi juga tahu bagaimana transisi terjadi, memungkinkan penggabungan yang jauh lebih cerdas.
Hal lain yang membuat penggabungan menjadi lebih mudah dalam DVCS adalah konsekuensi tidak langsung dari pemisahan konsep commit dan push, dan memungkinkan segala macam gabungan silang antara dua klon dari repositori yang sama setiap saat. Dengan svn, orang cenderung melakukan perubahan besar dengan perubahan yang sering tidak berhubungan, karena komitmen juga merupakan pembaruan pada repositori pusat yang mempengaruhi semua anggota tim lainnya; jika Anda melakukan versi yang rusak, semua orang akan marah kepada Anda. Karena sebagian besar pengaturan melibatkan server svn jaringan, melakukan juga melibatkan pemompaan data melalui jaringan, yang berarti melakukan menimbulkan penundaan yang cukup besar pada alur kerja (terutama ketika copy pekerjaan Anda sudah usang dan Anda harus menarik lebih dulu). Dengan git dan lincah, komit terjadi secara lokal, dan karena keduanya sangat efisien dalam menangani sistem file lokal, biasanya selesai secara instan. Akibatnya, orang-orang (begitu mereka terbiasa) melakukan perubahan bertahap kecil, dan ketika itu berhasil, dorong selusin atau lebih komit dalam sekali jalan. Kemudian ketika waktu penggabungan muncul, SCM memiliki banyak informasi yang lebih detail untuk dilalui, dan dapat melakukan pekerjaan yang lebih baik dalam menyelesaikan konflik dengan aman dan otomatis.
Dan kemudian ada detail bagus yang membuat segalanya lebih mudah:
sumber
hg mv
atauhg addremove --similarity...
), sementara Git menggunakan heuristik, tetapi keduanya menangani penggantian nama . Saya bisa mendapatkan konflik pohon bahkan dengan perbedaan 1 string dalam file yang digabungkan! Anda harus mempelajari kembali beberapa aspek Subversi, maaf.rename a b
sebagaicopy a b; remove a
dan keduanya melakukannya dalam satu atom komit. Perbedaan dalam perilaku penggabungan berasal dari penanganan kasus sudut yang berbeda dan dari Subversion yang memungkinkan penggabungan lebih banyak daripada Mercurial dan Git. Akhirnya, Git mendeteksi nama-nama pada saat penggabungan dan waktu log - kami juga berpikir untuk menambahkan ini dalam Mercurial.