ทำการผสานการคืนค่าใน Git อีกครั้ง


231

ฉันพบปัญหาเล็กน้อยที่นี่: ฉันมีสาขาเฉพาะปัญหา28sใน Git ที่ฉันรวมอยู่ในdevelopสาขาทั่วไป ปรากฎว่าฉันทำมันเร็วเกินไปดังนั้นฉันจึงใช้ git-revert เพื่อเลิกทำการผสาน อย่างไรก็ตามถึงเวลาแล้วที่จะรวม28sเข้าdevelopด้วยกัน แต่คำสั่ง git-merge จะเห็นการผสานดั้งเดิมและประกาศอย่างมีความสุขว่าทุกอย่างเป็นไปด้วยดีและมีการรวมสาขาเข้าด้วยกันแล้ว ฉันทำอะไรตอนนี้? สร้าง 'เปลี่ยนกลับ "เปลี่ยนกลับ" 28s -> พัฒนา ""' กระทำหรือไม่ ดูเหมือนจะไม่ใช่วิธีที่ดีที่จะทำ แต่ฉันไม่สามารถจินตนาการได้ในขณะนี้

โครงสร้างต้นไม้มีลักษณะอย่างไร:

Git log output


4
มันคือ GitX ( gitx.frim.nl )
Toms Mikoss

คำตอบ:


169

คุณต้อง "เปลี่ยนคืน" ทั้งนี้ขึ้นอยู่กับคุณว่าการคืนค่าดั้งเดิมนั้นอาจไม่ง่ายอย่างที่คิด ดูเอกสารอย่างเป็นทางการในหัวข้อนี้

---o---o---o---M---x---x---W---x---Y
              /
      ---A---B-------------------C---D

อนญาต:

---o---o---o---M---x---x-------x-------*
              /                       /
      ---A---B-------------------C---D

แต่มันทำงานทั้งหมดหรือไม่ แน่นอนค่ะ คุณสามารถย้อนกลับการผสานและจากมุมมองทางเทคนิคล้วนๆคอมไพล์ทำได้อย่างเป็นธรรมชาติและไม่มีปัญหาจริง
มันเพิ่งพิจารณาว่าเป็นการเปลี่ยนจาก "state before merge" เป็น "state after merge" และนั่นก็คือ
ไม่มีอะไรซับซ้อนไม่มีอะไรแปลกไม่มีอันตรายจริงๆ Git จะทำมันโดยไม่ได้คิดถึงมันเลย

ดังนั้นจากมุมมองทางเทคนิคมีอะไรผิดปกติกับการคืนค่าการผสาน แต่จากมุมเวิร์กโฟลว์บางสิ่งบางอย่างมันเป็นเรื่องที่คุณมักควรพยายามหลีกเลี่ยง

ถ้าเป็นไปได้ตัวอย่างเช่นถ้าคุณพบปัญหาที่ได้ผสานเข้ากับต้นไม้หลักเป็นมากกว่าการเปลี่ยนกลับผสานลองมันยากที่จะ :

  • แบ่งปัญหาออกเป็นสาขาที่คุณรวมและเพียงแก้ไข
  • หรือพยายามที่จะย้อนกลับการกระทำของบุคคลที่ทำให้เกิด

ใช่มันเป็นความซับซ้อนมากขึ้นและไม่มันไม่เสมอไปการทำงาน (บางครั้งคำตอบคือ: "โอ๊ะผมไม่ควรได้รวมมันเพราะมันก็ยังไม่พร้อมและฉันจริงๆต้องยกเลิกทั้งหมดของ ผสาน"). ดังนั้นคุณควรคืนค่าการผสานจริงๆ แต่เมื่อคุณต้องการทำการผสานอีกครั้งตอนนี้คุณต้องทำโดยการคืนค่าการย้อนกลับ


10
ลิงก์ดี (+1) ฉันใช้เสรีภาพในการคัดลอกบางส่วนของเอกสารในคำตอบของคุณเพื่อให้ผู้อ่านเห็นตัวเลือกที่เกี่ยวข้องได้ทันทีในกรณีนี้ หากคุณไม่เห็นด้วยอย่าลังเลที่จะยกเลิก
VonC

5
เราพบกรณีที่เราต้องทำสิ่งนี้และพบว่าความสนุกไม่ได้หยุดอยู่แค่นี้ มันเป็นสาขาที่ใช้งานมายาวนานซึ่งถูกรวมเข้าด้วยกันดังนั้นเราจึงจำเป็นต้องปรับปรุงต่อไป แนวทางของฉันที่นี่: tech.patientslikeme.com/2010/09/29/…
jdwyah

ฉันติดตาม @ โพสต์บล็อกของ @ jdwyah และมันก็รุ่งโรจน์ (อย่างจริงจังมันยอดเยี่ยมมากที่มันใช้งานได้)
hellatan

2
@jdwyah ที่ดูเหมือนจะเป็นลิงก์ที่ขาดหาย แต่ดูเหมือนว่าการอ่านที่น่าสนใจ นี่คือกระจก archive.org แต่ภาพหายไป: web.archive.org/web/20111229193713/http://…
Alex KeySmith

15
โพสต์บล็อกได้รับการฟื้นคืนชีพขอบคุณ: blog.jdwyah.com/2015/07/dealing-with-git-merge-revisions.html
jdwyah

53

สมมติว่าคุณมีประวัติดังกล่าว

---o---o---o---M---W---x-------x-------*
              /                      
      ---A---B

โดยที่ A, B ล้มเหลวในการส่งข้อมูลและ W - ถูกเปลี่ยนกลับจาก M

ดังนั้นก่อนที่ฉันจะเริ่มแก้ไขปัญหาที่พบฉันเลือกเชอร์รี่เลือก W ที่ส่งไปยังสาขาของฉัน

git cherry-pick -x W

จากนั้นฉันจะคืนค่า W ที่ทำกับสาขาของฉัน

git revert W 

หลังจากฉันแก้ไขต่อไปได้

ประวัติสุดท้ายอาจมีลักษณะดังนี้:

---o---o---o---M---W---x-------x-------*
              /                       /     
      ---A---B---W---W`----------C---D

เมื่อฉันส่ง PR มันจะแสดงให้เห็นอย่างชัดเจนว่า PR นั้นยกเลิกการย้อนกลับและเพิ่มความมุ่งมั่นใหม่ ๆ


3
ดูเหมือนว่าจะมีประโยชน์ แต่มีรายละเอียดน้อยมาก (อะไรคือ C, D ในแผนภาพสุดท้าย) ว่ามันน่าผิดหวังมากกว่าประโยชน์
Isochronous

4
@Isochronous C และ D ดูเหมือนว่าจะกระทำเพื่อแก้ไขปัญหาที่แนะนำโดย A และ B
Thomas

@Thomas อย่างแน่นอน
Maksim Kotlyar

เป็นเรื่องที่ดีที่คุณเน้นการใช้งาน PR ในกรณีนี้เนื่องจากสามารถให้ 'ตรวจสุขภาพจิตขั้นสุดท้าย' ก่อนที่จะรวมกลับไปเป็นหลัก
Willem van Ketwich

ใช้ทำไมคุณรีสตาร์ทสาขาของคุณจาก W เดิม? คือปล่อยให้หัวข้อของคุณดำเนินการต่อจาก W พร้อมด้วย W` ตามด้วย C และ D? ที่ลบการทำซ้ำบางอย่าง
Erik Carstensen

12

หากต้องการคืนค่าการเปลี่ยนกลับโดยไม่ทำให้เวิร์กโฟลว์ของคุณมากเกินไป:

  • สร้างสำเนาถังขยะท้องถิ่นของการพัฒนา
  • ย้อนกลับการคืนค่ากระทำบนสำเนาของการพัฒนาท้องถิ่น
  • รวมที่คัดลอกลงในสาขาฟีเจอร์ของคุณและผลักสาขาฟีเจอร์ของคุณไปยังเซิร์ฟเวอร์ git ของคุณ

สาขาฟีเจอร์ของคุณควรจะสามารถรวมกันได้ตามปกติเมื่อคุณพร้อม ข้อเสียเพียงอย่างเดียวที่นี่ก็คือคุณจะมีการรวม / ย้อนกลับเพิ่มอีกสองสามอย่างในประวัติของคุณ


เพียงเพื่อป้องกันไม่ให้มิกซ์อีกต่อไปฉันยังสร้างสำเนา 'ถังขยะ' ของสาขาคุณลักษณะของฉันและผสานการแปลงกลับเป็นพัฒนา
jhhwilliams

ขอบคุณ! นี่เป็นคำตอบเดียวที่อธิบายวิธีการทำแทนการบอกว่าคุณไม่ควรทำ มีประโยชน์จริงๆ
Emmy

ขอบคุณนี่ช่วยฉันได้จริงๆ :)
Daniel Stracaboško

11

ในการเปลี่ยนกลับเป็น GIT:

git revert <commit-hash-of-previous-revert>

1
ใช้สิ่งนี้ในสาขาการทำงานของฉันเพื่อแปลงกลับเป็นค่า PR ใหม่เพื่อพัฒนา ตอนนี้ git เห็นการเปลี่ยนแปลงทั้งหมดที่อยู่ใน PR ก่อนหน้าซึ่งถูกเปลี่ยนกลับ ขอบคุณ
Danstan

3

แทนที่จะใช้git-revertคุณสามารถใช้คำสั่งนี้ในdevelสาขาเพื่อทิ้ง (เลิกทำ) ผสานการกระทำที่ผิด (แทนการคืนค่า)

git checkout devel
git reset --hard COMMIT_BEFORE_WRONG_MERGE

สิ่งนี้จะปรับเนื้อหาของไดเรกทอรีทำงานตามด้วย ระวัง :

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

ฉันแนะนำให้ศึกษา git-resetคนอย่างถี่ถ้วนก่อนลองสิ่งนี้

ตอนนี้หลังจากที่รีเซ็ตคุณสามารถสมัครใหม่ในการเปลี่ยนแปลงของคุณdevelแล้วทำ

git checkout devel
git merge 28s

นี่จะเป็นการผสานที่แท้จริงจาก28sในdevelตอนแรก (ซึ่งตอนนี้ถูกลบออกจากประวัติของ git)


8
สำหรับใครที่ไม่คุ้นเคยกับซูเปอร์คอมไพล์และอาจต้องการที่จะปฏิบัติตามคำแนะนำเหล่านี้ใช้ความระมัดระวังกับการรวมและreset --hard push originนอกจากนี้ระวังแรงผลักดันไปยังแหล่งกำเนิดอาจทำให้โคลน PRs ที่เปิดอยู่บน GitHub
funroll

มีประโยชน์มากสำหรับการแก้ไขปัญหาการผสานบนเซิร์ฟเวอร์ git ส่วนตัว ขอบคุณ!
mix3d

1
+1 สำหรับเทคนิคนี้ การทำลายล้างที่อาจเกิดขึ้น แต่สามารถช่วยให้คุณปวดหัวได้มาก (และมีประวัติที่ยุ่งเหยิง) เมื่อใช้อย่างรอบคอบ
siliconrockstar

1

ฉันเพิ่งพบโพสต์นี้เมื่อประสบปัญหาเดียวกัน ฉันพบว่ามีวิธีที่น่ากลัวในการรีเซ็ต hards เป็นต้นฉันจะจบการลบบางอย่างที่ฉันไม่ต้องการและจะไม่สามารถกู้คืนได้

git checkout 123466t7632723แต่ฉันจะตรวจสอบการกระทำที่ผมอยากสาขาที่จะกลับไปเช่น git checkout my-new-branchจากนั้นแปลงเป็นสาขา ฉันลบสาขาที่ฉันไม่ต้องการอีกแล้ว แน่นอนว่ามันจะใช้ได้ถ้าคุณสามารถโยนสาขาที่คุณทำไปยุ่ง


1
git reflogจะปกป้องคุณในการตั้งค่ายากสำหรับคู่ของเดือนในกรณีที่คุณในภายหลังพบว่าคุณต้องกระทำที่หายไป การอ้างอิงจะถูก จำกัด เฉพาะ repo ในพื้นที่ของคุณ
ทอดด์

1

ฉันขอแนะนำให้คุณทำตามขั้นตอนด้านล่างเพื่อยกเลิกการคืนค่า SHA1

git checkout develop #go to develop branch
git pull             #get the latest from remote/develop branch
git branch users/yourname/revertOfSHA1 #having HEAD referring to develop
git checkout users/yourname/revertOfSHA1 #checkout the newly created branch
git log --oneline --graph --decorate #find the SHA of the revert in the history, say SHA1
git revert SHA1
git push --set-upstream origin users/yourname/revertOfSHA1 #push the changes to remote

ตอนนี้สร้าง PR สำหรับสาขา users/yourname/revertOfSHA1


1
  1. สร้างสาขาใหม่ที่คอมมิชชันก่อนที่จะผสานเดิม - เรียกมันว่า 'พัฒนาฐาน'
  2. ดำเนินการรีบูตแบบโต้ตอบของ 'พัฒนา' ที่ด้านบนของ 'ฐานการพัฒนา' (แม้ว่าจะอยู่ด้านบน) ระหว่างการรีบูตแบบโต้ตอบคุณจะมีโอกาสที่จะลบทั้งการรวมการกระทำและการกระทำที่ย้อนกลับการผสานคือลบทั้งสองเหตุการณ์ออกจากประวัติคอมไพล์

ณ จุดนี้คุณจะมีสาขา 'พัฒนา' ที่สะอาดซึ่งคุณสามารถผสานฟีเจอร์ของคุณได้ตามปกติ


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