Tôi mới trải nghiệm điều này - máy của tôi bị hỏng trong khi viết cho repo Git, và nó bị hỏng. Tôi đã sửa nó như sau.
Tôi đã bắt đầu với việc xem xét bao nhiêu cam kết mà tôi đã không bị đẩy vào repo từ xa, do đó:
gitk &
Nếu bạn không sử dụng công cụ này thì nó rất tiện dụng - có sẵn trên tất cả các hệ điều hành theo như tôi biết. Điều này chỉ ra rằng điều khiển từ xa của tôi đã thiếu hai lần xác nhận. Do đó, tôi đã nhấp vào nhãn cho biết cam kết từ xa mới nhất (thường là như vậy /remotes/origin/master
) để có được hàm băm (hàm băm dài 40 ký tự, nhưng để đơn giản tôi đang sử dụng 10 ở đây - dù sao thì nó vẫn hoạt động).
Đây là:
14c0fcc9b3
Sau đó tôi nhấp vào cam kết sau (tức là lần đầu tiên mà điều khiển từ xa không có) và nhận được hàm băm ở đó:
04d44c3298
Sau đó tôi sử dụng cả hai thứ này để tạo một bản vá cho cam kết này:
git diff 14c0fcc9b3 04d44c3298 > 1.patch
Sau đó, tôi đã làm tương tự với các cam kết bị thiếu khác, tức là tôi đã sử dụng hàm băm của cam kết trước đó và hàm băm của chính xác nhận đó:
git diff 04d44c3298 fc1d4b0df7 > 2.patch
Sau đó tôi chuyển đến một thư mục mới, nhân bản repo từ xa:
git clone git@github.com:username/repo.git
Sau đó tôi đã di chuyển các tệp vá vào thư mục mới, áp dụng chúng và cam kết chúng với các thông điệp cam kết chính xác của chúng (chúng có thể được dán từ git log
hoặc gitk
cửa sổ):
patch -p1 < 1.patch
git commit
patch -p1 < 2.patch
git commit
Điều này khôi phục lại cho tôi (và lưu ý có lẽ có một cách nhanh hơn để làm điều đó cho một số lượng lớn các cam kết). Tuy nhiên tôi rất muốn xem liệu cây trong repo bị hỏng có thể được sửa chữa hay không, và câu trả lời là nó có thể. Với một repo đã sửa chữa có sẵn như trên, hãy chạy lệnh này trong thư mục bị hỏng:
git fsck
Bạn sẽ nhận được một cái gì đó như thế này:
error: object file .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d is empty
error: unable to find ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
error: sha1 mismatch ca539ed815fefdbbbfae6e8d0c0b3dbbe093390d
Để sửa chữa, tôi sẽ làm điều này trong thư mục bị hỏng:
rm .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
cp ../good-repo/.git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d .git/objects/ca/539ed815fefdbbbfae6e8d0c0b3dbbe093390d
tức là loại bỏ các tập tin bị hỏng và thay thế nó bằng một tập tin tốt. Bạn có thể phải làm điều này nhiều lần. Cuối cùng sẽ có một điểm mà bạn có thể chạy fsck
mà không gặp lỗi. Bạn có thể sẽ có dòng "dangling commit" và "dangling blob" trong báo cáo, đây là hậu quả của sự nổi loạn của bạn và sửa đổi trong thư mục này, và đều ổn. Người thu gom rác sẽ loại bỏ chúng trong khóa học do.
Do đó (ít nhất là trong trường hợp của tôi), một cây bị hỏng không có nghĩa là các cam kết không được đánh dấu bị mất.