Git: วิธีการแก้ไข / reword ข้อความผสานกระทำของ?


148

ฉันจะแก้ไขหรือใส่ข้อความของจดหมายเวียนได้อย่างไร

git commit --amendทำงานถ้าหากมันเป็นครั้งสุดท้ายที่ทำ ( HEAD) แต่สิ่งที่ถ้ามันมาก่อนHEAD?

git rebase -i HEAD~5 ไม่แสดงรายการการรวมการกระทำ

คำตอบ:


207

หากคุณเพิ่ม--preserve-mergesตัวเลือก (หรือคำพ้องความหมาย-p) ลงในgit rebase -iคำสั่ง git จะพยายามรักษาการรวมไว้เมื่อทำการรีบูตแทนที่จะทำให้เป็นเชิงเส้นตรงกับประวัติและคุณควรจะสามารถแก้ไขคอมมิชชันได้เช่นกัน:

git rebase -i -p HEAD~5

1
ฉันทำสิ่งนี้แล้ว แต่หลังจากทำการเปลี่ยนแปลงแล้วฉันก็ลองและผลักดันการเปลี่ยนแปลงของฉันฉันจะได้รับสิ่งนี้! [rejected] HEAD -> master (non-fast-forward)error: failed to push some refs to
Marc

1
พยายามเรียกใช้ git push -f จากนั้นสาขาต้นกำเนิดของคุณ สิ่งนี้น่าจะใช้ได้ ฉันมีปัญหาเดียวกันด้วยเหตุผลบางอย่างนี่เป็นสิ่งประดิษฐ์ของการรีบูตเพราะสิ่งที่เกิดขึ้นโดยทั่วไปคือหลังจากที่คุณทำการรีบูทคุณจบลงด้วยการแยกออกจากกันดังนั้นผู้บังคับการจึงควรแก้ไขและควรผลักดันทุกอย่าง
Radu Comaneci

11
@Marc สิ่งนี้เกิดขึ้นเนื่องจากคุณแก้ไขที่คุณส่งไปแล้ว ถือว่าเป็นการปฏิบัติที่ไม่ดีในการบังคับให้ส่งไปยังเซิร์ฟเวอร์เนื่องจากจะทำให้คุณและเพื่อนร่วมงานของคุณไม่สามารถซิงค์ได้อย่างสมบูรณ์ ถ้าคุณอยู่คนเดียวก็ไม่ควรมีปัญหา
ibizaman

ที่HEAD~5เป็นพาเรนต์ของการส่งที่คุณต้องการแก้ไข (โดยปกติคือ sha1 ^)
Gabriel Devillers

2
--preserve-mergesได้แล้วตอนนี้--rebase-merges
OrangeDog

32

โปรดทราบว่าการเริ่มต้น git1.7.9.6 (และ git1.7.10 +) git mergeจะทำให้เกิดการแก้ไขเสมอเพื่อให้คุณเพิ่มรายละเอียดในการรวม

" git merge $tag" เพื่อรวมแท็กที่มีหมายเหตุประกอบเปิดตัวแก้ไขเสมอในระหว่างเซสชันการแก้ไขแบบโต้ตอบ ชุด v1.7.10 นำเสนอตัวแปรสภาพแวดล้อม GIT_MERGE_AUTOEDIT เพื่อช่วยให้สคริปต์เก่าปฏิเสธพฤติกรรมนี้ แต่แทร็กการบำรุงรักษาควรสนับสนุน

นอกจากนี้ยังแนะนำตัวแปรสภาพแวดล้อมGIT_MERGE_AUTOEDITเพื่อช่วยให้สคริปต์เก่าปฏิเสธพฤติกรรมนี้

ดูที่ "การคาดการณ์ Git 1.7.10 ":

เมื่อเร็ว ๆ นี้ในการสนทนาในรายการส่งจดหมายของ Git Linus ยอมรับ (และฉันเห็นด้วย) ว่านี่เป็นหนึ่งในข้อผิดพลาดในการออกแบบที่เราทำไว้ตั้งแต่ต้นในประวัติศาสตร์ของ Git
และใน 1.7.10 ขึ้นไปคำสั่ง git merge ที่รันในเซสชันแบบโต้ตอบ (เช่นทั้งอินพุตมาตรฐานและเอาต์พุตมาตรฐานที่เชื่อมต่อกับเทอร์มินัล) จะเปิดตัวแก้ไขก่อนที่จะสร้างคอมมิทเพื่อบันทึกผลการผสานเพื่อให้ ผู้ใช้มีโอกาสอธิบายการรวมเช่นเดียวกับคำสั่ง git ที่ผู้ใช้รันหลังจากแก้ไขการผสานที่ขัดแย้งกันแล้ว

ไลนัสกล่าวว่า:

แต่ฉันไม่สนใจอย่างจริงจังว่ามันใช้งานได้จริงอย่างไรปัญหาหลักของฉันคือคอมไพล์ทำให้มันง่ายเกินไปที่จะมีข้อความที่ไม่ถูกต้องผสาน
ฉันคิดว่าส่วนหนึ่งของมันนั้นง่ายกว่าคนอื่น: เราไม่เคยแม้แต่จะแก้ไขมันโดยปริยายสำหรับ "git merge" แต่เราทำเพื่อ " git commit"
นั่นเป็นความผิดพลาดในการออกแบบและหมายความว่าถ้าคุณต้องการเพิ่มบันทึกย่อไปยังการรวมคุณต้องทำงานพิเศษ
ดังนั้นคนทำไม่ได้


โปรดทราบว่าก่อนหน้า Git 2.17 (Q2 2018) " git rebase -p" บันทึกข้อความแบบ mangled ของการรวมผสานซึ่งได้รับการแก้ไขแล้ว

ดูกระทำ ed5144d (8 กุมภาพันธ์ 2018) โดยเกรกอรี่ Herrero ( ``)
แนะนำโดย: Vegard Nossum ( vegard)และเควนติน Casasnovas (casasnovas )
(ผสานโดยJunio ​​C Hamano - gitster- in 8b49408 , 27 Feb 2018)

rebase -p: git mergeการแก้ไขที่ไม่ถูกต้องกระทำข้อความเมื่อโทร

ตั้งแต่คอมมิชชัน dd6fb00 (" rebase -p: แก้ไขการอ้างถึงเมื่อเรียกgit merge", มกราคม 2018, Git 2.16.0-rc2) ข้อความคอมมิชชันของการคอมมิทคอมมิทที่กำลังทำการ rebased จะถูกส่งไปยังคำสั่ง merge โดยใช้ subshell เพื่อเรียกใช้ ' git rev-parse --sq-quote'

จำเป็นต้องใช้อัญประกาศคู่ล้อมรอบเชลล์ย่อยนี้เพื่อให้บรรทัดใหม่ถูกเก็บไว้สำหรับgit mergeคำสั่ง

ก่อนที่แพ็ตช์นี้จะรวมข้อความต่อไปนี้:

"Merge mybranch into mynewbranch

Awesome commit."

กลายเป็น:

"Merge mybranch into mynewbranch Awesome commit."

rebase -pหลังจากที่


ด้วย Git 2.23 (Q2 2019) merge -cคำสั่ง "" ในระหว่าง " git rebase --rebase-merges" ควรเปิดโอกาสให้ผู้ใช้แก้ไขข้อความบันทึกแม้ว่าจะไม่จำเป็นต้องสร้างจดหมายเวียนใหม่และแทนที่ข้อความปัจจุบันที่มีอยู่ (เช่นการส่งต่ออย่างรวดเร็วแทน ) แต่ไม่ได้
ซึ่งได้รับการแก้ไข

ดูกระทำ 6df8df0 (2 พฤษภาคม 2019) โดยฟิลลิปไม้ (phillipwood )
(ผสานโดยJunio ​​C Hamano - gitster- in c510261 , 13 Jun 2019)


16

อีกหนึ่งคำตอบที่ดีโดยใช้คำสั่งดั้งเดิมเท่านั้น - โดย knittl https://stackoverflow.com/a/7599522/94687 :

git checkout <sha of merge>
git commit --amend # edit message
git rebase HEAD previous_branch

หรือคำสั่ง rebase สุดท้ายที่ดีกว่า (ถูกต้องมากขึ้น):

git rebase <sha of merge> previous_branch --onto HEAD

BTW การใช้คำสั่งดั้งเดิมอาจมี "คุณสมบัติ" ที่ดีของการไม่ใช้ CPU มากเกินไปและทำให้คุณรอเวลาที่ไม่รู้จักจนกระทั่ง Git เสร็จสิ้นการคิดเกี่ยวกับรายการการกระทำที่จำเป็นต้องมีการรีบูทในกรณีของgit rebase -p -i HEAD^^^^(คำสั่งดังกล่าวซึ่งจะทำให้ รายชื่อเพียง 4 ครั้งล่าสุดที่คอมมิชชันผสานเป็นรายการสุดท้ายในกรณีของฉันในกรณีของฉันใช้เวลาประมาณ 50 วินาที!)


2
สิ่งนี้มีประโยชน์จริง ๆ ช่วยฉันสักหน่อย บริษัท ของฉันบล็อกข้อความคอมมิทบางส่วนในที่เก็บซึ่งง่ายต่อการ - แก้ไขหรือด้วยคำสั่ง rebase แต่: ปัญหาใหญ่ถ้าเรารวมสาขาบางส่วนเข้ากับคุณทำคอมมิทบางส่วนและพยายามที่จะผลักดันข้อความผสานเริ่มต้นของคอมไพล์ถูกบล็อก สิ่งนี้ควรได้รับการแก้ไขฉันรู้) ซึ่งบังคับให้เราเปลี่ยนข้อความนั้น จนกระทั่งคำตอบนี้ฉันได้ลองหลายสิ่งหลายอย่างในการเปลี่ยนข้อความผสานระหว่างประวัติของการกระทำที่ไม่ประสบความสำเร็จ
Giovanni Silva

2

git merge --edit
ช่วยให้คุณสามารถแสดงความคิดเห็นได้แม้ในกรณีที่ไม่รวมการโต้ตอบ

git merge --edit --no-ff อาจมีประโยชน์หากคุณติดตามกระแส git ด้วยการรีบูทในสาขาการพัฒนาและการรวมเข้าด้วยกันโดยไม่มีการกรอไปข้างหน้าอย่างรวดเร็ว


2

สำหรับเวอร์ชั่น Git ปัจจุบัน (เชียงใหม่ 2020):

git rebase -i -r <parent>,

แล้วแทนที่ในการแก้ไขด้วยmerge -C ...merge -c ...

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

(ขอบคุณVonCสำหรับคำใบ้ )


0

git rebase -i HEAD~5คำสั่งปรากฏขึ้นบรรณาธิการ มันแสดงรายการการกระทำที่ระบุ (ในกรณีนี้คือห้าข้อ) คอลัมน์แรกมีpickไว้สำหรับทุกการกระทำ เพียงแทนที่pickด้วยrewordในเครื่องมือแก้ไขนั้นและบันทึก + ปิดโปรแกรมแก้ไข จากนั้น git จะปรากฏตัวแก้ไขสำหรับทุกการกระทำที่คุณเปลี่ยนpickไปrewordและจะช่วยให้คุณแก้ไขข้อความการส่งข้อความ


6
วิธีนี้ใช้ไม่ได้กับการรวมการกระทำเว้นแต่ว่าคุณ-pจะเพิ่มgit rebaseคำสั่งด้วย
ราคาพอล

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