Jak usunąć wiele usuniętych plików w repozytorium Git


236

Usunąłem niektóre pliki i pokazuje status git jak poniżej.

Popełniłem i popchnąłem.

GitHub nadal pokazuje usunięte pliki w repozytorium. Jak mogę usunąć pliki z repozytorium GitHub?

# 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)
#
#   deleted:    modules/welcome/language/english/kaimonokago_lang.php
#   deleted:    modules/welcome/language/french/kaimonokago_lang.php
#   deleted:    modules/welcome/language/german/kaimonokago_lang.php
#   deleted:    modules/welcome/language/norwegian/kaimonokago_lang.php

Jeśli używam git rm, daje to następujące.

usage: git rm [options] [--] <file>...

-n, --dry-run         dry run
-q, --quiet           do not list removed files
--cached              only remove from the index
-f, --force           override the up-to-date check
-r                    allow recursive removal
--ignore-unmatch      exit with a zero status even if nothing matched


Odpowiedzi:


637
git add -u 

aktualizuje wszystkie twoje zmiany


31
Działa urok. Kiedy zobaczysz coś w rodzaju „git status | sed -n '/ ^ # * usunięty: / s /// p' | xargs git rm” jako proponowane rozwiązanie dla tak prostego, ale częstego wymagania, wtedy wiesz, że lepszym rozwiązaniem jest: albo niedługo będzie za rogiem.
— arcseldon

proste jest lepsze, jest to naprawdę przydatne, niż „bash”
— castiel

1
Autor pyta, jak usunąć pliki, dlaczego dodawanie plików jest prawidłową odpowiedzią?
— kelin

3
@kelin: z git docs ( git-scm.com/docs/git-add ): "-u --update Zaktualizuj indeks dokładnie tam, gdzie ma już wpis pasujący do <pathspec>. To usuwa, a także modyfikuje wpisy indeksu do dopasuj działające drzewo, ale nie dodaje żadnych nowych plików. Jeśli nie podano <spathspec>, gdy użyta jest opcja -u, wszystkie śledzone pliki w całym pracującym drzewie są aktualizowane (stare wersje Git były używane do ograniczenia aktualizacji do bieżącego katalogu i jego podkatalogi). ”
— HEDMON,

92

Bądź bardzo ostrożny git rm .; może usunąć więcej niż chcesz. Oczywiście możesz wyzdrowieć, ale łatwiej jest tego nie robić.

Najprostsze byłoby:

git rm modules/welcome/language/english/kaimonokago_lang.php \
       modules/welcome/language/french/kaimonokago_lang.php \
       modules/welcome/language/german/kaimonokago_lang.php \
       modules/welcome/language/norwegian/kaimonokago_lang.php

Nie możesz używać symboli wieloznacznych powłoki, ponieważ pliki nie istnieją, ale możesz użyć (przynajmniej w Bash):

git rm modules/welcome/language/{english,french,german,norwegian}/kaimonokago_lang.php

Lub rozważ:

git status | sed -n '/^# *deleted:/s///p' | xargs git rm

Trwa to wyjście git status, nic nie drukuje (domyślnie sed -n), ale na liniach, które są uruchamiane # deleted:, to pozbywa się #a deleted:i drukuje co pozostało; xargszbiera argumenty i przekazuje je do git rmpolecenia. Działa to dla dowolnej liczby plików bez względu na podobieństwo (lub odmienność) w nazwach.


6
Ty można używać symboli wieloznacznych (choć być może trzeba je uciec) i git będzie pasował ścieżek w indeksie, a nie tylko te w drzewie pracy, więc to nie ma znaczenia, że nie istnieje w systemie.
— Ben James

109
git diff --diff-filter=D --name-only -z | xargs -0 git rmjest bardziej niezawodnym podejściem niż próba parsowania, git statusktóra jest zorientowana na użytkownika i nie gwarantuje stabilności w przyszłych wersjach.
— CB Bailey,

@Charles: to z pewnością lepsze, ale wymaga sporo wiedzy na temat dostępnych opcji git diff(których nie miałem, wcześniej nie miałem takiej potrzeby). Dzięki!
— Jonathan Leffler

8
Zauważ, że istnieją także „git ls-files --deleted”
— Petr Gladkikh

1
więc git ls-files --deleted | xargs git rmzrobiłem dla mnie lewę.
— fiacobelli,

50

Inną wersją odpowiedzi ByScripts jest

git rm $(git ls-files --deleted)

Spowoduje to WYŁĄCZNIE usunięcie usuniętych plików z git.

Można go również wykorzystać do dodawania TYLKO zmodyfikowanych plików.

git add $(git ls-files --modified)

Te polecenia działają również w gitbash dla Windows.


2
Bezcenne, git ls-filesze statusem usuniętym lub zmodyfikowanym jest bardzo pomocny.
— Mario Peshev,

1
Zachowanie 'git add --update (or -u)'się bez argumentu ścieżki z podkatalogu drzewa zmieni się w Git 2.0 i nie powinno być już używane. Aby dodać zawartość do całego drzewa, uruchom: git add --update :/ (lub git add -u: /) Aby ograniczyć polecenie do bieżącego katalogu, uruchom: git add --update . (lub git add -u.) W bieżącej wersji Git polecenie jest ograniczone do katalog bieżący
— Ans

1
Masz pomysł, jak obsługiwać ścieżki ze spacjami w nich? Przykład: src/my spaced directory/myfile. Można to rozwiązać indywidualnie, ale jak można to zrobić za pomocą poleceń zawartych w tej odpowiedzi?
— Muhammad Gelbana

35

Zaktualizuj wszystkie wprowadzone zmiany:

git add -u

Usunięte pliki powinny zmienić się z niestabilnego (zwykle kolor czerwony) na etapowe (zielony). Następnie potwierdź usunięcie usuniętych plików:

git commit -m "note"

1
Zasługuje na populistyczną odznakę.
— Jan

1
To zdecydowanie najlepsze rozwiązanie. Bez włamań do skryptów, bez długiego procesu, tylko flaga informująca git o konieczności dokładnej aktualizacji indeksu.
— Ron Dahlgren,

Znakomity! Uratowało mnie to od konieczności wpisywania ponad 20 ścieżek plików. Dzięki!
— allardbrain

12

Najlepszym rozwiązaniem, jeśli nie obchodzi Cię przemieszczanie zmodyfikowanych plików, jest użycie, git add -ujak mówią mshameers i / lub pb2q .

Jeśli chcesz po prostu usunąć usunięte pliki, ale nie wprowadzasz żadnych zmodyfikowanych plików, myślę, że powinieneś użyć ls-filesargumentu z --deletedopcją (nie musisz używać wyrażenia regularnego ani innych złożonych argumentów / opcji):

git ls-files --deleted | xargs git rm

1
git add -Arozwiązuje ten problem ... na wypadek, gdyby ktoś chciał wiedzieć w przyszłości. sprawdź poniższą odpowiedź
— Ja8zyjits

8

Tak, git rm <filename>wyreżyseruje stan usuniętego pliku, gdzie <filename>może być wzorzec globalny:

$ git rm modules/welcome/language/*/kaimonokago_lang.php
rm modules/welcome/language/english/kaimonokago_lang.php
rm modules/welcome/language/french/kaimonokago_lang.php
rm modules/welcome/language/german/kaimonokago_lang.php
rm modules/welcome/language/norwegian/kaimonokago_lang.php

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       deleted:    modules/welcome/language/english/kaimonokago_lang.php
#       ...

Następnie możesz zatwierdzić.

git commit -a zrobię to za jednym razem, jeśli chcesz.

Możesz także użyć, git add -uaby wprowadzić wszystkie zmiany, w tym wszystkie usunięte pliki, a następnie zatwierdzić.


więc rm. (kropka) usunąć je jednocześnie?
— shin

więc po prostu git rm usunie wszystko naraz?
— shin

1
Za pomocą wzorca globalnego można usunąć wiele plików; Zaktualizowałem swoją odpowiedź, aby pokazać przykład.
— Ben James

5
Wygląda na git add -uto, że dokładnie tego szukamy - jeśli wykonasz wiele operacji usunięcia, a następnie zechcesz dokonać wszystkich operacji usuwania, wydaje się, że jest to najłatwiejszy i najbardziej „standardowy” sposób (to znaczy bez globów specyficznych dla danego przypadku lub złożonego przetwarzania powłoki w xargs). Czy jest jakiś powód, dla którego nie chcielibyśmy tego używać, oprócz faktu, że dodaje on wszystkie zmiany naraz?
— trisweb

7

Kiedy mam wiele usuniętych przeze mnie plików, które nie są wystawiane do zatwierdzenia, możesz git rmje wszystkie w jednym programie:

for i in `git status | grep deleted | awk '{print $3}'`; do git rm $i; done

Jak wspomniano w odpowiedzi na pytanie, bądź ostrożny git rm.



3

Możesz użyć

git commit -m "remove files" -a
git push

Po ręcznym usunięciu plików.


1
Lub identycznie, ale bardziej zwięźle: git commit -am „usuń pliki”
— BradChesney79

3

Możesz utworzyć skrypt powłoki, który usunie wszystkie twoje pliki po uruchomieniu:

git status | grep deleted | awk '{print "git rm " $3;}' > ../remove.sh

Skrypt, który jest tworzony remove.sh, zawiera pełną listę git rmpoleceń.


2
git status | sed 's/^#\s*deleted:\s*//' | sed 's/^#.*//' | xargs git rm -rf


2

Jeśli chcesz usunąć je wszystkie za pomocą „git rm”. Tym się właśnie zajmuję:

git ls-files --deleted -z | xargs -0 git rm

To zapytanie zawiera listę wszystkich plików, które zostały usunięte i usuwa je z repozytorium git. Mam nadzieję, że to pomoże.



1

Miałem problem z plikami ducha pojawiającymi się w moim repozytorium po ich usunięciu i napotkaniu tego porządnego polecenia!

git add -A

Zasadniczo jest to samo git add -ai git add -upołączone, ale rozróżnia duże i małe litery. Mam go z tego niesamowitego linku (ten link wskazuje teraz wersję na archive.org, ponieważ oryginał został przekształcony w stronę spamu / phishingu w czerwcu 2016 r.)


0

Oto jak wykryć usunięte pliki i wprowadzić etap ich usuwania w ramach następnego zatwierdzenia. Wszystkie rozwiązania w tym wątku mają różne zalety. To rozwiązanie w szczególności dotyczy problemu nazw plików ze spacjami.

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm '{}'

upewnij się, że przetestowałeś to z opcją --dry-run gita przed uruchomieniem go z następującymi:

git status --porcelain | awk '/^.D .*$/ {print $0}' | sed 's/.D \(.*\)/\1/' | tr -d '"' | xargs -I {} git rm --dry-run '{}'

wyjaśnienie:

git status --porcelain

Spowoduje to wydrukowanie czegoś takiego jak D „/ ścieżka do folderu / ścieżka do pliku”, co dzieje się tylko wtedy, gdy w nazwach ścieżek są spacje

awk '/^.D .*$/ {print $0}'

dopasuj tylko linie rozpoczynające się od „D”

sed 's/ D \(.*\)/\1/'

usuń „D” z przodu każdego łańcucha

tr -d '"'

usuń cytaty, jeśli istnieją

xargs -I {} git rm '{}'

zdefiniuj zmienne nazw plików jako {} uruchom nazwę pliku w git rm ujętym w pojedyncze cudzysłowy, aby upewnić się, że obsługuje nazwy plików ze spacjami.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.