git ลบการผสานรวมออกจากประวัติ


99

ประวัติ Git ของฉันมีลักษณะดังนี้:

ประวัติ Git

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

ฉันพยายามทำ a git rebase -i 1แล้ว แต่ถึงแม้ว่าจะ1อยู่บนกิ่งไม้สีน้ำเงิน (ภาพเปรียบเทียบ) ฉันก็ยังเห็นทุกข้อตกลงในสาขาสีม่วงของฉัน

ฉันจะลบสาขาสีม่วงทั้งหมด (จากบันทึกการคอมมิต) ได้อย่างไร


repo ของคุณถูกผลักดันไปทุกที่ที่คนอื่นดึงมาหรือไม่?
Schleis

ทั้งสองสาขาเป็นสาขาในท้องถิ่นล้วนๆ
Benjamin Toueg

คำตอบ:


101

การทำgit rebase -i <sha before the branches diverged>เช่นนี้จะช่วยให้คุณสามารถลบคอมมิตการผสานและบันทึกจะเป็นบรรทัดเดียวตามที่คุณต้องการ คุณยังสามารถลบคอมมิตที่คุณไม่ต้องการได้อีกต่อไป สาเหตุที่ rebase ของคุณไม่ทำงานคือคุณไม่ได้ย้อนกลับไปไกลพอ

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


4
แม้ว่าฉันจะเลือก sha ก่อนที่กิ่งจะแตกออกฉันก็เห็นการกระทำทั้งหมดของสาขาสีม่วง -_-
Benjamin Toueg

1
ใช่แล้วคุณลบออกในตัวแก้ไขที่เกิดขึ้นgit rebaseและจะถูกลบออก
Schleis

4
การลบคอมมิตส่งผลให้สูญเสียการแก้ไขการผสานทั้งหมด แต่ฉันทำการซอฟต์รีเซ็ตและได้บางอย่างที่ต้องการ (คำสั่งไม่ตรงกับความคาดหวังเริ่มต้น)
Benjamin Toueg

2
คำตอบนี้ไม่สมบูรณ์ในรายละเอียดคุณเริ่มต้น rebase จากสาขาใด
grgry

3
ค่อนข้างแน่ใจว่าคุณไม่ต้องการ "ลบ" การกระทำ "ลบ" ไม่ใช่ตัวเลือกใน rebase แต่ลบคือ หากคุณลบคอมมิตคุณจะสูญเสียการเปลี่ยนแปลงที่แนะนำ คุณต้องการสควอชการกระทำ
thecoshman

71

เริ่มต้นด้วย repo ในสถานะเดิม

ประวัติ repo ดั้งเดิม

ในการลบคอมมิตการผสานและสควอชสาขาเป็นคอมมิตเดียวในเมนไลน์

บีบคอมมิตไม่มีการรวมคอมมิต

ใช้คำสั่งเหล่านี้ (แทนที่ 5 และ 1 ด้วย SHAs ของคอมมิตที่เกี่ยวข้อง):

git checkout 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git rebase HEAD master

หากต้องการรักษาการผสานรวม แต่สควอชสาขาจะรวมเป็นหนึ่ง:

Squashed กระทำการรวมการกระทำที่ยังคงอยู่

ใช้คำสั่งเหล่านี้ (แทนที่ 5, 1 และ C ด้วย SHAs ของคอมมิตที่เกี่ยวข้อง):

git checkout -b tempbranch 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git checkout C
git merge --no-ff tempbranch
git rebase HEAD master

ในการลบคอมมิตการผสานและแทนที่ด้วยคอมมิตแต่ละรายการจากสาขา

ย้ายสาขาเข้าสู่เมนไลน์ไม่มีการรวมคอมมิต

เพียงแค่ทำ (แทนที่ 5 ด้วย SHA ของคอมมิตที่เกี่ยวข้อง):

git rebase 5 master

และสุดท้ายเพื่อลบสาขาทั้งหมด

ลบสาขาทั้งหมด

ใช้คำสั่งนี้ (แทนที่ C และ D ด้วย SHAs ของคอมมิตที่เกี่ยวข้อง):

git rebase --onto C D~ master

ในgit rebase 5 masterกรณีทำไมจึงไม่ใช่คำสั่ง "ABC 1 2 3 4 5 D ... "
รอย

1
คำสั่งนั้นรับคอมมิตที่masterไม่มีเหมือนกัน5และวางไว้ด้านบนของ5. ได้กระทำการที่Cไม่ได้เป็นส่วนหนึ่งของวงศ์ตระกูลของมันเป็นครั้งแรกที่จะย้ายไปอยู่ด้านบนของ5 5
Allen Luce

2
หากคุณต้องการลงท้ายด้วย "ABC 1 2 3 4 5 D ... " คุณสามารถทำได้:git rebase C 5; git rebase 5 master
Allen Luce

19

เพื่อลบคอมมิตการผสาน

หากสิ่งที่คุณต้องการทำคือการลบการรวมคอมมิต (2) เพื่อให้เหมือนไม่เคยเกิดขึ้นคำสั่งมีดังนี้

git rebase --onto <sha of 1> <sha of 2> <blue branch>

และตอนนี้สาขาสีม่วงไม่ได้อยู่ในบันทึกของสีน้ำเงินเลยและคุณมีสองสาขาแยกกัน จากนั้นคุณสามารถสควอชสีม่วงได้อย่างอิสระและทำอะไรก็ได้ที่คุณต้องการโดยไม่ต้องผสานเข้าด้วยกัน


1
จากคำตอบทั้งหมดฉันพบว่าทั้งตรงไปตรงมาที่สุดและทำได้ง่ายที่สุด ขอบคุณ.
Roshambo

16

มีสองวิธีในการจัดการกับสิ่งที่คุณต้องการ:

โซลูชันที่ 1 : ลบคอมมิตสีม่วงรักษาประวัติ (ในกรณีที่คุณต้องการย้อนกลับ)

git revert -m 1 <SHA of merge>

-m 1 ระบุบรรทัดหลักที่จะเลือก

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


โซลูชันที่ 2 : ลบการคอมมิตสีม่วงโดยสิ้นเชิง (การเปลี่ยนแปลงที่ก่อกวนหากแชร์ repo)

git rebase -i <SHA before branching out>

และลบ (ลบบรรทัด) ที่สอดคล้องกับการกระทำสีม่วง

สิ่งนี้จะยุ่งยากน้อยกว่าหากไม่มีการคอมมิตหลังจากรวม revert/rebaseกระทำเพิ่มเติมเพิ่มโอกาสของความขัดแย้งระหว่าง


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

@ คัพเค้กมีสองคำตอบแยกกัน ฉันได้แก้ไขคำตอบเพื่อให้เกิดความสับสนน้อยลง: P
เปรม

AFAIK นี่ไม่ใช่สิ่งที่ OP ขอ เขาต้องการเก็บการเปลี่ยนแปลง แต่ลบเสียงออกจากบันทึกของเขา ด้วยเหตุนี้เขาจำเป็นต้องลดการกระทำลงการลบจะลบการเปลี่ยนแปลง
thecoshman

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