ย้อนกลับการผสาน Git


225
develop branch
--> dashboard (working branch)

ฉันใช้git merge --no-ff developเพื่อรวมการเปลี่ยนแปลงต้นน้ำเข้ากับแผงควบคุม

บันทึก git:

commit 88113a64a21bf8a51409ee2a1321442fd08db705
Merge: 981bc20 888a557
Author: XXXX <>
Date:   Mon Jul 30 08:16:46 2012 -0500

    Merge branch 'develop' into dashboard

commit 888a5572428a372f15a52106b8d74ff910493f01
Author: root <root@magneto.giveforward.com>
Date:   Sun Jul 29 10:49:21 2012 -0500

    fixed end date edit display to have leading 0

commit 167ad941726c876349bfa445873bdcd475eb8cd8
Author: XXXX <>
Date:   Sun Jul 29 09:13:24 2012 -0500

การรวมมีความมุ่งมั่นมากกว่า 50 ข้อและฉันสงสัยว่าจะเปลี่ยนการรวมกลับอย่างไรเพื่อให้แดชบอร์ดกลับสู่สถานะก่อนรวม

ส่วนที่สองของเรื่องนี้คือถ้าฉันไม่รวมกับ--no-ffฉันไม่ได้รับความมุ่งมั่น ' สาขาผสาน' พัฒนา 'เป็นแผงควบคุม ' .. ฉันจะม้วนที่ผสานกลับมาได้อย่างไร


3
มีความเป็นไปได้ที่จะทำการเลิกทำการคอมไพล์ Git หรือไม่ .

คำตอบ:


321

การคืนค่าการรวมได้รับการครอบคลุมอย่างละเอียดในคำถามอื่น ๆ เมื่อคุณทำการผสานไปข้างหน้าอย่างรวดเร็วส่วนที่สองที่คุณอธิบายคุณสามารถใช้git resetเพื่อกลับไปยังสถานะก่อนหน้า:

git reset --hard <commit_before_merge>

คุณสามารถค้นหา<commit_before_merge>ด้วยgit reflog, git logหรือ, ถ้าคุณรู้สึกว่า moxy (และยังไม่ได้ทำอะไรเลย):git reset --hard HEAD@{1}


6
ขอบคุณสำหรับการตอบกลับอย่างรวดเร็ว .. ดูที่บันทึกการคอมไพล์คอมมิทการคอมไพล์ก่อนหน้าการคอมไพล์คือ 50+ คอมมิชชันย้อนกลับเนื่องจากการคอมไพล์แบบคอมไพล์พัฒนาขึ้นจริง ๆ ฉันเดาว่าสิ่งที่ฉันไม่ได้รับคืออะไรถ้าฉันไม่รู้ว่าผสานนั้นอยู่ที่ไหน - ฉันจะหามันได้อย่างไร คุณพูดถึงการหา commit_before_merge .. ฉันเดาว่าฉันไม่เข้าใจส่วนนั้น
cgmckeever

4
ดูเหมือนกับ git reflog ดูเหมือนว่ามันจะสรุปหัวสุดท้ายได้ดีและช่วยให้ฉันรู้ว่าฉันต้องรีเซ็ตที่ใด ดูเหมือนว่าบันทึก git มีความละเอียดมากเกินกว่าที่จะระบุตำแหน่งที่จะรีเซ็ตเป็น ขอบคุณ
cgmckeever

1
ใช่reflogผู้ช่วยชีวิต HEAD@{1}เพิ่งอธิบายสถานะล่าสุดของ HEAD ครั้งที่สองหรือมากกว่านั้นในทางเทคนิค: "การอ้างอิงตามด้วยคำต่อท้าย @ พร้อมกับข้อกำหนดลำดับที่อยู่ในวงเล็บปีกกา (เช่น {1}, {15}) ระบุค่าก่อนหน้าของ n-th โทษ."
คริสโตเฟอร์

4
สิ่งที่เกี่ยวกับการผลักดันการเปลี่ยนกลับเป็นระยะไกล ฉันไม่เห็นว่ามันจะทำงานอย่างไร
Anton Savelyev

2
นี่คือความสิ้นหวัง มันทำลายการกระทำทั้งหมดหลังจากการผสาน
aaa90210

151

จากที่นี่:

http://www.christianengvall.se/undo-pushed-merge-git/

git revert -m 1 <merge commit hash>

Git revert เพิ่มการคอมมิตใหม่ที่ย้อนกลับการคอมมิทที่ระบุ

ใช้ -m 1 บอกว่านี่คือการผสานและเราต้องการย้อนกลับไปยังผู้ปกครองกระทำในสาขาต้นแบบ คุณจะใช้ -m 2 เพื่อระบุสาขาการพัฒนา


30
โปรดทราบว่าคุณไม่สามารถรวมสาขาอีกครั้งหลังจากนี้ตามที่เอกสารระบุว่า: "การคืนค่าการรวมการกระทำประกาศว่าคุณจะไม่ต้องการให้การเปลี่ยนแปลงแบบต้นไม้นำมาโดยการผสานดังนั้นการผสานในภายหลังจะนำมาสู่การเปลี่ยนแปลงแบบต้นไม้เท่านั้น โดยยอมรับว่าไม่ใช่บรรพบุรุษของการผสานที่ย้อนกลับก่อนหน้านี้อาจเป็นหรือไม่เป็นสิ่งที่คุณต้องการ "
Dalibor Karlović

23
@ DaliborKarlovićคำสั่งนั้นค่อนข้างรุนแรง คุณสามารถนำการเปลี่ยนแปลงเหล่านั้นกลับมาในภายหลังได้อย่างแน่นอนเคล็ดลับคือการคืนค่าการคืนค่า ข้อมูลเพิ่มเติมที่นี่ในส่วน "การคืนค่าการเปลี่ยนกลับ"
Hilikus

3
น่าเสียดายที่hereลิงก์ในความคิดเห็น @Hilikus ไม่สามารถใช้งานได้อีกต่อไป เว็บไซต์อ้างว่าเนื้อหาถูกย้ายไปที่หนังสือ ( git-scm.com/book/en/v2 ) แต่ถ้าเป็นเช่นนั้นมันไม่สำคัญที่จะค้นหาในนั้น
Jesse Chisholm

@ DaliborKarlovićเป็นกรณีนี้หรือไม่กับคำตอบข้างต้นจาก @Christopher?
James B

3
เนื้อหาการรวมการเลิกทำถูกย้ายไปที่นี่
SEK

28

git reset --hard HEAD^เพียงแค่ตั้งค่าการผสานกระทำด้วย

หากคุณใช้ - no-ff git จะสร้างการผสานเสมอแม้ว่าคุณจะไม่ได้ทำอะไรระหว่างนั้นก็ตาม หากปราศจาก - ไม่มีการคอมไพล์เพียงแค่ทำไปข้างหน้าอย่างรวดเร็วหมายถึงสาขาของคุณหัวจะถูกตั้งค่าเป็นหัวหน้าของสาขาที่ผสาน เพื่อแก้ปัญหานี้พบว่ากระทำ-ID git reset --hard $COMMITIDคุณต้องการที่จะกลับไปใช้และ


1
วิธีแก้ปัญหาที่ดีถ้าคุณไม่ทราบความมุ่งมั่นก่อนที่จะผสาน
iglesiasedd

ทำงานให้ฉันโดยที่ฉันไม่รู้กระทำรหัส + 1
Anant Singh --- ยังมีชีวิตอยู่

หากการรวมที่ไม่ต้องการได้รับมอบหมายจากระยะไกลฉันใช้git push -fเพื่ออัปเดตสาขาระยะไกลหลังจากคืนค่า
zumek

16
git revert -m 1 88113a64a21bf8a51409ee2a1321442fd08db705

แต่อาจมีผลข้างเคียงที่ไม่คาดคิด ดู--mainline parent-numberตัวเลือกในgit-scm.com/docs/git-revert

อาจเป็นวิธีที่ฉลาด แต่มีประสิทธิภาพคือการตรวจสอบพาเรนต์ด้านซ้ายของคอมมิทนั้นทำสำเนาไฟล์ทั้งหมดเช็คเอาต์HEADอีกครั้งและแทนที่เนื้อหาทั้งหมดด้วยไฟล์เก่า จากนั้นคอมไพล์จะบอกคุณว่ามีการย้อนกลับอย่างไรและคุณสร้างการคืนค่าของคุณเอง :)!


1
+1 เพราะคำตอบนี้ไม่ยุ่งกับประวัติขณะที่ทำการรีเซ็ต (สำคัญมากถ้าคุณผลักไปที่รีโมตแล้ว) แต่ฉันควรคาดหวังผลข้างเคียงอะไรบ้าง
pedromanoel

3
นี่เป็นผลข้างเคียงที่คุณพูดถึงหรือไม่? Reverting a merge commit declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want.
pedromanoel

1
คุณบอกว่าgit resetเป็นวิธีแก้ปัญหา แต่ก็พูดถึงว่ามันอาจมีผลข้างเคียงที่ไม่คาดคิด อย่างไรก็ตามลิงค์นี้มาจากgit revertไม่ใช่git reset:)
Mark

2
โปรดทราบว่าการรีเซ็ต git ไม่มีแฟล็ก -m นอกจากนี้โปรดทราบ @JorgeOrpinel อ้างอิง git-revert docs ไม่ใช่ git-reset ฉันคิดว่าเขาตั้งใจจะgit revertไม่พูดgit reset
Devin Gleason Lambert

วิธีการหลีกเลี่ยงการระบุว่าพ้นจากตำแหน่ง แต่กระทำ 1234xyz ไม่ใช่ข้อผิดพลาดในการผสาน
Achal

0

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

วิธีที่ง่ายที่สุดที่ฉันรู้สึกคือ:

  1. นำสาขาใหม่ออกจากการพัฒนา / หลัก (ที่คุณผสาน)
  2. เปลี่ยนกลับเป็น "เปลี่ยนกลับ" โดยใช้git revert -m 1 xxxxxx(หากมีการเปลี่ยนกลับถูกผสานโดยใช้สาขา) หรือใช้git revert xxxxxxหากเป็นการเปลี่ยนกลับแบบง่าย
  3. ตอนนี้สาขาใหม่ควรมีการเปลี่ยนแปลงที่คุณต้องการผสานอีกครั้ง
  4. ทำการเปลี่ยนแปลงหรือผสานสาขานี้เพื่อพัฒนา / ต้นแบบ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.