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.