จะแก้ไขข้อความคอมมิชชันที่มีอยู่และไม่ได้กดได้อย่างไร?


7664

ฉันเขียนสิ่งผิดในข้อความยืนยัน

ฉันจะเปลี่ยนข้อความได้อย่างไร ความมุ่งมั่นยังไม่ได้รับการผลักดัน


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

คำตอบ:


16127

แก้ไขข้อความการส่งข้อความล่าสุด

git commit --amend

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

git commit --amend -m "New commit message"

... อย่างไรก็ตามสิ่งนี้สามารถทำให้ข้อความหลายบรรทัดส่งข้อความหรือแก้ไขได้ง่ายขึ้น

ตรวจสอบให้แน่ใจว่าคุณไม่มีการเปลี่ยนแปลงการคัดลอกการทำงานใด ๆ ที่จัดทำไว้ก่อนที่จะทำสิ่งนี้หรือพวกเขาจะได้รับการมุ่งมั่นเกินไป ( unstagedเปลี่ยนแปลงจะไม่ได้รับความมุ่งมั่น.)

การเปลี่ยนข้อความของการส่งข้อความที่คุณผลักไปยังสาขาระยะไกลของคุณแล้ว

หากคุณผลักดันการกระทำของคุณไปยังสาขาระยะไกลแล้ว - หลังจากแก้ไขข้อผูกพันในพื้นที่ (ดังที่อธิบายไว้ด้านบน) - คุณจะต้องบังคับให้ส่งการกระทำด้วย:

git push <remote> <branch> --force
# Or
git push <remote> <branch> -f

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

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


ดำเนินการ rebase เชิงโต้ตอบ

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

ในการทำสควอช Git ให้ทำตามขั้นตอนเหล่านี้:

// n is the number of commits up to the last commit you want to be able to edit
git rebase -i HEAD~n

เมื่อคุณสควอชกระทำของคุณ - เลือกe/rสำหรับการแก้ไขข้อความ:

ป้อนคำอธิบายภาพที่นี่

หมายเหตุสำคัญเกี่ยวกับการปฏิเสธแบบโต้ตอบ

เมื่อคุณใช้git rebase -i HEAD~nอาจมีมากขึ้นกว่ากระทำ n Git จะ "รวบรวม" การคอมมิชชันทั้งหมดใน n การคอมมิทล่าสุดและถ้ามีการผสานที่ใดที่หนึ่งในช่วงนั้นคุณจะเห็นคอมมิททั้งหมดเช่นกันดังนั้นผลลัพธ์จะเป็น n +

เคล็ดลับที่ดี:

หากคุณต้องทำมากกว่าสาขาเดียวและคุณอาจเผชิญความขัดแย้งเมื่อแก้ไขเนื้อหาให้ตั้งค่าgit rerereและให้ Git แก้ไขข้อขัดแย้งเหล่านั้นโดยอัตโนมัติ


เอกสาร


257
แต่ไม่ได้ประสิทธิภาพเท่าgit commit --amend git rebase -i
Jeffrey Jose

76
@ jeffjose มันไม่จำเป็นต้องเป็นอย่างแน่นอน นอกจากนี้ยังgit commit --amendสามารถแก้ไขการมอบหมายหลัก (a?)
แปลกหน้า

116
หากคุณได้ผลักดันอยู่แล้วเพียงแค่บังคับผลักดันอีกครั้ง:git push -f origin branchname
ฮิวจ์

177
@hughes ไม่git push -fเป็นอันตรายหากคนอื่นกำลังใช้ที่เก็บเดียวกัน
อาร์มันด์

91
หากคุณไม่ต้องการเขียนข้อความยืนยันทั้งหมดgit commit --amend -c HEADอีกครั้งให้ทำต่อ สิ่งนี้จะเปิดตัวแก้ไขที่เติมข้อมูลไว้ล่วงหน้าด้วยข้อความการส่งข้อความเก่าของคุณเพื่อให้คุณสามารถเปลี่ยนแปลงได้
Sam

2506
git commit --amend -m "your new message"

7
ฉันคอมไพล์ยอมรับ - แก้ไข -m "ข้อความใหม่" แต่การกดไปที่ Github สร้าง "รวมการเปลี่ยนแปลงระยะไกลก่อนที่จะผลักดันอีกครั้ง" หลังจากดึงแล้วยืนยัน - แก้ไขแล้วกดอีกครั้งข้อความใหม่จะไม่ปรากฏ แต่ฉันมี "รวมสาขา 'หลัก' ของ github.com: [mymyrepo]"
Dave Everitt

8
@DaveEveritt คุณน่าจะผลักดันการส่งข้อมูลก่อนที่จะพยายามแก้ไข
Thorbjørn Ravn Andersen

12
@ Kyralessa ไม่เป็นความจริง ในทุบตีคุณสามารถเขียนข้อความหลายบรรทัดโดยเพียงแค่ไม่ปิดข้อความจนกว่าคุณจะเสร็จสิ้น (กดปุ่มย้อนกลับที่จุดสิ้นสุดของแต่ละบรรทัดภายในเครื่องหมายคำพูด)
เตา

32
ฉันไม่เข้าใจว่าคำตอบที่ดูเหมือนกับแนวคิดหลักของคำตอบที่เขียนเมื่อสองปีก่อนและคำตอบที่ได้รับนั้นได้รับการโหวตมากมาย แปลก. (ไม่มีอะไรผิดปกติกับคำตอบแม้ว่า)
coder มีความสุข

7
@Amalmurali ดี ประเด็นของฉันไม่มากเกี่ยวกับความนิยมของคำถามหรือประโยชน์ของคำตอบ แต่คำตอบเฉพาะนี้ไม่ใช่คำตอบที่เก่าที่สุดและไม่ได้ให้คำตอบที่ลึกกว่าต่อคำตอบที่ยอมรับ ดูเหมือนจะเป็นสำเนาของส่วนของคำตอบที่ยอมรับ นั่นคือประเด็นของฉัน ไชโย!
coder มีความสุข

2376

หากความมุ่งมั่นที่คุณต้องการแก้ไขไม่ใช่สิ่งล่าสุด:

  1. git rebase --interactive $parent_of_flawed_commit

    หากคุณต้องการแก้ไขข้อผูกพันหลายข้อให้ส่งพาเรนต์ของอันที่เก่าแก่ที่สุดมาหนึ่งอัน

  2. ตัวแก้ไขจะปรากฏขึ้นพร้อมกับรายการการกระทำทั้งหมดตั้งแต่ที่คุณให้

    1. เปลี่ยนpickเป็นreword(หรือบน Git เวอร์ชันเก่าเป็นedit) ด้านหน้าคำมั่นสัญญาใด ๆ ที่คุณต้องการแก้ไข
    2. เมื่อคุณบันทึกแล้ว Git จะเล่นซ้ำการกระทำที่ระบุไว้

  3. สำหรับการกระทำที่คุณต้องการใส่ข้อความซ้ำ Git จะส่งคุณกลับไปที่เครื่องมือแก้ไขของคุณ สำหรับแต่ละการกระทำที่คุณต้องการแก้ไข Git จะนำคุณไปสู่เปลือก หากคุณอยู่ในเปลือก:

    1. เปลี่ยนการกระทำในแบบที่คุณชอบ
    2. git commit --amend
    3. git rebase --continue

ส่วนใหญ่ของลำดับนี้จะอธิบายให้คุณทราบโดยผลลัพธ์ของคำสั่งต่างๆที่คุณไป มันง่ายมาก; คุณไม่จำเป็นต้องจดจำ - เพียงจำไว้ว่าgit rebase --interactiveให้คุณแก้ไขการกระทำได้ไม่ว่าจะนานแค่ไหนก็ตาม


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


39
หนึ่งสามารถเปลี่ยนข้อความของการกระทำครั้งแรก (ซึ่งไม่มีผู้ปกครอง)?
13ren

27
นี่คือคำตอบหนึ่งในคำตอบอื่น ๆ แต่ฉันจะใส่มันไว้ที่นี่ ตั้งแต่ git 1.6.6 คุณสามารถใช้rewordแทนpickการแก้ไขข้อความบันทึก
MitMaro

89
อนึ่งเทียบเท่ากับ$parent_of_flawed_commit $flawed_commit^
Peeja

67
ไม่เคยทำเช่นนี้ (หรือรีบูตโดยทั่วไป) หากคุณได้ผลักดันอัปสตรีมแล้ว!
Daniel Rinser

20
ใช้-p( --preserve-merges) หากมีการรวมหลังจากการคอมมิทที่มีข้อบกพร่อง
ahven

778

หากต้องการแก้ไขการกระทำก่อนหน้าให้ทำการเปลี่ยนแปลงที่คุณต้องการและจัดลำดับการเปลี่ยนแปลงเหล่านั้นแล้วเรียกใช้

git commit --amend

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

ในการแก้ไขการคอมมิชชันก่อนหน้าและเก็บข้อความบันทึกเดิมให้รัน

git commit --amend -C HEAD

หากต้องการแก้ไขการคอมมิชชันก่อนหน้าโดยลบทั้งหมดให้รัน

git reset --hard HEAD^

หากคุณต้องการแก้ไขข้อความยืนยันมากกว่าหนึ่งข้อความให้เรียกใช้

git rebase -i HEAD~commit_count

(แทนที่commit_countด้วยจำนวนการคอมมิตที่คุณต้องการแก้ไข) คำสั่งนี้เรียกทำงานโปรแกรมแก้ไขของคุณ ทำเครื่องหมายการกระทำแรก (สิ่งที่คุณต้องการเปลี่ยน) เป็น "แก้ไข" แทน "เลือก" จากนั้นบันทึกและออกจากตัวแก้ไขของคุณ ทำการเปลี่ยนแปลงที่คุณต้องการกระทำแล้วเรียกใช้

git commit --amend
git rebase --continue

หมายเหตุ: นอกจากนี้คุณยังสามารถ "ทำการเปลี่ยนแปลงที่คุณต้องการ" จากตัวแก้ไขที่เปิดโดย git commit --amend


18
git rebase -i HEAD~commit_countจะช่วยให้คุณเปลี่ยนข้อความการส่งข้อความของคอมมิชชันที่คุณเลือกได้ เพียงทำเครื่องหมายการกระทำที่เลือกไว้ว่า "reword" แทน "pick"
โจ

2
ถ้าคุณไม่ต้องการลดระดับ คุณต้องการเปลี่ยนข้อความเก่าหรือไม่
SuperUberDuper

3
git reset --hardทำลายการเปลี่ยนแปลงที่ไม่มีข้อผูกมัด โปรดแทนที่ด้วย--hard --soft
ปลาไหล gEEE

1
เห็นด้วยgit reset --hardเป็นคำสั่งที่ถูกต้องตามกฎหมายอย่างสมบูรณ์ แต่มันทำให้เข้าใจผิดได้รับคำถาม คุณใช้--hardถ้าคุณกระทำการเปลี่ยนแปลงที่คุณต้องการทิ้งไม่ใช่ว่าคุณพิมพ์ผิดในข้อความยืนยัน!
Soren

398

ดังที่ได้กล่าวไปแล้วgit commit --amendคือวิธีการเขียนทับคำสั่งล่าสุด One note: หากคุณต้องการเขียนทับไฟล์คำสั่งก็จะเป็นเช่นกัน

git commit -a --amend -m "My new commit message"

4
และถ้าคุณไม่ต้องการเพิ่มทุกอย่างคุณสามารถทำได้git add file.extก่อนอื่นเพียงgit commit --amend
MalcolmOcean

358

คุณยังสามารถใช้git filter-branchสำหรับสิ่งนั้น

git filter-branch -f --msg-filter "sed 's/errror/error/'" $flawed_commit..HEAD

มันไม่ใช่เรื่องง่ายเหมือนเรื่องเล็กน้อยgit commit --amendแต่มีประโยชน์อย่างยิ่งหากคุณมีการรวมบางอย่างหลังจากข้อความคอมมิทที่ผิดพลาด

หมายเหตุที่ว่านี้จะพยายามที่จะเขียนทุกกระทำระหว่างHEADและข้อบกพร่องกระทำดังนั้นคุณควรเลือกของคุณmsg-filterคำสั่งอย่างชาญฉลาดมาก ;-)


4
มีรุ่นนี้ที่ไม่เปลี่ยนการกระทำถ้า regex ไม่พบอะไร?
sjakubowski

3
AFAIK filter-branch --msg-filter จะสร้างความมุ่งมั่นใหม่ในทุกกรณี อย่างไรก็ตามคุณสามารถตรวจสอบภายในตัวกรอง msg ได้หากผู้ประสบความสำเร็จและใช้ข้อมูลนี้เมื่อการดำเนินการของสาขาตัวกรองสิ้นสุดลงเพื่อรีเซ็ตต้นไม้ของคุณเป็นผู้อ้างอิง / ต้นฉบับ
Mark

4
@DavidHogue สิ่งนี้เป็นจริงเฉพาะเมื่อใช้วิธีการกรองสาขา ID การคอมมิชชันที่ตามหลังการคอมมิทที่แก้ไขแล้วจะไม่เปลี่ยนแปลงหากคุณใช้ rebase เชิงโต้ตอบ
Mark

6
@ มาร์คใช่พวกเขาทำพวกเขาจะต้อง รหัสการกระทำขึ้นอยู่กับการกระทำก่อนหน้า หากพวกเขาไม่เปลี่ยน git จะไร้ประโยชน์
เส้นทาง Miles

2
คุณต้องไม่$flawed_commit^..HEAD $flawed_commit..HEADตามที่ระบุไว้ใน man page: « คำสั่งจะเขียนเฉพาะ refs เชิงบวกที่กล่าวถึงในบรรทัดคำสั่ง (เช่นถ้าคุณผ่าน a .. b, b เท่านั้นจะถูกเขียนใหม่) »
Ángel

319

ฉันชอบวิธีนี้:

git commit --amend -c <commit ID>

มิฉะนั้นจะมีการส่งมอบใหม่พร้อมกระทำการส่งมอบใหม่


7
สำหรับฉันการใช้คำสั่งของคุณด้านบนสร้างการส่งมอบแบบใหม่ด้วยการส่งมอบรหัสใหม่บวกการส่งแบบพิเศษที่ระบุว่า "การรวมสาขา" เป็นข้อความส่งเริ่มต้น
Jan

46
การแก้ไขจะสร้างการส่งมอบใหม่ด้วยการส่งมอบรหัสใหม่ รหัสการกระทำคือการแฮช SHA ของเนื้อหาของการกระทำรวมถึงข้อความการส่งและการบันทึกเวลา / ผู้แต่ง นี่คือคุณสมบัติของ Git ที่จะป้องกันการชนกันของแฮชทำให้แน่ใจได้ว่าการกระทำสองรายการที่มี ID เดียวกันนั้นเป็นการกระทำที่เหมือนกันโดยมีเนื้อหาประวัติและอื่น ๆ
Emil Lundberg

7
เห็นด้วยกับ Emil นอกจากนี้การอ่านเอกสาร - ดูเหมือนว่า "-c" ทั้งหมดจะบอก git ว่าข้อความของคอมมิทใดที่จะใช้เป็นค่าเริ่มต้น / เทมเพลตสำหรับการส่งข้อความใหม่ของคุณ ดังนั้นไม่จำเป็นต้องระบุ
Gal

2
-cสิ่งที่ไม่กี่ มันใช้ข้อความเก่าโดยค่าเริ่มต้น แต่ก็ยังคัดลอกข้อมูลการประพันธ์ (บุคคลและเวลา) -Cทำสิ่งเดียวกันยกเว้นว่าจะไม่ขอให้คุณแก้ไขข้อความ
Joseph K. Strauss

1
เช่น @SantanuDey มันไม่ได้ผลสำหรับฉัน ฉันได้fatal: Option -m cannot be combined with -c/-C/-F/--fixup.
Andrew Grimm

312

หากคุณกำลังใช้เครื่องมือ Git GUI มีปุ่มชื่อแก้ไขครั้งสุดท้าย คลิกที่ปุ่มนั้นแล้วมันจะแสดงไฟล์และข้อความคอมมิทล่าสุดของคุณ เพียงแค่แก้ไขข้อความนั้นและคุณสามารถส่งข้อความด้วยข้อความยืนยันใหม่

หรือใช้คำสั่งนี้จากคอนโซล / เทอร์มินัล:

git commit -a --amend -m "My new commit message"

4
คำตอบนี้เป็นตัวอักษรที่เหมือนกันนี้พี่ คุณได้ตรวจสอบคำตอบที่มีอยู่ก่อนส่งอีกหรือไม่
Dan Dascalescu

284

คุณสามารถใช้Git rebasing ตัวอย่างเช่นหากคุณต้องการแก้ไขกลับเพื่อส่งมอบ bbc643cd ให้รัน

$ git rebase bbc643cd^ --interactive

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

$ git add <filepattern>

ตอนนี้คุณสามารถใช้

$ git commit --amend

เพื่อแก้ไขการกระทำและหลังจากนั้น

$ git rebase --continue

เพื่อย้อนกลับไปที่การกระทำก่อนหน้า


1
หากคุณต้องการให้แน่ใจว่าการเปลี่ยนแปลงของคุณgit commit --amendมีผลคุณสามารถใช้git showและมันจะแสดงข้อความใหม่
Steve Tauber

279
  1. หากคุณต้องการแก้ไขข้อความการส่งข้อความครั้งล่าสุดเท่านั้นให้ทำดังนี้

    git commit --amend
    

สิ่งนั้นจะนำคุณไปสู่โปรแกรมแก้ไขข้อความและให้คุณเปลี่ยนข้อความการส่งข้อความครั้งล่าสุด

  1. หากคุณต้องการเปลี่ยนข้อความการส่งข้อความสามข้อความล่าสุดหรือข้อความการส่งข้อความถึงจุดนั้นHEAD~3ให้ระบุgit rebase -iคำสั่ง:

    git rebase -i HEAD~3
    

6
คำตอบก่อนหน้านี้แล้วบอกว่าคุณสามารถใช้git commit --amendและยังบอกว่าคุณสามารถใช้git rebase -i HEAD~commit_countสิ่งที่คุณไม่ได้เสียบสำหรับ3 commit_count

ลงคะแนนเช่นกัน แค่คนไม่รำคาญที่จะอ่านคำตอบที่มีอยู่
Dan Dascalescu

261

หากคุณต้องเปลี่ยนข้อความการส่งข้อความเก่าในหลายสาขา (เช่นการส่งข้อความที่มีข้อผิดพลาดมีอยู่ในหลายสาขา) คุณอาจต้องการใช้:

git filter-branch -f --msg-filter \
'sed "s/<old message>/<new message>/g"' -- --all

Git refs/original/จะสร้างไดเรกทอรีชั่วคราวสำหรับการเขียนและการอ้างอิงเก่าสำรองเพิ่มใน

  • -fจะบังคับใช้การดำเนินการ นี่เป็นสิ่งจำเป็นหากไดเรกทอรีชั่วคราวมีอยู่แล้วหรือมีการอ้างอิงที่เก็บไว้refs/originalแล้ว หากไม่เป็นเช่นนั้นคุณสามารถปล่อยธงนี้

  • -- แยกตัวเลือกสาขาตัวกรองออกจากตัวเลือกการแก้ไข

  • --allจะทำให้แน่ใจว่าสาขาและแท็กทั้งหมดถูกเขียนใหม่

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

สมมติว่าคุณต้องการกู้คืนต้นแบบของคุณและเข้าถึงในสาขาold_master:

git checkout -b old_master refs/original/refs/heads/master

3
คำตอบนี้ไม่ได้ตอบคำถามของ OP เนื่องจากพวกเขาสนใจที่จะแก้ไขข้อผูกมัดที่พวกเขาเพิ่งทำไป ฉันใช้เป็นประจำgit commit --amendเพื่อแก้ไขความคิดเห็นหรือเพิ่มไฟล์ที่ฉันลืมgit addแต่เคยมีมาก่อนที่ฉันจะgit pushแก้ไข ฉันยังใช้git filter-branchเมื่อฉันต้องการยุ่งกับประวัติรุ่นโดยสิ้นเชิง แต่ OP ไม่ต้องการสิ่งนี้ดังนั้นคำตอบนี้จำเป็นต้องมีคำเตือนเรื่องสุขภาพ - อย่าลองทำที่บ้านดูสิ !!
kbro

226

ใช้

git commit --amend

เพื่อให้เข้าใจในรายละเอียดการโพสต์ที่ยอดเยี่ยม4. การเขียนใหม่ประวัติศาสตร์ นอกจากนี้ยังพูดถึงเกี่ยวกับเมื่อไม่ใช้งาน git commit --amend


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

2
ในคำ NOPE! ไม่มีวิธีที่ดีในการถอนสิ่งที่คุณผลัก การเพิกถอนทั้งหมดเป็น BAD ในระดับที่มากขึ้นหรือน้อยลง คุณต้องใช้ระเบียบวินัยในการทำงานในสาขาในพื้นที่เก็บข้อมูลส่วนตัวของคุณทำหลายกระทำในขณะที่คุณเพิ่มบิตทดสอบบิตปรับแต่งเล็กน้อย จากนั้นผสานทั้งสาขาของคุณไว้ในการคอมมิชชันเดียวเขียนข้อความการคอมมิทใหม่ที่อธิบายการเปลี่ยนแปลงโดยรวม PROOFREAD และกด
kbro

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

1
git commit --amendคำตอบที่ได้รับการกำหนด (หลายครั้ง) ก่อนที่คุณเขียนแสดงความนับถือ ทำไมคุณโพสต์อีกครั้ง หากคุณต้องการเพิ่มลิงค์ไปยัง "เขียนประวัติ Git ใหม่" คุณสามารถแก้ไขหนึ่งในคำตอบที่มีอยู่หรือออกความคิดเห็น
Dan Dascalescu

199

แก้ไข

คุณมีตัวเลือกสองทางที่นี่ คุณทำได้

git commit --amend

ตราบใดที่คุณยังเป็นคนสุดท้าย

rebase แบบโต้ตอบ

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

git rebase -i [branched_from] [hash before commit]

จากนั้นภายใน rebase เชิงโต้ตอบคุณเพียงแค่เพิ่มการแก้ไขในการกระทำนั้น เมื่อเกิดขึ้นให้ทำgit commit --amendและแก้ไขข้อความคอมมิท หากคุณต้องการย้อนกลับก่อนจุดส่งมอบคุณสามารถใช้git reflogและเพียงลบการส่งมอบ จากนั้นคุณทำgit commitอีกครั้ง


191

หากเป็นการกระทำครั้งสุดท้ายของคุณเพียงแก้ไขการกระทำ:

git commit --amend -o -m "New commit message"

(ใช้แฟล็ก-o( --only) เพื่อให้แน่ใจว่าคุณเปลี่ยนเฉพาะข้อความยืนยัน)


ถ้าเป็นการกระทำที่ถูกฝังอยู่ให้ใช้rebase เชิงโต้ตอบที่ยอดเยี่ยม :

git rebase -i @~9   # Show the last 9 commits in a text editor

ค้นหาการกระทำที่คุณต้องการเปลี่ยนpickเป็นr( reword) และบันทึกและปิดไฟล์ ทำ!



กวดวิชาขนาดเล็กจิ้ม (หรือวิธีการรีบูตด้วยการกดแป้นเพียง 8 ครั้ง3jcwrEscZZ):

  • ทำงานvimtutorหากคุณมีเวลา
  • hjkl สอดคล้องกับปุ่มการเคลื่อนไหว
  • คำสั่งทั้งหมดสามารถนำหน้าด้วย "ช่วง" เช่น3jเลื่อนลงสามบรรทัด
  • i เพื่อเข้าสู่โหมดแทรก - ข้อความที่คุณพิมพ์จะปรากฏในไฟล์
  • EscหรือCtrlcเพื่อออกจากโหมดแทรกและกลับสู่โหมด "ปกติ"
  • u เพื่อยกเลิก
  • Ctrlr เพื่อทำซ้ำ
  • dd, dw, dlลบบรรทัดคำหรือตัวอักษรตามลำดับ
  • cc, cw, clการเปลี่ยนแปลงบรรทัดคำหรือตัวอักษรตามลำดับ (เหมือนddi)
  • yy, yw, ylการคัดลอก ( "งัด") บรรทัดคำหรือตัวอักษรตามลำดับ
  • pหรือPเพื่อวางหลังหรือก่อนตำแหน่งปัจจุบันตามลำดับ
  • :wEnter เพื่อบันทึก (เขียน) ไฟล์
  • :q!Enter เพื่อเลิกโดยไม่บันทึก
  • :wqEnterหรือZZเพื่อบันทึกและออก

หากคุณแก้ไขข้อความจำนวนมากให้สลับไปที่รูปแบบแป้นพิมพ์ Dvorakเรียนรู้วิธีพิมพ์ด้วยสัมผัสและเรียนรู้ Vim มันคุ้มค่ากับความพยายามหรือไม่? ใช่.



ProTip ™: อย่ากลัวที่จะทดสอบด้วยคำสั่ง "อันตราย" ที่เขียนประวัติใหม่ * - Git จะไม่ลบการกระทำของคุณเป็นเวลา 90 วันโดยค่าเริ่มต้น คุณสามารถค้นหาได้ใน reflog:

$ git reset @~3   # Go back three commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* ระวังตัวเลือกเช่น--hardและ--force- พวกเขาสามารถทิ้งข้อมูล * นอกจากนี้อย่าเขียนประวัติในสาขาใด ๆ ที่คุณร่วมมือ


3
ส่วนที่เป็นกลุ่มนอกหัวข้อและแทนที่จะสนับสนุนให้ผู้ใช้ใช้เวลาเรียนรู้ที่จะใช้เครื่องมือแก้ไข arcane ทำไมไม่สอนอะไรเพิ่มเติมในหัวข้อเช่นวิธีการตั้งค่าเครื่องมือแก้ไข git เริ่มต้นให้เป็นสิ่งที่ใช้ง่ายเช่นnano? เรากำลังพูดถึงการดัดแปลงเล็กน้อยที่จำเป็นต้องทำกับไฟล์ข้อความไม่ใช่การเข้ารหัสฮาร์ดคอร์ที่จะสร้างสงครามลุกลี้เกี่ยวกับโปรแกรมแก้ไขข้อความ "ดีที่สุด"
Dan Dascalescu

1
@DanDascalescu: เพราะมันเร็วกว่าที่จะเรียนรู้ Vim โดยใช้คำแนะนำข้างต้นมากกว่าทำการรีบาวด์หลายครั้งโดยใช้ nano เหตุผลที่คอมไพล์ทั้งเปิดโปรแกรมแก้ไขข้อความและไม่อินเตอร์เฟซของตัวเองสำหรับ rebasing เป็นเพราะเป็นกลุ่มที่มีอยู่: มันมีน้ำหนักเบาติดตั้งโดยเริ่มต้นในระบบมากที่สุดและง่ายมากที่จะเรียนรู้พอที่จะดำเนิน rebase อย่างง่ายดาย: เช่นddjjpZZย้ายกระทำ 2 ลง ไม่มีอะไรที่เป็นความลับเกี่ยวกับความรู้ Vim พื้นฐาน ใช้เวลา 10 นาทีในการรู้สึกสะดวกสบายยิ่งขึ้นเมื่อใช้ Vim มากกว่านาโน
Zaz

185

หากคุณใช้ Git GUI คุณสามารถแก้ไขการคอมมิทครั้งล่าสุดที่ยังไม่ได้กด:

Commit/Amend Last Commit

168

ฉันใช้Git GUIมากเท่าที่จะทำได้และนั่นทำให้คุณมีตัวเลือกในการแก้ไขการส่งมอบครั้งล่าสุด:

ทำเครื่องหมายในช่องนั้น

นอกจากนี้ยังgit rebase -i origin/masterเป็นมนต์ที่ดีที่จะนำเสนอคุณเสมอกับการกระทำที่คุณได้ทำไว้ด้านบนของต้นแบบและให้คุณเลือกที่จะแก้ไขลบเรียงลำดับหรือสควอช ไม่จำเป็นต้องถือแฮชนั้นก่อน


4
ฉันจะไปที่หน้าจอที่คุณแสดงในตัวอย่างได้อย่างไร
Marwan مروان

2
เป็นส่วนล่างขวาของ Windows Git Gui เพียงเลือกการสลับ 'แก้ไขคำมั่นสัญญาสุดท้าย' และมันจะเติมข้อมูลการคอมมิทล่าสุด
wbdarby

138

ว้าวดังนั้นมีหลายวิธีในการทำเช่นนี้

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

git reset --soft HEAD~1
git commit -m 'New and corrected commit message'

ฉันมักจะทำสิ่งนี้ถ้าฉันลืมเพิ่มไฟล์หรือทำการเปลี่ยนแปลง

จำไว้ว่าให้ระบุ--softแทน--hardมิฉะนั้นคุณจะเสียความมุ่งมั่นทั้งหมดไป


5
สิ่งนี้ทำสิ่งเดียวกันแน่นอนgit commit --amendยกเว้นว่าเป็นกระบวนการ 2 ขั้นตอน
Joseph K. Strauss

3
@ JosephK.Strauss ฉันเชื่อว่าการทำลายการกระทำยังคงเก็บข้อมูลผู้แต่งและวันที่ดั้งเดิมไว้โดยแยกข้อมูล commiter และ date ใหม่ออกจากกัน ฉันไม่แน่ใจว่าวิธีการนี้จะทำเช่นนั้น
Everton

4
@EvertonAgner คุณถูกต้อง --amendจะเก็บข้อมูลผู้แต่ง แต่คำถามเพียงขอให้เปลี่ยนข้อความ
Joseph K. Strauss

131

สำหรับใครที่กำลังมองหาที่ใช้ Windows / Mac GUI เพื่อความช่วยเหลือเกี่ยวกับการแก้ไขข้อความที่เก่า (คือไม่ได้เป็นเพียงข้อความล่าสุด) ผมอยากแนะนำให้Sourcetree ขั้นตอนในการติดตามมีดังนี้

การรีบูตแบบโต้ตอบ Sourcetree

สำหรับการคอมมิทที่ยังไม่ได้ถูกส่งไปยังรีโมต:

  1. ตรวจสอบให้แน่ใจว่าคุณได้ยืนยันหรือทำให้การเปลี่ยนแปลงปัจจุบันทั้งหมด (เช่นไม่มีไฟล์ที่แสดงในแท็บ "สถานะไฟล์") - มันจะไม่ทำงาน
  2. ในแท็บ "บันทึก / ประวัติ" คลิกขวาที่รายการที่มีบรรทัดที่อยู่ติดกันในกราฟด้านล่างรายการที่คุณต้องการแก้ไขและเลือก "Rebase children of <commit ref>แบบโต้ตอบ ... "
  3. เลือกแถวทั้งหมดสำหรับการกระทำข้อความที่คุณต้องการที่จะเปลี่ยนแปลง(คลิกที่ปุ่ม "ข้อความ" คอลัมน์)
  4. คลิกปุ่ม "แก้ไขข้อความ"
  5. OKแก้ไขข้อความตามที่ต้องการในกล่องโต้ตอบที่ขึ้นมาแล้วคลิก
  6. ทำซ้ำขั้นตอนที่ 3-4 หากมีข้อความยืนยันการเปลี่ยนแปลงอื่น ๆ
  7. คลิกOK: การรีบูตจะเริ่มขึ้น ถ้าทั้งหมดเป็นอย่างดีเอาท์พุทจะสิ้นสุด "เสร็จสมบูรณ์แล้ว" หมายเหตุ:บางครั้งฉันเคยเห็นสิ่งนี้ล้มเหลวUnable to create 'project_path/.git/index.lock': File exists.เมื่อพยายามแก้ไขข้อความยืนยันหลายข้อความพร้อมกัน ไม่แน่ใจว่าสิ่งที่เป็นปัญหาหรือไม่ว่าจะได้รับการแก้ไขใน Sourcetree รุ่นในอนาคต แต่ถ้าเกิดเหตุการณ์นี้ขอแนะนำให้ทำการรีบูตทีละครั้ง (ช้ากว่า แต่น่าเชื่อถือกว่า)

... หรือ ... สำหรับการกระทำที่ถูกผลักไปแล้ว:

ทำตามขั้นตอนในคำตอบนี้ซึ่งคล้ายกับด้านบน แต่ต้องการคำสั่งเพิ่มเติมที่จะเรียกใช้จากบรรทัดคำสั่ง ( git push origin <branch> -f) เพื่อบังคับให้ดันสาขา ฉันขอแนะนำให้อ่านทั้งหมดและใช้ความระมัดระวังที่จำเป็น!


จากคำตอบทั้งหมด - นี่คือสิ่งที่เหมาะสมที่สุดสำหรับมือใหม่ทั้งหมดคอมไพล์ ^^^ (ใช้โปรแกรมฟรี SourceTree และใช้ "Rebase children of" ในการส่งก่อนที่คุณต้องการแก้ไข)
รู้สึก

127

หากคุณต้องการแก้ไขการคอมมิชชันล่าสุดให้ใช้:

git commit --amend

หรือ

git commit --amend -m 'one line message'

แต่ถ้าคุณต้องการแก้ไขหลายคอมมิทในแถวคุณควรใช้การรีบูตแทน:

git rebase -i <hash of one commit before the wrong commit>

Git rebase edit

ในไฟล์เช่นเดียวกับข้างบนเขียนedit/eหรือหนึ่งในตัวเลือกอื่น ๆ แล้วกดบันทึกและออก

ตอนนี้คุณจะผิดที่กระทำครั้งแรก ทำการเปลี่ยนแปลงในไฟล์และพวกเขาจะถูกจัดฉากให้คุณโดยอัตโนมัติ ชนิด

git commit --amend

บันทึกและออกจากนั้นและพิมพ์

git rebase --continue

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

โปรดทราบว่าสิ่งเหล่านี้เปลี่ยนแฮช SHA ของคุณทั้งหมดหลังจากการคอมมิทนั้น


2
git rebase -i <hash of one commit ก่อนการกระทำผิด> ทำงานให้ฉัน ขอบคุณ
Viraths

127

หากคุณต้องการเปลี่ยนข้อความล่าสุดคุณควรใช้การ--onlyตั้งค่าสถานะหรือทางลัด-oด้วยcommit --amend:

git commit --amend -o -m "New commit message"

สิ่งนี้ช่วยให้มั่นใจได้ว่าคุณจะไม่เพิ่มความมุ่งมั่นกับสิ่งที่จัดฉาก แน่นอนว่าควรมีการ$EDITORกำหนดค่าที่เหมาะสม จากนั้นคุณสามารถปล่อยให้-mตัวเลือกออกมาและ Git จะเติมข้อความกระทำการไว้ล่วงหน้าด้วยข้อความเก่า ด้วยวิธีนี้สามารถแก้ไขได้ง่าย


1
คำตอบ "ด้านบน" ไม่ตอบคำถาม git commit --amendมันก็จะช่วยให้การแนะนำทั่วไป คำถามนั้นเจาะจงมากดังนั้นอีกต่อไป! = ดีกว่า การเอ่ยถึงการแตกหักของ-oธงอาจจะถูกฝังอยู่ในข้อมูลที่เหลือ ฉันยังไม่สบายใจที่จะแก้ไขคำตอบที่มีคะแนนโหวตจำนวนมากอยู่แล้ว
David Ongaro

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

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

1
เพื่อความเป็นธรรม: ถึงแม้ว่า--onlyตัวเลือก--amendจะพร้อมใช้งานตั้งแต่ git 1.3.0 แต่ก็ไม่ทำงานอย่างถูกต้องจนกว่าจะได้รับการแก้ไขใน 1.7.11.3 ( ea2d4ed35902ce15959965ab86d80527731a177c ) ดังนั้นคำตอบกลับมาทางขวาในปี 2008 git stash; git commit --amend; git stash popอาจจะได้รับสิ่งที่ต้องการ:
David Ongaro

103

อัปเดตข้อความการส่งข้อความผิดครั้งล่าสุดด้วยข้อความการส่งข้อความใหม่ในบรรทัดเดียว:

git commit --amend -m "your new commit message"

หรือลองรีเซ็ต Git เหมือนด้านล่าง:

# You can reset your head to n number of commit
# NOT a good idea for changing last commit message,
# but you can get an idea to split commit into multiple commits
git reset --soft HEAD^

# It will reset you last commit. Now, you
# can re-commit it with new commit message.

การใช้การตั้งค่าใหม่เพื่อแบ่งการกระทำเป็นการกระทำที่เล็กลง

git reset สามารถช่วยคุณแบ่งข้อผูกพันออกเป็นหลายข้อผูกพันเช่นกัน:

# Reset your head. I am resetting to last commits:
git reset --soft HEAD^
# (You can reset multiple commit by doing HEAD~2(no. of commits)

# Now, reset your head for splitting it to multiple commits
git reset HEAD

# Add and commit your files separately to make multiple commits: e.g
git add app/
git commit -m "add all files in app directory"

git add config/
git commit -m "add all files in config directory"

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


3
หากสิ่งที่คุณต้องการทำคือแก้ไขข้อความการส่งข้อความครั้งล่าสุดของคุณการใช้ซอฟต์รีเซ็ตสำหรับวัตถุประสงค์นั้นคือการฆ่ามากกว่า เพียงแค่ใช้git commit --amend, เหมือนวิธีการที่จะกล่าวว่าในด้านบนลงมติคำตอบ นอกจากนี้ยังgit reset --soft HEAD^ทำงานเหมือนกันกับการรีเซ็ตแบบซอฟต์ในคำตอบก่อนหน้านี้เพราะทั้งคู่รีเซ็ตกลับไปเป็นพาเรนต์แรกที่คอมมิท

3
ฉันรำคาญที่จะเพิ่มgit resetในการแก้ปัญหาเพียงเพื่อให้ความคิดในการแยกข้อความคอมมิชชันหนึ่งออกเป็นข้อความการคอมมิตหลายข้อความ gitเพราะผมได้ประสบปัญหาว่าเมื่อผมได้เริ่มต้นที่จะใช้ บางครั้งสิ่งนี้สามารถช่วยได้จริงๆ :)
przbadu

87

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

ฉันต้องการเปลี่ยนห้าข้อผูกพันล่าสุดที่ฉันผลักไปยังเซิร์ฟเวอร์แล้ว สิ่งนี้ค่อนข้าง 'อันตราย' เพราะถ้ามีคนอื่นดึงคุณออกไปจากสิ่งนี้คุณสามารถทำสิ่งต่าง ๆ โดยการเปลี่ยนข้อความการส่งข้อความ อย่างไรก็ตามเมื่อคุณทำงานในสาขาเล็ก ๆ ของคุณและแน่ใจว่าไม่มีใครดึงมันมาได้คุณสามารถเปลี่ยนได้ดังนี้:

สมมติว่าคุณต้องการเปลี่ยนการกระทำล่าสุดห้ารายการจากนั้นคุณพิมพ์สิ่งนี้ในเทอร์มินัล:

git rebase -i HEAD~5

* โดยที่ 5 คือจำนวนข้อความการส่งที่คุณต้องการเปลี่ยน (ดังนั้นหากคุณต้องการเปลี่ยนการส่งข้อความที่ 10 เป็นครั้งสุดท้ายให้พิมพ์ 10)

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

pick <commit hash> commit message

แทนการที่คุณจำเป็นต้องเขียนpick คุณสามารถทำเช่นนี้ในกลุ่มโดยการพิมพ์ในreword iนั่นทำให้คุณเข้าสู่โหมดแทรก (คุณเห็นว่าคุณอยู่ในโหมดแทรกโดยใช้คำว่าINSERTที่ด้านล่าง) สำหรับคอมมิทที่คุณต้องการเปลี่ยนให้พิมพ์rewordแทนpickแทน

จากนั้นคุณต้องบันทึกและออกจากหน้าจอนี้ คุณทำได้โดยไปที่ 'โหมดคำสั่ง' โดยกดEscปุ่ม (คุณสามารถตรวจสอบว่าคุณอยู่ในโหมดคำสั่งหากคำว่าINSERTที่ด้านล่างหายไป) :จากนั้นคุณสามารถพิมพ์คำสั่งโดยการพิมพ์ wqคำสั่งในการบันทึกและออกจากการมี ดังนั้นหากคุณพิมพ์:wqคุณอยู่ในเส้นทางที่ถูกต้อง

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

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

ตอนนี้คุณเปลี่ยนข้อความคอมมิตของคุณแล้ว!

(อย่างที่คุณเห็นฉันไม่ได้มีประสบการณ์ใน Vim ดังนั้นถ้าฉันใช้ 'lingo' ผิดเพื่ออธิบายสิ่งที่เกิดขึ้นรู้สึกฟรีเพื่อแก้ไขฉัน!)


4
<nitpick>ไม่มี "กระทู้" ใน Stack Overflow เนื่องจากไม่ใช่กระดานสนทนามีเพียง "คำถาม", "คำตอบ" และ "โพสต์" </nitpick>. นอกจากนี้เวอร์ชันทั้งหมดของ Vim จะไม่เหมือนกันไม่ใช่ทั้งหมดที่จะให้คุณลบตัวอักษรในโหมดแทรก (เข้าท่าใช่ไหม?) หากคุณต้องการที่จะสามารถลบตัวอักษรในกลุ่มXและxจะทำเช่นนั้น ( xลบตัวอักษรเล็ก ๆ ที่ด้านหน้าของเคอร์เซอร์Xจะลบด้านหลัง) หากคุณทำผิดพลาดคุณสามารถใช้uซ้ำ ๆ เพื่อเลิกทำ ในที่สุดrก็มีการจดชวเลขrewordในตัวแก้ไขการปฏิเสธแบบโต้ตอบ

1
หากต้องการเปลี่ยนคำเป็นกลุ่มจะcwพิมพ์ที่จุดเริ่มต้น (แม้ว่าคำถามจะไม่เกี่ยวกับกลุ่มฉันเห็นด้วย)
Yaroslav Nikitenko

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

79

คุณสามารถใช้git-rebase-reword

มันถูกออกแบบมาเพื่อแก้ไขการกระทำใด ๆ (ไม่ใช่แค่ครั้งสุดท้าย) เช่นเดียวกับ commit --amend

$ git rebase-reword <commit-or-refname>

มันตั้งชื่อตามการกระทำบน rebase แบบโต้ตอบเพื่อแก้ไขการกระทำ: "reword" ดูโพสต์นี้และโหมดโต้ตอบแบบมนุษย์ - ส่วน -

ตัวอย่าง:

$ git rebase-reword b68f560
$ git rebase-reword HEAD^

6
ต้องมีการติดตั้งโปรแกรมภายนอก ในความคิดของฉันมันจะเป็นการดีกว่าที่จะเรียนรู้การใช้เครื่องมือและนามแฝงในตัวได้อย่างมีประสิทธิภาพยิ่งขึ้น ฉันจะพิมพ์: g c; g rb -i @~9(commit และ rebase) ย้ายคอมมิทใหม่ไปยังตำแหน่งที่ฉันต้องการเปลี่ยนcommitเป็นf( fixup) และบันทึก หากคุณต้องการบางสิ่งที่เร็วกว่านั้นคุณสามารถใช้นามแฝงได้ git commit --fixup=<commit>; git rebase -i --autosquash <commit>^
Zaz

79

ฉันได้เพิ่มนามแฝงreciและrecmสำหรับrecommit (amend)มัน ตอนนี้ฉันสามารถทำได้ด้วยgit recmหรือgit recm -m:

$ vim ~/.gitconfig

[alias]

    ......
    cm = commit
    reci = commit --amend
    recm = commit --amend
    ......

57

ฉันรู้ว่าฉันผลักความมุ่งมั่นด้วยการพิมพ์ผิดในนั้น เพื่อที่จะเลิกทำฉันทำสิ่งต่อไปนี้:

git commit --amend -m "T-1000, advanced prototype"
git push --force

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


7
ไม่มีอะไรที่เคย "เขียนทับ" ในคอมไพล์ ในกรณีนี้ตัวชี้แบรนช์จะถูกตั้งค่าเป็นคอมมิชชันใหม่ของคุณและคอมมิชชันเก่าจะได้รับการอัปเดตหากไม่มีการอ้างอิงที่เหลืออยู่ (จนกว่าจะถึงตอนนั้นคนอื่น ๆ ยังสามารถค้นหาและอ้างอิงได้เช่นโดยดูที่การอ้างอิง)
David Ongaro

51

ฉันชอบที่จะใช้ต่อไปนี้:

  1. git status
  2. git add --all
  3. git commit -am "message goes here about the change"
  4. git pull <origin master>
  5. git push <origin master>

46

หากคุณยังไม่ได้ส่งรหัสไปยังสาขาระยะไกลของคุณ ( GitHub / Bitbucket ) คุณสามารถเปลี่ยนข้อความยืนยันในบรรทัดคำสั่งดังต่อไปนี้

 git commit --amend -m "Your new message"

หากคุณกำลังทำงานในสาขาเฉพาะทำเช่นนี้:

git commit --amend -m "BRANCH-NAME: new message"

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

โปรดอ่านคำตอบทั้งหมดของฉันก่อนที่จะทำ

git commit --amend -m "BRANCH-NAME : your new message"

git push -f origin BRANCH-NAME                # Not a best practice. Read below why?

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

 git commit --amend -m "BRANCH-NAME : your new message"
 git pull origin BRANCH-NAME
 git push -f origin BRANCH-NAME

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

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