Pertanyaan Cara menyelesaikan konflik gabungan di Git


Apakah ada cara yang baik untuk menjelaskan cara menyelesaikan konflik gabungan di Git?


4123
2017-10-02 11:31


asal


Jawaban:


Mencoba: git mergetool

Ini membuka GUI yang menuntun Anda melalui setiap konflik, dan Anda bisa memilih cara menggabungkan. Terkadang membutuhkan sedikit penyuntingan tangan setelahnya, tetapi biasanya cukup dengan sendirinya. Ini jauh lebih baik daripada melakukan semuanya dengan tangan tentunya.

Sesuai komentar @JoshGlover:

Perintah tidak harus membuka GUI kecuali Anda menginstalnya. Lari git mergetool bagi saya menghasilkan vimdiff sedang digunakan. Anda dapat menginstal salah satu alat berikut untuk menggunakannya sebagai gantinya: meld, opendiff, kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse, ecmerge, p4merge, araxis, vimdiff, emerge.

Di bawah ini adalah prosedur sampel untuk digunakan vimdiff untuk menyelesaikan menggabungkan konflik. Berdasarkan Link ini

Langkah 1: Jalankan perintah berikut di terminal Anda

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

Ini akan mengatur vimdiff sebagai alat penggabungan default.

Langkah 2: Jalankan perintah berikut di terminal

git mergetool

Langkah 3: Anda akan melihat tampilan vimdiff dalam format berikut

  +----------------------+
  |       |      |       |
  |LOCAL  |BASE  |REMOTE |
  |       |      |       |
  +----------------------+
  |      MERGED          |
  |                      |
  +----------------------+

4 tampilan ini

LOKAL - ini adalah file dari cabang saat ini

DASAR - leluhur yang sama, bagaimana tampilan file sebelum keduanya berubah

REMOTE - file yang Anda gabungkan ke cabang Anda

MERGED - menggabungkan hasil, inilah yang disimpan di repo

Anda dapat bernavigasi di antara tampilan ini menggunakan ctrl+w. Anda dapat langsung mencapai tampilan MERGED menggunakan ctrl+w diikuti oleh j.

Info lebih lanjut tentang navigasi vimdiff sini dan sini

Langkah 4. Anda dapat mengedit tampilan MERGED dengan cara berikut

Jika Anda ingin mendapatkan perubahan dari REMOTE

:diffg RE  

Jika Anda ingin mendapatkan perubahan dari BASE

:diffg BA  

Jika Anda ingin mendapatkan perubahan dari LOKAL

:diffg LO 

Langkah 5. Simpan, Keluar, Komit dan Bersihkan

:wqa simpan dan keluar dari vi

git commit -m "message"

git clean Hapus file ekstra (misalnya * .orig) yang dibuat oleh alat diff.


2415
2017-10-02 17:50



Berikut adalah kasus penggunaan yang mungkin, dari atas:

Anda akan menarik beberapa perubahan, tetapi oops, Anda tidak diperbarui:

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

Jadi Anda mendapatkan yang terbaru dan coba lagi, tetapi memiliki konflik:

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

Jadi Anda memutuskan untuk melihat perubahannya:

git mergetool

Oh saya, oh saya, hulu mengubah beberapa hal, tetapi hanya untuk menggunakan perubahan saya ... tidak ... perubahan mereka ...

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

Dan kemudian kami mencoba waktu terakhir

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

Ta-da!


1607
2017-08-04 17:04



Saya merasa alat penggabungan jarang membantu saya memahami konflik atau resolusinya. Saya biasanya lebih berhasil melihat penanda konflik dalam editor teks dan menggunakan git log sebagai suplemen.

Berikut beberapa kiatnya:

Tip One

Hal terbaik yang saya temukan adalah menggunakan gabungan gaya konflik "diff3":

git config merge.conflictstyle diff3

Ini menghasilkan penanda konflik seperti ini:

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a 
feature/topic branch.
>>>>>>>

Bagian tengah adalah seperti apa rupa leluhur yang sama. Ini berguna karena Anda dapat membandingkannya dengan versi teratas dan terbawah untuk mendapatkan pemahaman yang lebih baik tentang apa yang diubah pada setiap cabang, yang memberi Anda ide yang lebih baik untuk apa tujuan dari setiap perubahan itu.

Jika konflik hanya beberapa baris, ini biasanya membuat konflik sangat jelas. (Mengetahui cara memperbaiki konflik sangat berbeda; Anda perlu menyadari apa yang sedang dikerjakan oleh orang lain. Jika Anda bingung, mungkin sebaiknya Anda memanggil orang itu ke kamar Anda agar mereka dapat melihat apa yang Anda cari di.)

Jika konflik lebih panjang, maka saya akan memotong dan menempelkan masing-masing dari tiga bagian menjadi tiga file terpisah, seperti "milikku", "umum", dan "milik mereka".

Lalu saya dapat menjalankan perintah berikut untuk melihat dua orang yang berbeda yang menyebabkan konflik:

diff common mine
diff common theirs

Ini tidak sama dengan menggunakan alat gabungan, karena alat penggabungan akan menyertakan semua bongkahan diff yang tidak bertentangan juga. Saya menemukan bahwa untuk mengalihkan perhatian.

Tip Dua

Seseorang sudah menyebutkan ini, tetapi memahami maksud dibalik setiap bongkahan yang berbeda-beda pada umumnya sangat membantu untuk memahami darimana suatu konflik berasal dan bagaimana mengatasinya.

git log --merge -p <name of file>

Ini menunjukkan semua komit yang menyentuh file itu di antara leluhur bersama dan dua kepala yang Anda gabungkan. (Jadi itu tidak termasuk komit yang sudah ada di kedua cabang sebelum bergabung.) Ini membantu Anda mengabaikan bongkahan diff yang jelas bukan merupakan faktor dalam konflik Anda saat ini.

Tip Tiga

Verifikasi perubahan Anda dengan alat otomatis.

Jika Anda memiliki tes otomatis, jalankan itu. Jika Anda punya serat, jalankan itu. Jika itu adalah proyek yang dapat dibangun, maka buatlah sebelum Anda berkomitmen, dll. Dalam semua kasus, Anda perlu melakukan sedikit pengujian untuk memastikan perubahan Anda tidak merusak apa pun. (Heck, bahkan penggabungan tanpa konflik dapat merusak kode kerja.)

Tip Empat

Rencanakan ke depan; berkomunikasi dengan rekan kerja.

Merencanakan sebelumnya dan menyadari apa yang sedang dikerjakan oleh orang lain dapat membantu mencegah penggabungan konflik dan / atau membantu menyelesaikannya lebih awal - sementara detailnya masih segar dalam pikiran.

Misalnya, jika Anda tahu bahwa Anda dan orang lain sama-sama mengerjakan refactoring yang berbeda yang akan memengaruhi set file yang sama, Anda harus berbicara satu sama lain sebelumnya dan mendapatkan pengertian yang lebih baik untuk jenis perubahan apa yang Anda masing-masing adalah pembuatan. Anda dapat menghemat banyak waktu dan usaha jika Anda melakukan perubahan yang direncanakan secara serial daripada secara paralel.

Untuk refactorings utama yang memotong sebagian besar kode, Anda harus mempertimbangkan bekerja secara serial: semua orang berhenti bekerja pada area kode tersebut sementara satu orang melakukan refactoring lengkap.

Jika Anda tidak dapat bekerja secara serial (karena tekanan waktu, mungkin), maka berkomunikasi tentang konflik penggabungan yang diharapkan setidaknya membantu Anda menyelesaikan masalah lebih cepat sementara detailnya masih segar dalam pikiran. Misalnya, jika seorang rekan kerja membuat serangkaian komit yang mengganggu selama periode satu minggu, Anda dapat memilih untuk menggabungkan / rebase pada cabang rekan kerja itu sekali atau dua kali setiap hari selama minggu itu. Dengan begitu, jika Anda menemukan konflik gabungan / rebase, Anda dapat menyelesaikannya lebih cepat daripada jika Anda menunggu beberapa minggu untuk menggabungkan semuanya bersama-sama dalam satu gumpalan besar.

Tip Lima

Jika Anda tidak yakin menggabungkan, jangan memaksanya.

Penggabungan dapat terasa luar biasa, terutama ketika ada banyak file yang bertentangan dan penanda konflik mencakup ratusan baris. Sering kali ketika memperkirakan proyek perangkat lunak, kami tidak menyertakan cukup waktu untuk item overhead seperti menangani penggabungan yang gnarly, sehingga terasa seperti hambatan nyata untuk menghabiskan beberapa jam untuk membedah setiap konflik.

Dalam jangka panjang, merencanakan dan menyadari apa yang sedang dikerjakan orang lain adalah alat terbaik untuk mengantisipasi konflik gabungan dan mempersiapkan diri Anda untuk menyelesaikannya dengan benar dalam waktu yang lebih singkat.


683
2017-09-28 21:08



  1. Identifikasi file mana yang bertentangan (Git harus memberi tahu Anda ini).

  2. Buka setiap file dan periksa diff; Git mendemarkasi mereka. Mudah-mudahan itu akan menjadi versi yang jelas dari setiap blok untuk disimpan. Anda mungkin perlu mendiskusikannya dengan sesama pengembang yang melakukan kode.

  3. Setelah Anda menyelesaikan konflik dalam file git add the_file.

  4. Setelah Anda selesai semua konflik, lakukan git rebase --continue atau perintah apa pun Git berkata harus dilakukan ketika Anda selesai.


321
2017-10-02 12:41



Lihat jawabannya di pertanyaan Stack Overflow Membatalkan penggabungan di Git, khususnya Jawaban Charles Bailey yang menunjukkan cara melihat berbagai versi file dengan masalah, misalnya,

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp

97
2017-10-03 15:15



Gabung konflik terjadi ketika perubahan dilakukan ke file pada saat yang bersamaan. Berikut adalah cara mengatasinya.

git CLI

Berikut ini langkah-langkah sederhana apa yang harus dilakukan ketika Anda masuk ke keadaan konflik:

  1. Perhatikan daftar file yang konflik dengan: git status (dibawah Unmerged paths bagian).
  2. Selesaikan konflik secara terpisah untuk setiap file dengan salah satu pendekatan berikut:

    • Gunakan GUI untuk menyelesaikan konflik: git mergetool (cara termudah).

    • Untuk menerima versi remote / lainnya, gunakan: git checkout --theirs path/file. Ini akan menolak setiap perubahan lokal yang Anda lakukan untuk file itu.

    • Untuk menerima versi lokal / kami, gunakan: git checkout --ours path/file

      Namun Anda harus berhati-hati, karena perubahan jarak jauh yang dilakukan untuk beberapa alasan.

      Terkait: Apa arti tepat dari "milik kita" dan "milik mereka" dalam git?

    • Edit file yang konflik secara manual dan cari blok kode di antaranya <<<<</>>>>> lalu pilih versi dari atas atau bawah =====. Lihat: Bagaimana konflik disajikan.

    • Konflik jalur dan nama file dapat diselesaikan dengan git add/git rm.

  3. Terakhir, tinjau file yang siap untuk dikomit menggunakan: git status.

    Jika Anda masih memiliki file di bawah Unmerged paths, dan Anda menyelesaikan konflik secara manual, lalu memberi tahu bahwa Anda memecahkannya dengan: git add path/file.

  4. Jika semua konflik berhasil diselesaikan, lakukan perubahan dengan: git commit -a dan dorong ke remote seperti biasa.

Lihat juga: Menyelesaikan konflik gabungan dari baris perintah di GitHub

DiffMerge

Saya telah berhasil digunakan DiffMerge yang dapat membandingkan dan menggabungkan file di Windows, macOS dan Linux / Unix secara visual.

Secara grafis dapat menunjukkan perubahan antara 3 file dan memungkinkan penggabungan otomatis (ketika aman untuk melakukannya) dan kontrol penuh atas pengeditan file yang dihasilkan.

DiffMerge

Sumber gambar: DiffMerge (Screenshot Linux)

Cukup unduh dan jalankan repo sebagai:

git mergetool -t diffmerge .

macOS

Di macOS Anda dapat menginstal melalui:

brew install caskroom/cask/brew-cask
brew cask install diffmerge

Dan mungkin (jika tidak disediakan) Anda perlu pembungkus ekstra sederhana berikut yang ditempatkan di PATH Anda (mis. /usr/bin):

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"

Kemudian Anda dapat menggunakan pintasan keyboard berikut:

  • -Alt-Naik/Turun untuk melompat ke perubahan sebelumnya / berikutnya.
  • -Alt-Kiri/Kanan untuk menerima perubahan dari kiri atau kanan

Atau Anda dapat menggunakan opendiff (bagian dari Xcode Tools) yang memungkinkan Anda menggabungkan dua file atau direktori bersama-sama untuk membuat file atau direktori ketiga.


88
2017-08-05 14:29



Jika Anda sering membuat komitmen kecil, mulailah dengan melihat komentar komit dengan git log --merge. Kemudian git diff akan menunjukkan kepada Anda konflik.

Untuk konflik yang melibatkan lebih dari beberapa baris, lebih mudah untuk melihat apa yang terjadi di alat GUI eksternal. Saya suka opendiff - Git juga mendukung vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, muncul di luar kotak dan Anda dapat menginstal yang lain: git config merge.tool "your.tool" akan mengatur alat yang Anda pilih dan kemudian git mergetool setelah penggabungan gagal akan menunjukkan diffs dalam konteks.

Setiap kali Anda mengedit file untuk menyelesaikan konflik, git add filename akan memperbarui indeks dan diff Anda tidak akan lagi menampilkannya. Ketika semua konflik ditangani dan file-file mereka telah git add-ed, git commit akan menyelesaikan penggabungan Anda.


73
2017-10-02 16:11



Lihat Bagaimana Konflik Disampaikan atau, di Git, the git merge dokumentasi untuk memahami apa yang menggabungkan penanda konflik.

Juga Cara Mengatasi Konflik Bagian menjelaskan cara menyelesaikan konflik:

Setelah melihat konflik, Anda dapat melakukan dua hal:

  • Putuskan untuk tidak menggabungkan. Satu-satunya pembersihan yang Anda butuhkan adalah mereset file indeks ke HEAD berkomitmen untuk membalik 2. dan membersihkan perubahan pohon kerja yang dibuat oleh 2. dan 3 .; git merge --abort dapat digunakan untuk ini.

  • Selesaikan konflik. Git akan menandai konflik di pohon kerja. Edit file menjadi bentuk dan git add mereka ke indeks. Menggunakan git commit untuk menyegel kesepakatan.

Anda dapat menyelesaikan konflik dengan sejumlah alat:

  • Gunakan mergetool. git mergetool untuk meluncurkan mergetool grafis yang akan bekerja Anda melalui penggabungan.

  • Lihatlah diffs. git diff akan menampilkan diff tiga arah, menyoroti perubahan dari keduanya HEAD dan MERGE_HEAD versi.

  • Lihatlah diffs dari masing-masing cabang. git log --merge -p <path> akan menampilkan diff pertama untuk HEAD versi dan kemudian MERGE_HEAD versi.

  • Lihatlah yang asli. git show :1:filename menunjukkan leluhur yang sama, git show :2:filename menunjukkan HEAD versi, dan git show :3:filename menunjukkan MERGE_HEAD versi.

Anda juga dapat membaca tentang penggabungan penanda konflik dan cara mengatasinya dalam Pro Git bagian buku Konflik Penggabungan Dasar.


43
2017-07-14 18:34



Untuk Emacs pengguna yang ingin menyelesaikan menggabungkan konflik semi-manual:

git diff --name-status --diff-filter=U

menunjukkan semua file yang membutuhkan resolusi konflik.

Buka masing-masing file satu per satu, atau semuanya sekaligus dengan:

emacs $(git diff --name-only --diff-filter=U)

Saat mengunjungi buffer yang membutuhkan suntingan di Emacs, ketik

ALT+x vc-resolve-conflicts

Ini akan membuka tiga buffer (milikku, milik mereka, dan buffer output). Navigasikan dengan menekan 'n' (region berikutnya), 'p' (wilayah previsi). Tekan 'a' dan 'b' untuk menyalin tambang atau wilayah mereka ke buffer output, masing-masing. Dan / atau mengedit buffer output secara langsung.

Setelah selesai: Tekan 'q'. Emacs bertanya apakah Anda ingin menyimpan buffer ini: ya. Setelah menyelesaikan tanda penyangga, diselesaikan dengan berlari dari teriminal:

git add FILENAME

Setelah selesai dengan semua jenis buffer

git commit

untuk menyelesaikan penggabungan.


36
2018-02-22 23:04



Harap ikuti langkah-langkah berikut untuk memperbaiki konflik gabungan di Git:

  1. Periksa status Git: status git

  2. Dapatkan tambalan: git fetch (checkout patch yang tepat dari commit Git Anda)

  3. Checkout cabang lokal (temp1 dalam contoh saya di sini): git checkout -b temp1

  4. Tarik konten terbaru dari master: git pull - master asalrebase

  5. Mulai mergetool dan periksa konflik dan perbaiki ... dan periksa perubahan di cabang jarak jauh dengan cabang Anda saat ini: git mergetool

  6. Periksa kembali statusnya:   status git

  7. Hapus file yang tidak diinginkan yang dibuat secara lokal oleh mergetool, biasanya mergetool membuat file ekstra dengan ekstensi * .orig. Hapus file itu karena itu hanya duplikat dan perbaiki perubahan secara lokal dan tambahkan versi yang benar dari file Anda. git tambahkan #your_changed_correct_files

  8. Periksa kembali statusnya: status git

  9. Komit perubahan ke id komit yang sama (ini menghindari set patch baru yang terpisah): git commit --amend

  10. Dorong ke cabang master: git push (ke repositori Git Anda)


28
2018-04-16 07:02