ค้นหาและกู้คืนไฟล์ที่ถูกลบในที่เก็บ Git


2802

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

ฉันรู้ว่าฉันสามารถเช็คเอาต์ไฟล์โดยใช้git checkout HEAD^ foo.barแต่ฉันไม่รู้จริง ๆ ว่าไฟล์นั้นถูกลบเมื่อใด

  1. อะไรจะเป็นวิธีที่เร็วที่สุดในการค้นหาการกระทำที่ลบชื่อไฟล์ที่กำหนด?
  2. อะไรจะเป็นวิธีที่ง่ายที่สุดในการนำไฟล์นั้นกลับมาไว้ในสำเนาการทำงาน

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


39
ทราบว่าก่อนหน้านี้แสดงความคิดเห็นตอบคำถามในชื่อเรื่องไม่ได้อยู่ในร่างกาย - ที่มีการค้นหาออกเมื่อไฟล์ถูกลบ
avdgaag

8
ในการค้นหาการส่งไฟล์ถูกลบใน:git log --diff-filter=D -- path/to/file
titaniumdecoy



54
@hhh git checkout deletedFileจะยกเลิกการลบdeletedFileถ้ามันถูกลบ แต่ลบที่ยังไม่ได้รับการจัดฉากหรือความมุ่งมั่น นั่นไม่ใช่สิ่งที่คำถามนี้ถาม คำถามนี้เกี่ยวกับวิธีการกู้คืนไฟล์ที่มีการลบหลายคอมมิชชันไปแล้ว
Mark Amery

คำตอบ:


3150

ค้นหาการกระทำครั้งสุดท้ายที่ส่งผลกระทบต่อเส้นทางที่กำหนด เนื่องจากไฟล์ไม่ได้อยู่ใน HEAD commit การกระทำนี้จะต้องลบมันทิ้ง

git rev-list -n 1 HEAD -- <file_path>

จากนั้นชำระเงินรุ่นที่กระทำก่อนหน้านี้โดยใช้^สัญลักษณ์caret ( ):

git checkout <deleting_commit>^ -- <file_path>

หรือในคำสั่งเดียวถ้า$fileเป็นไฟล์ที่มีปัญหา

git checkout $(git rev-list -n 1 HEAD -- "$file")^ -- "$file"

หากคุณกำลังใช้ zsh และเปิดใช้งานตัวเลือก EXTENDED_GLOB สัญลักษณ์รูปหมวกจะไม่ทำงาน คุณสามารถใช้~1แทน

git checkout $(git rev-list -n 1 HEAD -- "$file")~1 -- "$file"

94
บิตที่ยุ่งยากคือการตรวจสอบการกระทำก่อนที่จะใช้ ^ คำต่อท้าย ขอบคุณ
Christian Oudard

4
ด้วยเหตุผลบางอย่างสิ่งนี้จะไม่ทำงานใน zsh ± git checkout $(git rev-list -n 1 HEAD "spec/Sporkfile_example.rb")^ -- "spec/Sporkfile_example.rb" zsh: no matches found: b71c152d8f38dcd23ad7600a93f261a7252c59e9^ ฉันเปลี่ยนมาใช้ทุบตีและมันก็ใช้ได้ดี
zoras

20
จากบรรทัดคำสั่งของ windows ฉันได้รับข้อผิดพลาด error: pathspec <filename> did not match any file(s) known to git.. การแก้ปัญหาคือการใช้ทุบตีคอมไพล์
donturner

56
@zoras zsh มีการขยายตัวของตนเองใน '^' ฉันเชื่อว่า แต่คุณสามารถใช้ไวยากรณ์ทางเลือกของ '~ 1': git checkout <deleting-commit>~1 -- <file-path> ~ X ช่วยให้คุณระบุ X การมอบหมายก่อนการมอบหมายที่ระบุดังนั้น ~ 1 เป็นการกระทำก่อนหน้า ~ 2 คือสองกระทำก่อนหน้า ฯลฯ
Nils Luxton

22
บน windows cmd prompt, ^ตัวละครเป็นตัวละครหนี! ดังนั้นบน cmd คุณต้องพิมพ์^^เพื่อบอก cmd ว่าคุณต้องการตัวอักษรตัวเดียว ^ และคุณไม่ต้องหลบหนีอย่างอื่นหลังจากนั้น สิ่งที่เกิดขึ้นกับหลาย ๆ คนก็คือการ^ตามมาด้วยการเว้นวรรค ดังนั้น cmd จึงคิดว่าคุณกำลังหลบหนีพื้นที่ - ซึ่งให้ตัวละครที่ว่างเปล่า ดังนั้นโดยคอมไพล์เวลาที่ได้รับการขัดแย้ง CLI ก็เห็นSHA1และไม่ได้ SHA1^มันน่ารำคาญจริงๆ ~ไม่ได้เป็นตัวละครหนีดังนั้นนั่นเป็นเหตุผลที่ยังคงทำงาน (ป.ล. ถ้าคุณคิดว่าชาว Google จะต้องการข้อมูลนี้โปรดโหวตความคิดเห็นนี้)
Alexander Bird

875
  1. ใช้git log --diff-filter=D --summaryเพื่อรับคอมมิชชันทั้งหมดที่มีการลบไฟล์และไฟล์ที่ถูกลบ
  2. ใช้git checkout $commit~1 path/to/file.extเพื่อเรียกคืนไฟล์ที่ถูกลบ

ที่ไหน$commitคือค่าของการกระทำที่คุณได้พบในขั้นตอนที่ 1 เช่นe4cf499627


10
อยากรู้อยากเห็น ~ 1 หมายถึงอะไร
tommy chheng

7
@tommy - ข้อมูลจำเพาะตัวหนอนจะให้หลานหลานคนที่ n ของการมอบสิทธิ์ที่มีชื่อ ดูbook.git-scm.com/4_git_treeishes.htmlสำหรับรายละเอียดเพิ่มเติม
Robert Munteanu

5
นี่เป็นวิธีที่ง่ายและใช้งานง่ายที่สุด git log -- *PartOfMyFileName*. ขอบคุณสำหรับ$commit~1
bgs

3
git checkout $commit~1 filenameไวยากรณ์การทำงานที่สมบูรณ์แบบสำหรับแต่ละไฟล์และยังสามารถใช้ได้กับทั้งไดเรกทอรี คือ: เพื่อเรียกคืนภาพลบทั้งหมดใน ./images จากหม่า git checkout 12345~1 images12345: ขอบคุณสำหรับคำตอบนี้!
noinput

34
@Alexar $commit~1หมายความว่าคุณควรเพิ่มชื่อของการส่ง สิ่งที่ต้องการ1d0c9ef6eb4e39488490543570c31c2ff594426cที่$commitเป็น
ยูจีน

319

ในการกู้คืนไฟล์ที่ถูกลบทั้งหมดในโฟลเดอร์ให้ป้อนคำสั่งต่อไปนี้

git ls-files -d | xargs git checkout --

1
ไฟล์จะถูกไพพ์ไปที่ใด? ฉันไม่เห็นการเปลี่ยนแปลง
William Grand

21
นี่อาจเป็นวิธีที่ง่ายที่สุด ในทางที่ผิดความยากลำบากgitทำให้ได้งานที่ง่ายที่สุด
jww

git checkout - [file] จะยกเลิกการเปลี่ยนแปลงใน [file] ไพพ์จะแทนที่ [ไฟล์] ด้วยชื่อของไฟล์ที่ถูกลบ
มนู

6
ls-filesคำสั่งย่อยเป็นประโยชน์ แต่ดูเหมือนจะไม่ทำงานสำหรับไฟล์ที่ได้รับการลบออกด้วยgit rmเช่นฉากให้อยู่คนเดียวมุ่งมั่นซึ่งเป็นสิ่งที่ OP ถาม
MarkHu

นี้ทำงานสำหรับการเรียกคืนไฟล์ที่ถูกลบ แต่วิธีการที่ฉันสามารถอัปเดตไฟล์ที่ที่เปลี่ยนแปลงและแสดงเป็น M myChangedFileหลังจากที่git checkout?
libby

124

ฉันมาถึงคำถามนี้ที่ต้องการกู้คืนไฟล์ที่ฉันเพิ่งลบ แต่ฉันยังไม่ได้ยืนยันการเปลี่ยนแปลง ในกรณีที่คุณพบว่าตัวเองอยู่ในสถานการณ์นี้สิ่งที่คุณต้องทำมีดังต่อไปนี้:

git checkout HEAD -- path/to/file.ext


93

git-bisectหากคุณเป็นคนบ้าใช้ นี่คือสิ่งที่ต้องทำ:

git bisect start
git bisect bad
git bisect good <some commit where you know the file existed>

ตอนนี้ถึงเวลาทำการทดสอบอัตโนมัติแล้ว คำสั่งเชลล์'[ -e foo.bar ]'จะส่งคืน 0 ถ้าfoo.barมีอยู่และ 1 เป็นอย่างอื่น คำสั่ง "run" git-bisectจะใช้การค้นหาแบบไบนารีเพื่อค้นหาการคอมมิทครั้งแรกโดยที่การทดสอบล้มเหลว มันเริ่มครึ่งทางผ่านช่วงที่กำหนด (จากดีไปจนถึงไม่ดี) และลดลงครึ่งหนึ่งตามผลการทดสอบที่ระบุ

git bisect run '[ -e foo.bar ]'

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

git bisect reset
git revert <the offending commit>

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

git checkout HEAD^
cp foo.bar /tmp
git bisect reset
cp /tmp/foo.bar .

2
คุณสามารถอธิบายรายละเอียดเกี่ยวกับgit bisect run '[ -e foo.bar ]'?
avdgaag

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

1
@avdgaag the git bisect runบอกให้ Git ทำการแบ่งคำแบบอัตโนมัติโดยการเรียกใช้คำสั่งต่อไปนี้คำว่า 'เรียกใช้' โดยที่คำสั่งนั้นต้องส่งคืน0สำหรับgoodเวอร์ชัน (ดูgit help bisectรายละเอียด) '[ -e foo.bar ]'คือการแสดงออกมาตรฐานสำหรับการทดสอบว่าไฟล์foo.barไม่อยู่ (การดำเนินการมักจะอยู่ในแฟ้ม/usr/bin/[ซึ่งมักจะ hardlinked ไป/usr/bin/test) และเครื่องหมาย quation เดียวจะใช้ในการวางว่าทั้งหมดเป็นอาร์กิวเมนต์บรรทัดคำสั่งเดียว
Mikko Rantalainen

ความคิดที่ดี. ฉันลองวิธีนี้แล้วระบุการกระทำก่อนที่จะลบ แต่ไม่ใช่การกระทำที่ลบไฟล์จริงๆ และในการทดสอบอื่นระบุว่า 2 คอมมิทก่อนการลบ
Michael Osofsky

บ้า? อาจจะ. แต่การแบ่งออกเป็นวิธีที่ยอดเยี่ยมในการช่วยค้นหาจุดบกพร่องที่แนะนำและดังนั้นจึงเป็นทักษะที่มีค่าในการเรียนรู้ต่อไป ดังนั้นแม้ว่าอาจไม่ใช่วิธีที่ 'ถูกต้อง' หรือ 'ถูกต้องที่สุด' ที่นี่ก็ยังเป็นแนวคิดที่ดีและคุ้มค่า +1 แน่นอน!
Pryftan

77

นามแฝงใหม่ที่ฉันโปรดปรานขึ้นอยู่กับคำตอบของbonyiii (upvoted) และคำตอบของฉันเกี่ยวกับ " ส่งอาร์กิวเมนต์ไปยังคำสั่ง Git alias ":

git config alias.restore '!f() { git checkout $(git rev-list -n 1 HEAD -- $1)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- $1)~1 | grep '^D' | cut -f 2); }; f'

ฉันทำแฟ้มหายแล้วลบไปโดยไม่ตั้งใจเมื่อสองสามปีก่อน?
ด่วน:

git restore my_deleted_file

วิกฤตหันไป

คำเตือนด้วย Git 2.23 (Q3 2019) มาพร้อมกับคำสั่งทดลองชื่อgit restore(!)
ดังนั้นเปลี่ยนชื่อนามแฝงนี้ (ดังแสดงด้านล่าง)


Robert Daileyเสนอความคิดเห็นนามแฝงต่อไปนี้:

restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"

และjeganเพิ่มในความคิดเห็น :

สำหรับการตั้งค่านามแฝงจากบรรทัดคำสั่งฉันใช้คำสั่งนี้:

git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\"" 

7
เป็นการคืนค่าการคอมมิททั้งหมดไม่ใช่เฉพาะไฟล์ที่ร้องขอ
Daniel Bang

5
นี่คือนามแฝงของฉันทำงานได้อย่างยอดเยี่ยม:restore-file = !git checkout $(git rev-list -n 1 HEAD -- "$1")^ -- "$1"
void.pointer

1
@RobertDailey ดูดีมาก! ฉันได้รวมนามแฝงของคุณไว้ในคำตอบเพื่อให้มองเห็นได้ชัดเจนขึ้น
VonC

1
สำหรับการตั้งค่านามแฝงจากบรรทัดคำสั่งฉันใช้คำสั่งนี้:git config --global alias.restore "\!git checkout \$(git rev-list -n 1 HEAD -- \"\$1\")^ -- \"\$1\""
jegan

2
Expansion of alias 'restore' failed; '!git' is not a git command
Karl Morrison

55

หากคุณรู้จักชื่อไฟล์นี่เป็นวิธีง่ายๆที่มีคำสั่งพื้นฐาน:

แสดงรายการคอมมิททั้งหมดสำหรับไฟล์นั้น

git log -- path/to/file

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

git checkout {second to last commit} -- path/to/file

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

การกระทำครั้งต่อไปที่ผ่านมา (การกระทำก่อนหน้านี้ต่อการลบ) จะมีไฟล์ที่ถูกลบเวอร์ชันล่าสุดหรือไม่ ลำดับที่สองถึงครั้งสุดท้าย (การกระทำก่อนที่จะส่งการลบหน้าที่ก่อนหน้านี้) อาจล้าสมัยอย่างสิ้นหวัง
Suncat2000

1
นี่เป็นทางออกแรกที่ฉันเห็นว่าง่ายพอที่ฉันจะได้ไม่ต้องกลับมาที่นี่เพื่อค้นหาในครั้งต่อไป อาจจะ.
Eloff

@ Suncat2000 "สองถึงสาม" หมายถึง "การกระทำก่อนหน้านี้ไปยังการลบ" เช่นเดียวกับ "ถัดจากครั้งสุดท้าย" en.wiktionary.org/wiki/penultimate#Synonyms
wisbucky

ขอบคุณ zillion ครั้งสำหรับคำตอบนี้ !!!!!
Rakesh Bk

29

วิธีคืนค่าไฟล์ที่ถูกลบและถูกคอมมิต:

git reset HEAD some/path
git checkout -- some/path

มันถูกทดสอบใน Git รุ่น 1.7.5.4


1
นั่นไม่ได้ผลสำหรับฉัน หลังจากเช็คเอาต์ฉันได้error: pathspec 'foo' did not match any file(s) known to git.ฉันแน่ใจว่าชื่อไฟล์นั้นถูกต้อง Git เวอร์ชั่น 2.7.0
wisbucky

-1; นี่มันผิด คำสั่งเหล่านี้จะยกเลิกการลบที่ยังไม่ได้รับการมุ่งมั่น (คนแรก unstages ลบถ้ามันจัดฉากและการเปลี่ยนแปลงที่สองเหลือใช้ unstaged ไปยังแฟ้ม) แต่คุณกำลังอ้างนี่ว่าพวกเขาจะเรียกคืนความมุ่งมั่นการลบไฟล์ซึ่งไม่เป็นความจริงและจะล้มเหลวด้วยข้อผิดพลาดเช่นนั้นในความคิดเห็นของ @ wisbucky ด้านบน
Mark Amery

@MarkAmery แน่นอนฉันคิดว่าคำสั่งนี้ใช้ได้ดีสำหรับนักพัฒนาเหล่านั้นซึ่งไม่ได้ทำการ staging อย่างชัดเจนสำหรับการส่งไฟล์ที่ถูกลบด้วยgit add -Aแต่ไฟล์ที่กู้คืนนั้นยังอยู่ในขั้นตอนที่ไม่ได้รับการยืนยัน
Fedir RYKHTIK

25

หากคุณทำการเปลี่ยนแปลงและลบไฟล์ แต่ไม่ยอมรับและตอนนี้คุณเลิกกับการเปลี่ยนแปลงของคุณ

git checkout -- .

แต่ไฟล์ที่ถูกลบของคุณไม่ส่งคืนคุณเพียงแค่ทำตามคำสั่งต่อไปนี้:

git checkout <file_path>

และ presto ไฟล์ของคุณก็กลับมาแล้ว


24

ฉันมีทางออกนี้

  1. รับรหัสการกระทำที่ไฟล์ถูกลบโดยใช้วิธีใดวิธีหนึ่งด้านล่าง

    • git log --grep=*word*
    • git log -Sword
    • git log | grep --context=5 *word*
    • git log --stat | grep --context=5 *word* # แนะนำถ้าคุณจำอะไรไม่ได้เลย
  2. คุณควรได้รับ:

กระทำ bfe68bd117e1091c96d2976c99b3bcc8310bebe7 ผู้แต่ง: Alexander Orlov วันที่: พ.ค. 12 23:44:27 2011 +0200

replaced deprecated GWT class
- gwtI18nKeySync.sh, an outdated (?, replaced by a Maven goal) I18n generation script

กระทำ 3ea4e3af253ac6fd1691ff6bb89c964f54802302 ผู้แต่ง: Alexander Orlov วันที่: พฤหัสบดี 12 พฤษภาคม 22:10:22 2011 +0200

3 . ตอนนี้ใช้การกระทำรหัส bfe68bd117e1091c96d2976c99b3bcc8310bebe7 ทำ:

git checkout bfe68bd117e1091c96d2976c99b3bcc8310bebe7^1 yourDeletedFile.java

ในฐานะที่เป็นกระทำอ้างอิงรหัสกระทำที่ไฟล์นั้นถูกลบไปแล้วคุณจะต้องอ้างอิงกระทำก่อน bfe68b ^1ซึ่งคุณสามารถทำโดยการผนวก นี่หมายถึง: มอบความรับผิดชอบให้ฉันก่อน bfe68b


นี่เป็นวิธีการเดียวกับคำตอบที่ได้รับการยอมรับ แต่ด้วยวิธีการอื่น ๆ ในการค้นหาการลบ ฉันยังคงชอบวิธีการในคำตอบที่ยอมรับ แต่สิ่งเหล่านี้เป็นทางเลือกที่ดี ขอบคุณ!
avdgaag

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


12

git undelete path/to/file.ext

  1. วางสิ่งนี้ลงใน.bash_profile(หรือไฟล์อื่น ๆ ที่เกี่ยวข้องที่โหลดเมื่อคุณเปิดเชลล์คำสั่ง):

    git config --global alias.undelete '!sh -c "git checkout $(git rev-list -n 1 HEAD -- $1)^ -- $1" -'
    
  2. จากนั้นใช้:

    git undelete path/to/file.ext
    

นามแฝงนี้จะตรวจสอบเพื่อค้นหาการคอมมิทล่าสุดที่มีไฟล์นี้อยู่จากนั้นทำการตรวจสอบ Git ของพา ธ ไฟล์นั้นจากการคอมมิทครั้งล่าสุดที่มีไฟล์นี้อยู่ แหล่ง


11

ในหลายกรณีมันจะมีประโยชน์ในการใช้coreutils (grep, sed, ฯลฯ ) ร่วมกับ Git ฉันรู้แล้วเครื่องมือเหล่านี้ค่อนข้างดี แต่ Git น้อยลง หากฉันต้องการค้นหาไฟล์ที่ถูกลบฉันจะทำสิ่งต่อไปนี้:

git log --raw | grep -B 30 $'D\t.*deleted_file.c'

เมื่อฉันพบการแก้ไข / การกระทำ:

git checkout <rev>^ -- path/to/refound/deleted_file.c

เช่นเดียวกับคนอื่น ๆ ได้กล่าวไว้ก่อนหน้าฉัน

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


7

ฉันต้องกู้คืนไฟล์ที่ถูกลบจำนวนมากจากการคอมมิทเฉพาะและฉันจัดการมันด้วยสองคำสั่ง:

git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git checkout <rev>^ -- 
git show <rev> --diff-filter=D --summary --name-only --no-commit-id | xargs git reset HEAD 

(สังเกตช่องว่างท้ายท้ายแต่ละคำสั่ง)

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


7

ที่จริงแล้วคำถามนี้เกี่ยวกับ Git โดยตรง แต่บางคนอย่างฉันทำงานกับเครื่องมือ GUI เช่นWebStorm VCSนอกเหนือจากการรู้เกี่ยวกับคำสั่ง Git CLI

ผมคลิกขวาบนเส้นทางที่มีไฟล์ที่ถูกลบและจากนั้นไปที่ Git แล้วคลิกที่แสดงประวัติความเป็นมา

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

เครื่องมือ VCS แสดงการฝึกอบรมการแก้ไขทั้งหมดและฉันสามารถเห็นการกระทำและการเปลี่ยนแปลงทั้งหมดของแต่ละรายการ

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

จากนั้นฉันเลือกคอมมิตที่เพื่อนของฉันลบPostAd.jsไฟล์ ตอนนี้ดูด้านล่าง:

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

และตอนนี้ฉันเห็นไฟล์ที่ต้องการลบแล้ว ฉันเพียงแค่ดับเบิลคลิกที่ชื่อไฟล์และกู้คืน

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

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


1
นี่มันเจ๋งมาก! ขอบคุณ. ทางออกที่ง่ายขึ้นสำหรับผู้ใช้ IDEB ของ JetBrains
Fabiano Arruda

เราจะเรียกคืนไฟล์ได้อย่างไรถ้าเป็นภาพ?
Nodirabegimxonoyim

เรียน @FabianoArruda JetBrains IDEs เป็นเครื่องมือที่ทรงพลังสำหรับการพัฒนา ขอบคุณสำหรับความคิดเห็นที่น่ารักของคุณ
AmerllicA

ขอบคุณที่รัก @PeterMortensen สำหรับรุ่น
AmerllicA

6

ฉันมีคำถามเดียวกัน ฉันได้สร้างความมุ่งมั่นที่ห้อยต่องแต่งโดยไม่รู้ตัวห้อยกระทำ

รายการห้อยกระทำ

git fsck --lost-found

ตรวจสอบการกระทำที่ห้อยต่องแต่งทุกครั้ง

git reset --hard <commit id>

ไฟล์ของฉันปรากฏขึ้นอีกครั้งเมื่อฉันย้ายไปที่การมอบหมายห้อย

git status ด้วยเหตุผล:

“HEAD detached from <commit id where it detached>”


2
ขอบคุณมาก. คุณช่วยฉันกู้คืนรหัสหลายพันบรรทัด
รูเบน

5
user@bsd:~/work/git$ rm slides.tex
user@bsd:~/work/git$ git pull 
Already up-to-date.
user@bsd:~/work/git$ ls slides.tex
ls: slides.tex: No such file or directory

กู้คืนไฟล์ที่ถูกลบ:

user@bsd:~/work/git$ git checkout
D       .slides.tex.swp
D       slides.tex
user@bsd:~/work/git$ git checkout slides.tex 
user@bsd:~/work/git$ ls slides.tex
slides.tex

2
คำถามคือเกี่ยวกับการกู้คืนไฟล์หลังจากที่ถูกลบและการเปลี่ยนแปลงได้รับการมุ่งมั่น คำตอบนี้เกี่ยวกับการกู้คืนไฟล์ที่ถูกลบในไดเรกทอรีการทำงานเท่านั้น
akaihola

นั่นเป็นความจริงและนั่นคือสิ่งที่ฉันกำลังมองหา
Hola Soy Edu Feliz Navidad

4

หากคุณรู้จักคอมมิชชันที่ลบไฟล์ให้รันคำสั่งนี้โดยที่คอมมิท<SHA1_deletion>ที่ลบไฟล์นั้น:

git diff --diff-filter=D --name-only <SHA1_deletion>~1 <SHA1_deletion> | xargs git checkout <SHA1_deletion>~1 --

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


4

ค้นหาการกระทำที่ลบไฟล์ของคุณ:

git log --diff-filter=D --oneline -- path/to/file | cut -f -d ' '

ตัวอย่างผลลัพธ์:

4711174

ในฐานะของ Git 2.23 มีrestoreคำสั่งจริง มันยังคงอยู่ในช่วงทดลองแต่เพื่อที่จะกู้คืนสิ่งที่คุณลบออกไปในคอมมิท (4711174 ในกรณีนี้) คุณสามารถพิมพ์:

git restore --source=4711174^ path/to/file

หมายเหตุ^หลังจากกระทำรหัสที่เราต้องการคืนค่าบางอย่างจากกระทำก่อนหน้านี้ลบไฟล์

--sourceอาร์กิวเมนต์บอกrestoreคำสั่งที่จะมองหาไฟล์ (s) เพื่อเรียกคืนและมันสามารถใดกระทำและแม้กระทั่งดัชนี

ดู: git-restore doc สำหรับ git 2.23.0


4

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

จากคำตอบที่ยอดเยี่ยมของ Charles Bailey นี่คือหนึ่งในซับของฉัน:

git co $(git rev-list -n 1 HEAD -- <file_path>)~1 -- $(git diff --name-status $(git rev-list -n 1 HEAD -- <file_path>)~1 head | grep '^D' | cut -f 2)

2

ง่ายและแม่นยำ -

ก่อนอื่นรับการกระทำที่เสถียรล่าสุดที่คุณมีไฟล์นั้นด้วย -

git log 

สมมติว่าคุณพบ $ commitid 1234567 ... จากนั้น

git checkout <$commitid> $fileName

นี่จะคืนค่าเวอร์ชันไฟล์ที่ใช้


1

สำหรับวิธีที่ดีที่สุดในการทำเช่นนั้นลอง


ก่อนอื่นให้ค้นหาการส่งมอบรหัสการกระทำที่ลบไฟล์ของคุณ มันจะทำให้คุณสรุปการกระทำที่ไฟล์ถูกลบ

บันทึก git --diff-filter = D - สรุป

git checkout 84sdhfddbdddf ~ 1

หมายเหตุ: 84sdhfddbdddเป็นของคุณcommit id

ด้วยวิธีนี้คุณสามารถกู้คืนไฟล์ที่ถูกลบทั้งหมดได้อย่างง่ายดาย


1

คุณสามารถgit revertกระทำของคุณที่จะลบไฟล์ ( นี่ถือว่าการลบเป็นการเปลี่ยนแปลงเพียงอย่างเดียวในการส่ง )

> git log
commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:11:06 2019 -0700

    deleted readme.md

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

> git revert 2994bd

ตอนนี้git logแสดงให้เห็นว่า:

> git log
Author: Dave <dave@domain.com>
Date:   Thu May 9 11:17:41 2019 -0700

    Revert "deleted readme"

    This reverts commit 2994bda49cd97ce49099953fc3f76f7d3c35d1d3.

และreadme.mdได้รับการคืนสู่พื้นที่เก็บข้อมูล


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

1
อ้อ! คุณสามารถทำการคอมมิตในภายหลังและยังคงยกเลิกการคอมมิตการลบ ดังนั้นถ้าคอมมิชชัน 111 ลบไฟล์และคอมมิชชัน 222, 333, 444, เพิ่ม / แก้ไขสิ่งต่าง ๆ , คุณยังสามารถย้อนกลับ 111 เพื่อเลิกทำการลบได้, และมันจะทำการคอมมิชชัน 555
Dave Baghdanov

0

ฉันยังมีปัญหานี้โดยใช้รหัสด้านล่างเพื่อดึงไฟล์ก่อนหน้านี้ไปยังไดเรกทอรีท้องถิ่น:

git checkout <file path with name>

ตัวอย่างด้านล่างใช้งานได้สำหรับฉัน:

git checkout resources/views/usaSchools.blade.php


กรุณาพูดถึงสิ่งที่เป็นปัญหา
Akbor

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


-1

หากการลบยังไม่ได้รับการยืนยันคำสั่งด้านล่างจะคืนค่าไฟล์ที่ถูกลบในแผนผังการทำงาน

$ git checkout -- <file>

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

$ git ls-files --deleted

หากการลบถูกส่งไปแล้วให้ค้นหาการกระทำที่เกิดขึ้นจากนั้นกู้คืนไฟล์จากการส่งนี้

$ git rev-list -n 1 HEAD -- <file>
$ git checkout <commit>^ -- <file>

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

$ git log --diff-filter=D --summary

-1

ในการกู้คืนไฟล์ที่ถูกลบทั้งหมดด้วย Git คุณสามารถทำได้:

git checkout $(git ls-files --deleted)

โดยที่git ls-files --deletedรายการไฟล์ที่ถูกลบทั้งหมดและgit checkout $(git command)เรียกคืนรายชื่อไฟล์ในพารามิเตอร์

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