Saya mengalami konflik gabungan. Bagaimana saya bisa membatalkan penggabungan?

2539

Saya menggunakan git pulldan memiliki konflik gabungan:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Saya tahu bahwa versi lain dari file tersebut baik dan milik saya buruk sehingga semua perubahan saya harus ditinggalkan. Bagaimana saya bisa melakukan ini?

Gwyn Morfey
sumber
30
Saya menyadari bahwa ini adalah pertanyaan yang sangat lama, tetapi apakah Anda ingin membatalkan seluruh penggabungan, dan meninggalkan cabang tempat Anda bergabung tidak digabung, atau abaikan saja file yang satu ini sebagai bagian dari penggabungan yang lebih besar, membiarkan semua file lainnya bergabung sebagai normal? Bagi saya, judul Anda menyiratkan yang pertama, badan pertanyaan Anda menginginkan yang terakhir. Jawabannya melakukan keduanya, tanpa membuat semuanya jelas.
rjmunro
Saya mendapat kasus serupa di komit yang mengatakan bahwa penggabungan otomatis gagal; perbaiki konflik dan kemudian lakukan hasilnya:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana
4
Gwyn, mungkin berguna untuk memilih jawaban yang diterima di sini. Yang terpilih teratas sedikit lebih tidak aman daripada beberapa solusi yang lebih terkini, jadi saya pikir ini akan membantu untuk menyoroti orang lain di atasnya :)
Amicable

Jawaban:

2222

Karena Anda pulltidak berhasil maka HEAD(tidak HEAD^) adalah komit "valid" terakhir di cabang Anda:

git reset --hard HEAD

Bagian lain yang Anda inginkan adalah membiarkan perubahan mereka menunggangi perubahan Anda.

Versi git yang lebih lama memungkinkan Anda untuk menggunakan strategi gabungan "mereka":

git pull --strategy=theirs remote_branch

Tapi ini sejak itu telah dihapus, seperti yang dijelaskan dalam pesan ini oleh Junio ​​Hamano (pengelola Git). Seperti tercantum dalam tautan , Anda justru akan melakukan ini:

git fetch origin
git reset --hard origin
Pat Notz
sumber
49
Alih-alih melakukan hard reset, Anda bisa membawanya ke level yang lebih terperinci dengan melakukan: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Saya tidak pernah menggunakan git pull lagi. Karena dalam pertarungan antara kode terbaru saya dan asal, asal harus selalu menang, saya selalu git fetchdan git rebase origin. Ini sebenarnya membuat merger dan konflik saya sedikit dan jarang.
Kzqai
7
Saya setuju. Saya juga suka mengambil dulu, dan kemudian memeriksa perubahan hulu ( git log ..@{upstream}atau git diff ..@{upstream}). Setelah itu, seperti Anda, saya akan memulai kembali pekerjaan saya.
Pat Notz
162
Seperti disebutkan dalam jawaban yang lebih baru, pada versi 1.6.1, dimungkinkan untuk menggunakan 'git reset --merge'
Matt Ball
5
Saya menggunakan git merge -X theirs remote_branchbukannya git pull --strategy=theirs remote_branchsebagai theirsterlihat seperti sebuah pilihanrecursive
MLT
14
git merge --abortjauh lebih disukai.
Daniel Cassidy
1956

Jika versi git Anda>> 1.6.1, Anda dapat menggunakan git reset --merge.

Juga, seperti yang disebutkan @Michael Johnson, jika versi git Anda>> 1.7.4, Anda juga dapat menggunakan git merge --abort.

Seperti biasa, pastikan Anda tidak memiliki perubahan yang tidak dikomit sebelum Anda memulai penggabungan.

Dari halaman manual git merge

git merge --abortsetara dengan git reset --mergekapan MERGE_HEADhadir.

MERGE_HEAD hadir saat penggabungan sedang berlangsung.

Juga, tentang perubahan yang tidak dikomit ketika memulai penggabungan:

Jika Anda memiliki perubahan yang tidak ingin Anda komit sebelum memulai penggabungan, cukup git stashmereka sebelum penggabungan dan git stash popsetelah menyelesaikan penggabungan atau batalkan.

Carl
sumber
3
Menarik - tetapi manualnya membuatku takut. Kapan tepatnya itu layak digunakan? Kapan Anda harus menentukan opsi <commit>? #GitMoment: -o
conny
1
Anda biasanya menggunakan ini ketika Anda ingin mengulang gabungan dari awal. Saya tidak pernah harus menentukan komit opsional sendiri, jadi default (no opsional <commit>) baik-baik saja
Carl
44
Saya berharap jawaban ini memiliki lebih banyak suara! Pada titik ini, sepertinya solusi yang paling relevan dalam banyak kasus.
Jay Taylor
1
Bahkan dengan perubahan yang tidak dikomit, git dapat mengembalikan status sebelum penggabungan. Bagus!
T3rm1
2
Apakah git merge --aborthanya sinonim untuk git reset --merge? Nama itu tentu saja lebih masuk akal, tetapi apakah ia memiliki fungsi yang sama?
Tikhon Jelvis
518
git merge --abort

Batalkan proses resolusi konflik saat ini, dan cobalah untuk merekonstruksi negara pra-penggabungan.

Jika ada perubahan worktree yang tidak dikomit hadir saat penggabungan dimulai, git merge --abortdalam beberapa kasus tidak akan dapat merekonstruksi perubahan ini. Oleh karena itu disarankan untuk selalu melakukan atau menyembunyikan perubahan Anda sebelum menjalankan git merge.

git merge --abortsetara dengan git reset --mergekapan MERGE_HEADhadir.

http://www.git-scm.com/docs/git-merge

ignis
sumber
16
Ini sudah tersedia sejak git v1.7.4. Ini alias untuk git reset --merge.
Michael Johnson
162

Ini sangat mudah.

git merge --abort

Git sendiri menunjukkan kepada Anda solusinya ketika Anda berada dalam masalah seperti ini dan menjalankan perintah status git.

git status

Semoga ini bisa membantu orang.

Jagruttam Panchal
sumber
97

Saya pikir itu yang git resetAnda butuhkan.

Waspadalah itu git revertberarti sesuatu yang sangat berbeda dengan, katakanlah, svn revert- di Subversion, revert akan membuang perubahan Anda (yang tidak dikomit), mengembalikan file ke versi saat ini dari repositori, sedangkan git revert"undo" komit.

git resetharus melakukan hal yang setara dengan svn revert, yaitu, buang perubahan yang tidak diinginkan.

David Precious
sumber
76

Dalam kasus penggunaan khusus ini, Anda tidak benar-benar ingin membatalkan penggabungan, cukup selesaikan konflik dengan cara tertentu.

Tidak ada kebutuhan khusus untuk mengatur ulang dan melakukan penggabungan dengan strategi yang berbeda. Konflik telah disorot dengan benar oleh git dan persyaratan untuk menerima perubahan pihak lain hanya untuk file yang satu ini.

Untuk file yang tidak di-unmerged di dalam git konflik, tersedia versi dasar, lokal dan jarak jauh dari file dalam indeks. (Di sinilah mereka dibaca dari untuk digunakan dalam alat diff 3-cara oleh git mergetool.) Anda dapat menggunakan git showuntuk melihatnya.

# common base:
git show :1:_widget.html.erb

# 'ours'
git show :2:_widget.html.erb

# 'theirs'
git show :3:_widget.html.erb

Cara paling sederhana untuk menyelesaikan konflik untuk menggunakan versi jauh kata demi kata adalah:

git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb

Atau, dengan git> = 1.6.1:

git checkout --theirs _widget.html.erb
CB Bailey
sumber
5
terima kasih atas petunjuknya. bukankah ini bukan antarmuka pengguna git yang buruk?
Peter
@ Peter: Saya tidak yakin. Hasil yang diinginkan dapat dicapai dengan beberapa perintah dasar dengan opsi sederhana. Perbaikan apa yang akan Anda sarankan?
CB Bailey
10
Saya pikir git 1.6.1perintah itu masuk akal, dan bagus. Itulah tepatnya yang saya inginkan. Saya pikir solusi pra-1.6.1 tidak sempurna dan membutuhkan pengetahuan tentang bagian-bagian lain dari git yang harus dipisahkan dari proses resolusi gabungan. Tapi versi baru itu hebat!
Peter
67

Untuk skenario seperti, saya lakukan git fetchdan git pull, kemudian menyadari bahwa cabang hulu bukan cabang utama, yang mengakibatkan konflik yang tidak diinginkan.

git reset --merge 

Ini dikembalikan kembali tanpa mengatur ulang perubahan lokal saya.

naamadheya
sumber
45

Komentar menyarankan itu git reset --mergeadalah alias untuk git merge --abort. Perlu diperhatikan bahwa git merge --aborthanya setara dengan yang git reset --mergediberikan MERGE_HEAD. Ini bisa dibaca di git help untuk menggabungkan perintah.

git merge --abort sama dengan git reset --merge saat MERGE_HEAD ada.

Setelah penggabungan yang gagal, saat tidak ada MERGE_HEAD, gabungan yang gagal dapat diurungkan git reset --merge, tetapi tidak harus dengan git merge --abort. Mereka tidak hanya sintaks lama dan baru untuk hal yang sama .

Secara pribadi, saya menemukan git reset --mergejauh lebih kuat untuk skenario yang mirip dengan yang dijelaskan, dan gagal menggabungkan secara umum.

Martin G
sumber
2
apa yang sebenarnya dimaksud dengan "penggabungan gagal"? Gabung dengan konflik atau hal lain? Atau untuk mengulanginya: kapan MERGE_HEAD tidak ada? Pertanyaan tindak lanjut saya ada di sana untuk memahami penggunaan "git reset --merge" yang lebih baik.
Ewoks
@Ewoks git stash applymenyebabkan konflik gabungan bagi saya tetapi git merge --aborttidak membantu saat git reset --mergemelakukannya.
nitzel
27

Jika Anda berakhir dengan konflik gabungan dan tidak memiliki apa pun untuk dikomit, tetapi kesalahan gabungan masih ditampilkan. Setelah menerapkan semua perintah yang disebutkan di bawah ini,

git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin

Tolong di hapus

.git \ index.lock

File [cut paste ke beberapa lokasi lain dalam kasus pemulihan] dan kemudian masukkan perintah di bawah ini tergantung pada versi yang Anda inginkan.

git reset --hard HEAD
git reset --hard origin

Semoga itu bisa membantu !!!

Nirav Mehta
sumber
19

Alternatif, yang mempertahankan status copy pekerjaan adalah:

git stash
git merge --abort
git stash pop

Saya biasanya menyarankan ini, karena ini efektif seperti bergabung dalam Subversion karena membuang hubungan cabang di komit berikut.

Alain O'Dea
sumber
Saya menemukan pendekatan ini berguna ketika saya secara tidak sengaja bergabung ke cabang git-svn, yang tidak menangani dengan baik. Penggabungan squash atau ceri lebih baik ketika bekerja dengan cabang pelacakan git-svn. Akibatnya solusi saya mengubah penggabungan menjadi penggabungan squash setelah fakta.
Alain O'Dea
Jawaban terbaik untuk pertanyaan
Fouad Boukredine
18

Karena Git 1.6.1.3 git checkouttelah dapat keluar dari kedua sisi penggabungan:

git checkout --theirs _widget.html.erb
Alain O'Dea
sumber
3

Saya menemukan yang berikut ini berfungsi untuk saya (kembalikan satu file ke status pra-penggabungan):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*
Malcolm Boekhoff
sumber
-5

Sourcetree

Karena Anda tidak melakukan penggabungan, maka cukup klik dua kali pada cabang lain (yang berarti checkout) dan ketika sourcetree bertanya kepada Anda tentang membuang semua perubahan maka setujui :)

Kamil Kiełczewski
sumber