Duyệt qua các cam kết mồ côi trong Git


102

Kho lưu trữ git của tôi bằng cách nào đó đã không hoạt động - tôi đã tải msysgit sáng nay và thay vì tên chi nhánh được hiển thị sau thư mục hiện tại, nó cho biết "((ref: re ...))", 'trạng thái git' báo cáo mọi thứ dưới dạng tệp mới, 'git log' và 'git reflog' cho tôi biết "nghiêm trọng: bản sửa đổi mặc định không hợp lệ 'HEAD'", v.v.

Thực hiện 'git reflog --all' hoặc 'gitk --all' cho tôi thấy phần còn lại của kho lưu trữ vẫn còn nguyên vẹn, nhưng có vẻ như nhánh tôi đang làm việc vừa biến mất, điều này giải thích tại sao HEAD dường như không tồn tại / chỉ vào bất cứ thứ gì.

Tôi biết git lưu giữ tất cả các loại thông tin và tôi cho rằng các cam kết của tôi vừa mới bị bỏ quên bằng cách nào đó, vậy có lệnh nào đó sẽ hiển thị cho tôi các cam kết đó để tôi có thể đặt lại HEAD cho chúng không?

CHỈNH SỬA: Ôi trời. Tôi đã phát hiện ra 'git fsck' và 'git fsck --full' báo cáo "nghiêm trọng: đối tượng 03ca4 ... bị hỏng". Tôi có thể làm gì ma quỷ về điều đó?

CHỈNH SỬA: Ôi trời ơi. Tôi đã kiểm tra một nhánh khác, sau đó cố gắng tạo lại nhánh gốc có cùng tên bằng cách sử dụng 'git checkout -b lostbranchname' và git nói rằng "lỗi: không thể giải quyết tham chiếu refs / heads / lostbranchname: Không có lỗi, nghiêm trọng: Không thành công để khóa ref để cập nhật: Không có lỗi ”. 'Không có lỗi' phải là một lỗi đặc biệt khó chịu. Vì vậy, có vẻ như nó vẫn còn quanh quẩn, nhưng không thể sử dụng và không thể bị giết.

EDIT: Siêu duper oh thân yêu. Tôi đã thực hiện một loạt các giải nén và đóng gói lại và thay thế mọi thứ như được đề xuất ở đây: Làm thế nào để khôi phục các đối tượng Git bị hỏng do lỗi đĩa cứng? , nhưng bây giờ tôi đang nhận được một hàm băm khác được báo cáo là hỏng, vì một thứ vô hại như 'trạng thái git'. Tôi nghĩ rằng toàn bộ điều đã được hoàn thành. Git thật đáng yêu và tất cả, nhưng tôi không nên phải đối mặt với những thứ như thế này.


Liên quan đến git checkout -b lostbranchname- nếu bạn chỉ quan tâm đến tên của nhánh (không phải nội dung của nó), bạn có thể xóa (hoặc đổi tên) theo cách thủ công .git/refs/heads/lostbranchname- điều đó hy vọng sẽ làm được thủ thuật.
Antony Hatchkins

1
Và bạn không có một dòng nào để đẩy thư mục git này vào?
Lakshman Prasad

1
Đáng buồn là không, nó thực sự là một kho lưu trữ thay thế cho một hệ thống kiểm soát nguồn kém hơn, tôi chỉ sử dụng nó cục bộ để nhận tất cả các tính năng và tiện ích của git mà không gặp rắc rối với hệ thống khác. Nhưng ít nhất hệ thống khác không tự làm hỏng chính nó một cách ngẫu nhiên. Tuy nhiên, điều đó có nghĩa là tất cả những gì tôi đã mất là những thay đổi của tôi kể từ lần cuối tôi đăng nhập vào hệ thống khác, mà tôi đã khôi phục được. Đã đến lúc bắt đầu một kho lưu trữ mới!
Ben Hymers

7
Tôi ngần ngại khi nói rằng git đã khiến bạn "đối phó với loại điều này" hoặc rằng nó tự làm hỏng. Không có gì ngoài bản sao lưu có thể hoàn toàn ổn định chống lại mất dữ liệu.
Cascabel

1
Tôi thực sự biết, tôi (tự nhiên) hơi bối rối rằng tôi đã đánh mất lịch sử xinh đẹp của mình. Đó không phải là lỗi của git, bất kỳ hệ thống nào khác cũng sẽ xử lý cùng một lỗi hệ thống tệp nhất định.
Ben Hymers

Câu trả lời:


134

Thay vì để ngỏ điều này, tôi nghĩ tôi sẽ đưa ra câu trả lời cho câu hỏi của chính mình. Sử dụng git reflog --alllà một cách tốt để duyệt qua các cam kết mồ côi - và sử dụng hàm băm SHA1 để bạn có thể tạo lại lịch sử.

Trong trường hợp của tôi, kho lưu trữ đã bị hỏng nên điều này không giúp được gì; git fsckcó thể giúp bạn tìm và đôi khi sửa lỗi trong chính kho lưu trữ.


3
Cảm ơn. Đây là nơi duy nhất tôi tìm thấy thông tin này khi cố gắng kéo một yêu cầu kéo mồ côi trên github. Đã giải quyết vấn đề của tôi.
SystemParadox

6
trong trường hợp bất cứ ai muốn tất cả trong gitk: [alias] orphank = !gitk --all --date-order ``git reflog | cut -c1-7``&(chỉnh sửa: tưởng tượng những backticks đôi nơi những người duy nhất - thoát dường như không làm việc ở đây)
mbx

1
Mẹo tuyệt vời @mbx! Rất hữu ích để có thể xem các liên kết giữa các cam kết mồ côi bằng đồ thị!
Ben Hymers

@BenHymers Sẽ rất tuyệt nếu chúng ta cũng có thể nhận được các đường chấm cho các quan hệ cam kết giống như "rebase / squash". Tôi vẫn chưa tìm ra cách để làm điều đó.
mbx

Tôi không biết về reflog khi tôi viết câu trả lời ở trên. Nó là một công cụ hữu ích!
Jamey Hicks

17

Với git 2.9.x / 2.10 (Q3 2016), bạn sẽ không phải sử dụng git reflog --allnữa, git reflogsẽ là đủ.

Xem cam kết 71abeb7 (03/06/2016) bởi SZEDER Gábor ( szeder) .
(Merged bởi Junio C Hamano - gitster- trong phạm 7.949.837 , 6 tháng 7 năm 2016)

reflog: tiếp tục đi reflogqua các cam kết gốc

Nếu một kho lưu trữ chứa nhiều hơn một cam kết gốc, thì HEAD reflog của nó có thể chứa nhiều "sự kiện tạo", tức là các mục nhập có giá trị "from" là giá trị null sha1.
Việc liệt kê một bản cập nhật như vậy hiện đang dừng sớm ở lần nhập đầu tiên, ngay cả khi bản nhật ký vẫn chứa các mục cũ hơn.
Điều này có thể khiến người dùng sợ rằng bản cập nhật của họ đã bị cắt ngắn sau khi ' git checkout --orphan'.

Tiếp tục xem lại nhật ký qua các sự kiện tạo như vậy dựa trên giá trị "mới" của mục nhập nhật ký trước đó.


4

Một tính năng tốt của git là nó phát hiện tham nhũng. Tuy nhiên, nó không bao gồm sửa lỗi để bảo vệ khỏi tham nhũng.

Tôi hy vọng rằng bạn đã đẩy nội dung của kho lưu trữ này sang một máy khác hoặc bạn có các bản sao lưu để khôi phục các phần bị hỏng.

Tôi không có bất kỳ kinh nghiệm nào với git trên windows nhưng chưa bao giờ thấy loại hành vi này với git trên Linux hoặc OS X.


3

Tôi thường thấy git reflogđầu ra là khó hiểu. Đối với tôi, nó dễ dàng hơn nhiều để hiểu một biểu đồ cam kết git log --graph --reflog. Ghi đè định dạng để chỉ hiển thị tóm tắt cam kết cũng có thể làm cho biểu đồ dễ theo dõi hơn:

$ git alias graph "log --graph --all --format='%h %s%n        (%an, %ar)%d' --abbrev-commit
$ git graph --reflog

* f06abeb Add feature
|         (Sue Dakota, 4 days ago) (HEAD -> master)
* f126291 Fix the build
|         (Oski M. Wizard, 5 days ago) (origin/master, master)
* 3c4fb9c Break the build
|         (Alyssa P. Hacker, 5 days ago)
| * e3124bf fixup! More work for feature
| |         (Sue Dakota, 4 days ago)
| | * 6a7a52e Lost commit
| |/          (Sue Dakota, 4 days ago)
| * 69d9438 More work for feature
| |         (Sue Dakota, 2 weeks ago)
| * 8f69aba Initial work for feature
|/          (Sue Dakota, 3 weeks ago)
* d824fa9 Fix warnings from the linter
|         (Theo Ristudent, 4 weeks ago)
* 9f782b8 Fix tests flakes
|         (Tess Driven, 5 weeks ago)

Từ đó thì rõ ràng rằng e3124bf6a7a52elà trẻ mồ côi unreferenced, và có bối cảnh từ các cam kết tổ tiên của họ.


Vừa mới tiết kiệm cho tôi hàng giờ làm việc đã mất! đã vô tình xóa một chi nhánh cục bộ có các cam kết chưa được xóa trên đó, git reflog --allkhông hiển thị chúng, với git log --graph --reflogchúng rất hiển thị ...
Adam.Er
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.