Saya sering membaca bahwa Hg (dan Git dan ...) lebih baik dalam menggabungkan daripada SVN tetapi saya belum pernah melihat contoh praktis di mana Hg / Git dapat menggabungkan sesuatu di mana SVN gagal (atau di mana SVN membutuhkan intervensi manual). Bisakah Anda memposting beberapa langkah demi langkah daftar cabang / memodifikasi / melakukan / ...- operasi yang menunjukkan di mana SVN akan gagal sementara Hg / Git dengan senang hati melanjutkan? Kasus praktis, bukan sangat luar biasa, mohon ...
Beberapa latar belakang: kami memiliki beberapa lusin pengembang yang mengerjakan proyek menggunakan SVN, dengan masing-masing proyek (atau kelompok proyek serupa) di repositori sendiri. Kami tahu cara menerapkan rilis dan fitur-cabang sehingga kami tidak mengalami masalah sangat sering (yaitu, kami sudah ada di sana, tetapi kami telah belajar untuk mengatasi masalah Joel tentang "satu programmer yang menyebabkan trauma bagi seluruh tim" atau "membutuhkan enam pengembang selama dua minggu untuk mengintegrasikan kembali cabang"). Kami memiliki cabang rilis yang sangat stabil dan hanya digunakan untuk menerapkan perbaikan bug. Kami memiliki batang yang harus cukup stabil untuk dapat membuat rilis dalam satu minggu. Dan kami memiliki cabang fitur yang dapat dikembangkan oleh pengembang tunggal atau grup pengembang. Ya, mereka dihapus setelah reintegrasi sehingga mereka tidak mengacaukan repositori. ;)
Jadi saya masih mencoba mencari keuntungan dari Hg / Git dibandingkan SVN. Saya ingin mendapatkan pengalaman langsung, tetapi belum ada proyek yang lebih besar yang bisa kami pindah ke Hg / Git, jadi saya terjebak dengan bermain dengan proyek buatan kecil yang hanya berisi beberapa file buatan. Dan saya sedang mencari beberapa kasus di mana Anda dapat merasakan kekuatan Hg / Git yang mengesankan, karena sejauh ini saya sering membaca tentang mereka tetapi gagal menemukannya sendiri.
Jawaban:
Saya tidak menggunakan Subversion sendiri, tetapi dari catatan rilis untuk Subversion 1.5: Pelacakan gabungan (dasar) sepertinya ada perbedaan berikut dari cara kerja pelacakan gabungan dalam sistem kontrol versi DAG penuh seperti Git atau Mercurial.
Menggabungkan batang ke cabang berbeda dari menggabungkan cabang ke batang: untuk beberapa alasan penggabungan batang ke cabang membutuhkan
--reintegrate
opsi untuksvn merge
.Dalam sistem kontrol versi terdistribusi seperti Git atau Mercurial tidak ada perbedaan teknis antara trunk dan cabang: semua cabang dibuat sama (mungkin ada perbedaan sosial ). Penggabungan kedua arah dilakukan dengan cara yang sama.
Anda perlu memberikan opsi baru
-g
(--use-merge-history
) kesvn log
dansvn blame
untuk menggabungkan pelacakan ke akun.Dalam Git dan Mercurial merge tracking secara otomatis diperhitungkan saat menampilkan histori (log) dan menyalahkan. Di Git Anda dapat meminta untuk mengikuti induk pertama saja dengan
--first-parent
(saya kira opsi serupa juga ada untuk Mercurial) untuk "membuang" menggabungkan info pelacakan digit log
.Dari apa yang saya pahami
svn:mergeinfo
, toko properti informasi per-lintasan tentang konflik (Subversion berbasis-ubah), sedangkan di Git dan Mercurial, ia hanya melakukan objek yang dapat memiliki lebih dari satu orangtua.Subbagian "Masalah yang Diketahui" untuk pelacakan gabungan di Subversion menunjukkan bahwa gabungan berulang / siklik / reflektif mungkin tidak berfungsi dengan baik. Ini berarti bahwa dengan riwayat berikut, penggabungan kedua mungkin tidak melakukan hal yang benar ('A' dapat berupa batang atau cabang, dan 'B' masing-masing dapat berupa cabang atau batang):
Dalam kasus ASCII-art di atas rusak: Cabang 'B' dibuat (bercabang) dari cabang 'A' pada revisi 'x', kemudian cabang 'A' digabung pada revisi 'y' menjadi cabang 'B' sebagai cabang menggabungkan 'M1', dan akhirnya cabang 'B' digabung menjadi cabang 'A' sebagai gabungan 'M2'.
Dalam kasus ASCII-art di atas rusak: Cabang 'B' dibuat (bercabang) dari cabang 'A' pada revisi 'x', itu digabung menjadi cabang 'A' di 'y' sebagai 'M1', dan kemudian bergabung kembali ke cabang 'A' sebagai 'M2'.
Subversi mungkin tidak mendukung kasus penggabungan silang tingkat lanjut .
Git menangani situasi ini dengan baik dalam praktiknya menggunakan strategi gabungan "rekursif". Saya tidak yakin tentang Mercurial.
Dalam "Masalah yang Diketahui" ada peringatan bahwa penggabungan pelacakan mungkin tidak berfungsi dengan penggantian nama file, misalnya ketika satu sisi mengubah nama file (dan mungkin mengubahnya), dan sisi kedua memodifikasi file tanpa mengganti nama (dengan nama lama).
Baik Git dan Mercurial menangani kasus seperti itu dalam praktiknya: Git menggunakan deteksi nama , Mercurial menggunakan pelacakan nama .
HTH
sumber
<pre>...</pre>
blok tidak di-indentasi sebagaimana mestinya ...--reintegrate
sudah ditinggalkan.Saya juga telah mencari kasus di mana, katakanlah, Subversion gagal menggabungkan cabang dan Mercurial (dan Git, Bazaar, ...) melakukan hal yang benar.
Buku SVN menjelaskan bagaimana file yang diganti nama digabungkan secara tidak benar . Ini berlaku untuk Subversion 1.5 , 1.6 , 1.7 , dan 1.8 ! Saya telah mencoba membuat ulang situasi di bawah ini:
Menurut buku itu, penggabungan harus selesai dengan bersih, tetapi dengan data yang salah dalam file yang diubah namanya karena pembaruan pada
trunk
dilupakan. Sebaliknya saya mendapatkan konflik pohon (ini dengan Subversion 1.6.17, versi terbaru di Debian pada saat penulisan):Seharusnya tidak ada konflik sama sekali - pembaruan harus digabung dengan nama file yang baru. Sementara Subversion gagal, Mercurial menangani ini dengan benar:
Sebelum penggabungan, repositori terlihat seperti ini (dari
hg glog
):Output dari penggabungan adalah:
Dengan kata lain: Mercurial mengambil perubahan dari revisi 1 dan menggabungkannya ke nama file baru dari revisi 2 (
hello.en.txt
). Penanganan kasus ini tentu saja penting untuk mendukung refactoring dan refactoring adalah persis jenis hal yang Anda ingin lakukan pada cabang.sumber
Tanpa berbicara tentang keuntungan biasa (komit offline, proses publikasi , ...) di sini adalah contoh "gabungan" yang saya suka:
Skenario utama yang terus saya lihat adalah cabang di mana ... dua tugas yang tidak terkait sebenarnya dikembangkan
(dimulai dari satu fitur, tetapi mengarah pada pengembangan fitur lain ini.
Atau mulai dari tambalan, tetapi mengarah ke pengembangan fitur lain).
Bagaimana Anda menggabungkan hanya satu dari dua fitur di cabang utama?
Atau Bagaimana Anda mengisolasi dua fitur di cabang mereka sendiri?
Anda dapat mencoba untuk menghasilkan beberapa jenis tambalan, masalah dengan itu adalah Anda tidak yakin lagi tentang dependensi fungsional yang mungkin ada antara:
Git (dan Mercurial juga saya kira) mengusulkan opsi rebase --onto untuk rebase (reset root dari cabang) bagian dari cabang:
Dari pos Jefromi
Anda dapat menguraikan situasi ini di mana Anda memiliki tambalan untuk v2 serta fitur wss baru ke:
, memungkinkan Anda untuk:
Fitur lain yang saya sukai (yang memengaruhi penggabungan) adalah kemampuan untuk menekan komit (di cabang yang belum didorong ke repo lain) untuk menyajikan:
Itu memastikan penggabungan yang jauh lebih mudah, dengan lebih sedikit konflik.
sumber
Kami baru-baru ini bermigrasi dari SVN ke GIT, dan menghadapi ketidakpastian yang sama. Ada banyak bukti anekdotal bahwa GIT lebih baik, tetapi sulit untuk menemukan contoh apa pun.
Saya dapat memberitahu Anda, bahwa GIT adalah BANYAK LEBIH BAIK di penggabungan dari SVN. Ini jelas anekdotal, tetapi ada tabel untuk diikuti.
Berikut adalah beberapa hal yang kami temukan:
Ketika kami mengevaluasi GIT, kami menjalankan tes berikut. Ini menunjukkan GIT sebagai pemenang dalam hal penggabungan, tetapi tidak sebanyak itu. Dalam praktiknya perbedaannya jauh lebih besar, tapi saya kira kita belum berhasil meniru situasi yang ditangani SVN dengan buruk.
sumber
Yang lain telah membahas aspek yang lebih teoretis dari ini. Mungkin saya bisa memberikan perspektif yang lebih praktis.
Saat ini saya bekerja untuk perusahaan yang menggunakan SVN dalam model pengembangan "cabang fitur". Itu adalah:
Secara umum, ini berfungsi. SVN dapat digunakan untuk aliran seperti ini, tetapi itu tidak sempurna. Ada beberapa aspek SVN yang menghalangi dan membentuk perilaku manusia. Itu memberinya beberapa aspek negatif.
^/trunk
. Sampah ini menggabungkan catatan informasi di seluruh pohon, dan akhirnya memecah pelacakan gabungan. Konflik palsu mulai muncul, dan kebingungan berkuasa.svn merge
lakukan apa yang kamu inginkan. Menggabungkan perubahan Anda membutuhkan (kami diberitahu)--reintegrate
pada perintah penggabungan. Saya tidak pernah benar-benar memahami saklar ini, tetapi itu berarti bahwa cabang tidak dapat digabungkan menjadi bagasi lagi. Ini berarti cabang yang mati dan Anda harus membuat yang baru untuk melanjutkan pekerjaan. (Lihat Catatan)Apa yang cenderung terjadi adalah bahwa seorang insinyur membuat cabang pada hari 1. Dia memulai pekerjaannya dan melupakannya. Beberapa waktu kemudian seorang bos datang dan bertanya apakah dia bisa melepaskan pekerjaannya ke bagasi. Insinyur telah takut hari ini karena reintegrasi berarti:
... dan karena insinyur melakukan ini sesedikit mungkin, mereka tidak dapat mengingat "mantra sihir" untuk melakukan setiap langkah. Sakelar dan URL salah terjadi, dan tiba-tiba berantakan dan mereka mendapatkan "pakar".
Akhirnya semuanya beres, dan orang-orang belajar bagaimana mengatasi kekurangannya, tetapi setiap pemula baru melewati masalah yang sama. Realitas akhirnya (yang bertentangan dengan apa yang saya jelaskan saat dia mulai) adalah:
...tapi...
Syukurlah tim ini cukup kecil untuk mengatasinya, tetapi tidak akan berkembang. Masalahnya, semua ini bukan masalah dengan CVCS, tetapi lebih dari itu karena penggabungan tidak sepenting di DVCS mereka tidak selipis. "Gesekan gabungan" itu menyebabkan perilaku yang berarti bahwa model "Cabang Fitur" mulai rusak. Penggabungan yang baik harus menjadi fitur dari semua VCS, bukan hanya DVCS.
Menurut ini sekarang ada
--record-only
saklar yang dapat digunakan untuk menyelesaikan--reintegrate
masalah, dan tampaknya v1.8 memilih kapan melakukan reintegrasi secara otomatis, dan itu tidak menyebabkan cabang mati setelah itusumber
Sebelum subversi 1.5 (jika saya tidak salah), subversi memiliki kelemahan yang signifikan karena tidak ingat menggabungkan sejarah.
Mari kita lihat kasus yang diuraikan oleh VonC:
Perhatikan revisi A dan B. Katakanlah Anda menggabungkan perubahan dari revisi A di cabang "wss" ke cabang "hanya-v2" di revisi B (untuk alasan apa pun), tetapi terus menggunakan kedua cabang. Jika Anda mencoba untuk menggabungkan dua cabang lagi menggunakan lincah, itu hanya akan menggabungkan perubahan setelah revisi A dan B. Dengan subversi, Anda harus menggabungkan semuanya, seolah-olah Anda tidak melakukan penggabungan sebelumnya.
Ini adalah contoh dari pengalaman saya sendiri, di mana penggabungan dari B ke A memakan waktu beberapa jam karena volume kode: itu akan sangat menyebalkan untuk dilalui lagi , yang akan menjadi kasus dengan subversi pra-1.5.
Lain, mungkin perbedaan yang lebih relevan dalam perilaku menggabungkan dari Hginit: Pendidikan ulang Subversion :
Singkatnya, cara Mercurial menganalisis perbedaan adalah (apakah?) Lebih unggul daripada subversi.
sumber