Czuję się jak dziecko w biurze dyrektora wyjaśniające, że pies zjadł moją pracę domową w noc przed jej terminem, ale gapię się na jakiś szalony błąd utraty danych w twarz i nie mogę zrozumieć, jak to się stało. Chciałbym wiedzieć, jak git mógłby zjeść całe moje repozytorium! Wiele razy przerzucałem gitarzystę i nigdy nie mrugał. Użyłem go, aby podzielić repozytorium 20 Gig Subversion na 27 repozytoriów git i rozgałęzić foo z nich, aby rozwiązać bałagan i nigdy nie straciłem bajta na mnie. Reflog jest zawsze dostępny. Tym razem dywan zniknął!
Z mojej perspektywy wszystko, co zrobiłem, to uruchomić git pull
i zniszczyć moje całe lokalne repozytorium. Nie chodzi mi o to, że „popsuła sprawdzoną wersję”, „gałąź, w której byłam”, czy coś w tym rodzaju. Mam na myśli, że cała rzecz zniknęła .
Oto zrzut ekranu mojego terminalu podczas incydentu:
Pozwól mi przejść przez to. Mój wiersz polecenia zawiera dane o bieżącym repozytorium git (używając implementacji vcs_info prezto), dzięki czemu możesz zobaczyć, kiedy repozytorium git zniknęło. Pierwsze polecenie jest wystarczająco normalne:
» caleb » jaguar » ~/p/w/incil.info » ◼ zend ★ »
❯❯❯ git co master
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Tam widać, że byłem w gałęzi „zend” i sprawdziłem master. Na razie w porządku. Zobaczysz w pytaniu przed moim następnym poleceniem, że pomyślnie przełącza gałęzie:
» caleb » jaguar » ~/p/w/incil.info » ◼ master ★ »
❯❯❯ git pull
remote: Counting objects: 37, done.
remote: Compressing objects: 100% (37/37), done.
remote: Total 37 (delta 25), reused 0 (delta 0)
Unpacking objects: 100% (37/37), done.
From gitlab.alerque.com:ipk/incil.info
+ 7412a21...eca4d26 master -> origin/master (forced update)
f03fa5d..c8ea00b devel -> origin/devel
+ 2af282c...009b8ec verse-spinner -> origin/verse-spinner (forced update)
First, rewinding head to replay your work on top of it...
>>> elapsed time 11s
I po prostu zniknęło. Znacznik czasu, który upłynął, wyświetla się przed następnym monitem, jeśli upłynęło więcej niż 10 sekund. Git nie dał żadnego wyjścia poza powiadomieniem, że przewijało się, by powtórzyć. Nic nie wskazuje na to, że się skończyło.
Następny monit nie zawiera danych o tym, w której gałęzi jesteśmy ani o stanie git.
Nie zauważając, że się nie powiodło, nieświadomie próbowałem uruchomić inną komendę git, aby powiedzieć, że nie jestem w repozytorium git. Uwaga: PWD nie zmieniło się:
» caleb » jaguar » ~/p/w/incil.info »
❯❯❯ git fetch --all
fatal: Not a git repository (or any parent up to mount point /home)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
Po tym rozejrzenie się wykazało, że jestem w całkowicie pustym katalogu. Nic. Brak katalogu „.git”, nic. Pusty.
Mój lokalny git jest w wersji 2.0.2. Oto kilka ciekawostek z mojej konfiguracji git, które mogą być istotne dla zrozumienia, co się stało:
[branch]
autosetuprebase = always
rebase = preserve
[pull]
rebase = true
[rebase]
autosquash = true
autostash = true
[alias]
co = checkout
Na przykład git pull
ustawiłem, aby zawsze wykonywać rebase zamiast scalania, aby część powyższego wyniku była normalna.
Mogę odzyskać dane. Nie sądzę, żeby istniały jakieś przedmioty git inne niż nieistotne skrytki, które nie zostały przekazane innym repozytoriom, ale chciałbym wiedzieć, co się stało .
Sprawdziłem:
- Wiadomości w dmesg lub dzienniku systemowym. Nic, nawet zdalnie istotne.
- Nic nie wskazuje na awarię dysku lub systemu plików (wszystkie LVM + LUKS + EXT4 wyglądają normalnie). Nic nie znaleziono w Lost +.
- Nie prowadziłem nic innego. W historii nie ma niczego, czego nie pokazuję powyżej, i w tym czasie nie były używane żadne inne terminale. Wokół nie ma żadnych
rm
poleceń, które mogłyby zostać wykonane w niewłaściwym CWD itp. - Grzebanie w innym repozytorium git w innym katalogu nie wykazuje widocznych nieprawidłowości w wykonywaniu
git pull
s.
Czego jeszcze powinienem tu szukać?
źródło
.git
nie istnieje. Nic nie robi - w katalogu głównym git nic nie ma.Odpowiedzi:
Tak,
git
zjadłem moją pracę domową. Wszystko.Zrobiłem
dd
obraz tego dysku po incydencie i pomieszałem go później. Rekonstruując serię zdarzeń z dzienników systemowych, dedukuję, że to, co się stało, było mniej więcej tak:pacman -Syu
) zostało wydane na kilka dni przed tym zdarzeniem.git checkout
i przedgit pull
.git
binarny został wymieniony pogit pull
uruchomieniu i przed zakończeniem.git
odpoczął od wszystkich wysiłków. I usunął świat, więc wszyscy inni też musieli odpocząć.Nie wiem dokładnie, jaki był warunek wyścigu, który to spowodował, ale zamiana plików binarnych w trakcie operacji z pewnością nie jest ani przyjemna, ani możliwa do przetestowania / powtarzalności. Zwykle kopia działającego pliku binarnego jest przechowywana w pamięci, ale
git
jest dziwna i coś w tym, jak odradza swoje wersje, jestem pewien, że doprowadziłem do tego bałaganu. Oczywiście powinno raczej umrzeć, niż wszystko zniszczyć, ale tak właśnie się stało.źródło
git-fetch
,git-rebase
czygit-merge
igit gc
Możliwe, że nie uda się zdefiniować ścieżki pliku do usunięcia.
Twoja sprawa przypomniała mi piękny dzień, kiedy moja domowa
remove(path)
metoda próbowała usunąć folder główny, ponieważ podanym parametrem był pusty ciąg, który system operacyjny poprawił (!) Jako folder główny.To może być podobny błąd git. Tak, że:
remove(project_folder + file_path)
(pseudo kod)file_path
był pusty.remove(project_folder)
źródło
Przy odrobinie szczęścia możesz to naprawić za pomocą następującego polecenia:
Gdy rozpoczną się potencjalne niebezpieczne zmiany, git ukrywa twój obecny stan w ORIG_HEAD. Za jego pomocą możesz cofnąć scalenie lub zmianę bazy.
Podręcznik Git: Cofanie scalenia
źródło
Wygląda
git push --force
na to, że ktoś uruchomił to repozytorium, a ty wprowadziłeś zmiany. Spróbuj sklonować repo na świeżo, co powinno przywrócić Cię do czystego stanu pracy.źródło
.git
katalog za pomocą wymuszonego pchnięcia