Dawno, dawno temu w moim projekcie był plik, który chciałbym teraz uzyskać.
Problem polega na tym: nie mam pojęcia, kiedy go usunąłem i na której ścieżce to było.
Jak zlokalizować zatwierdzenia tego pliku, gdy on istniał?
Dawno, dawno temu w moim projekcie był plik, który chciałbym teraz uzyskać.
Problem polega na tym: nie mam pojęcia, kiedy go usunąłem i na której ścieżce to było.
Jak zlokalizować zatwierdzenia tego pliku, gdy on istniał?
Odpowiedzi:
Jeśli nie znasz dokładnej ścieżki, której możesz użyć
git log --all --full-history -- "**/thefile.*"
Jeśli znasz ścieżkę do pliku, możesz to zrobić:
git log --all --full-history -- <path-to-file>
Powinno to pokazać listę zatwierdzeń we wszystkich gałęziach, które dotknęły tego pliku. Następnie możesz znaleźć żądaną wersję pliku i wyświetlić ją za pomocą ...
git show <SHA> -- <path-to-file>
Lub przywróć go do kopii roboczej za pomocą:
git checkout <SHA>^ -- <path-to-file>
Zwróć uwagę na symbol karetki ( ^
), który pobiera kasę przed zidentyfikowanym, ponieważ w momencie <SHA>
zatwierdzenia plik jest usuwany, musimy spojrzeć na poprzednie zatwierdzenie, aby uzyskać zawartość usuniętego pliku
git log -- <path>
będzie miał danych wyjściowych, gdy jesteś w gałęzi, w której plik nigdy nie istniał. Powinieneś zawsze używać git log --all -- <path>
, aby upewnić się, że nie przegapisz zmian, które miały miejsce w innych gałęziach. Polecenie git log -- <path>
może być bardzo niebezpieczne, jeśli masz więcej niż jedną gałąź i często zapominasz o ścieżkach i gałęziach (takich jak ja), a także niebezpieczne, jeśli pracujesz z innymi programistami.
--all
(dzięki Filipowi ) do swojej git log
odpowiedzi, aby ludzie nie przegapili zmian i plików w innych oddziałach. Pozwoliłoby to zaoszczędzić zapomnianym ludziom, takim jak ja, wiele smutku.
git checkout <SHA>^ -- <path-to-file>
(zwróć uwagę na symbol ^), ponieważ w momencie zatwierdzenia <SHA> plik jest usuwany, musimy spojrzeć na poprzednie zatwierdzenie, aby uzyskać zawartość usuniętego pliku
Uzyskaj listę usuniętych plików i skopiuj pełną ścieżkę usuniętego pliku
git log --diff-filter=D --summary | grep delete
Wykonaj następne polecenie, aby znaleźć identyfikator zatwierdzenia tego zatwierdzenia i skopiuj identyfikator zatwierdzenia
git log --all -- FILEPATH
Pokaż różnicę usuniętego pliku
git show COMMIT_ID -- FILE_PATH
Pamiętaj, że możesz zapisać dane wyjściowe do pliku za pomocą polecenia >
like
git show COMMIT_ID -- FILE_PATH > deleted.diff
unknown revision or path not in the working tree
.
git log --diff-filter=D --summary | grep -E 'delete|^commit\s+\S+'
git-grep-latest(){ result_path=$(git log --diff-filter=D --summary | grep $1 | head -1 | awk '{print $4;}'); latest_commit=$(git log --all -- $result_path | head -1 | awk '{print $2;}'); git show $latest_commit -- $result_path; }
a teraz możesz po prostu zrobić:git-grep-latest some_text
linux pipes
.. spodoba ci się.
Nie można edytować zaakceptowanej odpowiedzi, dlatego dodając ją jako odpowiedź tutaj,
aby przywrócić plik w git, użyj następującego polecenia (zwróć uwagę na znak „^” zaraz po SHA)
git checkout <SHA>^ -- /path/to/file
<SHA>~1
powinien działać tak samo, bez konieczności owijania go cudzysłowami.
Załóżmy, że chcesz odzyskać plik o nazwie MyFile
, ale nie masz pewności co do jego ścieżki (lub rozszerzenia, jeśli o to chodzi):
Prelim .: Unikaj zamieszania, przechodząc do korzenia git
Nietypowy projekt może mieć wiele katalogów o podobnych lub identycznych nazwach.
> cd <project-root>
Znajdź pełną ścieżkę
git log --diff-filter = D - podsumowanie | grep delete | grep MyFile
delete mode 100644 full/path/to/MyFile.js
full/path/to/MyFile.js
to ścieżka i plik, którego szukasz.
Określ wszystkie zatwierdzenia, które wpłynęły na ten plik
git log --oneline --follow - full / path / to / MyFile.js
bd8374c Some helpful commit message
ba8d20e Another prior commit message affecting that file
cfea812 The first message for a commit in which that file appeared.
Pobierz plik
Jeśli wybierzesz pierwszy wymieniony zatwierdzenie (ostatni chronologicznie, tutaj bd8374c), plik nie zostanie znaleziony, ponieważ został usunięty w tym zatwierdzeniu.
> git checkout bd8374c -- full/path/to/MyFile.js
`error: pathspec 'full/path/to/MyFile.js' did not match any file(s) known to git.`
Po prostu wybierz poprzedni (dodaj kursor) zatwierdzenie:
> git checkout bd8374c^ -- full/path/to/MyFile.js
git log --diff-filter=D --summary | find "delete" | find "MyFile"
I kroku 3 , zanotuj cudzysłowy wokół skrótu:git checkout "bd8374c^" -- full/path/to/MyFile.js
@Amber podał prawidłową odpowiedź! Jeszcze jeden dodatek, jeśli nie znasz dokładnej ścieżki do pliku, możesz użyć symboli wieloznacznych! To zadziałało dla mnie.
git log --all -- **/thefile.*
Poniżej znajduje się proste polecenie, w którym użytkownik programisty lub użytkownik git może przekazać usuniętą nazwę pliku z katalogu głównego repozytorium i uzyskać historię:
git log --diff-filter=D --summary | grep filename | awk '{print $4; exit}' | xargs git log --all --
Jeśli ktoś może poprawić polecenie, zrób to.
Spróbuj użyć jednej z przeglądarek, na przykład gitk
, aby przeglądać historię i znaleźć ten na pół zapamiętany plik. (użyj w gitk --all
razie potrzeby dla wszystkich oddziałów)
--all
opcja ma kluczowe znaczenie zarówno dla Twojej odpowiedzi, jak i dla odpowiedzi zaakceptowanej.
Podsumowanie:
Przeszukujesz pełną ścieżkę pliku w historii usuniętych plików git log --diff-filter=D --summary | grep filename
Przywracasz plik z zatwierdzenia przed jego usunięciem
restore () {
filepath="$@"
last_commit=$(git log --all --full-history -- $filepath | grep commit | head -1 | awk '{print $2; exit}')
echo "Restoring file from commit before $last_commit"
git checkout $last_commit^ -- $filepath
}
restore my/file_path
Oto moje rozwiązanie:
git log --all --full-history --oneline -- <RELATIVE_FILE_PATH>
git checkout <COMMIT_SHA>^ -- <RELATIVE_FILE_PATH>