Przez przypadek dodałem wiele plików tymczasowych git add -A
Udało mi się wycofać pliki za pomocą poniższych poleceń i usunąć brudny indeks.
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
Powyższe polecenia są wymienione w git help rm
. Ale niestety moje pliki zostały również usunięte podczas wykonywania, mimo że podałem opcję pamięci podręcznej. Jak mogę wyczyścić indeks bez utraty zawartości?
Byłoby również pomocne, gdyby ktoś mógł wyjaśnić sposób działania tej operacji potoku.
git
version-control
sarat
źródło
źródło
rm -f
nie jest poleceniem git i nie ma--cached
opcji. Twoje lokalne pliki zostały usunięte przed wykonaniem,git rm
więc nie sądzę, abyś mógłgit rm
cokolwiek za to winić .git reset --hard
jest to poprawna odpowiedź i faktycznie usunie treść. To wprowadzi użytkowników w błąd - tak jak ja to zrobiłem.Odpowiedzi:
git reset
Jeśli wszystko, czego chcesz, to cofnąć nadgorliwy bieg „git add”:
Twoje zmiany zostaną wycofane ze sceny i będą gotowe do ponownego dodania według uznania.
NIE URUCHAMIAJ
git reset --hard
.Nie tylko cofnie inscenizację dodanych plików, ale cofnie wszelkie zmiany wprowadzone w katalogu roboczym. Jeśli utworzyłeś nowe pliki w katalogu roboczym, nie zostaną one jednak usunięte.
źródło
git checkout -- *
, a takżeJeśli masz nieskazitelne repo (lub HEAD nie jest ustawiony) [1], możesz po prostu
Oczywiście, będzie to wymagać, aby ponownie dodać pliki, które nie chcą być dodawane.
[1] Uwaga (jak wyjaśniono w komentarzach) zwykle dzieje się tak tylko wtedy, gdy repozytorium jest nowe („nieskazitelne”) lub jeśli nie dokonano żadnych zobowiązań. Z technicznego punktu widzenia, ilekroć nie ma kasy ani drzewa pracy.
Po prostu wyjaśnienie :)
źródło
Służy
git reset HEAD
do resetowania indeksu bez usuwania plików. (Jeśli chcesz zresetować tylko określony plik w indeksie, możeszgit reset HEAD -- /path/to/file
to zrobić.)Operator potoku w powłoce przejmuje
stdout
proces z lewej strony i przekazuje gostdin
do procesu z prawej. Jest to w zasadzie odpowiednik:ale zamiast tego
$ proc1 | proc2
drugi proces może zacząć pobierać dane, zanim pierwszy zakończy ich wysyłanie, i nie jest w to zaangażowany żaden plik.źródło
git reset HEAD
bez określania niczego innego, a to zresetuje cały indeks. Następnie możesz ponownie dodać tylko wybrane pliki.$ git reset HEAD fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. Use '--' to separate paths from revisions
git reset
wtedy, bezHEAD
.$ git reset fatal: Failed to resolve 'HEAD' as a valid ref.
źródło
Jeśli HEAD nie jest ustawiony (tzn. Nie masz jeszcze żadnych zatwierdzeń, ale nie chcesz po prostu wysadzić w powietrze,
.git
ponieważ masz już skonfigurowaną inną konfigurację repozytorium, którą chcesz zachować), możesz również zrobićwszystko zepsuć. Jest to efektywnie to samo, co rozwiązanie sehe, ale pozwala uniknąć zlewania się z wewnętrznymi elementami Git.
źródło
.git
ponieważ skonfigurowałeś inną konfigurację repo chce zatrzymać. Zredagowałem to, aby to wyjaśnić.Ostrzeżenie: nie używaj następującego polecenia, chyba że chcesz stracić nieprzyznaną pracę!
Używanie
git reset
zostało wyjaśnione, ale poprosiłeś o wyjaśnienie potokowych poleceń, więc oto:Polecenie
git ls-files
wyświetla listę wszystkich plików, o których git wie. Opcja-z
nakłada na nie określony format, oczekiwany formatxargs -0
, który następnie sięrm -f
na nich wywołuje , co oznacza usunięcie ich bez sprawdzania Twojej zgody.Innymi słowy, „wyświetl listę wszystkich plików, o których git wie i usuń lokalną kopię”.
Następnie przechodzimy do
git diff
, który pokazuje zmiany między różnymi wersjami przedmiotów, o których wie git. Mogą to być zmiany między różnymi drzewami, różnice między kopiami lokalnymi a zdalnymi i tak dalej.W użytym tutaj znaczeniu pokazuje nieustawione zmiany; pliki, które zmieniłeś, ale jeszcze nie zatwierdziłeś. Ta opcja
--name-only
oznacza, że chcesz tylko (pełne) nazwy plików i--diff-filter=D
że interesują Cię tylko usunięte pliki. (Hej, czy nie usunęliśmy po prostu kilku rzeczy?) To jest następnie przesyłane strumieniowo do tego,xargs -0
co widzieliśmy wcześniej, cogit rm --cached
je wywołuje , co oznacza, że są usuwane z pamięci podręcznej, podczas gdy działające drzewo powinno zostać pozostawione w spokoju - poza tym, że właśnie usunąłeś wszystkie pliki z działającego drzewa. Teraz są również usuwane z Twojego indeksu.Innymi słowy, wszystkie zmiany, etapowe lub niestacjonarne, zniknęły, a twoje drzewo robocze jest puste. Wypłacz się, sprawdź swoje pliki od początku lub ze źródła, i ponownie wykonaj swoją pracę. Przeklnij sadystę, który napisał te piekielne linie; Nie mam pojęcia, dlaczego ktoś chciałby to zrobić.
TL; DR: po prostu wszystko nosiłeś; zacznij od nowa i używaj
git reset
od teraz.źródło
Obawiam się, że pierwsza z tych linii poleceń bezwarunkowo usunęła z kopii roboczej wszystkie pliki znajdujące się w obszarze testowym gita. Drugi usunął ze sceny wszystkie pliki, które były śledzone, ale zostały teraz usunięte. Niestety oznacza to, że utracisz wszelkie niezatwierdzone modyfikacje tych plików.
Jeśli chcesz odzyskać kopię roboczą i indeksować z powrotem do poprzedniego zatwierdzenia , możesz ( ostrożnie ) użyć następującego polecenia:
Mówię „ostrożnie”, ponieważ
git reset --hard
spowoduje to usunięcie niezatwierdzonych zmian w kopii roboczej i indeksie. Jednak w tej sytuacji brzmi to tak, jakbyś chciał po prostu wrócić do stanu przy ostatnim zatwierdzeniu, a nieprzyjęte zmiany i tak zostały utracone.Aktualizacja: z twoich komentarzy do odpowiedzi Amber brzmi, że nie stworzyłeś jeszcze żadnych zatwierdzeń (ponieważ HEAD nie można rozwiązać), więc obawiam się, że to nie pomoże.
Jeśli chodzi o działanie tych potoków:
git ls-files -z
igit diff --name-only --diff-filter=D -z
oba generują listę nazw plików oddzielonych bajtem0
. (Jest to przydatne, ponieważ w odróżnieniu od znaków nowej linii0
bajty nie mogą występować w nazwach plików w systemach uniksowych). Programxargs
zasadniczo buduje wiersze poleceń ze standardowego wejścia, domyślnie pobierając wiersze ze standardowego wejścia i dodając je na końcu z wiersza poleceń. Ta-0
opcja mówi, że należy oczekiwać standardowego wejścia oddzielonego przez0
bajtami.xargs
może kilkakrotnie wywołać polecenie, aby zużyć wszystkie parametry ze standardowego wejścia, upewniając się, że linia poleceń nigdy nie będzie zbyt długa.Jako prosty przykład, jeśli masz plik o nazwie
test.txt
, z następującą zawartością:... wtedy polecenie
xargs echo whatever < test.txt
wywoła polecenie:źródło
Jeśli chcesz wycofać wszystkie zmiany, użyj polecenia poniżej,
W przypadku, gdy chcesz wycofać zmiany i przywrócić je z katalogu roboczego,
źródło