วิธียกเลิกการคอมมิชต์ un-push ล่าสุดกระทำโดยไม่สูญเสียการเปลี่ยนแปลง


539

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

สิ่งนี้ไม่ได้ถูกผลักเพียง แต่มุ่งมั่น



6
git reset --softและgit reset --mixedทั้งสองจะทำเช่นนี้ (แตกต่างกันเล็กน้อย) ดูคอมไพล์รีเซ็ต
torek

คำตอบ:


930

มีหลายวิธีที่จะทำเช่น:

ในกรณีที่คุณยังไม่ได้ส่งคำมั่นสัญญาต่อสาธารณะ:

git reset HEAD~1 --soft   

เพียงเท่านี้การเปลี่ยนแปลงการส่งมอบของคุณจะอยู่ในไดเรกทอรีการทำงานของคุณในขณะที่การส่งมอบครั้งล่าสุดจะถูกลบออกจากสาขาปัจจุบันของคุณ ดูgit reset man


ในกรณีที่คุณทำแบบสาธารณะ (ในสาขาที่เรียกว่า 'ต้นแบบ'):

git checkout -b MyCommit //save your commit in a separate branch just in case (so you don't have to dig it from reflog in case you screw up :) )

ย้อนกลับกระทำตามปกติและผลักดัน

git checkout master
git revert a8172f36 #hash of the commit you want to destroy
# this introduces a new commit (say, it's hash is 86b48ba) which removes changes, introduced in the commit in question (but those changes are still visible in the history)
git push origin master

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

git revert --no-commit 86b48ba (hash of the revert commit).

ฉันทำตัวอย่างเล็ก ๆ น้อย ๆ : https://github.com/Isantipov/git-revert/commits/master


5
ขอบคุณมากในกรณีของฉันฉันมีข้อผูกพันสองข้อที่ฉันต้องการยกเลิกและใช้งาน 'git reset HEAD ~ 1 - soft' สองครั้งติดต่อกันพาฉันไปที่ที่ฉันต้องการ
Geoff Gunter

2
เพื่อเพิ่มความชัดเจนเล็กน้อยหากคุณไม่ได้ใช้ CLI resetคำสั่งแรกที่กล่าวถึงคือการพูดว่า "เบา ๆ " รีเซ็ตเป็น 1 รอบก่อนหัวซึ่งจะรักษาการเปลี่ยนแปลงในท้องถิ่นทั้งหมด นี่ไม่ปรากฏให้ฉันเห็นได้ทันทีสำหรับใช้ใน SourceTree ตรวจสอบให้แน่ใจว่าคุณรีเซ็ตซอฟท์แวร์เป็นเวอร์ชั่นก่อนหน้าอย่างนุ่มนวลไม่ใช่เวอร์ชั่นที่คุณพยายามรีเซ็ต
Jon B

1
ฉันลองใช้วิธี "ผลักแล้ว" และมันไม่ทำงานสำหรับฉันด้วย git 2.14.1: มันบอกว่า"Already up to date"เมื่อทำการผสาน
Fabio A.

1
@FabioA ฉันได้อัปเดตคำตอบด้วยเวอร์ชันที่ใช้งานได้แล้ว ขอบคุณที่สังเกตสิ่งนี้!
Isantipov

1
มันใช้งานไม่ได้ ฉันข้ามการรีเซ็ตและคอมมิชชันและทำการ git ย้อนกลับและผลักออก ... ตอนนี้อาจมีการเปลี่ยนแปลงที่หายไปยังไม่แน่ใจ ... โชคดีที่ฉันทำสำรองข้อมูลด้วยวิธีที่ง่ายหวังว่าจะยังคงใช้งานได้;) มิฉะนั้นก็สามารถคัดลอกการเปลี่ยนแปลงจาก .
Skybuck บิน

13

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

git show HEAD > patch
git revert HEAD
git apply patch

มันจะสร้างไฟล์ปะแก้ที่มีการเปลี่ยนแปลงสาขาล่าสุด จากนั้นมันจะคืนค่าการเปลี่ยนแปลง และสุดท้ายใช้ไฟล์แพทช์กับแผนผังการทำงาน


คุณอาจต้องการrm patchเช่นกัน
Max Coplan

6

สำหรับกรณีนี้: "สิ่งนี้ยังไม่ได้ถูกผลักทำมุ่งมั่นเท่านั้น " - หากคุณใช้IntelliJ (หรือ JetBrains IDE อื่น) และคุณยังไม่ได้ผลักดันการเปลี่ยนแปลงคุณสามารถทำสิ่งต่อไปได้

  1. ไปที่หน้าต่างควบคุมเวอร์ชัน ( Alt + 9 / Command + 9 ) - แท็บ "Log"
  2. คลิกขวาที่การกระทำก่อนที่จะส่งครั้งสุดท้าย
  3. รีเซ็ตสาขาปัจจุบันไปที่นี่
  4. เลือกซอฟท์ (!!!)
  5. กดปุ่ม Reset ที่ด้านล่างของหน้าต่างข้อความ

เสร็จสิ้น

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


2
ฉันชอบเรียนรู้วิธี JetBrains ขอบคุณ! นั่นเทียบเท่ากับgit reset --soft "HEAD^"บน Windows btw :)
เพน

3

กับฉันส่วนใหญ่มันเกิดขึ้นเมื่อฉันผลักดันการเปลี่ยนแปลงไปยังสาขาที่ไม่ถูกต้องและตระหนักในภายหลัง และงานต่อไปนี้ส่วนใหญ่

git revert commit-hash
git push

git checkout my-other-branch
git revert revert-commit-hash
git push
  1. คืนความมุ่งมั่น
  2. (สร้างและ) ชำระเงินสาขาอื่น
  3. ย้อนกลับเปลี่ยนกลับ

1
ฉันทดสอบสิ่งนี้ วิธีการของคุณยังใช้งานได้หากคุณไม่ได้ส่งสัญญาณระยะไกล $ git revert <commit-hash> ... จากนั้นชำระเงินสาขาอื่นแล้วพิมพ์ $ git revert <revert-commit-hash> (โดยไม่มีการกด) ขอบคุณสำหรับการแบ่งปันวิธีการง่ายๆนี้ !!
Natalie Cottrill

1

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

git checkout branch_name

ชำระเงินที่สาขาของคุณ

git merge --abort

ยกเลิกการผสาน

สถานะคอมไพล์

ตรวจสอบสถานะของรหัสหลังจากยกเลิกการผสาน

รีเซ็ต git - ต้นกำเนิดยาก / branch_name

คำสั่งเหล่านี้จะรีเซ็ตการเปลี่ยนแปลงของคุณและจัดแนวรหัสของคุณด้วยรหัส branch_name (สาขา)


1

2563 วิธีง่าย ๆ :

git reset <commit_hash>

กระทำการแฮชของการส่งข้อมูลล่าสุดที่คุณต้องการ

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