Dlaczego istnieją 2 sposoby na usunięcie pliku w git?

Czasami git sugeruje git rm --cached Usunięcie pliku, czasami git reset HEAD file. Kiedy powinienem użyć którego?

EDIT:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#
Author: Nick Volynkin, 2011-08-03

10 answers

git rm --cached <filePath> nie usuwa pliku, w rzeczywistości rozpoczyna usuwanie pliku(Plików) z repo (zakładając, że został on już popełniony), ale pozostawia plik w drzewie roboczym (pozostawiając plik bez śledzenia).

git reset -- <filePath> Czy odinstaluje wszelkie wprowadzone zmiany dla podanych plików.

To powiedziawszy, jeśli użyjesz git rm --cached na nowym pliku, który jest zainscenizowany, w zasadzie wyglądałoby to tak, jakbyś po prostu go odinstalował, ponieważ nigdy wcześniej nie został popełniony.

 1454
Author: Ryan Stewart,
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-08-06 13:45:31

git rm --cached służy do usuwania pliku z indeksu. W przypadku, gdy plik jest już w repo, git rm --cached usunie plik z indeksu, pozostawiając go w katalogu roboczym, a commit usunie go również z repo. Zasadniczo, po zatwierdzeniu, plik nie zostałby zmieniony i zachowałby lokalną kopię.

git reset HEAD file ( który domyślnie używa znacznika --mixed) różni się tym, że w przypadku, gdy plik jest już w repo, zastępuje on wersję indeksu Plik z repo (HEAD), skutecznie usuwając modyfikacje do niego.

W przypadku unversioned file, usunie cały plik, ponieważ nie było go w nagłówku. W tym aspekcie git reset HEAD file i git rm --cached są takie same, ale nie są takie same (jak wyjaśniono w przypadku plików już w repo)

Do pytania Why are there 2 ways to unstage a file in git? - w git nigdy nie ma tylko jednego sposobu na zrobienie czegokolwiek. o to właśnie chodzi:)

 306
Author: manojlds,
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
2011-08-02 23:00:25

Po Prostu:

  • git rm --cached <file> sprawia, że git przestaje całkowicie śledzić plik (pozostawiając go w systemie plików, w przeciwieństwie do zwykłego git rm*)
  • git reset HEAD <file> usuwa wszelkie modyfikacje wprowadzone do pliku od ostatniego commita (ale nie powoduje ich przywrócenia w systemie plików, w przeciwieństwie do tego, co może sugerować nazwa polecenia**). Plik pozostaje pod kontrolą wersji.

Jeśli plik nie był wcześniej kontrolowany (tzn. usuwasz plik, który właśnie git added po raz pierwszy), wtedy oba polecenia mają ten sam efekt, stąd pojawienie się tych "dwóch sposobów robienia czegoś".

* Należy pamiętać o zastrzeżeniu, o którym @DrewT wspomina w swojej odpowiedzi, dotyczącym git rm --cached pliku, który był wcześniej przekazany do repozytorium. W kontekście tego pytania, pliku właśnie dodanego i jeszcze nie zatwierdzonego, nie ma się czym martwić.

** bałem się żenująco długo korzystać z git Resetuj komendę ze względu na jej nazwę-i do dziś często sprawdzam składnię, aby upewnić się, że nie spieprzę. ( update : W końcu poświęciłem czas, aby podsumować użycie git reset na stronie tldr, więc teraz mam lepszy mentalny model tego, jak to działa, i szybkie odniesienie do kiedy zapominam o niektórych szczegółach.)

 94
Author: waldyrious,
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-11-04 10:54:10

Ten wątek jest trochę stary, ale nadal chcę dodać małą demonstrację, ponieważ nadal nie jest to intuicyjny problem:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD (Bez -q) wyświetla ostrzeżenie o zmodyfikowanym pliku i jego kodzie wyjścia to 1, co będzie uważane za błąd w skrypcie.

Edit: git checkout HEAD to-be-modified to-be-removed działa również do unstagingu, ale usuwa zmiany całkowicie z obszaru roboczego

 38
Author: Daniel Alder,
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-03-04 07:27:03

Jeśli przypadkowo Ustawiłeś pliki, których nie chcesz zatwierdzić I chcesz mieć pewność, że zachowasz zmiany, Możesz również użyć:

git stash
git stash pop

Spowoduje to reset do HEAD i ponownie zastosuje zmiany, umożliwiając ponowne przygotowanie poszczególnych plików do zatwierdzenia. jest to również pomocne, jeśli zapomniałeś utworzyć gałąź funkcji dla pull requests (git stash ; git checkout -b <feature> ; git stash pop).

 27
Author: ives,
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-09-17 01:26:28

Te 2 polecenia mają kilka subtelnych różnic, jeśli dany plik jest już w repo i pod kontrolą wersji (wcześniej zatwierdzona itp.):

  • git reset HEAD <file> usuwa plik w bieżącym zatwierdzeniu.
  • git rm --cached <file> usunie plik również dla przyszłych commitów. Jest unstaged dopóki nie zostanie dodany ponownie z git add <file>.

I jest jeszcze jedna ważna różnica:

  • Po uruchomieniu git rm --cached <file> i wciśnięciu gałąź do pilota, każdy ciągnie branch z pilota usunie plik faktycznie z ich folderu, nawet jeśli w lokalnym zestawie roboczym plik zostanie po prostu nie śledzony (tzn. nie zostanie fizycznie usunięty z folderu).

Ta ostatnia różnica jest ważna dla projektów zawierających plik konfiguracyjny, w którym każdy programista w zespole ma inny config (tj. inny podstawowy adres url, adres ip lub port), więc jeśli używasz git rm --cached <file> każdy, kto ściągnie Twoją gałąź, będzie musiał ręcznie odtworzyć konfigurację, albo możesz wysłać im swój i mogą ponownie edytować go z powrotem do swoich ustawień ip (itp .), ponieważ delete powoduje tylko, że ludzie wyciągają Twoją gałąź z pilota.

 15
Author: DrewT,
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-08-19 04:10:06

Powiedzmy, że masz stage cały katalog poprzez git add <folder>, ale chcesz wykluczyć plik z listy przechowywanej (tzn. listę, która generuje się podczas uruchamiania git status) i zachować modyfikacje w wyłączonym pliku (pracowałeś nad czymś i nie jest on gotowy do zatwierdzenia, ale nie chcesz stracić pracy...). Można po prostu użyć:

git reset <file>

Kiedy uruchomisz git status, zobaczysz, że niezależnie od tego, jaki plik(y) jesteś reset, to unstaged, a reszta plików added to wciąż na liście staged.

 8
Author: jiminikiz,
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-08-28 16:08:05

1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

(użyj " git RM --cached ..."do unstage)

  • Git jest systemem wskaźników

  • Nie masz jeszcze commita, aby zmienić wskaźnik na

  • Jedynym sposobem na "wyjęcie plików z wiadra, na które są wskazywane" jest usunięcie plików, które kazałeś gitowi obserwować pod kątem zmian

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

Git commit-m a

  • you commited, "zapisane "

3.

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

(użyj " git reset HEAD ..."do unstage)

  • zrobiłeś commit w swoim kodzie w tym czasie
  • Teraz możesz zresetować wskaźnik do commita ' wróć do ostatniego zapisu '
 7
Author: Timothy L.J. Stewart,
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-09-08 16:26:07

Jestem zaskoczony, że nikt nie wspomniał o git reflog ( http://git-scm.com/docs/git-reflog):

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

Reflog jest historią Gita, która nie tylko śledzi zmiany w repo, ale także śledzi działania użytkownika (np. pull, checkout do innej gałęzi, itp.) i pozwala cofnąć te działania. Zamiast więc odinstalowywać plik, który został omyłkowo zainscenizowany, możesz powrócić do punktu, w którym nie ustawiono plików.

Jest to podobne do git reset HEAD <file>, ale w niektórych przypadkach może być bardziej ziarniste.

Sorry-nie do końca odpowiadam na twoje pytanie, ale po prostu wskazuję kolejny sposób na usunięcie plików, których używam dość często (ja na przykład bardzo lubię odpowiedzi Ryana Stewarta i Waldy ' ego.);) Mam nadzieję, że to pomoże.

 5
Author: Alex,
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-02-10 12:06:40

Wydaje mi się, że git rm --cached <file> usuwa plik z indeksu bez usuwania go z katalogu, w którym zwykły git rm <file> zrobiłby oba, tak jak SYSTEM OPERACYJNY rm <file> usunie plik z katalogu bez usuwania jego wersji.

 3
Author: ernie.cordell,
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-01-24 10:55:30