git: ยกเลิกการคอมมิตในขณะที่พิมพ์ข้อความ


131

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

คำตอบ:


85

ใช่. เขียนข้อความคอมมิทไปที่ไฟล์อื่น ( :w /some/other/path.txt) จากนั้นออกจากเครื่องมือแก้ไขโดยไม่บันทึก ( :q!) หากก่อนหน้านี้คุณบันทึกไฟล์ไปที่พา ธ ดั้งเดิมให้ลบทุกอย่างแล้วเขียนไฟล์เปล่าก่อน (ข้อความยืนยันว่างจะยกเลิกการส่ง)

ตอนนี้เมื่อคุณพร้อมที่จะส่ง "for reals" ให้ใช้ไฟล์ข้อความที่คุณบันทึกไว้ที่เส้นทางอื่น

อีกทางหนึ่งคัดลอกข้อความการคอมมิตลงในบัฟเฟอร์ของกลุ่ม

เป็นเรื่องที่น่าสังเกตว่าคุณไม่จำเป็นต้องทำสิ่งนี้เลย : commit --amendช่วยให้คุณแก้ไขการกระทำหลังจากที่ทำไปแล้วดังนั้นวิธีแก้ปัญหาที่ง่ายคือการสร้างคำสั่งด้วยสิ่งที่คุณได้รับแล้วแก้ไขก่อนผลักดัน คุณสามารถทำคอมมิทให้เสร็จสิ้นในสถานะที่เสียreset HEAD~(รีเซ็ตคุณเป็นสถานะสำเนาการทำงานของคุณก่อนคอมมิท) แก้ไขสำเนาการทำงานของคุณจากนั้นcommit -a -c HEAD@{1}ใช้ข้อความคอมมิทเก่า


7
หมายเหตุ: การออกเป็นกลุ่มโดยใช้ ": q!" จะไม่ยกเลิกการคอมมิชชันถ้ามีข้อความความขัดแย้งที่ผสานอัตโนมัติ แต่การส่งข้อความจะดำเนินการต่อและข้อความจะไม่แสดงรายการไฟล์ที่มีข้อขัดแย้ง
stephenbez

write the empty file (an empty commit message will abort the commit)ส่วนหนึ่งทำงานเหมือนมีเสน่ห์ขอบคุณ!
СашаДавиденко

182

หากโปรแกรมแก้ไขของคุณสามารถออกจากพร้อมรหัสข้อผิดพลาด - Git จะยกเลิกการส่งข้อมูล เมื่อใช้ VIM ให้พิมพ์

:cq

เพื่อออกด้วยรหัสข้อผิดพลาดที่ไม่เป็นศูนย์และยกเลิกการกระทำ


5
นี่คือเคล็ดลับที่ดีสำหรับการแท้งที่เป็นคุณมิฉะนั้นจะต้องลบที่มีอยู่ในการกระทำและข้อความcommit --amend :wq
Alex Jasmin

2
เคล็ดลับดี! อย่างไรก็ตามคำถามคือวิธีบันทึกข้อความยืนยันไม่ใช่ลบทิ้ง
เอลียาห์ลินน์

ดังนั้น svn จัดการทำเช่นนี้ได้อย่างไร มันดูอะไรนอกจากรหัสออก?
Chaim Geretz

1
ยอดเยี่ยมเมื่อคุณกำลังทำการ
รีบูต

ช่วยชีวิตฉันเมื่อฉันทำgit commit --amendแทนgit rebase --continueในช่วง rebase
Weishi Zeng

68

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

Aborting commit due to empty commit message.

11
สิ่งนี้มีประโยชน์อย่างยิ่งเมื่อคุณต้องการยกเลิกการคอมไพล์คอมไพล์ - แก้ไข
edsko

1
คำถามคือวิธีการยกเลิกการกระทำ แต่บันทึกข้อความการกระทำ การลบบรรทัดที่ไม่ขึ้นต้นด้วย # ลบข้อความยอมรับอย่างมีประสิทธิภาพไม่บันทึกข้อความยืนยัน ไม่แน่ใจว่าสิ่งนี้มี upvotes มากมาย
Elijah Lynn

2
ggdGจะตัดเนื้อหาทั้งหมดของข้อความจากนั้นในครั้งต่อไปที่คุณเรียกใช้vimคุณสามารถเพียงแค่Pข้อความที่คุณตัดก่อนหน้านี้
oromoiluig

ทำงานโดยใช้นาโน ctrl + k ทุกบรรทัดจากนั้นบันทึกและออกจะยกเลิก
Juh_

9

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


7

ใช่มันเป็นไปได้ เพื่อคอมมิชชันเอดิเตอร์ของคุณต้องเขียนข้อความคอมมิทไปยังไฟล์.git/COMMIT_EDITMSGและออกด้วยรหัสสถานะ 0

ดังนั้นหากคุณใช้ VI / VIM คุณอาจต้องการทำสิ่งต่อไปนี้ ...

  1. เขียนข้อความกระทำของคุณ
  2. บันทึกข้อความยืนยันด้วย:w(โดยค่าเริ่มต้นระบบจะบันทึกเนื้อหาปัจจุบันไว้.git/COMMIT_EDITMSG)
  3. ออกจากตัวแก้ไขด้วยข้อผิดพลาด :cq
  4. ... ทำในสิ่งที่คุณต้องทำ ... แม้แต่เพิ่ม / ลบไฟล์ไปยังพื้นที่จัดเตรียม
  5. ดำเนินการต่อด้วยการแก้ไขข้อความกระทำที่มีอยู่ของคุณด้วย git commit -eF .git/COMMIT_MESSAGE

-F /path/to/fileจะเติมบรรณาธิการที่มีเนื้อหาใด ๆ ที่ได้รับจากเส้นทาง / / เพื่อ / ไฟล์ อย่างไรก็ตามโดยค่าเริ่มต้นนี้ได้ทันทีจะดำเนินการกระทำเว้นแต่คุณจะให้-eธงนอกจากนี้สำหรับการแก้ไข


ใช้งานได้ แต่จะดีกว่าเพราะ 1) ถือว่าฉันเป็น CWD ที่โฟลเดอร์. git คือ 2) ฉันใช้git worktreesและ git worktrees, .git เป็นไฟล์ที่บอกว่าโฟลเดอร์. git แท้จริงอยู่ที่ไหน
Alexander Bird

@AlexanderBird สิ่งนี้ไม่เป็นความจริง ... เมื่อคุณต้องการรับข่าวสารการส่งข้อความเก่าในขั้นตอนที่ 5) คุณเพียงแค่ต้องระบุเส้นทางสัมพัทธ์ (บอกว่าคุณอยู่ใน/foo/bar/ไดเรกทอรีโดยอ้างอิงจากโครงการราก)git commit -eF ../../.git/COMMIT_MESSAGE
Rudolf Tucek

@AlexanderBird เจ๋งยังไม่ได้สังเกตด้วยคุณสมบัติของต้นไม้ทำงานหลายชนิดในคอมไพล์ ขอบคุณสำหรับคำใบ้! ฉันเชื่อว่าข้อเสียเพียงอย่างเดียวคือคุณต้องเก็บภาพรวมทั่วไปไว้ในหัวซึ่งจะป้องกันไม่ให้คุณมุ่งเน้นไปที่รหัสจริง และเพียงแค่สำหรับการเก็บค่ากระทำข้อความที่ "ที่ฉันได้ทิ้ง off` มันเป็นบิตหนัก :)
รูดอล์ฟ Tucek

1
@AlexanderBird แล้วแทนที่จะ:wทำ:sav committmpและgit commit -eF committmp
Hashbrown

0

ฉันมักจะทำให้ฉันมุ่งมั่นภายในการIntelliJใช้อาคารที่จัดไว้ให้ น่าเสียดายที่ความมุ่งมั่นของฉันเป็นคู่มือ:

git commit -m'my message' // etc

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


-2

@bdonlan คำตอบนั้นดีสำหรับคำถามนี้ แต่ฉันจะชี้ให้เห็นถึงสถานการณ์ที่คุณอาจต้องการทางออกที่ดีกว่า

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

git add files
git commit --amend

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

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

Aborting commit due to empty commit message.

และคุณยังไม่ได้เปลี่ยนการกระทำสุดท้ายเลย


ถ้าฉันเข้าใจสิ่งที่คุณกำลังพูดว่าเป็นปัญหาแสดงว่าคุณไม่ถูกต้อง ดังที่แสดงไว้ที่นี่: git commit; vim ....; git commit --amend; git reset HEAD@{1}. นั่นคือ: ถ้าฉันต้องการที่จะ "เลิกทำ" การแก้ไขแล้วฉันไม่ต้องแยกการกระทำก่อนหน้านี้ HEAD@{1}กระทำวัตถุซึ่งเป็นหัวก่อนที่จะมีการแก้ไขจะถูกบันทึกเป็น นอกจากนี้ zetta ยังแนะนำให้ลบบรรทัดที่ไม่ใช่ความคิดเห็นทั้งหมด
Alexander Bird
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.