Cofnięcie modyfikacji kopii roboczej jednego pliku w Git?

Po ostatnim commicie zmodyfikowałem kilka plików w mojej kopii roboczej, ale chcę cofnąć zmiany w jednym z tych plików, jak w resetowaniu go do tego samego stanu, co najnowszy commit.

Jednak chcę tylko cofnąć zmiany kopii roboczej tylko tego jednego pliku, nic więcej z nim.

Jak to zrobić?

Author: S H, 2009-03-28

12 answers

Możesz użyć

git checkout -- file

Można to zrobić bez -- (Jak sugeruje nimrodm), ale jeśli nazwa pliku wygląda jak gałąź lub znacznik (lub inny identyfikator rewizji), może się pomylić, więc użycie -- jest najlepsze.

Możesz również sprawdzić konkretną wersję pliku:

git checkout v1.2.3 -- file         # tag v1.2.3
git checkout stable -- file         # stable branch
git checkout origin/master -- file  # upstream master
git checkout HEAD -- file           # the version from the most recent commit
git checkout HEAD^ -- file          # the version before the most recent commit
 1841
Author: Brian Campbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-30 02:30:59
git checkout <commit> <filename>

Użyłem tego dzisiaj, ponieważ zdałem sobie sprawę, że mój favicon został nadpisany kilka commitów temu, kiedy zaktualizowałem Drupala 6.10, więc musiałem go odzyskać. Oto co zrobiłem:

git checkout 088ecd favicon.ico
 118
Author: neoneye,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-28 10:25:25

Po prostu użyj

git checkout filename

Spowoduje zastąpienie nazwy pliku najnowszą wersją z bieżącej gałęzi.

Ostrzeżenie: twoje zmiany zostaną odrzucone - Żadna kopia zapasowa nie jest przechowywana.

 103
Author: nimrodm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-30 02:32:10

Jeśli Twój plik jest już wystawiony (dzieje się to, gdy wykonujesz git add etc po edycji pliku), aby usunąć zmiany.

Użyj

git reset HEAD <file>

Then

git checkout <file>

Jeśli jeszcze nie wystawione, wystarczy użyć

git checkout <file>
 52
Author: thanikkal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-31 07:08:00

Jeśli chcesz cofnąć zmiany poprzedniego commita w tym jednym pliku, możesz spróbować tego:

git checkout branchname^ filename

Spowoduje to sprawdzenie pliku tak, jak było przed ostatnim zatwierdzeniem. Jeśli chcesz cofnąć kilka commitów, użyj notacji branchname~n.

 15
Author: sykora,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-30 02:32:42

Zawsze się z tym mylę, więc oto przypadek testowy przypomnienia; powiedzmy, że mamy skrypt bash do przetestowania git: {21]}

set -x
rm -rf test
mkdir test
cd test
git init
git config user.name test
git config user.email [email protected]
echo 1 > a.txt
echo 1 > b.txt
git add *
git commit -m "initial commit"
echo 2 >> b.txt
git add b.txt
git commit -m "second commit"
echo 3 >> b.txt

W tym momencie zmiana nie jest przechowywana w pamięci podręcznej, więc git status jest:

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

Jeśli od tego momentu zrobimy git checkout, wynik jest taki:

$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean

Jeśli zamiast tego zrobimy git reset, wynik będzie następujący:

$ git reset HEAD -- b.txt
Unstaged changes after reset:
M   b.txt
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

Więc w tym przypadku-jeśli zmiany nie są wystawione, git reset nie robi różnicy, podczas gdy git checkout nadpisuje zmiany.


Teraz, powiedzmy, że ostatnia zmiana z powyższego skryptu jest przechowywana/buforowana, to znaczy, że zrobiliśmy również git add b.txt na końcu.

W tym przypadku git status w tym momencie jest:

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    modified:   b.txt

Jeśli od tego momentu zrobimy git checkout, wynik jest taki:

$ git checkout HEAD -- b.txt
$ git status
On branch master
nothing to commit, working directory clean

Jeśli zamiast tego zrobimy git reset, wynik będzie następujący:

$ git reset HEAD -- b.txt
Unstaged changes after reset:
M   b.txt
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   b.txt

no changes added to commit (use "git add" and/or "git commit -a")

Tak więc, w tym przypadku-jeśli zmiany są wystawione, git reset zasadniczo zmieni wystawione zmiany w nie-zmienione-podczas gdy git checkout nadpisze zmiany całkowicie.

 7
Author: sdaau,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-09 08:56:33

Przywracam pliki używając SHA id, to co robię to git checkout <sha hash id> <file name>

 5
Author: Beto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-22 20:39:17

Zrobiłem przez git bash:

(use "git checkout -- <file>..." to discard changes in working directory)

  1. Git status. [więc widzieliśmy jeden plik wad zmodyfikowany.]
  2. Git checkout -- index.html [zmieniłem w indeksie.plik html:
  3. Git status [Teraz te zmiany zostały usunięte]

Tutaj wpisz opis obrazka

 5
Author: Shivanandam Sirmarigari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 13:04:25

Ta odpowiedź dotyczy polecenia potrzebnego do cofnięcia zmian lokalnych, które znajdują się w wielu określonych plikach w tych samych lub wielu folderach(lub katalogach). To odpowiada konkretnie na pytanie, gdzie użytkownik ma więcej niż jeden plik, ale użytkownik nie chce cofnąć wszystkich lokalnych zmian:

Jeśli masz jeden lub więcej plików, możesz zastosować polecenie samne (git checkout -- file ) do każdy z tych plików, wymieniając każdą ich lokalizację oddzieloną spacja jak w:

git checkout -- name1/name2/fileOne.ext nameA/subFolder/fileTwo.ext

Zwróć uwagę na odstęp pomiędzy name1/name2 / fileOne.ext nameA / subFolder / fileTwo.ext

Dla wielu plików w tym samym folderze:

Jeśli zdarzy ci się, że będziesz musiał odrzucić zmiany dla wszystkich plików w niektóre katalogi, użyj git checkout w następujący sposób:

git checkout -- name1/name2/*

Gwiazdka w powyższej sztuczce polega na cofnięciu wszystkich plików w tej lokalizacji pod nazwą1/nazwą2.

I podobnie poniższe mogą cofnąć zmiany we wszystkich plikach dla wielokrotne foldery:

git checkout -- name1/name2/* nameA/subFolder/*

Ponownie zwróć uwagę na spację pomiędzy name1/ name2/* nameA/ subFolder / * w powyżej.

Uwaga: name1, name2 , nameA, podfolder - wszystkie te przykładowe nazwy folderów wskazują folder lub pakiet, w którym dany plik(Y) może znajdować się.

 3
Author: Nirmal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-23 21:26:27

Jeśli jeszcze nie wypchnąłeś lub w inny sposób nie udostępniłeś swojego commita:

git diff --stat HEAD^...HEAD | \
fgrep filename_snippet_to_revert | cut -d' ' -f2 | xargs git checkout HEAD^ --
git commit -a --amend
 2
Author: Jesse Glick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-30 02:28:41

Dla mnie tylko ten zadziałał

git checkout -p filename

Tutaj wpisz opis obrazka

 1
Author: Ramesh Bhupathi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-19 14:28:04

Jeśli jest już zatwierdzony, możesz cofnąć zmianę dla pliku i zatwierdzić ponownie, a następnie usunąć nowy commit z ostatnim commitem.

 0
Author: Gina,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-26 19:17:07