Pytanie Zresetować lub przywrócić określony plik do konkretnej wersji za pomocą Git?


Wprowadziłem kilka zmian w pliku, który został popełniony kilka razy jako część grupy plików, ale teraz chce zresetować / przywrócić zmiany z powrotem do poprzedniej wersji.

Zrobiłem git log wraz z git diff znaleźć wersję, której potrzebuję, ale po prostu nie mam pojęcia, jak przywrócić plik do poprzedniego stanu.


3452
2017-10-18 23:34


pochodzenie


Po powrocie nie zapomnij --cached podczas sprawdzania git diff. połączyć - Geoffrey Hale
Znalazłem twoje pytanie, kiedy zgłosiłem się do mojego. Ale po przeczytaniu tego rozwiązania sprawdziłem swój dziennik i dowiedziałem się, że wprowadziłem te zmiany jako samodzielne zatwierdzenie, więc zrobiłem polecenie git dla tego zatwierdzenia, a wszystko inne pozostało tak, jak chciałem. Nie jest to rozwiązanie, po prostu inny sposób, aby to zrobić. - sudo97


Odpowiedzi:


Zakładając, że hash commit, który chcesz, jest c5f567:

git checkout c5f567 -- file1/to/restore file2/to/restore

The git checkout strona podręcznika zawiera więcej informacji.

Jeśli chcesz powrócić do zatwierdzenia wcześniej c5f567, dołącz ~1 (działa z dowolnym numerem):

git checkout c5f567~1 -- file1/to/restore file2/to/restore

Na marginesie, zawsze czułem się niekomfortowo z tym poleceniem, ponieważ jest używane zarówno do zwykłych rzeczy (zmiana między gałęziami), jak i nietypowych, destrukcyjnych rzeczy (odrzucając zmiany w katalogu roboczym).


4672
2017-10-18 23:39



Jeśli zawiedliście w "abbcdf" i chcecie wersji tuż przed "abbcdf", możesz zrobić git checkout "abbcdf~1" path/to/file. - shadowhand
@shadowhand: Czy istnieje sposób, aby to odwrócić, więc jest to wersja zaraz po? - aliteralmind
@aliteralmind: Nie, niestety notacja skrótu historii Git cofa się tylko w historii. - Greg Hewgill
Jeśli zamierzasz użyć nazwy oddziału dla abcde (na przykład. develop) będziesz chciał git checkout develop -- file/to/restore (zauważ podwójny kreska) - Ohad Schneider
@aliteralmind: Właściwie, tak, jest sposób, aby to zrobić: "git log --reverse -1 --ancestry-path yourgitrev..master", a następnie użyj odpowiednich opcji, aby uzyskać tylko git rev. --ancestry-path "narysuje linię" pomiędzy dwoma zatwierdzeniami, a -1 wyświetli tylko jedną wersję, a --reverse zapewni, że pierwszy wpis będzie najstarszy. - Chris Cogdon


Możesz szybko przejrzeć zmiany wprowadzone do pliku za pomocą polecenia diff:

git diff <commit hash> <filename>

Następnie, aby przywrócić określony plik do tego zatwierdzenia, użyj polecenia reset:

git reset <commit hash> <filename>

Może być konieczne użycie --hard opcja, jeśli masz lokalne modyfikacje.

Dobry przepływ pracy do zarządzania punktami drogi polega na użyciu znaczników do czystego oznaczania punktów na osi czasu. Nie bardzo rozumiem twoje ostatnie zdanie, ale możesz chcieć rozdzielić gałąź z poprzedniego punktu w czasie. Aby to zrobić, użyj podręcznego polecenia kasy:

git checkout <commit hash>
git checkout -b <new branch name>

Możesz następnie dokonać ponownego porównania z głównym, kiedy będziesz gotowy do scalenia tych zmian:

git checkout <my branch>
git rebase master
git checkout master
git merge <my branch>

508
2017-12-17 06:59



Polecenie 'git checkout <commit hash>' dało mi starszą wersję projektu dokładnie tego, dla którego szukałem Dzięki Chris. - vidur punj
'git reset <commit hash> <filename>' nie zmieniło mojego pliku, który chciałem zmienić. Czy istnieje sposób, aby sprawdzić wersję pliku, w szczególności, a nie kasę całego projektu? - Danny
Aby przywrócić plik git checkout <commit hash> <filename> pracował dla mnie lepiej niż git reset - Motti Strom
nie można użyć git reset aby zresetować pojedynczy plik, pojawi się błąd fatal: Cannot do hard reset with paths - slier
Co slier powiedział: nie możesz git reset --hard <commit hash> <filename>. To spowoduje błąd z fatal: Cannot do hard reset with paths. Co powiedział Motti Strom: użyj git checkout <commit hash> <filename> - Hawkeye Parker


Możesz użyć dowolnego odniesienia do zatwierdzenia git, w tym SHA-1, jeśli jest to najwygodniejsze. Chodzi o to, że polecenie wygląda następująco:

git checkout [commit-ref] -- [filename]


306
2018-04-07 21:48



Jaka jest różnica między tą odpowiedzią, która ma --i zaakceptowany, który nie ma? - 2rs2ts
W git, '-' przed listą plików mówi git, że wszystkie następne argumenty powinny być interpretowane jako nazwy plików, a nie jako nazwy rozgałęzień lub cokolwiek innego. To czasami pomocny disambiguator. - foxxtrot
"-" to nie tylko konwencja git, ale coś, co można znaleźć w różnych miejscach w linii poleceń * nix. rm -- -f (usuń plik o nazwie -f) wydaje się być kanonicznym przykładem. Więcej szczegółów tutaj - Hawkeye Parker
Po prostu dodaj do tego, co powiedział @HawkeyeParker, rm command używa getopt (3) do parsowania swoich argumentów. getopt to polecenie do analizowania argumentów poleceń. gnu.org/software/libc/manual/html_node/Getopt.html - Devy
@ Kochanie Tak, właśnie o to mi chodzi, i tak, prawdopodobnie nie jest to powszechne. Widziałem ten przykład w różnych miejscach, może po to, aby uczynić go niezapomnianym: rm -f jest dobrze znany jako straszny / niebezpieczny. Ale chodzi o to, że w * nix nazwa pliku mogą zacznij od "-", a to zmyli różnych interpretatorów linii poleceń, którzy, gdy zobaczą znak "-", oczekują opcji polecenia do naśladowania. Może to być dowolny plik rozpoczynający się od "-"; np. "-mySpecialFile". - Hawkeye Parker


git checkout -- foo

To się zresetuje foo kierować się. Możesz również:

git checkout HEAD^ foo

za jedną powtórkę z powrotem itp.


244
2017-08-29 20:56



Proponuję użyć składni git checkout -- foo aby uniknąć błędów, jeśli foo jest czymś specjalnym (jak katalog lub plik o nazwie -f). Z git, jeśli nie masz pewności, zawsze prefiksuj wszystkie pliki i katalogi specjalnym argumentem --. - Mikko Rantalainen
Dodatkowa uwaga do komentarza Mikko: -- nie jest poleceniem git i nie jest specjalne dla git. Jest to wbudowane bash oznaczające koniec opcji poleceń. Możesz go używać również z wieloma innymi poleceniami basha. - matthaeus
@matthaeus nie jest ani specyficzny dla basha, ani dla powłoki. Jest to konwencja zaimplementowana w wielu różnych poleceniach (i obsługiwana przez getopt). - Greg Hewgill


Aby powrócić do ostatnio zatwierdzonej wersji, która jest najczęściej potrzebna, możesz użyć tego prostszego polecenia.

git checkout HEAD file/to/restore

106
2018-01-14 06:15



jaka jest różnica między tym (git checkout plik HEAD / to / restore) i git reset - twardy plik / do / przywrócić ??? - Motti Shneor
1) łatwiej zapamiętać bardziej ogólny sposób 2) nie martw się, aby nacisnąć Enter przed wprowadzeniem nazwy pliku - Roman Susi


Miałem ten sam problem właśnie teraz i znalazłem ta odpowiedź najłatwiejszy do zrozumienia (commit-ref jest wartością SHA zmiany w dzienniku, do którego chcesz wrócić):

git checkout [commit-ref] [filename]

Spowoduje to umieszczenie starej wersji w twoim katalogu roboczym, a stamtąd możesz ją zatwierdzić, jeśli chcesz.


100
2018-05-27 17:52





Jeśli wiesz, ile commitów potrzebujesz, możesz użyć:

git checkout master~5 image.png

Zakłada się, że jesteś na master gałąź, a żądana wersja to 5 zatwierdzeń.


85
2018-04-07 14:03





Myślę, że znalazłem to ... od http://www-cs-students.stanford.edu/~blynn/gitmagic/ch02.html

Czasami po prostu chcesz wrócić i zapomnieć o każdej zmianie po pewnym punkcie, ponieważ wszystkie one są złe.

Zacząć od:

$ git log

który pokazuje listę ostatnich zatwierdzeń i ich skrótów SHA1.

Następnie wpisz:

$ git reset --hard SHA1_HASH

przywrócić stan do danego zatwierdzenia i trwale usunąć wszystkie nowsze zatwierdzenia z rekordu.


75
2017-12-17 06:53



Git nigdy niczego nie usuwa. Twoje stare zatwierdzenia wciąż tam są, ale jeśli nie ma na nich wskazówki gałęzi, nie są już dostępne. git reflog będzie je wyświetlał, dopóki nie wyczyścisz swojego repozytorium za pomocą git-gc. - Bombe
@Bombe: Dziękuję za informacje. Sprawdziłem starą wersję pliku. Po przeczytaniu komentarza mogłem użyć "gitref" do wyszukania częściowego skrótu SHA1 i użyć "kasy", aby powrócić do najnowszej wersji. Inni użytkownicy git mogą uznać te informacje za pomocne. - Winston C. Yang
ewentualnie po którym następuje git push --force - bshirley
Jeśli masz niezatwierdzone zmiany, przegrasz jeśli zrobią reset git - trudno - Boklucius
@Bombe - "Git nigdy niczego nie usuwa, twoje stare zatwierdzenia wciąż tam są, ale jeśli nie ma na nich wskazówki gałęzi, nie są już dostępne." - ale zatwierdzenia takie jak te są przycinane po pewnym ustalonym czasie, więc "Git nigdy niczego nie usuwa" jest nieprawdziwe. - Bulwersator


To zadziałało dla mnie:

git checkout <commit hash> file

Następnie zatwierdz zmianę:

git commit -a

59
2017-08-25 22:12





Musisz zachować ostrożność, kiedy mówisz "wycofywanie". Jeśli kiedyś miałeś jedną wersję pliku w zatwierdzeniu $ A, a później wprowadziłeś dwie zmiany w dwóch oddzielnych zatwierdzeniach $ B i $ C (to co widzisz jest trzecią iteracją pliku), i jeśli powiesz " Chcę wrócić do pierwszego ", naprawdę masz na myśli?

Jeśli chcesz pozbyć się zmian drugiej i trzeciej iteracji, jest to bardzo proste:

$ git checkout $A file

a następnie zatwierdzasz wynik. Komenda pyta "Chcę pobrać plik ze stanu zarejestrowanego przez commit $ A".

Z drugiej strony chodziło o to, aby pozbyć się zmiany, do której wprowadziła druga iteracja (tj. Commit $ B), zachowując to, co commit $ C zrobił dla pliku, i chcesz przywrócić $ B

$ git revert $B

Zauważ, że ktokolwiek stworzył commit $ B może nie był bardzo zdyscyplinowany i mógł popełnić całkowicie niezwiązane zmiany w tym samym zatwierdzeniu, a to odwrócenie może dotknąć plików innych niż plik widzisz obraźliwe zmiany, więc możesz uważnie sprawdzić wynik po tym.


53
2018-01-11 08:13



Zrobiłem to, ale potem "plik dziennika git" powiedziałby, że byłem na pierwotnym zatwierdzeniu, HEAD. Wyglądało na to, że "git checkout" zawodzi. Jednak status git pokazał, że plik został faktycznie zmieniony, a "plik różnicowy git diff" pokazuje rzeczywiste zmiany. Również "status git" pokazał, że plik również się zmienił. Więc nie używaj "git log" tutaj, aby śledzić, które pliki zostały zmienione. - Frederick Ollinger