ฉันพบความขัดแย้งในการผสาน ฉันจะยกเลิกการรวมได้อย่างไร


2538

ฉันใช้git pullและมีข้อขัดแย้งที่ผสาน:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

ฉันรู้ว่าไฟล์รุ่นอื่นดีและของฉันนั้นแย่ดังนั้นการเปลี่ยนแปลงทั้งหมดของฉันควรถูกยกเลิก ฉันจะทำสิ่งนี้ได้อย่างไร


30
ฉันรู้ว่านี่เป็นคำถามที่เก่ามาก แต่คุณต้องการที่จะยกเลิกการผสานทั้งหมดและปล่อยให้สาขาที่คุณผสานถูกรวมหรือไม่สนใจไฟล์นี้เดียวซึ่งเป็นส่วนหนึ่งของการรวมที่มีขนาดใหญ่กว่า ปกติ? สำหรับฉันชื่อของคุณมีความหมายถึงอดีตหน่วยคำถามของคุณต้องการอย่างหลัง คำตอบทำทั้งสองอย่างโดยไม่ทำให้ชัดเจน
rjmunro

ฉันได้รับกรณีที่คล้ายกันในการกระทำโดยบอกว่าการผสานอัตโนมัติล้มเหลว แก้ไขข้อขัดแย้งแล้วส่งผลให้:[rejected] gh-pages -> gh-pages (non-fast-forward)
Chetabahana

4
Gwyn อาจเป็นประโยชน์ในการเลือกคำตอบที่ยอมรับได้ที่นี่ ด้านบนโหวตให้เป็นหนึ่งเป็นบิตปลอดภัยน้อยกว่าบางส่วนของมากขึ้นถึงวันที่การแก้ปัญหาดังนั้นฉันคิดว่ามันจะช่วยในการไฮไลท์อื่น ๆ มากกว่านั้น :)
มิตร

คำตอบ:


2219

เนื่องจากคุณpullไม่ประสบความสำเร็จดังนั้นHEAD(ไม่ใช่HEAD^) คือการกระทำ "ที่ถูกต้อง" ครั้งล่าสุดในสาขาของคุณ:

git reset --hard HEAD

อีกส่วนที่คุณต้องการคือให้การเปลี่ยนแปลงเปลี่ยนแปลงไปตามการเปลี่ยนแปลงของคุณ

รุ่นเก่าของ git อนุญาตให้คุณใช้กลยุทธ์การผสาน "พวกเขา":

git pull --strategy=theirs remote_branch

แต่สิ่งนี้ได้ถูกลบไปแล้วตามที่อธิบายไว้ในข้อความนี้โดย Junio ​​Hamano (ผู้ดูแล Git) ดังที่ระบุไว้ในลิงค์แทนคุณจะทำสิ่งนี้:

git fetch origin
git reset --hard origin

49
แทนที่จะทำการฮาร์ดรีเซ็ตคุณสามารถนำไปใช้ในระดับที่ละเอียดยิ่งขึ้นโดยทำ: 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) ฉันไม่เคยใช้ git pull อีกต่อไป เนื่องจากในการต่อสู้ระหว่างรหัสล่าสุดของฉันและต้นกำเนิดที่มาควรชนะผมเสมอและgit fetch git rebase originสิ่งนี้ทำให้การควบรวมกิจการและความขัดแย้งของฉันมีน้อยมาก
Kzqai

7
ฉันเห็นด้วย. ฉันต้องการดึงข้อมูลก่อนจากนั้นตรวจสอบการเปลี่ยนแปลงต้นน้ำ ( git log ..@{upstream}หรือgit diff ..@{upstream}) หลังจากนั้นเช่นเดียวกับคุณฉันจะลดงานของฉัน
Pat Notz

162
ตามที่ระบุไว้ในคำตอบล่าสุดเป็นของรุ่น 1.6.1 เป็นไปได้ที่จะใช้ 'รีเซ็ต git --merge'
แมตต์บอล

5
ผมใช้git merge -X theirs remote_branchแทนgit pull --strategy=theirs remote_branchเป็นtheirsลักษณะเหมือนตัวเลือกของrecursive
mlt

14
git merge --abortเป็นที่นิยมมากกว่า
Daniel Cassidy

1956

ถ้ารุ่นคอมไพล์ของคุณ> = 1.6.1 git reset --mergeคุณสามารถใช้

นอกจากนี้ในฐานะ @Michael จอห์นสันกล่าวถึงหากรุ่นคอมไพล์ของคุณ> = 1.7.4, git merge --abortคุณยังสามารถใช้

ตรวจสอบให้แน่ใจเสมอว่าคุณไม่มีการเปลี่ยนแปลงที่ไม่ผูกมัดก่อนที่จะเริ่มการผสาน

จากหน้าคนที่คอมไพล์ผสาน

git merge --abortเทียบเท่ากับgit reset --mergeเมื่อMERGE_HEADมีอยู่

MERGE_HEAD ปรากฏขึ้นเมื่อการผสานกำลังดำเนินการอยู่

นอกจากนี้เกี่ยวกับการเปลี่ยนแปลงที่ไม่มีข้อผูกมัดเมื่อเริ่มผสาน:

หากคุณมีการเปลี่ยนแปลงที่คุณไม่ต้องการคอมมิทก่อนเริ่มการรวมgit stashให้ทำการเปลี่ยนแปลงก่อนทำการผสานและgit stash popหลังจากทำการผสานเสร็จหรือยกเลิก


3
ที่น่าสนใจ - แต่คู่มือทำให้ฉันกลัว เมื่อใดควรใช้หรือไม่ คุณจะต้องระบุตัวเลือกเมื่อ<commit>ใด #GitMoment: -o
conny

1
โดยปกติแล้วคุณจะใช้สิ่งนี้เมื่อคุณต้องการทำซ้ำการผสานตั้งแต่เริ่มต้น ฉันไม่เคยระบุตัวเลือกกระทำเองดังนั้นค่าเริ่มต้น (ไม่มีตัวเลือก <commit>) ก็ใช้ได้
Carl

44
ฉันหวังว่าคำตอบนี้จะได้รับการโหวตมากขึ้น! ณ จุดนี้ดูเหมือนว่าทางออกที่เกี่ยวข้องมากที่สุดในหลายกรณี
Jay Taylor

1
แม้จะมีการเปลี่ยนแปลงที่ไม่ธรรมดา git ก็สามารถกู้คืนสถานะก่อนรวมได้ ดี!
T3rm1

2
เป็นgit merge --abortเพียงคำพ้องความหมายสำหรับgit reset --merge? ชื่อนี้เหมาะสมกว่า แต่มีฟังก์ชั่นเหมือนกันหรือไม่?
Tikhon Jelvis

518
git merge --abort

ยกเลิกกระบวนการแก้ไขข้อขัดแย้งในปัจจุบันและพยายามสร้างสถานะ pre-merge ใหม่

หากมีการเปลี่ยนแปลงเวิร์คทรีที่ไม่มีข้อผูกมัดเกิดขึ้นเมื่อการรวมเริ่มต้นขึ้นgit merge --abortในบางกรณีจะไม่สามารถสร้างการเปลี่ยนแปลงเหล่านี้ขึ้นใหม่ได้ ดังนั้นจึงขอแนะนำให้คอมมิชชันหรือซ่อนการเปลี่ยนแปลงของคุณก่อนที่จะทำการคอมไพล์ผสาน

git merge --abortเทียบเท่ากับgit reset --mergeเมื่อ MERGE_HEADมีอยู่

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


16
สิ่งนี้มีให้ตั้งแต่ git v1.7.4 มันเป็นชื่อแทนการรีเซ็ต git --merge
Michael Johnson

162

มันง่ายมาก

git merge --abort

Git เองแสดงวิธีแก้ปัญหาเมื่อคุณอยู่ในปัญหาประเภทนี้และเรียกใช้คำสั่งสถานะ git

git status

หวังว่าสิ่งนี้จะช่วยให้ผู้คน


97

ฉันคิดว่าgit resetคุณต้องการ

ระวังที่git revertหมายถึงบางสิ่งที่แตกต่างกันมากในการพูดการsvn revertโค่นล้มการเปลี่ยนกลับจะยกเลิกการเปลี่ยนแปลง (ปราศจากข้อผูกมัด) การคืนไฟล์ไปเป็นเวอร์ชั่นปัจจุบันจากที่เก็บในขณะที่git revert"เลิกทำ" คอมมิชชัน

git resetควรทำเทียบเท่าsvn revertนั่นคือยกเลิกการเปลี่ยนแปลงที่ไม่พึงประสงค์ของคุณ


76

ในกรณีการใช้งานเฉพาะนี้คุณไม่ต้องการยกเลิกการผสานจริงๆเพียงแค่แก้ไขข้อขัดแย้งด้วยวิธีการเฉพาะ

ไม่จำเป็นต้องรีเซ็ตและดำเนินการผสานกับกลยุทธ์ที่แตกต่างกันโดยเฉพาะ ความขัดแย้งได้รับการเน้นอย่างถูกต้องโดย git และความต้องการที่จะยอมรับการเปลี่ยนแปลงด้านอื่น ๆ สำหรับไฟล์นี้เพียงไฟล์เดียวเท่านั้น

สำหรับไฟล์ที่ไม่ได้ถูกรวมใน git ข้อขัดแย้งจะทำให้มีฐานร่วมเป็นเวอร์ชันทั่วไปของโลคัลและไฟล์ระยะไกลในดัชนี (นี่คือตำแหน่งที่พวกเขาถูกอ่านเพื่อใช้ในเครื่องมือ diff 3 ทางโดยgit mergetool) คุณสามารถใช้git showเพื่อดู

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

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

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

วิธีที่ง่ายที่สุดในการแก้ไขข้อขัดแย้งเพื่อใช้คำต่อคำแบบรีโมตเวอร์ชันคือ:

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

หรือด้วย git> = 1.6.1:

git checkout --theirs _widget.html.erb

5
ขอบคุณสำหรับคำใบ้ ไม่ได้เป็นอินเทอร์เฟซผู้ใช้คอมไพล์ที่แย่ขนาดนี้
ปีเตอร์

@ Peter: ฉันไม่มั่นใจ ผลลัพธ์ที่ต้องการสามารถทำได้ด้วยคำสั่งพื้นฐานสองสามข้อพร้อมตัวเลือกง่าย ๆ คุณจะแนะนำการปรับปรุงอะไรบ้าง
CB Bailey

10
ฉันคิดว่าgit 1.6.1คำสั่งนี้สมเหตุสมผลดีและดีมาก นั่นคือสิ่งที่ฉันต้องการ ฉันคิดว่าโซลูชัน pre-1.6.1 นั้นไม่เหมาะสมและต้องการความรู้เกี่ยวกับส่วนอื่น ๆ ของ git ที่ควรจะแยกออกจากกระบวนการแก้ไขปัญหาผสาน แต่เวอร์ชั่นใหม่ยอดเยี่ยมมาก!
ปีเตอร์

67

สำหรับสถานการณ์อย่างที่ฉันทำgit fetchและgit pullจากนั้นตระหนักว่าสาขาต้นน้ำไม่ใช่สาขาหลักซึ่งส่งผลให้เกิดความขัดแย้งที่ไม่พึงประสงค์

git reset --merge 

ย้อนกลับโดยไม่รีเซ็ตการเปลี่ยนแปลงในพื้นที่ของฉัน


45

ความคิดเห็นที่แสดงให้เห็นว่าเป็นนามแฝงสำหรับgit reset --merge git merge --abortมันคุ้มค่าที่จะสังเกตเห็นว่าgit merge --abortมีเพียงเทียบเท่ากับgit reset --mergeที่มีMERGE_HEADอยู่ สามารถอ่านได้ในวิธีใช้ git สำหรับคำสั่งผสาน

git merge --abort เทียบเท่ากับ git reset --merge เมื่อ MERGE_HEAD ปรากฏขึ้น

หลังจากที่มีการผสานล้มเหลวเมื่อไม่มีMERGE_HEADการผสานล้มเหลวสามารถยกเลิกได้ด้วยแต่ไม่จำเป็นต้องมีgit reset --merge พวกเขาไม่เพียงไวยากรณ์เก่าและใหม่สำหรับสิ่งเดียวกันgit merge --abort

โดยส่วนตัวแล้วฉันพบว่าgit reset --mergeมีประสิทธิภาพมากขึ้นสำหรับสถานการณ์ที่คล้ายกับที่อธิบายไว้และล้มเหลวในการรวมโดยทั่วไป


2
อะไรคือความหมายที่แท้จริงของ "การผสานล้มเหลว"? รวมกับความขัดแย้งหรืออะไรอย่างอื่น? หรือจะใช้ถ้อยคำใหม่เมื่อ: MERGE_HEAD ไม่มีอยู่เมื่อใด คำถามติดตามของฉันอยู่ที่นั่นเพื่อให้เข้าใจการใช้ "git reset --merge" ได้ดีขึ้น
Ewoks

@Ewoks git stash applyทำให้เกิดความขัดแย้งในการผสานสำหรับฉัน แต่git merge --abortไม่ได้ช่วยในขณะgit reset --mergeนั้น
nitzel

27

หากคุณจบลงด้วยการรวมความขัดแย้งและไม่มีอะไรที่จะต้องทำ แต่ยังคงมีข้อผิดพลาดในการรวมปรากฏขึ้น หลังจากใช้คำสั่งที่ระบุไว้ด้านล่างทั้งหมด

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

โปรดลบ

.git \ index.lock

ไฟล์ [ตัดแปะไปยังตำแหน่งอื่นในกรณีที่กู้คืน] จากนั้นป้อนคำสั่งด้านล่างใด ๆ ตามรุ่นที่คุณต้องการ

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

หวังว่าจะช่วย !!!


19

ทางเลือกซึ่งเก็บรักษาสถานะของสำเนาการทำงานคือ:

git stash
git merge --abort
git stash pop

ฉันมักจะแนะนำต่อเรื่องนี้เพราะมันมีประสิทธิภาพเช่นเดียวกับการผสานในการโค่นล้มในขณะที่มันทิ้งความสัมพันธ์สาขาในการกระทำดังต่อไปนี้


ฉันพบว่าวิธีนี้มีประโยชน์เมื่อฉันบังเอิญรวมเข้ากับสาขา git-svn ซึ่งไม่ได้จัดการอย่างนั้น การรวมสควอชหรือการหยิบเชอร์รี่จะดีกว่าเมื่อทำงานกับสาขาการติดตาม git-svn ผลที่ได้คือโซลูชันของฉันเปลี่ยนการรวมเป็นสควอชผสานหลังจากความจริง
Alain O'Dea

คำตอบที่ดีที่สุดสำหรับคำถาม
Fouad Boukredine

18

เนื่องจาก Git 1.6.1.3 git checkoutสามารถทำการเช็คเอาท์จากทั้งสองด้านของการผสาน:

git checkout --theirs _widget.html.erb

3

ฉันพบสิ่งต่อไปนี้ใช้งานได้สำหรับฉัน (เปลี่ยนไฟล์เดียวให้เป็นสถานะก่อนรวม):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

-5

Sourcetree

เพราะคุณไม่ได้รวมกิจการของคุณเพียงคลิกสองครั้งที่สาขาอื่น (ซึ่งหมายถึงชำระเงิน) และเมื่อ sourcetree ถามคุณเกี่ยวกับการยกเลิกการเปลี่ยนแปลงทั้งหมดแล้วก็เห็นด้วย :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.