Czasami git sugeruje, git rm --cached
aby oderwać plik, czasem git reset HEAD file
. Kiedy powinienem użyć które?
EDYTOWAĆ:
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
#
git rm
można zarówno etap usunięcie , a także unstage się dodatek )rm
jest cofanieadd
? Jak myślisz, jakrm
powinien się zachowywać?git init
nie maHEAD
możliwości zresetowania.rm
oznacza usunięcie w kontekście uniksowym. Nie jest odwrotnością dodawania do indeksu. Funkcja usuwania plików nie powinna być przeciążona funkcjami zmieniającymi stan przemieszczania. Jeśli istnieją szczegóły implementacji, które ułatwiają łączenie, oznacza to po prostu brak przemyślanej warstwy abstrakcji w git, co uczyniłoby użyteczność jasną.Odpowiedzi:
git rm --cached <filePath>
nie usuwa scenografii z pliku, w rzeczywistości dokonuje etapów usuwania pliku (ów) z repozytorium (zakładając, że został już wcześniej popełniony), ale pozostawia plik w twoim drzewie roboczym (pozostawiając plik bez śledzenia).git reset -- <filePath>
będzie unstage wszelkie stopniowe zmiany dla danego pliku (ów).To powiedziawszy, jeśli używałeś
git rm --cached
nowego pliku, który został zainscenizowany, w zasadzie wyglądałby tak, jakbyś go po prostu wystawił scenę, ponieważ nigdy wcześniej nie został popełniony.Zaktualizuj git 2.24
W tej nowszej wersji git możesz używać
git restore --staged
zamiastgit reset
. Zobacz dokumenty git .źródło
git rm --cached
wycofuje plik, ale nie usuwa go z katalogu roboczego.git rm --cached <filePath>
do usunięcia niektórych plików z repozytorium po uświadomieniu sobie, że nigdy nie powinno być w repozytorium: najprawdopodobniej uruchomienie tego polecenia i dodanie odpowiednich plików dogitignore
. Mam rację?unstage
rozkazgit
.git rm --cached
służy do usunięcia pliku z indeksu. W przypadku, gdy plik jest już w repozytorium,git rm --cached
usunie plik z indeksu, pozostawiając go w katalogu roboczym, a zatwierdzenie usunie go również z repozytorium. Zasadniczo po zatwierdzeniu plik zostałby cofnięty i zachowana lokalna kopia.git reset HEAD file
(który domyślnie używa--mixed
flagi) różni się tym, że w przypadku, gdy plik znajduje się już w repozytorium, zastępuje wersję indeksu pliku wersją z repozytorium (HEAD), skutecznie cofając zmiany w tym pliku .W przypadku pliku niewersjonowanego, odłączy scenę całego pliku, ponieważ pliku nie było w HEAD. W tym aspekcie
git reset HEAD file
igit rm --cached
są takie same, ale nie są takie same (jak wyjaśniono w przypadku plików już w repozytorium)Na pytanie
Why are there 2 ways to unstage a file in git?
- nigdy tak naprawdę nie ma tylko jednego sposobu na zrobienie czegokolwiek w git. to jest jego piękno :)źródło
there is never really only one way to do anything in git. that is the beauty of it
- Hmm dlaczego ? zawsze jest świetnie, gdy jest tylko jeden oczywisty sposób. oszczędza to wiele naszego czasu i pamięci w mózgu))Całkiem proste:
git rm --cached <file>
sprawia, że git przestaje całkowicie śledzić plik (pozostawiając go w systemie plików, w przeciwieństwie do zwykłegogit rm
*)git reset HEAD <file>
wycofuje sceny z modyfikacji dokonanych w pliku od czasu ostatniego zatwierdzenia (ale nie przywraca ich w systemie plików, w przeciwieństwie do tego, co sugeruje nazwa polecenia **). Plik pozostaje pod kontrolą wersji.Jeśli plik nie był wcześniej w kontroli wersji (tzn. Odtwarzasz plik, który właśnie edytowałeś
git add
po raz pierwszy), to te dwa polecenia mają ten sam efekt, stąd ich pojawienie się jest „dwoma sposobami zrobienia czegoś” „.* Pamiętaj, że zastrzeżenie @DrewT wspomina w swojej odpowiedzi dotyczącej
git rm --cached
pliku, który został wcześniej zatwierdzony w repozytorium. W kontekście tego pytania o plik, który właśnie został dodany i jeszcze nie został popełniony, nie ma się o co martwić.** Bałam się żenująco długiego czasu, aby użyć polecenia git reset ze względu na jego nazwę - i nadal często szukam składni, aby upewnić się, że nie spieprzę. ( aktualizacja : W końcu poświęciłem czas na podsumowanie użycia
git reset
na stronie tldr , więc teraz mam lepszy mentalny model tego, jak to działa, i szybkie odniesienie, gdy zapomnę o niektórych szczegółach.)źródło
git rm <file> --cached
rm --cached
i pchasz , każdy ciągnący tę samą gałąź będzie miał faktycznie usunięte pliki z drzewa roboczego.Ten wątek jest nieco stary, ale nadal chcę dodać małą demonstrację, ponieważ nadal nie jest to intuicyjny problem:
git reset HEAD
(bez-q
) wyświetla ostrzeżenie o zmodyfikowanym pliku, a jego kod zakończenia to 1, co zostanie uznane za błąd w skrypcie.Edycja:
git checkout HEAD to-be-modified to-be-removed
działa również w przypadku wycofywania scen, ale całkowicie usuwa zmianę z obszaru roboczegoZaktualizuj git 2.23.0: od czasu do czasu polecenia zmieniają się. Teraz
git status
mówi:... który działa dla wszystkich trzech rodzajów zmian
źródło
jeśli przypadkowo przygotowałeś pliki, których nie chciałbyś zatwierdzić i chcesz mieć pewność, że zachowasz zmiany, możesz również użyć:
powoduje to zresetowanie HEAD i ponowne zastosowanie zmian, umożliwiając ponowne ustawienie poszczególnych plików do zatwierdzenia. jest to również pomocne, jeśli zapomniałeś utworzyć gałąź funkcji dla żądań ściągania (
git stash ; git checkout -b <feature> ; git stash pop
).źródło
git stash
ma inne powiązane korzyści, ponieważ tworzy wpisy w dzienniku reflogu, które są następnie dostępne w przyszłości. w razie wątpliwości idź dalej i zróbgit stash
(np.git stash save -u "WIP notes to self"
(„-u” oznacza włączenie nowych / nieśledzonych plików do zatwierdzenia ukrytego) ... następnie spróbujgit reflog show stash
zobaczyć listę zatwierdzeń ukrytych i ich sha. Polecam powłokę alias likealias grs="git reflog show stash"
Te 2 polecenia mają kilka subtelnych różnic, jeśli dany plik znajduje się już w repozytorium i jest pod kontrolą wersji (wcześniej zatwierdzony itp.):
git reset HEAD <file>
rozpakowuje plik w bieżącym zatwierdzeniu.git rm --cached <file>
usunie scenę z pliku dla przyszłych zatwierdzeń. Nie jest wystawiany, dopóki nie zostanie ponownie dodanygit add <file>
.I jest jeszcze jedna ważna różnica:
git rm --cached <file>
i przekazaniu gałęzi do pilota każdy, kto wyciągnie gałąź ze zdalnego, otrzyma AKTUALNIE usunięty plik ze swojego folderu, nawet jeśli w lokalnym zestawie roboczym plik po prostu nie zostanie wyśledzony (tzn. Nie zostanie fizycznie usunięty z folderu).Ta ostatnia różnica jest ważna w przypadku projektów, które zawierają plik konfiguracyjny, w którym każdy programista w zespole ma inną konfigurację (tj. Inny podstawowy adres URL, adres IP lub ustawienie portu), więc jeśli używasz
git rm --cached <file>
kogoś, kto pobierze twój oddział, będzie musiał ręcznie ponownie utwórz konfigurację lub możesz wysłać je do Ciebie, a oni mogą ponownie edytować go z powrotem do ustawień IP (itp.), ponieważ usunięcie powoduje tylko efekt ściągania twojej gałęzi z pilota.źródło
Załóżmy, że masz
stage
cały katalog za pośrednictwemgit add <folder>
, ale chcesz wykluczyć plik z listy etapowej (tj. Listy generowanej podczas działaniagit status
) i zachować zmiany w wykluczonym pliku (pracujesz nad czymś i nie jest on gotowy do zatwierdzenia, ale nie chcesz stracić pracy ...). Możesz po prostu użyć:git reset <file>
Po uruchomieniu
git status
, można zauważyć, że niezależnie od pliku (ów), którereset
sąunstaged
i resztę plików, któreadded
są nadal wstaged
liście.źródło
1.
(użyj „git rm --cached ...”, aby cofnąć scenę)
git to system wskaźników
nie masz jeszcze zatwierdzenia, aby zmienić swój wskaźnik na
jedynym sposobem na „wyjęcie plików z wskazanego segmentu” jest usunięcie plików, które poleciłeś gitowi, aby obserwował zmiany
2)
git commit -ma
3)
(użyj „git reset HEAD ...”, aby się wycofać)
źródło
git init
po raz pierwszy.Dziwię się, że nikt nie wspominał o dzienniku git ( http://git-scm.com/docs/git-reflog ):
Reflog jest historią git, która nie tylko śledzi zmiany w repozytorium, ale także śledzi akcje użytkownika (np. Ściąganie, pobieranie do innej gałęzi itp.) I pozwala cofnąć te akcje. Zamiast odstawiać plik, który został omyłkowo zainscenizowany, w którym można powrócić do punktu, w którym pliki nie były etapowane.
Jest to podobne,
git reset HEAD <file>
ale w niektórych przypadkach może być bardziej szczegółowe.Przepraszam - tak naprawdę nie odpowiadam na twoje pytanie, ale po prostu wskazuję kolejny sposób na wycofanie plików, których często używam (na przykład lubię odpowiedzi Ryana Stewarta i bardzo waldyrious.);) Mam nadzieję, że to pomoże.
źródło
Po prostu użyj:
git reset HEAD <filename>
Spowoduje to rozproszenie pliku i zachowanie wprowadzonych zmian, dzięki czemu możesz z kolei zmienić gałęzie, jeśli chcesz, a
git add
te pliki na inną gałąź. Wszystkie zmiany są zachowywane.źródło
Wydaje mi się, że
git rm --cached <file>
usuwa plik z indeksu bez usuwania go z katalogu, w którym zwykłygit rm <file>
zrobiłby oba, podobnie jak system operacyjnyrm <file>
usuwałby plik z katalogu bez usuwania jego wersji.źródło
Tylko dla wersji 2.23 i nowszych
Zamiast tych sugestii możesz użyć
git restore --staged <file>
w celuunstage
uzyskania pliku (ów).źródło
--stage
jak i--staged
.