Bạn sẽ có thể khôi phục bất kỳ tệp nào trở lại mà bạn đã thêm vào chỉ mục (ví dụ: như trong trường hợp của bạn, với git add .
) mặc dù có thể hơi vất vả. Để thêm tệp vào chỉ mục, git sẽ thêm tệp đó vào cơ sở dữ liệu đối tượng, có nghĩa là tệp có thể được phục hồi miễn là việc thu gom rác chưa diễn ra. Có một ví dụ về cách làm điều này được đưa ra trong câu trả lời của Jakub Narębski ở đây:
Tuy nhiên, tôi đã thử điều đó trên một kho lưu trữ thử nghiệm và có một vài vấn đề - --cached
nên xảy ra --cache
và tôi thấy rằng nó không thực sự tạo ra .git/lost-found
thư mục. Tuy nhiên, các bước sau đã hiệu quả với tôi:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)")
Điều đó sẽ xuất ra tất cả các đối tượng trong cơ sở dữ liệu đối tượng mà bất kỳ ref nào không thể truy cập được, trong chỉ mục hoặc thông qua reflog. Đầu ra sẽ giống như sau:
unreachable blob 907b308167f0880fb2a5c0e1614bb0c7620f9dc3
unreachable blob 72663d3adcf67548b9e0f0b2eeef62bce3d53e03
... và đối với mỗi đốm màu đó, bạn có thể làm:
git show 907b308
Để xuất nội dung của tệp.
Quá nhiều sản lượng?
Cập nhật phản hồi cho bình luận của sehe bên dưới:
Nếu bạn thấy rằng bạn có nhiều cam kết và cây được liệt kê trong đầu ra từ lệnh đó, bạn có thể muốn xóa khỏi đầu ra bất kỳ đối tượng nào được tham chiếu từ các cam kết không được tham chiếu. (Thông thường, bạn vẫn có thể quay lại các cam kết này thông qua reflog - chúng tôi chỉ quan tâm đến các đối tượng đã được thêm vào chỉ mục nhưng không bao giờ có thể được tìm thấy thông qua cam kết.)
Đầu tiên, lưu đầu ra của lệnh, với:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") > all
Bây giờ bạn có thể tìm thấy tên đối tượng của những cam kết không thể truy cập đó bằng:
egrep commit all | cut -d ' ' -f 3
Vì vậy, bạn chỉ có thể tìm thấy các cây và đối tượng đã được thêm vào chỉ mục, nhưng không được cam kết tại bất kỳ điểm nào, với:
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3)
Điều đó làm giảm đáng kể số lượng đối tượng mà bạn sẽ phải xem xét.
Cập nhật: Philip Oakley dưới đây đề xuất một cách khác để cắt giảm số lượng đối tượng cần xem xét, đó là chỉ xem xét các tệp được sửa đổi gần đây nhất .git/objects
. Bạn có thể tìm thấy những thứ này với:
find .git/objects/ -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort
(Tôi tìm thấy find
lời gọi đó ở đây .) Phần cuối của danh sách đó có thể giống như sau:
2011-08-22 11:43:43.0234896770 .git/objects/b2/1700b09c0bc0fc848f67dd751a9e4ea5b4133b
2011-09-13 07:36:37.5868133260 .git/objects/de/629830603289ef159268f443da79968360913a
Trong trường hợp đó, bạn có thể xem các đối tượng đó với:
git show b21700b09c0bc0fc848f67dd751a9e4ea5b4133b
git show de629830603289ef159268f443da79968360913a
(Lưu ý rằng bạn phải loại bỏ /
phần cuối của đường dẫn để lấy tên đối tượng.)