Przeglądaj osierocone zatwierdzenia w Git

102

Moje repozytorium git w jakiś sposób nie działa - załadowałem msysgit dziś rano i zamiast nazwy gałęzi wyświetlanej po bieżącym katalogu, wyświetla się "((ref: re ...))", 'git status' zgłasza wszystko jako new file, 'git log' i 'git reflog' powiedz mi "fatal: zła domyślna wersja 'HEAD'" i tak dalej.

Wykonanie polecenia „git reflog --all” lub „gitk --all” pokazuje mi, że reszta repozytorium jest nienaruszona, ale wygląda na to, że gałąź, nad którą pracowałem, właśnie zniknęła, co wyjaśnia, dlaczego HEAD nie wydaje się istnieć / wskazywać na cokolwiek.

Wiem, że git przechowuje wszystkie rodzaje informacji i zakładam, że moje zatwierdzenia zostały w jakiś sposób osierocone, więc czy jest jakieś polecenie, które pokaże mi te zatwierdzenia, abym mógł zresetować do nich HEAD?

EDYCJA: Ojej. Odkryłem „git fsck”, a „git fsck --full” zgłasza „fatal: obiekt 03ca4 ... jest uszkodzony”. Co do diabła mogę z tym zrobić?

EDYCJA: Ojej oh kochany. Sprawdziłem inną gałąź, a następnie próbowałem odtworzyć oryginalną gałąź o tej samej nazwie, używając 'git checkout -b lostbranchname', a git mówi: „błąd: nie można rozwiązać referencji refs / heads / lostbranchname: brak błędu, krytyczny: niepowodzenie aby zablokować odniesienie do aktualizacji: brak błędu ”. „Brak błędu” musi być szczególnie paskudnym błędem. Wygląda więc na to, że wciąż się kręci, ale nie można go użyć ani zabić.

EDYCJA: Super duper ojej. Zrobiłem mnóstwo rozpakowywania, przepakowywania i wymiany rzeczy, jak zasugerowałem tutaj: Jak odzyskać obiekty Gita uszkodzone przez awarię dysku twardego? , ale teraz otrzymuję kolejny hash zgłaszany jako uszkodzony, dla czegoś tak nieszkodliwego jak „status gita”. Myślę, że wszystko jest wężem. Git jest uroczy iw ogóle, ale nie powinienem mieć do czynienia z takimi rzeczami.

Ben Hymers
źródło
Co do git checkout -b lostbranchname- jeśli zależy Ci tylko na nazwie gałęzi (a nie na jej zawartości), możesz ręcznie usunąć (lub zmienić nazwę) .git/refs/heads/lostbranchname- mam nadzieję, że załatwi sprawę.
Antony Hatchkins
1
I nie masz upstream, do którego wysyłasz ten folder git?
Lakshman Prasad
1
Niestety nie, w rzeczywistości jest to repozytorium zastępcze dla gorszego systemu kontroli źródła, używam go tylko lokalnie, aby uzyskać wszystkie funkcje i subtelności gita bez kłopotów z innym systemem. Ale przynajmniej drugi system nie psuje się przypadkowo. Mimo to oznacza to, że wszystko, co straciłem, to zmiany wprowadzone od czasu ostatniego logowania do innego systemu, które już odzyskałem. Czas zacząć nowe repozytorium!
Ben Hymers,
7
Wahałbym się powiedzieć, że drań zmusił cię do „poradzenia sobie z tego rodzaju rzeczami” lub że sam się zepsuł. Nic poza kopią zapasową nie może być całkowicie stabilne przed utratą danych.
Cascabel
1
Wiem naprawdę, jestem po prostu (naturalnie) trochę poirytowany, że straciłem swoją piękną historię. To nie wina gita, każdy inny system zachowywałby się tak samo, jak podane błędy systemu plików.
Ben Hymers,

Odpowiedzi:

135

Zamiast zostawiać to otwarte, myślę, że udzielę odpowiedzi na moje własne pytanie. Używanie git reflog --allto dobry sposób na przeglądanie osieroconych zatwierdzeń - i używanie skrótów SHA1, które pozwalają na rekonstrukcję historii.

Jednak w moim przypadku repozytorium było uszkodzone, więc to nie pomogło; git fsckmoże pomóc Ci znaleźć, a czasem naprawić błędy w samym repozytorium.

Ben Hymers
źródło
3
Dzięki. To jedyne miejsce, w którym znalazłem te informacje, próbując wyciągnąć osierocone żądanie ściągnięcia na githubie. Rozwiązał mój problem.
SystemParadox
6
na wypadek, gdyby ktoś chciał wszystko w gitk: [alias] orphank = !gitk --all --date-order ``git reflog | cut -c1-7``&(edytuj: wyobraź sobie te podwójne grawerunki, w których pojedyncze - ucieczka nie wydaje się działać tutaj)
mbx
1
Niesamowita wskazówka @mbx! Bardzo przydatne, aby móc graficznie zobaczyć linki między osieroconymi zatwierdzeniami!
Ben Hymers
@BenHymers Byłoby fajnie, gdybyśmy mogli również uzyskać przerywane linie dla relacji w stylu „rebase / squash”. Jeszcze nie znalazłem sposobu, żeby to zrobić.
mbx
Nie wiedziałem o reflogu, kiedy pisałem powyższą odpowiedź. To takie przydatne narzędzie!
Jamey Hicks
17

Z git 2.9.x / 2.10 (Q3 2016), nie będziesz już musiał używać git reflog --all, git reflogwystarczy.

Zobacz zatwierdzenie 71abeb7 (03 czerwca 2016) autorstwa SZEDER Gábor ( szeder) .
(Połączone przez Junio ​​C Hamano - gitster- w zobowiązaniu 7949837 , 06 lipca 2016 r.)

reflog: kontynuuj przechodzenie po reflogprzeszłych zatwierdzeniach root

Jeśli repozytorium zawiera więcej niż jedno zatwierdzenie roota, jego reflog HEAD może zawierać wiele „zdarzeń tworzenia”, tj. Wpisów, których wartością „from” jest null sha1.
Wyświetlanie takiego reflogu obecnie zatrzymuje się przedwcześnie przy pierwszym takim wpisie, nawet jeśli reflog nadal zawiera starsze wpisy.
Może to przestraszyć użytkowników, którzy pomyślą, że ich reflog został obcięty po ' git checkout --orphan'.

Kontynuuj przechodzenie przez reflog obok takich wydarzeń tworzenia w oparciu o „nową” wartość poprzedniego wpisu reflog.

VonC
źródło
4

Jedną z dobrych cech git jest to, że wykrywa korupcję. Jednak nie obejmuje korekcji błędów w celu ochrony przed korupcją.

Mam nadzieję, że przesłałeś zawartość tego repozytorium na inny komputer lub masz kopie zapasowe do odzyskania uszkodzonych części.

Nie mam żadnego doświadczenia z git w systemie Windows, ale nigdy nie widziałem tego rodzaju zachowania z git w systemie Linux lub OS X.

Jamey Hicks
źródło
3

Zwykle wydaje mi się, że dane git reflogwyjściowe są mylące. Znacznie łatwiej jest mi zrozumieć wykres zmian z git log --graph --reflog. Zastąpienie formatu, aby wyświetlać tylko podsumowania zatwierdzeń, również może ułatwić śledzenie wykresu:

$ 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)

Od tego jest jasne, że e3124bfi 6a7a52eto bez odnośników sierotami, a tam od kontekstu ich zatwierdzeń przodka.

jamesdlin
źródło
Zaoszczędziło mi to godzin straconej pracy właśnie teraz! przypadkowo usunął lokalny oddział, który miał niezakończone zatwierdzenia, git reflog --allnie pokazuje ich, git log --graph --reflogponieważ były bardzo widoczne ...
Adam.Er8