Twardy reset pojedynczego pliku

1004

Obecnie mam trzy zmodyfikowane pliki w moim katalogu roboczym. Chcę jednak, aby jeden z nich został zresetowany do stanu HEAD.

W SVN użyłbym svn revert <filename>(a następnie w svn update <filename>razie potrzeby), ale w Git powinienem użyć git reset --hard. To polecenie nie może jednak działać na jednym pliku.

Czy jest jakiś sposób w Git, aby odrzucić zmiany w jednym pliku i zastąpić go świeżą kopią HEAD?

Emiliano
źródło
3
git checkoutponiżej jest odpowiedź. W git „cofnij” to coś, co robisz w celu zatwierdzenia. „Cofnij” powoduje powtórzenie odwrotności historycznego zatwierdzenia w twoim katalogu roboczym, dzięki czemu możesz dokonać nowego zatwierdzenia, które „cofnie” cofnięte zatwierdzenie. Uważam, że jest to częste zamieszanie dla osób przychodzących do git z svn.
Dan Ray
Jeśli jesteś zainteresowany, dlaczego nie możesz wykonać twardego resetowania ścieżkami, sprawdź moją odpowiedź tam .
użytkownik
To pytanie zakłada, że ​​wiadomo, czym jest twardy reset.

Odpowiedzi:

1807

Możesz użyć następującego polecenia:

git checkout HEAD -- my-file.txt

... który zaktualizuje zarówno kopię roboczą, jak my-file.txti jej stan w indeksie, o tej z HEAD.

--w zasadzie oznacza: traktuj każdy argument po tym punkcie jako nazwę pliku . Więcej szczegółów w tej odpowiedzi . Dzięki VonC za zwrócenie na to uwagi.

Mark Longair
źródło
58
Pełniejsza odpowiedź. +1;) Jeśli chodzi o „-”, zobacz także stackoverflow.com/questions/6561142/… (i, bardziej ogólnie, stackoverflow.com/questions/1192180/… )
VonC
8
Nie zapomnij też, że możesz odwoływać się do poprzedniego zatwierdzenia, HEAD~1aby wskazać przedostatnie zatwierdzenie.
Ryanmt,
14
Możesz pominąć, HEADjeśli jesteś na czele obecnego oddziału - patrz norbauer.com/rails-consulting/notes/…
cxw
4
Jakiś wgląd w to, dlaczego resetpolecenie (jak to mówi) „nie można wykonać twardego resetu ze ścieżkami”, a następnie dlaczego to checkoutpolecenie nie jest (nie może być) użyte do twardego resetu całego zestawu? (Mam na myśli, dlaczego tak zostało zaprojektowane).
Sz.
1
@cxw Niestety, nie jest to do końca prawda. Ze strony podręcznika git checkout: „Zastąp ścieżki w drzewie roboczym, zastępując je zawartością w indeksie lub w <tree-ish>”. To <tree-ish>znaczy, jeśli zostanie pominięty, dowolna zawartość indeksu zostanie użyta do aktualizacji drzewa roboczego. To może, ale nie musi różnić się od HEAD.
tuntap
136

Zresetuj do głowy:

Aby na stałe zresetować pojedynczy plik do HEAD:

git checkout @ -- myfile.ext

Zauważ, że @to skrót HEAD. Starsza wersja git może nie obsługiwać krótkiej formy.

Resetuj do indeksu:

Aby na stałe zresetować pojedynczy plik do indeksu , zakładając, że indeks nie jest pusty, w przeciwnym razie HEAD:

git checkout -- myfile.ext

Chodzi o to, że aby być bezpiecznym, nie chcesz pomijać @ani HEADwykonywać polecenia, chyba że specjalnie chcesz zresetować tylko do indeksu .

Acumenus
źródło
1
O co chodzi z „-” przed myfile.ext?
Lance Kind
3
@LanceKind Jak rozumiem, służy do wytyczenia listy nazw plików, która następuje po niej. Bez niego git niepoprawnie interpretuje argumenty.
Acumenus
2
Nie tylko nazwy plików. Powszechnie stosowana konwencja oddziela opcje od argumentów pozycyjnych w wielu narzędziach. Patrz man bashstrona Wspomniany również w tej odpowiedzi: unix.stackexchange.com/a/187548/142855
boweeb
1
Konwencjonalnie --służy do informowania programu I've finished specifying "options", and from here on, everything will be a positional argument.. Tradycyjnie „opcje” to tokeny, --recursivektóre mogą pojawiać się w dowolnej kolejności, a nawet być łączone razem w krótkiej formie, np rm -rf. Z. Przeciwnie, „argumenty pozycyjne” są bardziej podobne do argumentów przekazywanych do funkcji w języku programowania: ich pozycja na liście tokenów określa, co dokładnie program ma zamiar z nimi zrobić (często są to nazwy plików). --usuwa niejasności co do tego, który jest który.
iono
42

Aby powrócić do upstream / master:

git checkout upstream/master -- myfile.txt
Ann Raiho
źródło
18

Od wersji Git 2.23 (sierpień 2019 r.) Możesz używać restore( więcej informacji ):

git restore pathTo/MyFile

Powyższy przywróci MyFilena HEAD(ostatni commit) na bieżącej gałęzi.

Jeśli chcesz uzyskać zmiany z innych zmian, możesz cofnąć się do historii zmian. Poniższe polecenie otrzyma MyFiledwa zatwierdzenia poprzedzające ostatnie. Potrzebujesz teraz opcji -s( --source), ponieważ teraz używasz, master~2a nie master(domyślnie) podczas przywracania źródła:

git restore -s master~2 pathTo/MyFile

Możesz także pobrać plik z innego oddziału!

git restore -s my-feature-branch pathTo/MyFile
AxeEffect
źródło
1
Jak dotąd najłatwiejszy sposób. Niestety ta odpowiedź nie przyciąga wystarczającej uwagi.
singrium
5

Odniesienie do HEAD nie jest konieczne.

git checkout -- file.js jest wystarczający

Emanuel Friedrich
źródło
4

możesz użyć poniższego polecenia do zresetowania pojedynczego pliku

git checkout HEAD -- path_to_file/file_name

Wyświetl wszystkie zmienione pliki, które chcesz uzyskać za path_to_file/filenamepomocą poniższego polecenia

git status
HariKishore
źródło
1

Możesz użyć następującego polecenia:

git reset -- my-file.txt

która zaktualizuje zarówno kopię roboczą my-file.txtpo dodaniu.

ADDYQU
źródło
Nie zmienia zawartości zmodyfikowanego pliku, zgodnie z żądaniem.
Rafael
Kiedy dodajesz do skrytki Czy edytowałeś plik?
ADDYQU,
1
To nie jest dokładnie punkt @ ADDQU. Pytanie brzmi: jak „zresetować” plik, a nie usuwać go z listy etapowej.
Rafael
@Rafael Masz rację, ale chcę poinformować, że jest też sposób.
ADDYQU
0

Możesz użyć następującego polecenia:

git checkout filename

Jeśli masz oddział o tej samej nazwie, musisz użyć tego polecenia:

git checkout -- filename
Milad Rahimi
źródło
1
Nie spowoduje to „twardego resetu” pliku - kopiuje jedynie stan indeksu do działającego drzewa. „Twardy reset” najpierw zeruje indeks.
AH
-21

Prosty, łatwy i praktyczny sposób na wyciągnięcie ciepłej wody, szczególnie jeśli nie czujesz się tak komfortowo z git:

  1. Wyświetl dziennik swojego pliku

    git log myFile.js

    popełnić 1023057173029091u23f01w276931f7f42595f84f Autor: kmiklas Data: Wt 7 sierpnia 09:29:34 2018 -0400

    JIRA-12345 - Refaktoryzacja z nową architekturą.

  2. Uwaga skrót pliku:

    1023057173029091u23f01w276931f7f42595f84f

  3. Pokaż plik za pomocą skrótu. Upewnij się, że tego chcesz:

    git show 1023057173029091u23f01w276931f7f42595f84f: ./ myFile.js

  4. Przekieruj plik do lokalnej kopii

    git show 1023057173029091u23f01w276931f7f42595f84f: ./ myFile.js> myFile.07aug2018.js

  5. Utwórz kopię zapasową bieżącego pliku.

    cp myFile.js myFile.bak.js

  6. Otwórz oba pliki w swoim ulubionym edytorze tekstu.

    vim myFile.js
    vim myFile.07aug2018.js

  7. Skopiuj i wklej kod z myFile.07aug2018.js do myFile.js i zapisz.

  8. Zatwierdź i wypisz plik myFile.js

  9. Ponownie przejrzyj dziennik i potwierdź, że plik jest poprawnie zainstalowany.

  10. Powiedz swoim klientom, aby pobrali najnowszą wersję, z radością obserwuj, jak działa ze starą wersją.

Nie jest to najseksowniejsze ani najbardziej skoncentrowane na gitach rozwiązanie i zdecydowanie „ręczne” resetowanie / przywracanie, ale działa. Wymaga minimalnej znajomości git i nie zaburza historii zmian.

kmiklas
źródło
2
Ta odpowiedź jest znacznie bardziej złożona i podatna na błędy niż jakiekolwiek z rozwiązań, które poprzedzały ją lata.
Artif3x
2
Dlaczego ktoś miałby korzystać z tego rozwiązania !? prawdziwa odpowiedź to tylko proste polecenie.
Milad Rahimi,
1
Jest to optymalne rozwiązanie w pewnych okolicznościach. Ma zalety dla tych, którzy są w opałach, gdzie git działa nieprawidłowo, i dla tych, którzy potrzebują obejścia.
kmiklas