กาลครั้งหนึ่งมีไฟล์ในโครงการของฉันที่ตอนนี้ฉันอยากจะได้
ปัญหาคือ: ฉันไม่รู้ว่าเมื่อไหร่ที่ฉันลบมันและเส้นทางที่มันเป็น
ฉันจะหาข้อผูกพันของไฟล์นี้เมื่อมีอยู่ได้อย่างไร?
กาลครั้งหนึ่งมีไฟล์ในโครงการของฉันที่ตอนนี้ฉันอยากจะได้
ปัญหาคือ: ฉันไม่รู้ว่าเมื่อไหร่ที่ฉันลบมันและเส้นทางที่มันเป็น
ฉันจะหาข้อผูกพันของไฟล์นี้เมื่อมีอยู่ได้อย่างไร?
คำตอบ:
หากคุณไม่ทราบเส้นทางที่แน่นอนคุณสามารถใช้
git log --all --full-history -- "**/thefile.*"
หากคุณรู้เส้นทางของไฟล์คุณสามารถทำได้ดังนี้:
git log --all --full-history -- <path-to-file>
นี่จะแสดงรายการการผูกพันในทุกสาขาที่แตะไฟล์นั้น จากนั้นคุณสามารถค้นหาเวอร์ชันของไฟล์ที่คุณต้องการและแสดงด้วย ...
git show <SHA> -- <path-to-file>
หรือคืนค่าเป็นสำเนาการทำงานของคุณด้วย:
git checkout <SHA>^ -- <path-to-file>
สังเกตสัญลักษณ์คาเร็ต ( ^
) ซึ่งได้รับเช็คเอาต์ก่อนที่จะมีการระบุเนื่องจากในขณะ<SHA>
ที่ทำการส่งไฟล์ถูกลบเราจำเป็นต้องดูการคอมมิชชันก่อนหน้าเพื่อรับเนื้อหาของไฟล์ที่ถูกลบ
git log -- <path>
จะไม่มีเอาต์พุตเมื่อคุณอยู่ในสาขาที่ไม่มีไฟล์อยู่ คุณควรใช้git log --all -- <path>
เพื่อให้แน่ใจว่าคุณจะไม่พลาดการเปลี่ยนแปลงที่เกิดขึ้นในสาขาอื่น คำสั่งgit log -- <path>
อาจเป็นอันตรายได้หากคุณมีสาขามากกว่าหนึ่งสาขาและมีแนวโน้มที่จะลืมเส้นทางและสาขา (เช่นฉัน) และมันก็อันตรายเช่นกันหากคุณทำงานกับผู้พัฒนารายอื่น
git checkout <SHA>^ -- <path-to-file>
(หมายเหตุสัญลักษณ์ ^) เนื่องจากในขณะที่ <SHA> ส่งไฟล์ถูกลบเราจำเป็นต้องดูการคอมมิชชันก่อนหน้าเพื่อรับเนื้อหาของไฟล์ที่ถูกลบ
รับรายการไฟล์ที่ถูกลบและคัดลอกพา ธ เต็มของไฟล์ที่ถูกลบ
git log --diff-filter=D --summary | grep delete
ดำเนินการคำสั่งถัดไปเพื่อค้นหากระทำ id ของการกระทำที่และคัดลอกกระทำรหัส
git log --all -- FILEPATH
แสดงส่วนต่างของไฟล์ที่ถูกลบ
git show COMMIT_ID -- FILE_PATH
จำไว้ว่าคุณสามารถเขียนผลลัพธ์ไปยังไฟล์โดยใช้>
ไลค์
git show COMMIT_ID -- FILE_PATH > deleted.diff
unknown revision or path not in the working tree
ถึงแม้ว่าผมจะพบเส้นทางด้วยความช่วยเหลือของขั้นตอนแรกขั้นตอนที่สองโยนข้อผิดพลาดนี้:
git log --diff-filter=D --summary | grep -E 'delete|^commit\s+\S+'
git-grep-latest(){ result_path=$(git log --diff-filter=D --summary | grep $1 | head -1 | awk '{print $4;}'); latest_commit=$(git log --all -- $result_path | head -1 | awk '{print $2;}'); git show $latest_commit -- $result_path; }
และตอนนี้คุณสามารถทำได้:git-grep-latest some_text
linux pipes
.. คุณจะชอบแบบนั้น
ไม่สามารถแก้ไขคำตอบที่ยอมรับเพื่อเพิ่มเป็นคำตอบที่นี่
เพื่อกู้คืนไฟล์ในคอมไพล์ใช้ต่อไปนี้ (สังเกตเครื่องหมาย '^' หลังจาก SHA)
git checkout <SHA>^ -- /path/to/file
<SHA>~1
ควรทำงานเหมือนเดิมโดยไม่จำเป็นต้องห่อด้วยเครื่องหมายคำพูด
สมมติว่าคุณต้องการกู้คืนไฟล์ที่เรียกว่าMyFile
แต่ไม่แน่ใจในพา ธ (หรือส่วนขยายของไฟล์สำหรับเรื่องนั้น):
คำนำ: หลีกเลี่ยงความสับสนด้วยการก้าวไปที่รากคอมไพล์
โครงการที่ไม่สำคัญอาจมีหลายไดเรกทอรีที่มีชื่อคล้ายหรือเหมือนกัน
> cd <project-root>
ค้นหาเส้นทางแบบเต็ม
บันทึก git --diff-filter = D - สรุป | grep ลบ grep MyFile
delete mode 100644 full/path/to/MyFile.js
full/path/to/MyFile.js
คือเส้นทางและไฟล์ที่คุณกำลังค้นหา
พิจารณาการกระทำทั้งหมดที่มีผลกับไฟล์นั้น
บันทึก git - ออนไลน์ - ติดตาม - เต็ม / เส้นทาง / ถึง / MyFile.js
bd8374c Some helpful commit message
ba8d20e Another prior commit message affecting that file
cfea812 The first message for a commit in which that file appeared.
ชำระเงินไฟล์
หากคุณเลือกคอมมิชชันรายการแรก (ลำดับสุดท้ายที่นี่ bd8374c) จะไม่พบไฟล์เนื่องจากถูกลบในคอมมิชชันนั้น
> git checkout bd8374c -- full/path/to/MyFile.js
`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`
เพียงเลือกก่อนหน้า (ผนวกเครื่องหมายรูปหมวก) กระทำ:
> git checkout bd8374c^ -- full/path/to/MyFile.js
git log --diff-filter=D --summary | find "delete" | find "MyFile"
และ step3 ให้สังเกตเครื่องหมายคำพูดรอบ ๆ แฮช:git checkout "bd8374c^" -- full/path/to/MyFile.js
@Amber ให้คำตอบที่ถูกต้อง! นอกจากนี้อีกหนึ่งถ้าคุณไม่ทราบเส้นทางที่แน่นอนของไฟล์คุณสามารถใช้อักขระตัวแทน! สิ่งนี้ใช้ได้สำหรับฉัน
git log --all -- **/thefile.*
ด้านล่างเป็นคำสั่งง่ายๆที่ผู้ใช้ dev หรือผู้ใช้ git สามารถส่งชื่อไฟล์ที่ถูกลบจากไดเรกทอรีรากที่เก็บและรับประวัติ:
git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all --
หากใครสามารถปรับปรุงคำสั่งโปรดทำ
ลองใช้หนึ่งในวิวเวอร์เช่นgitk
เพื่อให้คุณสามารถเรียกดูประวัติเพื่อค้นหาไฟล์ที่จำได้ครึ่งหนึ่ง (ใช้gitk --all
ถ้าจำเป็นสำหรับทุกสาขา)
--all
เป็นตัวเลือกที่สำคัญสำหรับทั้งคำตอบและคำตอบที่ได้รับการยอมรับของคุณ
สรุป:
คุณค้นหาเส้นทางแบบเต็มไฟล์ในประวัติของไฟล์ที่ถูกลบ git log --diff-filter=D --summary | grep filename
คุณกู้คืนไฟล์ของคุณจากการกระทำก่อนที่จะถูกลบ
restore () {
filepath="$@"
last_commit=$(git log --all --full-history -- $filepath | grep commit | head -1 | awk '{print $2; exit}')
echo "Restoring file from commit before $last_commit"
git checkout $last_commit^ -- $filepath
}
restore my/file_path
นี่คือทางออกของฉัน:
git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>
git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>