เปลี่ยนกลับช่วงของคอมมิตในคอมไพล์


128

ฉันจะเปลี่ยนค่าคอมมิชชันในคอมไพล์ได้อย่างไร? จากการดูเอกสารgitrevisionsฉันไม่เห็นวิธีระบุช่วงที่ต้องการ ตัวอย่างเช่น:

A -> B -> C -> D -> E -> HEAD

ฉันต้องการเทียบเท่ากับ:

git revert B-D

ซึ่งผลลัพธ์จะเป็น:

A -> B -> C -> D -> E -> F -> HEAD

โดยที่ F มีการย้อนกลับของ BD รวม


ในตอนท้ายของหน้า gitrevisions (7) จะมีหัวข้อ "SPECIFYING RANGES" สิ่งที่คุณต้องการแตกต่างจากที่อธิบายไว้อย่างไร
Gareth McCaughan

2
หน้า gitrevisions แนะนำว่า 'git revert A..D' จะทำในสิ่งที่ฉันต้องการ อย่างไรก็ตามเมื่อฉันลองฉันได้รับข้อผิดพลาด "ร้ายแรง: ไม่พบ" A..D ""
Alex Spurling

คำตอบ:


174

คุณใช้ Git เวอร์ชันใด

การคืนค่าคอมมิตหลายครั้งใน Git1.7.2 + ที่รองรับเท่านั้น: ดูรายละเอียดเพิ่มเติมที่" ย้อนกลับไปยังคอมมิตเก่าโดยใช้การย้อนกลับหลายครั้ง " หน้าคน
ปัจจุบันใช้สำหรับGit เวอร์ชันปัจจุบันเท่านั้น (1.7.4+)git revert


ตามที่OP Alex Spurlingรายงานในความคิดเห็น:

การอัพเกรดเป็น 1.7.4 ใช้งานได้ดี
เพื่อตอบคำถามของฉันเองนี่คือไวยากรณ์ที่ฉันกำลังมองหา:

git revert B^..D 

B^หมายถึง "พาเรนต์แรกคอมมิตของ B": ที่อนุญาตให้รวมBในการย้อนกลับ
ดู "การgit rev-parseระบุส่วนการแก้ไข " ซึ่งรวมถึงไวยากรณ์<rev>^เช่นHEAD^ : ดูเพิ่มเติมที่" อักขระคาเร็ต( ^) หมายถึงอะไร ")

โปรดทราบว่าแต่ละคอมมิตที่เปลี่ยนกลับถูกคอมมิตแยกกัน

Henrik Nชี้แจงในความคิดเห็น :

git revert OLDER_COMMIT^..NEWER_COMMIT

ดังที่แสดงด้านล่างคุณสามารถเปลี่ยนกลับได้โดยไม่ต้องดำเนินการทันที:

git revert -n OLDER_COMMIT^..NEWER_COMMIT
git commit -m "revert OLDER_COMMIT to NEWER_COMMIT"

1
ขอบคุณนั่นคือคำตอบ การอัพเกรดเป็น 1.7.4 ใช้งานได้ดี เพื่อตอบคำถามของฉันเองนี่คือไวยากรณ์ที่ฉันกำลังมองหา: git revert B ^ .. D
Alex Spurling

อัจฉริยภาพ ขอบคุณ มันไม่ได้เกิดขึ้นกับฉันฉันจำเป็นต้องยกเลิกการคอมมิตในลำดับย้อนกลับเพื่อให้แพตช์ใช้งานได้ คำสั่งนี้แสดงวิธี
Tim Abell

5
ฉันอ้างถึงคำตอบนี้บ่อยครั้งและฉันต้องใช้เวลาสักพักในการหาคำสั่งซื้อ เพื่อช่วยตัวเองในอนาคตของฉัน:git revert OLDER_COMMIT^..NEWER_COMMIT
Henrik N

2
^ หมายถึงอะไร
Dustin Getz

1
@DustinGetz พาเรนต์แรก: ดูgit-scm.com/docs/gitrevisions : "คำต่อท้ายของ^พารามิเตอร์การแก้ไขหมายถึงพาเรนต์แรกของอ็อบเจ็กต์คอมมิตนั้น"
VonC

15

หากคุณต้องการเปลี่ยนการคอมมิตช่วง B เป็น D (อย่างน้อยก็ใน git เวอร์ชัน 2) ในคอมมิตเดียวคุณสามารถทำได้

 git revert -n B^..D

สิ่งนี้จะเปลี่ยนกลับการเปลี่ยนแปลงที่ทำโดยคอมมิตจากพาเรนต์คอมมิต (ไม่รวม) เป็นคอมมิต D (รวม) แต่จะไม่สร้างคอมมิตใด ๆ กับการเปลี่ยนแปลงที่เปลี่ยนกลับ การย้อนกลับจะปรับเปลี่ยนโครงสร้างการทำงานและดัชนีเท่านั้น

อย่าลืมที่จะยอมรับการเปลี่ยนแปลงหลังจากนั้น

 git commit -m "revert commit range B to D"

คุณยังสามารถย้อนกลับการคอมมิตที่ไม่เกี่ยวข้องหลายครั้งในคอมมิตเดียวโดยใช้วิธีการเดียวกัน ตัวอย่างเช่นในการเปลี่ยนกลับ B และ D แต่ไม่ใช่ C

 git revert -n B D
 git commit -m "Revert commits B and D"

อ้างอิง: https://www.kernel.org/pub/software/scm/git/docs/git-revert.html

ขอบคุณHonza Haeringสำหรับการแก้ไข


3
git revert -n B..Dไม่ย้อนกลับการคอมมิต B มีเพียง C และ D. เท่านั้นที่เปลี่ยน git revert -n B^..Dกลับ B เช่นกัน
Honza Haering

ตามเอกสารคอมไพล์มันทำ อ้างอิงในโพสต์
Ramast

1
หากคุณอ้างถึงตัวอย่างนี้ (ซึ่งฉันคิดว่าสับสนเล็กน้อย) ในการอ้างอิง: git revert -n master~5..master~2มันระบุว่ามีการกระทำล่าสุดที่ห้ารวมอยู่ด้วย แต่master~5เป็นการกระทำล่าสุดครั้งที่ 6 ดูการเลือกแก้ไขในเอกสาร git สำหรับข้อมูลโดยละเอียดเกี่ยวกับ..สัญกรณ์ :-)
Honza Haering

6

การทำgit revert OLDER_COMMIT^..NEWER_COMMITไม่ได้ผลสำหรับฉัน

ฉันใช้git revert -n OLDER_COMMIT^..NEWER_COMMITและทุกอย่างดี 1.7.9.6ผมใช้รุ่นคอมไพล์


ฉันมีปัญหาเดียวกันและแก้ไขโดยใช้ -n แต่คุณควรปล่อย ^ ไว้กับ OLDER_COMMIT (git revert -n OLDER_COMMIT ^ .. NEWER_COMMIT)
FeelGood

@FeelGood ทำไมคุณควรออกจาก ^?
Orlando

ฉันมีประวัติ A -> B -> C และเป้าหมายคือการเปลี่ยนกลับ B และ C เมื่อฉันเรียกใช้ 'git revert -n B..C' มีเพียง C เท่านั้นที่ถูกเปลี่ยนกลับ เมื่อฉันใช้ 'git revert -n B ^ .. C' คอมไพล์ย้อนกลับทั้งสองคอมมิต บางทีฉันอาจจะทำอะไรผิด
FeelGood

เจ๋งดีต้องทดสอบ แต่ฉันคิดว่าในกรณีของฉันใช้งานได้ดี (เว้นแต่ฉันจะคืนค่าช่วงคอมมิต 1 ครั้งฮ่า ๆ ) ฉันจะแก้ไขคำตอบเพื่อรวม ^ ขอบคุณ
ออร์แลนโด

2
-nหรือ--no-commitตัวเลือกที่จะยกเลิกการเปลี่ยนแปลงทั้งหมดในช่วงในเดียวกระทำแทนการสร้างย้อนกลับกระทำทุกการกระทำในช่วง ผลลัพธ์สุดท้ายจะเหมือนกันเช่นเดียวกับในการเปลี่ยนแปลงเดียวกันจะถูกเปลี่ยนกลับ ขึ้นอยู่กับว่าคุณต้องการให้ประวัติคอมไพล์ของคุณเป็นอย่างไร
Dennis

0

ใช้git rebase -iเพื่อบีบการกระทำที่เกี่ยวข้องให้เป็นหนึ่งเดียว จากนั้นคุณก็มีข้อผูกมัดที่จะเปลี่ยนกลับ


7
หากใช้ git rebase คุณสามารถลบคอมมิตได้ ฉันคิดว่ามีเหตุผลที่จะไม่ปรับฐานใหม่เช่นต้องการให้ SHA1 ของการกระทำ F เหมือนเดิม
Paŭlo Ebermann

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