Bagaimana cara menyelesaikan konflik gabungan di Git?
git
instalasi default . Berhasil mencapai halaman mulai SE untuk saya hari ini, 2017, dengan pandangan 1,3 juta dan ribuan suara. Menarik.
Bagaimana cara menyelesaikan konflik gabungan di Git?
git
instalasi default . Berhasil mencapai halaman mulai SE untuk saya hari ini, 2017, dengan pandangan 1,3 juta dan ribuan suara. Menarik.
Jawaban:
Mencoba: git mergetool
Ini membuka GUI yang langkah Anda melalui setiap konflik, dan Anda bisa memilih cara untuk menggabungkan. Kadang-kadang membutuhkan sedikit pengeditan tangan setelahnya, tetapi biasanya cukup dengan sendirinya. Ini jauh lebih baik daripada melakukan semuanya dengan tangan.
Sesuai komentar @JoshGlover:
Perintah
tidak harus membuka GUI kecuali Anda menginstalnya. Menjalankan
git mergetool
untuk saya menghasilkanvimdiff
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 contoh prosedur yang digunakan vimdiff
untuk menyelesaikan konflik gabungan. Berdasarkan tautan 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 menetapkan 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 pandangan ini
LOCAL - ini adalah file dari cabang saat ini
DASAR - nenek moyang yang sama, bagaimana file terlihat sebelum kedua perubahan
REMOTE - file yang Anda gabungkan ke cabang Anda
MERGED - hasil merger, inilah yang akan disimpan dalam repo
Anda dapat menavigasi di antara tampilan ini menggunakan ctrl+ w. Anda dapat langsung mencapai tampilan MERGED menggunakan ctrl+ wdiikuti oleh j.
Info lebih lanjut tentang navigasi vimdiff di sini dan di 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 mendapat perubahan dari LOCAL
:diffg LO
Langkah 5 . Simpan, Keluar, Berkomitmen dan Bersihkan
:wqa
simpan dan keluar dari vi
git commit -m "message"
git clean
Hapus file tambahan (misalnya * .orig) yang dibuat oleh alat diff.
git mergetool -y
untuk menyimpan beberapa penekanan tombol jika Anda menggabungkan banyak file sekaligus.
git mergetool
untuk saya menghasilkan vimdiff
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
.
git mergetool -t bc3
).
Inilah kemungkinan kasus penggunaan, dari atas:
Anda akan melakukan beberapa perubahan, tetapi oops, Anda tidak up to date:
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 informasi terbaru dan coba lagi, tetapi mengalami 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 my, oh my, hulu mengubah beberapa hal, tetapi hanya 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 yang terakhir kalinya
git pull origin master
From ssh://gitosis@example.com:22/projectname
* branch master -> FETCH_HEAD
Already up-to-date.
Ta-da!
git merge --help
this question
Saya menemukan alat penggabungan jarang membantu saya memahami konflik atau resolusi. Saya biasanya lebih berhasil melihat penanda konflik dalam editor teks dan menggunakan git log sebagai pelengkap.
Berikut ini beberapa tips:
Hal terbaik yang saya temukan adalah menggunakan gaya konflik gabungan "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 leluhur yang sama itu terlihat. Ini berguna karena Anda dapat membandingkannya dengan versi atas dan bawah untuk mendapatkan pemahaman yang lebih baik tentang apa yang diubah pada setiap cabang, yang memberi Anda ide yang lebih baik tentang tujuan dari setiap perubahan itu.
Jika konflik hanya beberapa baris, ini umumnya membuat konflik menjadi sangat jelas. (Mengetahui cara memperbaiki konflik sangat berbeda; Anda perlu mengetahui apa yang sedang dikerjakan orang lain. Jika Anda bingung, mungkin lebih baik memanggil orang itu ke kamar Anda sehingga 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".
Kemudian saya dapat menjalankan perintah berikut untuk melihat dua bakhil berbeda yang menyebabkan konflik:
diff common mine
diff common theirs
Ini tidak sama dengan menggunakan alat gabungan, karena alat gabungan akan mencakup semua bakhil diff yang tidak saling bertentangan juga. Saya menemukan itu mengganggu.
Seseorang sudah menyebutkan ini, tetapi memahami maksud di balik setiap perbedaan biasanya sangat membantu untuk memahami dari mana konflik berasal dan bagaimana cara mengatasinya.
git log --merge -p <name of file>
Ini menunjukkan semua komit yang menyentuh file di antara leluhur yang sama dan dua kepala yang Anda gabungkan. (Jadi itu tidak termasuk komit yang sudah ada di kedua cabang sebelum penggabungan.) Ini membantu Anda mengabaikan bingkah yang berbeda yang jelas bukan merupakan faktor dalam konflik Anda saat ini.
Verifikasi perubahan Anda dengan alat otomatis.
Jika Anda memiliki tes otomatis, jalankan itu. Jika Anda memiliki serat , jalankan itu. Jika ini adalah proyek yang dapat dibangun, kemudian bangun sebelum Anda berkomitmen, dll. Dalam semua kasus, Anda perlu melakukan sedikit pengujian untuk memastikan perubahan Anda tidak merusak apa pun. (Heck, bahkan gabungan tanpa konflik dapat merusak kode kerja.)
Rencanakan ke depan; berkomunikasi dengan rekan kerja.
Merencanakan ke depan dan mengetahui apa yang sedang dikerjakan orang lain dapat membantu mencegah penggabungan konflik dan / atau membantu menyelesaikannya lebih awal - sementara perinciannya masih segar dalam ingatan.
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 pemahaman yang lebih baik tentang tipe perubahan apa yang Anda masing-masing lakukan. membuat. Anda mungkin menghemat banyak waktu dan usaha jika Anda melakukan perubahan yang direncanakan secara serial daripada secara paralel.
Untuk refactoring utama yang memotong sejumlah besar kode, Anda harus sangat mempertimbangkan bekerja secara seri: semua orang berhenti mengerjakan area kode itu sementara satu orang melakukan refactoring lengkap.
Jika Anda tidak dapat bekerja secara serial (karena tekanan waktu, mungkin), maka berkomunikasi tentang konflik gabungan yang diharapkan setidaknya membantu Anda menyelesaikan masalah lebih cepat sementara detailnya masih segar dalam ingatan. Sebagai contoh, jika seorang rekan kerja membuat serangkaian tindakan yang mengganggu selama periode satu minggu, Anda dapat memilih untuk bergabung / rebase di cabang rekan kerja itu satu atau dua kali sehari setiap hari selama minggu itu. Dengan begitu, jika Anda menemukan konflik merger / rebase, Anda dapat menyelesaikannya lebih cepat daripada jika Anda menunggu beberapa minggu untuk menggabungkan semuanya bersama dalam satu benjolan besar.
Jika Anda tidak yakin tentang penggabungan, jangan paksa itu.
Penggabungan dapat terasa luar biasa, terutama ketika ada banyak file yang saling bertentangan dan penanda konflik mencakup ratusan baris. Sering kali ketika memperkirakan proyek perangkat lunak kami tidak memasukkan cukup waktu untuk item overhead seperti menangani penggabungan degil, jadi terasa seperti hambatan nyata untuk menghabiskan beberapa jam membedah setiap konflik.
Dalam jangka panjang, perencanaan ke depan 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.
p4merge
, yang dapat diinstal dan digunakan secara terpisah dari alat Perforce lainnya (yang saya tidak pernah gunakan, tetapi mendengar keluhan tentang).
git config merge.conflictstyle diff3
- Terima kasih Pak. Ini luar biasa dan telah membebaskan saya dari upaya untuk menemukan (dan membayar $$) untuk GUI penggabungan 3 cara yang baik. IMO ini lebih baik karena menunjukkan leluhur bersama serta lokal / jauh, dan menunjukkan garis-garis log komit terakhir yang (AFAIK) tidak GUI lakukan. Komit pasti membantu Anda mengidentifikasi kode apa yang dimiliki cabang apa.
Identifikasi file mana yang dalam konflik (Git harus memberi tahu Anda ini).
Buka setiap file dan periksa perbedaannya; Git membatasi mereka. Semoga akan jelas versi mana dari setiap blok untuk disimpan. Anda mungkin perlu mendiskusikannya dengan sesama pengembang yang melakukan kode.
Setelah Anda menyelesaikan konflik dalam file git add the_file
.
Setelah Anda menyelesaikan semua konflik, lakukan git rebase --continue
atau perintah apa pun yang dikatakan Git lakukan ketika Anda selesai.
git add
file dalam indeks; itu tidak menambahkan apa pun ke repositori. git commit
menambahkan hal-hal ke repositori. Penggunaan ini masuk akal untuk penggabungan - penggabungan secara otomatis menggelar semua perubahan yang dapat digabungkan secara otomatis; Anda bertanggung jawab untuk menggabungkan sisa perubahan dan menambahkannya ke indeks saat Anda selesai.
Lihatlah jawaban di pertanyaan Stack Overflow. Batalkan penggabungan dalam Git , terutama jawaban Charles Bailey yang menunjukkan cara melihat versi berbeda dari file yang bermasalah, 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
Gabungkan konflik terjadi ketika perubahan dilakukan pada file pada saat yang bersamaan. Inilah cara mengatasinya.
git
CLIBerikut adalah langkah-langkah sederhana apa yang harus dilakukan ketika Anda masuk ke dalam keadaan konflik:
git status
(di bawah Unmerged paths
bagian).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 konflik karena beberapa alasan.
Terkait: Apa arti tepat dari "milik kita" dan "milik mereka" dalam git?
Edit file yang konflik secara manual dan cari blok kode antara <<<<<
/ >>>>>
lalu pilih versi dari atas atau bawah =====
. Lihat: Bagaimana konflik disajikan .
Konflik jalur dan nama file dapat diselesaikan dengan git add
/ git rm
.
Akhirnya, meninjau file siap berkomitmen menggunakan: git status
.
Jika Anda masih memiliki file di bawah Unmerged paths
, dan kau menyelesaikan konflik secara manual, kemudian membiarkan Git tahu bahwa Anda dipecahkan dengan: git add path/file
.
Jika semua konflik berhasil diselesaikan, lakukan perubahan dengan: git commit -a
dan dorong ke remote seperti biasa.
Lihat juga: Mengatasi konflik gabungan dari baris perintah di GitHub
Untuk tutorial praktis, periksa: Skenario 5 - Memperbaiki Konflik Penggabungan oleh Katacoda .
Saya telah berhasil menggunakan DiffMerge yang secara visual dapat membandingkan dan menggabungkan file pada Windows, macOS dan Linux / Unix.
Secara grafis dapat menunjukkan perubahan antara 3 file dan memungkinkan penggabungan otomatis (saat aman untuk melakukannya) dan kontrol penuh atas pengeditan file yang dihasilkan.
Sumber gambar: DiffMerge (tangkapan layar Linux)
Cukup unduh dan jalankan dalam repo sebagai:
git mergetool -t diffmerge .
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 ditempatkan di PATH Anda (misalnya /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:
Atau Anda dapat menggunakan opendiff (bagian dari Xcode Tools) yang memungkinkan Anda menggabungkan dua file atau direktori bersamaan untuk membuat file atau direktori ketiga.
Jika Anda sering melakukan komit kecil, maka mulailah dengan melihat 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 pada 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 yang gagal akan menunjukkan perbedaan 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 mereka telah git add
-ed, git commit
akan melengkapi penggabungan Anda.
Lihat Bagaimana Konflik Disajikan atau, dalam Git, git merge
dokumentasi untuk memahami apa yang menggabungkan penanda konflik.
Juga, bagian Bagaimana Mengatasi Konflik menjelaskan bagaimana menyelesaikan konflik:
Setelah melihat konflik, Anda dapat melakukan dua hal:
Putuskan untuk tidak bergabung. Satu-satunya pembersihan yang Anda butuhkan adalah mereset file indeks ke
HEAD
komit untuk membalik 2. dan untuk membersihkan perubahan susunan yang dibuat oleh 2. dan 3 .;git merge --abort
dapat digunakan untuk ini.Selesaikan konflik. Git akan menandai konflik di pohon kerja. Edit file ke dalam bentuk dan
git add
ke indeks. Gunakangit commit
untuk menyegel kesepakatan.Anda dapat mengatasi konflik dengan sejumlah alat:
Gunakan mergetool.
git mergetool
untuk meluncurkan mergetool grafis yang akan membantu Anda melalui penggabungan.Lihatlah perbedaannya.
git diff
akan menampilkan diff tiga arah, menyoroti perubahan dariHEAD
danMERGE_HEAD
versi.Lihatlah perbedaan dari setiap cabang.
git log --merge -p <path>
akan menampilkan diffs pertama untukHEAD
versi dan kemudianMERGE_HEAD
versi.Lihatlah yang asli.
git show :1:filename
menunjukkan leluhur yang sama,git show :2:filename
menunjukkanHEAD
versi, dangit show :3:filename
menunjukkanMERGE_HEAD
versi.
Anda juga dapat membaca tentang penanda konflik gabungan dan cara mengatasinya di bagian buku Pro Git Konflik Penggabungan Dasar .
Saya ingin versi saya atau versi mereka sepenuhnya, atau ingin meninjau perubahan individu dan memutuskan untuk masing-masing.
Sepenuhnya menerima versi saya atau mereka :
Terima versi saya (lokal, milik kami):
git checkout --ours -- <filename>
git add <filename> # Marks conflict as resolved
git commit -m "merged bla bla" # An "empty" commit
Terima versi mereka (jarak jauh, milik mereka):
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
Jika Anda ingin melakukannya untuk semua file konflik jalankan:
git merge --strategy-option ours
atau
git merge --strategy-option theirs
Tinjau semua perubahan dan terima satu per satu
git mergetool
git add <filename>
git commit -m "merged bla bla"
Default mergetool
berfungsi di baris perintah . Cara menggunakan mergetool baris perintah harus menjadi pertanyaan terpisah.
Anda juga dapat menginstal alat visual untuk ini, misalnya meld
dan jalankan
git mergetool -t meld
Ini akan membuka versi lokal (milik kita), versi "basis" atau "digabung" (hasil penggabungan saat ini) dan versi jarak jauh (milik mereka). Simpan versi gabungan ketika Anda selesai, jalankan git mergetool -t meld
lagi sampai Anda mendapatkan "Tidak ada file yang perlu digabung", kemudian pergi ke Langkah 3. dan 4.
Untuk pengguna Emacs yang ingin menyelesaikan konflik penggabungan secara semi-manual:
git diff --name-status --diff-filter=U
memperlihatkan semua file yang memerlukan resolusi konflik.
Buka masing-masing file satu per satu, atau sekaligus dengan:
emacs $(git diff --name-only --diff-filter=U)
Saat mengunjungi buffer yang membutuhkan pengeditan di Emacs, ketik
ALT+x vc-resolve-conflicts
Ini akan membuka tiga buffer (milikku, milik mereka, dan buffer output). Navigasi dengan menekan 'n' (wilayah berikutnya), 'p' (wilayah previsi). Tekan 'a' dan 'b' untuk menyalin masing-masing wilayah tambang atau mereka ke buffer output. Dan / atau edit buffer output secara langsung.
Setelah selesai: Tekan 'q'. Emacs bertanya apakah Anda ingin menyimpan buffer ini: ya. Setelah menyelesaikan tanda buffer itu diselesaikan dengan menjalankan dari teriminal:
git add FILENAME
Setelah selesai dengan semua tipe buffer
git commit
untuk menyelesaikan penggabungan.
Dalam berbicara tentang tarik / ambil / gabungkan jawaban di atas, saya ingin berbagi trik yang menarik dan produktif,
git pull --rebase
Perintah di atas adalah perintah yang paling berguna dalam hidup git saya yang menghemat banyak waktu.
Sebelum mendorong perubahan yang baru Anda komit ke server jarak jauh, coba git pull --rebase
agak git pull
dan manual merge
dan itu akan secara otomatis menyinkronkan perubahan server jarak jauh terbaru (dengan mengambil + gabungan) dan akan menempatkan komit terbaru lokal Anda di bagian atas di git log. Tidak perlu khawatir tentang tarikan / penggabungan manual.
Jika terjadi konflik, gunakan saja
git mergetool
git add conflict_file
git rebase --continue
Temukan detailnya di: http://gitolite.com/git-pull--rebase
Sederhananya, jika Anda tahu betul bahwa perubahan dalam salah satu repositori tidak penting, dan ingin menyelesaikan semua perubahan yang mendukung yang lain, gunakan:
git checkout . --ours
untuk menyelesaikan perubahan yang mendukung repositori Anda , atau
git checkout . --theirs
untuk menyelesaikan perubahan demi repositori lain atau utama .
Atau Anda harus menggunakan alat gabungan GUI untuk menelusuri file satu per satu, katakanlah alat gabungan p4merge
, atau tulis nama siapa pun yang telah Anda instal
git mergetool -t p4merge
dan setelah menyelesaikan file, Anda harus menyimpan dan menutup, sehingga yang berikutnya akan terbuka.
Harap ikuti langkah-langkah berikut untuk memperbaiki gabungan konflik di Git:
Periksa status Git: status git
Dapatkan patchset: git fetch (checkout patch yang tepat dari komit Git Anda)
Periksa cabang lokal (temp1 dalam contoh saya di sini): git checkout -b temp1
Tarik konten terbaru dari master: git pull - master asal asal
Mulai mergetool dan periksa konfliknya dan perbaiki ... dan periksa perubahan di cabang jarak jauh dengan cabang Anda saat ini: git mergetool
Periksa lagi statusnya: status git
Hapus file yang tidak diinginkan yang dibuat secara lokal oleh mergetool, biasanya mergetool membuat file tambahan dengan ekstensi * .orig. Silakan hapus file itu karena itu hanya duplikat dan perbaiki perubahan secara lokal dan tambahkan versi yang benar dari file Anda. git tambahkan #Anda_changed_correct_files
Periksa lagi statusnya: status git
Komit perubahan ke id komit yang sama (ini menghindari set patch terpisah baru): git commit --amend
Dorong ke cabang master: git push (ke repositori Git Anda)
Ada 3 langkah:
Temukan file mana yang menyebabkan konflik dengan perintah
git status
Periksa file, di mana Anda akan menemukan konflik ditandai seperti
<<<<<<<<head
blablabla
Ubah sesuai keinginan Anda, lalu komit dengan perintah
git add solved_conflicts_files
git commit -m 'merge msg'
Anda bisa memperbaiki gabungan konflik dalam beberapa cara seperti yang telah dijelaskan oleh pihak lain.
Saya pikir kunci sebenarnya adalah mengetahui bagaimana perubahan mengalir dengan repositori lokal dan jarak jauh. Kunci untuk ini adalah memahami cabang pelacakan. Saya telah menemukan bahwa saya menganggap cabang pelacakan sebagai 'bagian yang hilang di tengah' antara saya, direktori file aktual saya dan remote yang didefinisikan sebagai asal.
Saya pribadi memiliki kebiasaan 2 hal untuk membantu menghindari hal ini.
Dari pada:
git add .
git commit -m"some msg"
Yang memiliki dua kelemahan -
a) Semua file baru / yang diubah ditambahkan dan itu mungkin termasuk beberapa perubahan yang tidak diinginkan.
b) Anda tidak bisa meninjau daftar file terlebih dahulu.
Jadi saya malah melakukannya:
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
Dengan cara ini Anda lebih disengaja tentang file mana yang akan ditambahkan dan Anda juga bisa meninjau daftar dan berpikir lebih banyak saat menggunakan editor untuk pesan. Saya menemukan itu juga meningkatkan pesan komit saya ketika saya menggunakan editor layar penuh daripada -m
opsi.
[Pembaruan - seiring waktu berlalu saya telah beralih lebih ke:
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]
Juga (dan lebih relevan dengan situasi Anda), saya mencoba untuk menghindari:
git pull
atau
git pull origin master.
karena pull menyiratkan penggabungan dan jika Anda memiliki perubahan secara lokal yang tidak ingin digabungkan, Anda dapat dengan mudah berakhir dengan kode gabungan dan / atau menggabungkan konflik untuk kode yang seharusnya tidak digabungkan.
Sebaliknya saya coba lakukan
git checkout master
git fetch
git rebase --hard origin/master # or whatever branch I want.
Anda juga dapat menemukan ini bermanfaat:
git branch, fork, fetch, gabung, rebase dan clone, apa bedanya?
git checkout master
dan git fetch
dan git rebase --hard origin/master
git add .
, apakah ini akan menyimpan modifikasi lokal kami sehingga kami dapat menindaklanjutinya git checkout master
? atau mereka dua skenario yang berbeda?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard 'use: git rebase [-i] [options] [--exec <cmd>] [--tanggal <newbase>] [[upstream>] [<branch>] atau: git rebase [-i] [ options] [--exec <cmd>] [--onto <newbase>] --root [<branch>] atau: git rebase --continue | --abort | --skip | --edit-todo `
Jawaban CoolAJ86 meringkaskan semuanya. Jika Anda memiliki perubahan di kedua cabang dalam potongan kode yang sama Anda harus melakukan penggabungan manual. Buka file dalam konflik di editor teks apa pun dan Anda akan melihat struktur berikut.
(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too
<<<<<<<<<<<
(Code not in conflict here)
Pilih salah satu alternatif atau kombinasi keduanya dengan cara yang Anda inginkan kode baru, sambil menghapus tanda sama dan kurung sudut.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
Tampaknya tidak selalu bekerja untuk saya dan biasanya menampilkan setiap komit yang berbeda antara dua cabang, ini terjadi bahkan ketika menggunakan --
untuk memisahkan jalur dari perintah.
Apa yang saya lakukan untuk mengatasi masalah ini adalah membuka dua baris perintah dan dalam satu langkah
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
dan yang lainnya
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
Mengganti $MERGED_IN_BRANCH
dengan cabang saya bergabung dan [path]
dengan file yang bertentangan. Perintah ini akan mencatat semua komit, dalam bentuk tambalan, antara ( ..
) dua komit. Jika Anda membiarkan satu sisi kosong seperti pada perintah di atas git akan secara otomatis menggunakan HEAD
(cabang yang Anda gabungkan dalam hal ini).
Ini akan memungkinkan Anda untuk melihat komit apa yang masuk ke file di dua cabang setelah mereka menyimpang. Ini biasanya membuatnya lebih mudah untuk menyelesaikan konflik.
patience
Saya terkejut tidak ada orang lain yang berbicara tentang menyelesaikan konflik menggunakan patience
dengan strategi rekursif gabungan. Untuk konflik penggabungan besar, menggunakan patience
memberikan hasil yang baik untuk saya. Idenya adalah bahwa ia akan mencoba untuk mencocokkan blok daripada garis individual.
Misalnya, jika Anda mengubah lekukan program Anda, strategi penggabungan Git standar terkadang cocok dengan kawat gigi tunggal {
yang memiliki fungsi berbeda. Ini dihindari dengan patience
:
git merge -s recursive -X patience other-branch
Dari dokumentasi:
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
Jika Anda memiliki konflik penggabungan dan ingin melihat apa yang ada dalam pikiran orang ketika memodifikasi cabang mereka, kadang-kadang lebih mudah untuk membandingkan cabang mereka secara langsung dengan leluhur yang sama (bukan cabang kami). Untuk itu Anda bisa menggunakan merge-base
:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
Biasanya, Anda hanya ingin melihat perubahan untuk file tertentu:
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
Mulai 12 Desember 2016, Anda dapat menggabungkan cabang dan menyelesaikan konflik di github.com
Jadi, jika Anda tidak ingin menggunakan baris perintah atau alat pihak ketiga mana pun yang ditawarkan di sini dari jawaban yang lebih lama , gunakan alat asli GitHub.
Posting blog ini menjelaskan secara rinci, tetapi dasarnya adalah bahwa setelah 'menggabungkan' dua cabang melalui UI, Anda sekarang akan melihat opsi 'menyelesaikan konflik' yang akan membawa Anda ke editor yang memungkinkan Anda untuk menangani konflik gabungan ini.
Jika Anda ingin menggabungkan dari cabang (uji) untuk dikuasai, Anda dapat mengikuti langkah-langkah ini:
Langkah 1 : Pergi ke cabang
git checkout test
Langkah 2 :
git pull --rebase origin master
Langkah 3 : Jika ada beberapa konflik, buka file-file ini untuk memodifikasinya.
Langkah 4 : Tambahkan perubahan ini
git add #your_changes_files
Langkah 5 :
git rebase --continue
Langkah 6 : Jika masih ada konflik, kembali ke langkah 3 lagi. Jika tidak ada konflik, lakukan hal berikut:
git push origin +test
Langkah 7 : Dan kemudian tidak ada konflik antara tes dan master. Anda dapat menggunakan penggabungan secara langsung.
Saya selalu mengikuti langkah-langkah di bawah ini untuk menghindari konflik.
Sekarang Anda dapat melakukan hal yang sama dan mempertahankan sebanyak mungkin cabang lokal yang Anda inginkan dan bekerja secara simultan. Saya hanya melakukan checkout git ke cabang Anda bila diperlukan.
Menggabungkan konflik dapat terjadi dalam situasi yang berbeda:
Anda perlu menginstal alat gabungan yang kompatibel dengan Git untuk menyelesaikan konflik. Saya pribadi menggunakan KDiff3, dan menurut saya bagus dan praktis. Anda dapat mengunduh versi Windows-nya di sini:
https://sourceforge.net/projects/kdiff3/files/
BTW jika Anda menginstal Git Extensions ada opsi di setup wizard untuk menginstal Kdiff3.
Kemudian setup git configs untuk menggunakan Kdiff sebagai mergetool:
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false
$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false
(Ingatlah untuk mengganti path dengan path sebenarnya dari file exe Kdiff.)
Maka setiap kali Anda menemukan konflik gabungan Anda hanya perlu menjalankan perintah ini:
$git mergetool
Kemudian itu membuka Kdiff3, dan pertama-tama mencoba untuk menyelesaikan konflik gabungan secara otomatis. Sebagian besar konflik akan diselesaikan secara spontan dan Anda harus memperbaiki sisanya secara manual.
Inilah yang terlihat seperti Kdiff3:
Kemudian setelah Anda selesai, simpan file dan pergi ke file berikutnya dengan konflik dan Anda melakukan hal yang sama lagi sampai semua konflik diselesaikan.
Untuk memeriksa apakah semuanya berhasil digabungkan, jalankan saja perintah mergetool, Anda harus mendapatkan hasil ini:
$git mergetool
No files need merging
Jawaban ini adalah untuk menambahkan alternatif bagi para pengguna VIM seperti saya yang lebih suka melakukan semuanya di dalam editor.
Tpope datang dengan plugin hebat ini untuk VIM yang disebut buron . Setelah terinstal, Anda dapat menjalankan :Gstatus
untuk memeriksa file yang memiliki konflik dan:Gdiff
untuk membuka Git dalam penggabungan 3 cara.
Sekali dalam penggabungan 3-cara, buron akan membiarkan Anda mendapatkan perubahan dari salah satu cabang yang Anda gabungkan dengan cara berikut:
:diffget //2
, dapatkan perubahan dari cabang ( HEAD ) asli::diffget //3
, dapatkan perubahan dari menggabungkan cabang: Setelah Anda selesai menggabungkan file, ketik :Gwrite
buffer yang digabung. Vimcasts merilis video hebat yang menjelaskan secara rinci langkah-langkah ini.
git ambil
git checkout master git rebase cabang Anda
Pada langkah ini Anda akan mencoba untuk memperbaiki konflik menggunakan IDE pilihan Anda
Anda dapat mengikuti tautan ini untuk memeriksa bagaimana memperbaiki konflik di file
https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/
git add
git rebase --continue
git commit - ubah
git push origin HEAD: refs / draft / master (push like a draf)
Sekarang semuanya baik-baik saja dan Anda akan menemukan komit Anda di gerrit
Saya harap ini akan membantu setiap orang terkait masalah ini.
Coba Visual Studio Code untuk mengedit jika Anda belum melakukannya. Apa yang dilakukan adalah setelah Anda mencoba menggabungkan (dan mendarat di konflik gabungan). Kode VS secara otomatis mendeteksi konflik gabungan.
Ini dapat membantu Anda dengan sangat baik dengan menunjukkan apa saja perubahan yang dilakukan pada yang asli dan harus Anda terima incoming
atau
current change
(artinya yang asli sebelum penggabungan) '?.
Itu membantu saya dan juga bisa bekerja untuk Anda!
PS: Ini hanya akan berfungsi jika Anda telah mengkonfigurasi git dengan kode dan Visual Studio Code Anda.
Cara yang lebih aman untuk menyelesaikan konflik adalah dengan menggunakan git-mediate (solusi umum yang disarankan di sini cukup rentan terhadap kesalahan).
Lihat posting ini untuk pengantar cepat tentang cara menggunakannya.
Bagi mereka yang menggunakan Visual Studio (2015 dalam kasus saya)
Tutup proyek Anda di VS. Terutama dalam proyek-proyek besar VS cenderung panik ketika penggabungan menggunakan UI.
Lakukan penggabungan prompt perintah.
git checkout target_branch
git menggabungkan source_branch
Kemudian buka proyek dalam VS dan pergi ke Team Explorer -> Branch. Sekarang ada pesan yang mengatakan Gabung tertunda dan file yang bertentangan tercantum tepat di bawah pesan.
Klik file yang bertentangan dan Anda akan memiliki opsi untuk Gabung, Bandingkan, Ambil Sumber, Ambil Target. Alat penggabungan dalam VS sangat mudah digunakan.
Jika Anda menggunakan intelliJ sebagai IDE, Cobalah menggabungkan induk ke cabang Anda dengan
git checkout <localbranch>
git merge origin/<remotebranch>
Ini akan menampilkan semua konflik seperti ini
A_MBPro: test anu $ git merge origin / Penggabungan otomatis src / test / java / com /.../ TestClass.java CONFLICT (konten): Gabungkan konflik dalam src / test / java / com /.../ TestClass.java
Sekarang perhatikan bahwa file TestClass.java ditampilkan dengan warna merah di intelliJ Status git juga akan ditampilkan
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
Buka file di intelliJ, itu akan memiliki bagian dengan
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
di mana HEAD berubah pada cabang lokal Anda dan asal / adalah perubahan dari cabang jarak jauh. Di sini simpan barang-barang yang Anda butuhkan dan hapus barang-barang yang tidak Anda butuhkan. Setelah itu langkah-langkah normal harus dilakukan. Itu adalah
git add TestClass.java
git commit -m "commit message"
git push