เปลี่ยนข้อความคอมมิตเก่าใน Git


148

ผมพยายามที่จะแก้ไขข้อความกระทำเก่าตามที่อธิบายไว้ที่นี่

เป็นสิ่งที่ตอนนี้เมื่อฉันพยายามที่จะเรียกมันว่าrebase -i HEAD~5interactive rebase already started

จากนั้นฉันลอง: git rebase --continueแต่ได้รับข้อผิดพลาดนี้:

error: Ref refs/heads/master is at 7c1645b447a8ea86ee143dd08400710c419b945b but expected c7577b53d05c91026b9906b6d29c1cf44117d6ba
fatal: Cannot lock the ref 'refs/heads/master'.

ความคิดใด ๆ ?

คำตอบ:


134

มันบอกว่า:

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

$ git rebase -i HEAD~3
Stopped at 7482e0d... updated the gemspec to hopefully work better
You can amend the commit now, with

ไม่ได้หมายความว่า:

พิมพ์อีกครั้ง git rebase -i HEAD~3

พยายามอย่าพิมพ์ git rebase -i HEAD~3เมื่อออกจากโปรแกรมแก้ไขและควรใช้งานได้ดี
(มิฉะนั้นในสถานการณ์เฉพาะของคุณgit rebase -i --abortอาจจำเป็นต้องรีเซ็ตทุกอย่างและให้คุณลองอีกครั้ง)


ตามที่Dave Vogtกล่าวไว้ในความคิดเห็นgit rebase --continueมีไว้สำหรับไปที่ภารกิจต่อไปในกระบวนการปรับเปลี่ยนหลังจากที่คุณได้แก้ไขข้อตกลงครั้งแรกแล้ว

นอกจากนี้เกร็กลินด์กล่าวในคำตอบของเขาrewordคำสั่งของgit rebase :

ด้วยการแทนที่คำสั่ง "pick" ด้วยคำสั่ง "edit" คุณสามารถบอกgit rebaseให้หยุดหลังจากใช้คอมมิตนั้นเพื่อให้คุณสามารถแก้ไขไฟล์และ / หรือข้อความคอมมิตแก้ไขคอมมิตและทำการรีแบตต่อได้

หากคุณเพียงแค่ต้องการที่จะแก้ไขข้อความกระทำการกระทำแทนคำสั่ง " pick" กับคำสั่ง " reword"ตั้งแต่Git1.6.6 ( ม.ค. 2010)

มันจะเป็นสิ่งเดียวกัน ' edit' ไม่ในระหว่างการ rebase โต้ตอบยกเว้นก็เพียงช่วยให้คุณแก้ไขข้อความกระทำโดยไม่ต้องกลับควบคุมไปยังเปลือก นี่เป็นประโยชน์อย่างยิ่ง
ขณะนี้หากคุณต้องการล้างข้อความคอมมิตของคุณคุณต้อง:

$ git rebase -i next

จากนั้นตั้งค่าคอมมิตทั้งหมดเป็น "แก้ไข" จากนั้นในแต่ละรายการ:

# Change the message in your editor.
$ git commit --amend
$ git rebase --continue

การใช้ ' reword' แทน ' edit' ช่วยให้คุณสามารถข้ามgit-commitและgit-rebaseโทรได้


2
นอกจากนี้git rebase --continueให้ไปที่ภารกิจถัดไปในขั้นตอนการปรับใหม่หลังจากที่คุณแก้ไขข้อตกลงแรกแล้ว
Dave Vogt

1
การเพิ่มลิงก์ไปยังบทความ github wiki เพื่อเปลี่ยนข้อความคอมมิต
Joy

75

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

git rebase -i HEAD~n

นี่nคือรายการของ n ครั้งสุดท้าย

ตัวอย่างเช่นหากคุณใช้git rebase -i HEAD~4คุณอาจเห็นสิ่งนี้:

pick e459d80 Do xyz
pick 0459045 Do something
pick 90fdeab Do something else
pick facecaf Do abc

ตอนนี้แทนที่การเลือกด้วยrewordสำหรับคอมมิตที่คุณต้องการแก้ไขข้อความของ:

pick e459d80 Do xyz
reword 0459045 Do something
reword 90fdeab Do something else
pick facecaf Do abc

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

เรียนรู้เพิ่มเติมเกี่ยวกับหน้า GitHub สำหรับการเปลี่ยนกระทำข้อความ


อธิบายได้ดีมาก ขอบคุณ: D
Shubham Jain

ขอบคุณ @ShubhamJain ยินดีที่คำตอบของฉันมีประโยชน์
Punit Vara

ฉันทำอย่างนั้นแล้วคอมมิตจากสาขาอื่น ๆ ก็มาปรากฏตัวในสาขาของฉัน
เรซา

@ เรซ่าคุณอาจจะทำอะไรผิดพลาด ลองใช้สิ่งนี้ใน repo อื่น ๆ วิธีนี้ใช้ได้ผลดี
Punit Vara

คำตอบนี้ดีกว่าคำตอบที่ยอมรับเพราะสั้นและตรงประเด็น
ม. นุนิสา

56

FWIW ตอนนี้ git rebase โต้ตอบมีตัวเลือก "reword" ซึ่งทำให้เจ็บปวดน้อยลงมาก!


3
เมื่อใช้rewordทำไม git ไม่ให้คุณแก้ไขข้อความการกระทำในไฟล์นั้นด้วยรายการคอมมิต? แต่จะเปิดตัวแก้ไขด้วยไฟล์ข้อความคอมมิตต่อrewordบรรทัด นี่เป็นสิ่งที่ไม่จำเป็น แม้ว่าการดำเนินการอื่นที่ไม่ใช่pickหรือrewordต้องการการเรียกใช้คำสั่งภายนอกrewordก็ไม่จำเป็นต้องทำเช่นนั้น
Dan Dascalescu

11

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

เนื่องจาก git hook ที่ตรวจสอบหมายเลขตั๋วที่เหมาะสมบน Jira แต่เป็นกรณีที่ละเอียดอ่อนฉันจึงไม่สามารถกดรหัสของฉันได้ นอกจากนี้การคอมมิตเสร็จสิ้นไปนานแล้วและฉันไม่ต้องการนับจำนวนคอมมิตที่จะกลับไปในฐานข้อมูลใหม่

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

จากต้นแบบล่าสุด:

git checkout -b new-branch

แล้ว

git merge --squash problem-branch
git commit -m "new message" 

อ้างอิง: https://github.com/rotati/wiki/wiki/Git:-Combine-all-messy-commits-into-one-commit-before-merging-to-Master-branch


1
คำตอบของคุณช่วยวันของฉันได้จริงๆ :) ฉันต่อสู้กับมันrebase -iประมาณ 2 ชั่วโมงและไม่ประสบความสำเร็จ การกระทำของฉันอยู่เบื้องหลังการกระทำ 18 ครั้งดังนั้นคุณสามารถจินตนาการได้ นี่เป็นวิธีที่ง่ายและสะดวกกว่าที่ฉันพบได้โดยไม่ต้องใช้ rebase ขอบคุณเพื่อน!
Carlos Parra

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