Ngày xửa ngày xưa, có một tập tin trong dự án của tôi mà bây giờ tôi muốn có thể lấy.
Vấn đề là: Tôi không biết khi nào tôi đã xóa nó và nó đã đi trên con đường nào.
Làm cách nào để xác định vị trí của tệp này khi nó tồn tại?
Ngày xửa ngày xưa, có một tập tin trong dự án của tôi mà bây giờ tôi muốn có thể lấy.
Vấn đề là: Tôi không biết khi nào tôi đã xóa nó và nó đã đi trên con đường nào.
Làm cách nào để xác định vị trí của tệp này khi nó tồn tại?
Câu trả lời:
Nếu bạn không biết đường dẫn chính xác bạn có thể sử dụng
git log --all --full-history -- "**/thefile.*"
Nếu bạn biết đường dẫn của tập tin, bạn có thể làm điều này:
git log --all --full-history -- <path-to-file>
Điều này sẽ hiển thị một danh sách các cam kết trong tất cả các chi nhánh đã chạm vào tệp đó. Sau đó, bạn có thể tìm phiên bản của tệp bạn muốn và hiển thị nó với ...
git show <SHA> -- <path-to-file>
Hoặc khôi phục nó vào bản sao làm việc của bạn với:
git checkout <SHA>^ -- <path-to-file>
Lưu ý ký hiệu dấu mũ ( ^
), được kiểm tra trước khi xác định, vì tại thời điểm <SHA>
cam kết tệp bị xóa, chúng ta cần xem xét cam kết trước đó để lấy nội dung của tệp đã bị xóa
git log -- <path>
sẽ không có đầu ra khi bạn ở trên một nhánh trong đó tệp không bao giờ tồn tại. Bạn nên luôn luôn sử dụng git log --all -- <path>
, để đảm bảo bạn không bỏ lỡ những thay đổi xảy ra trên các chi nhánh khác. Lệnh git log -- <path>
có thể rất nguy hiểm nếu bạn có nhiều hơn một nhánh và có xu hướng quên các đường dẫn và nhánh (như tôi) và nó cũng nguy hiểm nếu bạn làm việc với các nhà phát triển khác.
git checkout <SHA>^ -- <path-to-file>
(lưu ý ký hiệu ^), vì tại thời điểm <SHA> cam kết tệp bị xóa, chúng ta cần xem xét cam kết trước đó để lấy nội dung của tệp đã bị xóa
Lấy danh sách các tệp đã xóa và sao chép toàn bộ đường dẫn của tệp đã xóa
git log --diff-filter=D --summary | grep delete
Thực hiện lệnh tiếp theo để tìm id xác nhận của cam kết đó và sao chép id xác nhận
git log --all -- FILEPATH
Hiển thị khác biệt của tập tin bị xóa
git show COMMIT_ID -- FILE_PATH
Hãy nhớ rằng, bạn có thể ghi đầu ra vào một tệp bằng cách sử dụng >
như
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; }
và bây giờ bạn có thể thực hiện:git-grep-latest some_text
linux pipes
.. bạn sẽ thích điều đó.
Không thể chỉnh sửa phản hồi được chấp nhận để thêm nó làm câu trả lời ở đây,
để khôi phục tệp trong git, hãy sử dụng thông tin sau (lưu ý dấu '^' ngay sau SHA)
git checkout <SHA>^ -- /path/to/file
<SHA>~1
nên hoạt động như nhau mà không cần phải bọc nó bằng dấu ngoặc kép.
Giả sử bạn muốn khôi phục một tệp được gọi MyFile
, nhưng không chắc chắn về đường dẫn của nó (hoặc phần mở rộng của nó, cho vấn đề đó):
Sơ bộ: Tránh nhầm lẫn bằng cách bước đến gốc git
Một dự án không cần thiết có thể có nhiều thư mục có tên tương tự hoặc giống hệt nhau.
> cd <project-root>
Tìm đường dẫn đầy đủ
nhật ký git --diff-filter = D --summary | xóa grep | grep MyFile
delete mode 100644 full/path/to/MyFile.js
full/path/to/MyFile.js
là đường dẫn và tập tin bạn đang tìm kiếm.
Xác định tất cả các cam kết ảnh hưởng đến tệp đó
git log --oneline --follow - full / path / to / 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.
Kiểm tra tập tin
Nếu bạn chọn cam kết được liệt kê đầu tiên (theo trình tự thời gian cuối cùng, ở đây bd8374c), tệp sẽ không được tìm thấy, vì nó đã bị xóa trong cam kết đó.
> git checkout bd8374c -- full/path/to/MyFile.js
`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`
Chỉ cần chọn cam kết trước (nối thêm dấu mũ):
> git checkout bd8374c^ -- full/path/to/MyFile.js
git log --diff-filter=D --summary | find "delete" | find "MyFile"
Và bước 3 , lưu ý các trích dẫn xung quanh hàm băm:git checkout "bd8374c^" -- full/path/to/MyFile.js
@Amber đã trả lời đúng! Chỉ cần thêm một lần nữa, nếu bạn không biết đường dẫn chính xác của tệp, bạn có thể sử dụng ký tự đại diện! Điều này làm việc cho tôi.
git log --all -- **/thefile.*
Dưới đây là một lệnh đơn giản, trong đó một người dùng dev hoặc git có thể chuyển tên tệp đã bị xóa khỏi thư mục gốc của kho lưu trữ và lấy lịch sử:
git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all --
Nếu ai, có thể cải thiện lệnh, xin vui lòng làm.
Hãy thử sử dụng một trong những người xem, chẳng hạn như gitk
để bạn có thể duyệt qua lịch sử để tìm tệp được nhớ một nửa. (sử dụng gitk --all
nếu cần cho tất cả các chi nhánh)
--all
Tùy chọn đó rất quan trọng cho cả câu trả lời của bạn và câu trả lời được chấp nhận.
Tóm lược:
Bạn tìm kiếm đường dẫn tập tin đầy đủ của bạn trong lịch sử của các tập tin bị xóa git log --diff-filter=D --summary | grep filename
Bạn khôi phục tệp của bạn từ cam kết trước khi nó bị xóa
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
Đây là giải pháp của tôi:
git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>
git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>