Git: ข้อผิดพลาด "ไม่สามารถ 'สควอช' โดยไม่มีการกระทำก่อนหน้านี้" ในขณะที่ rebase


101

ฉันมีสิ่งต่อไปนี้ในข้อความสิ่งที่ต้องทำของgit rebase -i HEAD~2:

pick 56bcce7 Closes #2774
pick e43ceba Lint.py: Replace deprecated link

# Rebase 684f917..e43ceba onto 684f917 (2 command(s))
#
...

ตอนนี้เมื่อฉันพยายามสควอชอันแรก ( 56bcce7) และเลือกอันที่สองโดยเพิ่ม "s" ก่อนอันแรกฉันได้รับข้อผิดพลาดต่อไปนี้:

Cannot 'squash' without a previous commit

ใครช่วยอธิบายหน่อยได้ไหมว่ามันหมายถึงอะไรและฉันต้องทำอย่างไร

ฉันต้องการสควอชคอมมิตแรก ( 56bcce7) และ "เลือกและรีเวิร์ด" คอมe43cebaมิตที่สอง ( )


1
เปลี่ยน HEAD ~ 2 เป็น HEAD ~ 3 ถ้าคุณต้องการสควอชจริงๆ
ElpieKay

1
และอาจใช้ --root ถ้า HEAD ~ 2 เป็นคอมมิตแรกของคุณ: stackoverflow.com/a/598788/2444812
Sybille Peters

คำตอบ:


88

ของขวัญ rebase git logอินเตอร์แอคทีมุ่งมั่นในลำดับที่กลับของสิ่งที่คุณจะใช้ในการเมื่อมีการใช้ git rebase -iเล่นซ้ำการคอมมิตที่เลือกตามลำดับ (จากบนลงล่าง) ที่ตรงกันซึ่งแสดงอยู่ในไฟล์คำสั่ง rebase ที่บันทึกไว้ เมื่อ squashing การกระทำที่เลือกสำหรับ squashing จะรวมกับการกระทำที่นำหน้าในรายการ (แก้ไข) นั่นคือการกระทำจากบรรทัดก่อนหน้า ในกรณีของคุณ - 56bcce7ไม่มีก่อนหน้านี้สำหรับการกระทำ คุณต้องดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้

  • git rebase -i HEAD~3(ถ้าคุณต้องการที่จะสควอช56bcce7เข้า684f917)
  • หากคุณต้องการรวมเข้า56bcce7ด้วยกันe43cebaและe43cebaไม่ได้ขึ้นอยู่กับ56bcce7ให้จัดลำดับใหม่:

    r e43ceba Lint.py: Replace deprecated link
    s 56bcce7 Closes #2774
    

    อัปเดต : คำตอบของกัสด้านล่างแนะนำวิธีที่ดีกว่าในการทำสิ่งเดียวกันโดยไม่ต้องเรียงลำดับการกระทำทั้งสองใหม่

    r 56bcce7 Closes #2774
    s e43ceba Lint.py: Replace deprecated link
    

    สิ่งนี้จะสควอช / รวมทั้งสองคอมมิตเข้าด้วยกัน เมื่อ rebase โต้ตอบขอ reworded กระทำข้อความ56bcce7ให้กระทำข้อความที่อธิบายสหภาพของและ56bcce7e43ceba


1
ฉันต้องการที่จะสควอชเข้า56bcce7 e43cebaฉันจะทำขั้นตอนที่ 1 ที่นี่ได้อย่างไร
Dawny33

86

ฉันมีปัญหาที่คล้ายกันซึ่งฉันแก้ไขได้ดังนี้:

นี่คือกลุ่มการกระทำที่ฉันต้องการสควอช:

1 s 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 pick 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

อย่างที่คุณเห็นฉันไม่ต้องการ 4 แต่ 1, 2 และ 3 ไม่เคยกระทำการสควอชมาก่อน ดังนั้นไม่สามารถ 'สควอช' ได้โดยไม่มีข้อผิดพลาดในการกระทำก่อนหน้านี้

วิธีแก้ปัญหาของฉันคือใช้rตัวเลือกสำหรับ# r, reword = use commit, but edit the commit message

รายการคอมมิตของฉันมีลักษณะดังนี้:

1 r 01cc5a08 Removes open div
2 s a2b6eecf Restores old fonts
3 s 603479ff Cleans left out div
4 s 5afdbc33 Update: show logo on landing page
5 s 04c1cb13 change version of dev and prod from 1 to 2
6 s bbe6a8f8 Update: show logo on landing page if they have one
7 s c0d6008a Adds check for C users

หลังจากบันทึกแล้วเชลล์แบบโต้ตอบจะขอให้ฉันทำการ rewording ของคอมมิตที่เลือก

หลังจากนั้นบันทึกการคอมมิตของฉันส่งผลให้เกิดการคอมมิตเดียวซึ่งส่งผลให้ประวัติการคอมมิตสะอาดขึ้น


2
เช่นฉันหากคุณมีข้อผิดพลาดเนื่องจากคุณไม่ได้เลือกข้อผิดพลาดใด ๆ ที่จะ reword หรือเลือกและได้รับข้อผิดพลาดที่กล่าวถึง (ในคำถาม) คุณจะต้องทำgit rebase --edit-todoและแก้ไขการอ้างอิงคำตอบนี้แล้วทำgit rebase --continue
พระ

คำตอบนี้กระชับและตรงประเด็นช่วยได้จริงๆขอบคุณ
gonzofish

20

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

1 pick 01mn9h78 The lastest commit
2 pick a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

ตอนนี้ถ้าคุณพูดgit rebase -i HEAD~3และคุณทำสิ่งที่ชอบ

1 pick 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 s 093479uf An old commit i made a while back

ซึ่งจะส่งผลให้เกิดข้อผิดพลาด:

ข้อผิดพลาด: ไม่สามารถ 'squash' โดยไม่มีการกระทำก่อนหน้านี้คุณสามารถแก้ไขได้ด้วย 'git rebase --edit-todo' จากนั้นเรียกใช้ 'git rebase --continue' หรือคุณสามารถยกเลิก rebase ด้วย "git rebase --abort"

วิธีการแก้ :

เมื่อสควอชคอมมิชชันคุณควรสควอชล่าสุดกับคนเก่าไม่ใช่ในทางกลับกันดังนั้นในตัวอย่างจะเป็นดังนี้:

1 s 01mn9h78 The lastest commit
2 s a2b6pcfr A commit before the latest
3 pick 093479uf An old commit i made a while back

หรูนี้จะทำงานในกรณีที่คุณต้องการกระทำข้อความทั้งหมดของคุณผมจะแนะนำfixupแทนสควอช


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

4

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

  • pickข้อตกลงแรกที่คุณไม่ต้องการให้ส่งข้อความ
  • squashหรือคอมfixupมิตที่คุณต้องการรวมเข้าด้วยกันจนกว่าจะมีข้อความคอมมิตที่คุณต้องการจริงๆ
pick 56bcce7 Closes #2774
squash e43ceba Lint.py: Replace deprecated link
  • ยืนยันการเปลี่ยนแปลง ( :x)
  • ลบข้อความกระทำ (s) ที่คุณไม่ต้องการและปล่อยเพียงข้อความจากกระทำที่คุณต้องการ (ในกรณีนี้: Lint.py: Replace deprecated link)
  • ยืนยันตัวเลือก ( :x)

หวังว่าจะชัดเจนกว่าสำหรับใครบางคน✌🏽


2

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


2

ฉันเพิ่งลองวิธีนี้

บันทึก git -n3

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

git rebase -i HEAD ~ 3

เลือกการกระทำสุดท้ายที่เราต้องการเพื่อเอาชนะอีกสองคน รหัสการกระทำที่ถูกเลือกเป็นฐานการกระทำจะเป็นอย่างไร

เลือก commit_id

สำหรับอีกสองรหัสคอมมิตให้เปลี่ยนเป็น

สควอชคอมมิต _id

หรือเพียงแค่

s Commit_id


0

ตอนนี้ฉันได้พบกับปัญหานี้แล้วนั่นเป็นเพียงความประมาทคุณสามารถแก้ปัญหาได้เช่นต่อไป: เมื่อคุณพยายามสควอชอันแรก (56bcce7) และเลือกอันที่สองคุณควรเพิ่ม "s" ก่อนบรรทัดที่สอง แต่ ไม่ใช่คนแรก คุณยังสามารถอ้างอิงเว็บไซต์ถัดไป: http://backlogtool.com/git-guide/en/stepup/stepup7_5.html


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