Bagaimana cara saya mendekati gabungan yang rumit

25

Ini kesepakatannya, saya telah bergabung dengan perusahaan baru dan telah diminta untuk menyelesaikan pekerjaan di cabang yang belum tersentuh selama hampir setahun. Sementara itu, cabang utama telah tumbuh dengan kecepatan tetap. Idealnya saya ingin menggabungkan semua perubahan dari cabang master ke cabang fitur dan melanjutkan pekerjaan dari sana, tapi saya tidak terlalu yakin bagaimana cara mendekati ini.

Bagaimana cara saya melakukan penggabungan ini dengan aman sambil mempertahankan perubahan penting di kedua sisi cabang?

Vlad Spreys
sumber
Terima kasih untuk semua orang atas umpan balik yang luar biasa. Saya akan coba git-imerge dan jika ternyata berantakan saya akan menggunakan pendekatan cabang baru!
Vlad Spreys
Adakah yang bisa menjelaskan mengapa kita tidak bisa menggunakan di git cherry-picksini?
Santosh Kumar
1. Doa. 2. rebase. 3. tes. 4. bergabung.
AK_
1
Saya lebih suka rebasing dalam situasi ini karena akan dilakukan dengan komitmen. Ini juga akan memungkinkan Anda untuk menekan fitur baru sebelum Anda membuat kode gabungan tersedia. YMMV.
Stephen

Jawaban:

27

Pada intinya, cara menggabungkan dua (mungkin tidak kompatibel) kode adalah masalah pengembangan , bukan masalah kontrol versi . Perintah Git merge dapat membantu dalam proses ini, tetapi itu tergantung pada bentuk masalah.

Membandingkan kedua versi dengan basis lebih masuk akal. Ini akan memberi Anda gambaran tentang strategi terbaik untuk meneruskan ini. Pendekatan Anda mungkin berbeda berdasarkan sifat dan tumpang tindih dari perubahan di setiap cabang.

Bayangkan skenario yang ideal: Anda akan menemukan bahwa cabang utama dan cabang fitur masing-masing hanya memodifikasi bagian-bagian kode yang saling eksklusif, sehingga Anda bisa melakukan semua perubahan dan menjadi baik untuk dilakukan.

Tentu saja, itu hampir pasti tidak akan menjadi masalah, tetapi pertanyaannya adalah: seberapa jauh hal itu akan dihapus dari skenario ideal ini? yaitu seberapa berbaurnya perubahan?

Juga, seberapa dewasa cabang fitur lama? Apakah itu dalam kondisi kerja yang baik, atau tidak (atau tidak diketahui)? Berapa banyak fitur yang selesai?

Jika kode yang relevan di cabang utama telah banyak berubah dalam satu tahun terakhir, atau fitur tidak dalam keadaan yang sangat matang, saya mungkin mempertimbangkan untuk membuat garpu baru dari yang terbaru dan secara manual memasukkan fitur lama lagi. Ini akan memungkinkan Anda untuk mengambil pendekatan tambahan untuk membuatnya bekerja.

Jika Anda melakukan banyak gabungan kode yang berantakan dan tidak berfungsi, itu akan sangat sulit untuk di-debug. Jika cabang utama telah banyak berubah selama setahun terakhir, perubahan desain utama mungkin diperlukan untuk fitur agar bisa berfungsi. Tidak akan tepat untuk melakukan perubahan ini melalui "menyelesaikan konflik", karena ini akan membutuhkan membuat semua perubahan sekaligus dan berharap itu berfungsi. Masalah ini akan diperparah oleh kemungkinan bug di cabang yang sudah jadi sebagian.


sumber
+1 "Saya mungkin mempertimbangkan untuk membuat garpu baru yang terbaru dan secara manual memasukkan fitur lama lagi"
mika
1
Pertanyaan kunci pertama adalah: apakah cabang fitur lama dibangun? Apakah ini berjalan? Jika tidak, akan sangat sulit untuk menguji penggabungan Anda.
Mo
22

Dalam pengalaman git terbatas saya, saya bisa mengatakan bahwa kadang-kadang lebih cepat untuk me-restart cabang fitur lagi jika master sudah terlalu jauh dari titik lepas.

Menggabungkan dua cabang tanpa mengetahui sejarah di balik kode (mengingat bahwa Anda baru saja bergabung dengan proyek) benar-benar sulit, dan saya bertaruh bahwa bahkan pengembang yang mengikuti proyek dari awal kemungkinan akan membuat beberapa kesalahan dalam penggabungan.

Ini tentu saja masuk akal jika cabang fitur tidak besar, tetapi Anda bisa tetap membuka cabang fitur lama , cabang lagi dari master dan secara manual memperkenalkan kembali perubahan yang menyusun fitur itu. Saya tahu ini pendekatan yang paling manual, tetapi memungkinkan Anda untuk memegang kendali penuh seandainya ada kode yang hilang atau dipindahkan.

Pairing programming dengan senior dalam hal ini akan menjadi skenario terbaik, membantu Anda untuk mengenal kode lebih baik.
Bahkan bisa berubah menjadi lebih cepat juga, jika Anda memperhitungkan konflik penggabungan akun dan waktu pengujian!

Saya agak berasumsi bahwa setidaknya mencoba melakukan penggabungan jelas merupakan hal terbaik untuk dilakukan. Jika itu gagal atau ternyata terlalu sulit, maka coba memetik ceri, jika itu salah pergi secara manual.

GavinoGrifoni
sumber
2
Jelas bukan pendekatan yang benar.
Andy
12
tidak, ini adalah pendekatan yang benar - jika Anda memiliki cabang kuno, dan Anda tidak tahu kodenya, mencoba bergabung tidak akan menjadi sangat sukses dan itu akan sangat berisiko. Menentukan perubahan yang awalnya dibuat, menyelidiki apakah mereka bahkan relevan dengan kode baru, dan kemudian menerapkannya masuk akal adalah cara untuk melakukannya. Ini adalah pendekatan manual, tetapi dalam keadaan ini, satu-satunya yang aman untuk diambil. Tentu saja, saya masih akan mencoba menggabungkan dulu, hanya untuk melihat apa yang terjadi, dan saya akan memeriksa log untuk melihat seberapa banyak perubahan yang terjadi pada cabang juga - bisa sepele.
gbjbaanb
10
@ Davidvider: Saya tidak berpikir GavianoGrifoni menyarankan untuk membuang semua pekerjaan ke laut. Dia menyarankan untuk mentransfer perubahan dari cabang lama secara manual ke jalur pengembangan saat ini, secara bertahap. Itu akan membuang sejarah lama , tidak lebih.
Doc Brown
3
@ Davidvider 1: cabang adalah tahun kedaluwarsa, ke-2: orang yang bertugas menyelesaikannya tidak tahu kode sama sekali. Dengan 2 faktor ini, mendaftar ulang secara manual adalah satu-satunya cara realistis untuk mendekati tugas. Tidak ada yang menyarankan copy-paste sederhana dari revisi tip cabang lama.
gbjbaanb
5
@ Davidvider: Menggabungkan konflik bisa menjadi kejahatan - jika Anda harus menyelesaikan 500 dari mereka sekaligus sebelum Anda mendapatkan program dalam keadaan dapat dikompilasi dan diuji lagi. Itulah situasi yang diharapkan OP di sini. Jika Anda berpikir mungkin menggunakan git secara efisien untuk menghindari situasi "semua atau tidak sama sekali" ini, mengapa Anda tidak mengedit jawaban Anda dan memberi tahu OP bagaimana hal ini dapat dicapai?
Doc Brown
16

git-imerge dirancang persis untuk tujuan ini. Ini adalah alat git yang menyediakan metode untuk penggabungan inkremental . Dengan menggabungkan secara bertahap, Anda hanya perlu berurusan dengan tabrakan antara dua versi, tidak pernah lagi. Selain itu, jumlah penggabungan yang jauh lebih besar dapat dilakukan secara otomatis karena perubahan individu lebih kecil.

Joe
sumber
6

Mencoba untuk menggabungkan kepala utama ke cabang basi setahun bisa menjadi latihan frustrasi dan memperdalam penyok di atas meja dengan dahi Anda.

Jalur utama tidak sampai ke tempatnya dalam satu bulan selama berbulan-bulan. Itu juga memiliki pengembangan dan rilis. Mencoba untuk memperbaruinya dalam satu penggabungan monolitik bisa sangat luar biasa.

Sebagai gantinya, mulailah dengan menggabungkan dari fitur pertama bergabung kembali ke garis utama setelah cabang basi terpecah. Dapatkan bahwa penggabungan kerja. Kemudian fitur selanjutnya bergabung. Dan seterusnya. Banyak dari gabungan fitur tersebut akan bergabung tanpa konflik. Masih penting untuk memastikan bahwa fungsi basi cabang saat ini tetap kompatibel dengan arah yang telah ditempuh jalur utama.

Anda mungkin ingin cabang dari kepala cabang basi untuk peran penggabungan dalam perubahan lainnya. Ini lebih lanjut tentang memastikan bahwa komitmen dan sejarah ketika seseorang melihat kembali jelas dan mengkomunikasikan apa peran dan kebijakan masing-masing cabang. Cabang basi adalah cabang fitur. Cabang tempat Anda bekerja adalah cabang akumulasi dan rekonsiliasi.

Sebagian besar ini akan lebih mudah jika fitur lama atau cabang rilis masih ada di luar sana dan mudah diakses (beberapa tempat memiliki kebijakan untuk membersihkan nama-nama cabang yang lebih tua dari beberapa tanggal sehingga daftar cabang tidak berlebihan) ).

Yang penting dalam semua ini adalah untuk memastikan bahwa Anda menguji dan memperbaiki setelah berhasil menggabungkan setiap bagian dari sejarah arus utama ke tempatnya. Meskipun sesuatu dapat bergabung tanpa konflik, itu berarti kode tersebut tidak bertentangan. Jika cara fitur basi diakses sudah usang atau dihapus, mungkin perlu ada perbaikan setelah penggabungan yang berhasil.

Selain itu, ini juga berfungsi untuk sistem kontrol versi lain. Saya kadang-kadang harus menggabungkan grup svn commit tertentu menjadi cabang (memetik ceri) untuk satu fitur, memperbaiki cabang untuk bekerja dengan fitur itu, dan kemudian menggabungkan grup svn commit berikutnya daripada hanya melakukan svn grosir menggabungkan.

Meskipun seseorang dapat melakukan git cherry-pick di sini, dan memungkinkan melakukan komitmen tertentu , ini memiliki beberapa kelemahan yang dapat mempersulit proses. Pilihan ceri tidak akan menampilkan informasi tentang komit yang Anda pilih (Anda dapat menambahkannya ke pesan komit). Hal ini membuat pelacakan komitmen dalam sejarah menjadi lebih sulit.

Selain itu, itu berarti bahwa Anda tidak akan memutar ulang master secara efektif ke cabang basi - Anda akan memilih fitur yang mungkin tidak lengkap - dan fitur-fitur tersebut mungkin dimainkan secara tidak berurutan.

Alasan utama seseorang harus bergabung dari komitmen historis untuk dikuasai ke cabang basi adalah untuk dapat mempertahankannya, sebut saja "sejarah masa depan" cabang basi dalam keadaan yang dapat Anda alasankan. Anda dapat dengan jelas melihat penggabungan dari sejarah ke cabang basi dan perbaikan untuk mengintegrasikan kembali fungsi. Fitur sedang ditambahkan dalam urutan yang sama seperti yang akan mereka kuasai. Dan ketika Anda selesai, dan akhirnya melakukan penggabungan dari kepala master ke cabang basi, Anda tahu bahwa semuanya telah digabung dan Anda tidak kehilangan komitmen.


sumber
+1 Ini adalah solusi alternatif potensial yang menarik yang menggunakan penggabungan untuk menggabungkan perubahan besar. Namun, saya dapat melihat sisi buruknya: misalkan Anda memiliki ABCDE versi utama dan Anda ingin memasukkan fitur branch A1 ke E. Mungkin ada banyak upaya yang sia-sia untuk menggabungkan kode menjadi BC dan D. Misalnya, bagaimana jika D ke E adalah perubahan desain besar yang membuat perubahan inkremental dalam B, C, dan D tidak relevan? Juga, sekali lagi tergantung pada seberapa matang fitur itu di tempat pertama. Pendekatan potensial yang bermanfaat, tetapi kesesuaiannya perlu dipertimbangkan sebelum memulai.
1

Langkah 1. Pelajari tentang kode, analisis arsitekturnya, dan perubahan yang telah dilakukan pada kedua cabang sejak leluhur bersama terbaru.

Langkah 2. Jika fitur ini muncul secara independen dan menyentuh sebagian besar area kode, menggabungkan, memperbaiki konflik, menguji, memperbaiki dll. Ini adalah jalan yang menyenangkan, Anda cukup baik untuk melakukannya. Kalau tidak, lanjutkan ke Langkah 3

Langkah 3. Analisis wilayah konflik, pahami dampak fungsional dan alasannya secara rinci. Mungkin ada konflik dalam persyaratan bisnis yang muncul di sini. Diskusikan dengan BA, pengembang lain yang sesuai. Dapatkan kerumitan yang terlibat dengan menyelesaikan gangguan.

Langkah 4. Sehubungan dengan hal di atas, putuskan apakah akan menggabungkan / memetik-ceri / bahkan memotong-paste hanya bagian-bagian yang tidak bertentangan dan menulis ulang bagian yang bertentangan, ATAU apakah akan menulis ulang seluruh fitur dari awal .

Brad Thomas
sumber
0

1. Beralih ke cabang yang digunakan sebagai cabang pengembang / rilis utama.

Ini adalah cabang yang berisi perubahan terbaru ke sistem. Bisa master, core, dev, itu tergantung pada perusahaan. Dalam kasus Anda itu mungkin masterlangsung.

git checkout master
git pull

Tarik untuk memastikan Anda memiliki versi terbaru dari cabang pengembangan utama yang diperoleh.

2. Periksa dan tarik cabang yang berisi pekerjaan yang seharusnya Anda selesaikan.

Anda menarik untuk memastikan Anda memang memiliki isi cabang terbaru. Dengan memeriksanya secara langsung, tanpa membuatnya secara lokal terlebih dahulu, Anda memastikan untuk tidak memiliki konten baru dari master(atau cabang dev utama masing-masing) di dalamnya.

git checkout <name of the obsolete branch>
git pull origin <name of the obsolete branch>

3. Gabungkan cabang pengembangan utama ke cabang usang.

Sebelum menjalankan perintah berikut, pastikan, baik dengan mengetik git branchatau git statusAnda berada di cabang usang.

git merge master

The git mergeperintah akan mencoba untuk menggabungkan isi dari cabang tertentu, dalam hal ini master, untuk cabang Anda saat ini di.

Penekanan pada akan mencoba . Mungkin ada konflik gabungan, yang perlu diselesaikan oleh Anda dan Anda saja.

4. Perbaiki gabungan konflik, komit, dan dorong perbaikan konflik

Setelah memperbaiki konflik gabungan di semua file di mana ada, panggung, komit, dan dorong resolusi konflik ke origin.

git add .
git commit -m "fixed the merge conflict from the past year to update the branch"
git push

Anda biasanya dapat menelepon git add .untuk menampilkan semua file untuk dikomit. Saat menangani penggabungan konflik, Anda ingin semua file yang diperlukan diperbarui.

Catatan tambahan

Menyelesaikan konflik gabungan bisa menjadi pekerjaan yang membosankan. Apalagi jika Anda baru di sebuah perusahaan. Anda mungkin belum memiliki pengetahuan yang tepat untuk menyelesaikan semua konflik penggabungan saja.

Luangkan waktu Anda untuk memeriksa dengan cermat semua konflik yang telah terjadi dan memperbaikinya dengan tepat, sebelum melanjutkan pekerjaan Anda.


Itu bisa terjadi begitu, Anda mulai bekerja pada cabang berumur satu tahun, menggabungkan keadaan perkembangan saat ini ke dalamnya dan tidak akan memiliki konflik penggabungan sama sekali.

Ini terjadi ketika meskipun sistem telah banyak berubah di tahun ini, tidak ada yang menyentuh file yang sebenarnya diubah di cabang berumur satu tahun.

Andy
sumber
6
# 4 berpotensi masalah. Jika ada banyak perubahan selama setahun terakhir, perubahan besar pada fitur lama mungkin diperlukan. Melakukan ini dengan menggabungkan mengharuskan Anda untuk membuat perubahan besar pada kode semua dalam satu pergi dan berharap itu berfungsi, yang bukan praktik pengembangan yang baik. Ditambah siapa yang tahu seperti apa fitur fitur yang belum selesai? Anda mungkin berakhir dengan kekacauan besar kode tidak berfungsi, dan siapa yang tahu apakah itu karena masalah dengan aslinya atau perubahan yang Anda buat?
David, selama pendekatan standar ini berfungsi, tidak apa-apa, dan OP harus mencobanya terlebih dahulu. Tetapi jelas ada risiko terlalu banyak menggabungkan konflik dalam situasi yang dijelaskan untuk menanganinya dengan cara "semua atau tidak sama sekali".
Doc Brown
@ dan1111 Bahwa ada konflik menggabungkan benar-benar OK, dan sebenarnya melalui mereka adalah cara untuk pergi Karena cabang dibiarkan tidak tersentuh selama setahun, Anda bisa yakin itu bukan hal yang penting dan tidak akan mempengaruhi banyak sistem. Jadi, meskipun cabang satu tahun di belakang, Anda bisa mendapatkan 2 hingga tidak ada yang menggabungkan konflik.
Andy
4
Asumsi bahwa cabang ini tidak penting adalah tidak beralasan. Itu bisa menjadi perubahan desain mendasar yang ditinggalkan dan sekarang diambil kembali. Itu bisa apa saja. Anda benar bahwa itu bisa menjadi masalah sederhana dan mungkin ada sedikit atau tidak ada konflik - dalam hal ini jawaban Anda akan benar. Tapi itu bukan satu-satunya kemungkinan.
@ dan1111 Jika seseorang belum menyentuh tempat fitur di cabang terpisah selama setahun, itu tidak akan mencerminkan banyak perubahan sistem. Ini berasal dari pengalaman saya sendiri dengan cabang yang sudah usang (6+ bulan).
Andy