Kapan Anda akan menggunakan strategi git merge yang berbeda?

430

Dari halaman manual di git-merge, ada sejumlah strategi penggabungan yang dapat Anda gunakan.

  • resolve - Ini hanya dapat menyelesaikan dua kepala (yaitu cabang saat ini dan cabang lain Anda menarik dari) menggunakan algoritma penggabungan 3 arah. Itu mencoba untuk hati-hati mendeteksi ambiguitas penggabungan silang dan dianggap umumnya aman dan cepat.

  • rekursif - Ini hanya dapat menyelesaikan dua kepala menggunakan algoritma penggabungan 3 arah. Ketika ada lebih dari satu leluhur umum yang dapat digunakan untuk penggabungan 3 arah, ia menciptakan pohon yang digabungkan dari leluhur yang sama dan menggunakannya sebagai pohon referensi untuk penggabungan 3 arah. Hal ini telah dilaporkan mengakibatkan lebih sedikit konflik penggabungan tanpa menyebabkan kesalahan penggabungan dengan pengujian yang dilakukan pada komitmen gabungan aktual yang diambil dari sejarah pengembangan kernel Linux 2.6. Selain itu, ini dapat mendeteksi dan menangani gabungan yang melibatkan penggantian nama. Ini adalah strategi penggabungan default saat menarik atau menggabungkan satu cabang.

  • gurita - Ini menyelesaikan lebih dari kasus dua-kepala, tetapi menolak untuk melakukan penggabungan kompleks yang membutuhkan resolusi manual. Ini terutama dimaksudkan untuk digunakan untuk bundling kepala cabang topik bersama. Ini adalah strategi penggabungan default saat menarik atau menggabungkan lebih dari satu cabang.

  • ours - Ini menyelesaikan sejumlah kepala, tetapi hasil penggabungan selalu kepala cabang saat ini. Ini dimaksudkan untuk menggantikan sejarah perkembangan lama dari cabang samping.

  • subtree - Ini adalah strategi rekursif yang dimodifikasi. Saat menggabungkan pohon A dan B, jika B berkorespondensi dengan subtree A, B pertama kali disesuaikan agar sesuai dengan struktur pohon A, alih-alih membaca pohon di tingkat yang sama. Penyesuaian ini juga dilakukan pada pohon leluhur yang sama.

Kapan saya harus menentukan sesuatu yang berbeda dari standar? Skenario apa yang terbaik untuk masing-masing?

Otto
sumber

Jawaban:

305

Saya tidak terbiasa dengan tekad, tapi saya sudah menggunakan yang lain:

Rekursif

Rekursif adalah default untuk gabungan non-maju cepat. Kita semua akrab dengan yang itu.

Gurita

Saya menggunakan gurita ketika saya memiliki beberapa pohon yang perlu digabung. Anda melihatnya dalam proyek yang lebih besar di mana banyak cabang memiliki pengembangan independen dan semuanya siap untuk bergabung menjadi satu kepala.

Cabang gurita menggabungkan beberapa kepala dalam satu komit selama ia dapat melakukannya dengan bersih.

Sebagai ilustrasi, bayangkan Anda memiliki proyek yang memiliki master, dan kemudian tiga cabang untuk bergabung (sebutlah a, b, dan c).

Serangkaian penggabungan rekursif akan terlihat seperti ini (perhatikan bahwa penggabungan pertama adalah maju cepat, karena saya tidak memaksakan rekursi):

serangkaian penggabungan rekursif

Namun, gabungan gurita tunggal akan terlihat seperti ini:

commit ae632e99ba0ccd0e9e06d09e8647659220d043b9
Merge: f51262e... c9ce629... aa0f25d...

gurita bergabung

Milik kita

Ours == Saya ingin menarik kepala yang lain, tetapi membuang semua perubahan yang diperkenalkan kepala.

Ini membuat sejarah cabang tanpa efek cabang.

(Baca: Bahkan tidak melihat perubahan di antara cabang-cabang itu. Cabang-cabang hanya digabung dan tidak ada yang dilakukan untuk file. Jika Anda ingin bergabung di cabang lain dan setiap kali ada pertanyaan "versi file kami atau mereka versi "Anda dapat menggunakan git merge -X ours)

Subtree

Subtree berguna ketika Anda ingin menggabungkan proyek lain menjadi subdirektori dari proyek Anda saat ini. Berguna saat Anda memiliki perpustakaan yang tidak ingin Anda sertakan sebagai submodule.

Dustin
sumber
1
Jadi satu-satunya keuntungan nyata Ocotopus adalah mengurangi jumlah gabungan yang dilakukan di pohon?
Otto
60
Anda tidak perlu menentukan strategi penggabungan gurita : ini digunakan secara otomatis jika Anda menggabungkan lebih dari dua cabang ( git merge A B ...).
Jakub Narębski
Maaf karena sudah di luar topik, tapi alat apa yang Anda buat tangkapan layar itu? Sepertinya visualisasi cabang yang benar-benar hebat / cantik ...
Bernd Haug
4
gitg untuk mereka yang ada di lingkungan linux.
Akash Agrawal
2
Petunjuk dengan -X oursini luar biasa, hanya menyelamatkan saya satu jam kerja.
Michael
49

Sebenarnya, hanya dua strategi yang ingin Anda pilih adalah milik kami jika Anda ingin meninggalkan perubahan yang dibawa oleh cabang, tetapi pertahankan cabang dalam sejarah, dan kurangi jika Anda menggabungkan proyek independen ke dalam subdirektori superproyek (seperti 'git-gui' dalam ' repositori git).

penggabungan gurita digunakan secara otomatis ketika menggabungkan lebih dari dua cabang. tekad ada di sini terutama karena alasan historis, dan ketika Anda terkena kasus sudut strategi penggabungan rekursif .

Jakub Narębski
sumber
Saya harus memilih 'resolusinya' daripada 'rekursif' default untuk penggabungan dua-kepala yang memiliki kesalahan fatal git-write-tree. Strategi 'diselesaikan' bergabung dengan bersih. Ini mungkin ada hubungannya dengan memindahkan banyak file di dalam cabang yang sedang digabung.
thaddeusmt
@ thaddeusmt: Menarik. Bisakah Anda, jika mungkin, memposting laporan bug tentang kegagalan strategi penggabungan "rekursif" ini untuk masuk milis? Terima kasih sebelumnya.
Jakub Narębski
@ JakubNarębski Saya tidak yakin bagaimana saya bisa mengumpulkan cukup informasi untuk mengajukan laporan bug yang berarti, saya n00b dengan Git, maaf. Seperti yang saya sebutkan dalam jawaban saya di sini ( stackoverflow.com/a/10636464/164439 ) dugaan saya adalah yang harus dilakukan dengan saya menduplikasi perubahan di kedua cabang, dan "menyelesaikan" melakukan pekerjaan yang lebih baik untuk melewatkan perubahan yang digandakan.
thaddeusmt
@ JakubNarębski sekarang Anda juga dapat memilih mereka , yang sesuai dengan manual "kebalikan dari kami . Mereka tidak dipilih secara otomatis untuk Anda. Semoga Anda dapat sedikit memperbarui server Anda, menambahkan opsi mereka
SebNag
3
@SebTu: tidak ada theirsstrategi gabungan (yaitu --strategy=theirs), tetapi ada theirsopsi untuk recursivestrategi gabungan standar (yaitu --strategy=recursive --strategy-option=theirs, atau adil -Xtheirs).
Jakub Narębski
23

"Gabungkan" vs "Rekursif" menggabungkan strategi

Rekursif adalah strategi dua kepala default saat ini, tetapi setelah beberapa pencarian saya akhirnya menemukan beberapa info tentang strategi menggabungkan "tekad".

Diambil dari buku O'Reilly Version Control with Git ( Amazon ) (diparafrasekan):

Awalnya, "tekad" adalah strategi default untuk gabungan Git.

Dalam situasi penggabungan berselang-seling, di mana ada lebih dari satu kemungkinan penggabungan dasar, strategi penyelesaian bekerja seperti ini: pilih salah satu dari basis pangkalan yang mungkin, dan harapkan yang terbaik. Ini sebenarnya tidak seburuk kedengarannya. Sering kali ternyata pengguna telah mengerjakan bagian kode yang berbeda. Dalam hal itu, Git mendeteksi bahwa ia sedang melakukan remergasi beberapa perubahan yang sudah ada dan melompati perubahan duplikat, menghindari konflik. Atau, jika ini adalah sedikit perubahan yang menyebabkan konflik, setidaknya konflik itu seharusnya mudah bagi pengembang untuk ditangani.

Saya telah berhasil menggabungkan pohon menggunakan "ketetapan" yang gagal dengan strategi rekursif default. Saya mendapatkan fatal: git write-tree failed to write a treekesalahan, dan berkat posting blog ini ( mirror ) saya mencoba "-s resolving", yang berhasil. Saya masih tidak yakin mengapa ... tapi saya pikir itu karena saya memiliki duplikat perubahan di kedua pohon, dan menyelesaikan "melewatkan" mereka dengan benar.

thaddeusmt
sumber
Saya menggunakan penggabungan 3-arah (p4merge) dan saya memiliki konflik yang ditulis ke file .BASE ketika penggabungan rekursif gagal. Kembali ke penyelesaian-strategi membantu dalam kasus ini.
mrzl
-2

Karena jawaban di atas tidak menunjukkan semua detail strategi. Sebagai contoh, beberapa jawaban yang hilang rincian tentang impor resolvepilihan dan recursiveyang memiliki banyak sub pilihan seperti ours, theirs, patience, renormalize, dll

Oleh karena itu, saya akan merekomendasikan untuk mengunjungi gitdokumentasi resmi yang menjelaskan semua fitur fitur yang mungkin:

https://git-scm.com/docs/merge-strategies

Rene B.
sumber