เลิกทำไฟล์ที่ถูกลบในคอมไพล์


504

โดยปกติแล้วหากต้องการยกเลิกการเปลี่ยนแปลงไฟล์ที่คุณต้องทำ:

git checkout -- <file>

จะทำอย่างไรถ้าการเปลี่ยนแปลงที่ฉันต้องการจะยกเลิกคือการลบไฟล์? บรรทัดข้างต้นจะทำให้เกิดข้อผิดพลาด:

error: pathspec '<file>' did not match any file(s) known to git.

คำสั่งใดจะคืนค่าไฟล์เดี่ยวนั้นโดยไม่ยกเลิกการเปลี่ยนแปลงอื่น ๆ

จุดโบนัส:นอกจากนี้จะเกิดอะไรขึ้นถ้าการเปลี่ยนแปลงที่ฉันต้องการจะยกเลิกคือการเพิ่มไฟล์? ฉันต้องการทราบวิธีการเปลี่ยนสถานะที่ไม่เปลี่ยนแปลงเช่นกัน


1
การละทิ้งการเปลี่ยนแปลงและการไม่แสดงตนเป็นสองสิ่งที่แตกต่างกันคุณพยายามทำอะไร
แอนดรูมาร์แชลล์

1
นี่เป็นสองคำถามและปัญหาที่แตกต่างกันในการโพสต์เดียว ทำให้คำตอบมากเกินไปและทำให้สับสนโดยไม่จำเป็น
David Sopko

คำตอบ:


779

สมมติว่าคุณต้องการยกเลิกผลกระทบของgit rm <file>หรือrm <file>ตามด้วยgit add -Aหรือสิ่งที่คล้ายกัน:

# this restores the file status in the index
git reset -- <file>
# then check out a copy from the index
git checkout -- <file>

หากต้องการยกเลิกgit add <file>บรรทัดแรกเหนือพอเพียงสมมติว่าคุณยังไม่ได้ยืนยัน


70
--เป็นกุญแจสำคัญ git reset <file>ไม่ทำงานซึ่งเป็นสิ่งที่ทำให้ฉันมาที่นี่

2
เหตุใดจึงend-of-options-markerต้องใช้ในกรณีของไฟล์ที่ถูกลบเท่านั้น
haridsv

5
@handsv ไม่จำเป็นอย่างเคร่งครัด (คุณสามารถทำสลับกันได้git reset HEAD <file>ซึ่งเทียบเท่า) แต่git resetถือว่าอาร์กิวเมนต์แรกend-of-options-markerเป็นชื่ออ้างอิงไม่ใช่ชื่อไฟล์ มันสามารถเขียนได้ยืดหยุ่นขึ้นอีกเล็กน้อย? อาจ. ทำไมไม่เป็นเช่นนั้น? อาจเป็นเพียงนักพัฒนาเท่านั้นที่รู้แน่
twalberg

2
@twalberg git reset filenameทำงานได้ดีสำหรับไฟล์ที่ไม่ถูกลบ
Brian Gordon

1
@AaronMahan - คุณสามารถกรุณาอธิบายความแตกต่างระหว่างและgit reset <file> git reset -- <file>ฉันมีเวลายากที่จะหาคำตอบสำหรับสิ่งนั้นบน google
Neeraj B.

56

git statusทั้งสองคำถามมีคำตอบใน

หากต้องการยกเลิกการเพิ่มการใช้ไฟล์ใหม่ git rm --cached filename.ext

# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   test

หากต้องการยกเลิกการลบการใช้ไฟล์ git reset HEAD filename.ext

# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    test

ในอีกทางหนึ่งgit checkout --ไม่เคยหยุดนิ่ง แต่จะทิ้งการเปลี่ยนแปลงที่ไม่มีการจัดฉาก


5
ฉันไม่เห็นคำแนะนำสำหรับไฟล์ที่ถูกลบใน git 1.7.2.5 ใน Debian
tripleee

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

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

11

คำตอบสำหรับคำถามสองข้อของคุณเกี่ยวข้องกัน ฉันจะเริ่มด้วยวินาที:

เมื่อคุณได้ฉากไฟล์ (มักจะมีgit addแต่บางคำสั่งอื่น ๆ โดยปริยายเวทีการเปลี่ยนแปลงด้วยเช่นgit rm) git reset -- <file>คุณสามารถสำรองออกจากการเปลี่ยนแปลงที่ว่าด้วย

ในกรณีของคุณคุณต้องใช้git rmในการลบไฟล์ซึ่งเทียบเท่ากับการลบไฟล์ด้วยrmการเตรียมการเปลี่ยนแปลงนั้น หากคุณเป็นครั้งแรก unstage มันด้วยแล้วคุณสามารถกู้คืนได้ด้วยgit reset -- <file>git checkout -- <file>


7

หากมีการจัดฉากและยืนยันแล้วข้อมูลต่อไปนี้จะรีเซ็ตไฟล์:

git reset COMMIT_HASH file_path
git checkout COMMIT_HASH file_path
git add file_path

วิธีนี้จะใช้งานได้สำหรับการลบที่เกิดขึ้นหลายครั้งก่อนหน้านี้


1
มันมีประสิทธิภาพมากกว่าในการgit revert COMMIT_HASH
Flair

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