Come rimuovere più file eliminati nel repository Git


237

Ho cancellato alcuni file e lo stato di Git mostra come di seguito.

Mi sono impegnato e spinto.

GitHub mostra ancora i file eliminati nel repository. Come posso eliminare i file nel repository 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

Se uso git rm, dà quanto segue.

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


Risposte:


638
git add -u 

aggiorna tutte le tue modifiche


31
Funziona con un fascino. Quando vedi qualcosa come "stato git | sed -n '/ ^ # * cancellato: / s /// p' | xargs git rm" come soluzione proposta per un requisito così semplice ma frequente, sai che una soluzione migliore è, o presto lo sarà, dietro l'angolo.
ArcSeldon,

semplice è meglio, questo è davvero utile quindi il modo "bash"
castiel

1
L'autore chiede come rimuovere i file, perché l'aggiunta di file è la risposta corretta?
Kelin,

3
@kelin: da git docs ( git-scm.com/docs/git-add ): "-u --update Aggiorna l'indice nel punto in cui ha già una voce corrispondente a <pathspec>. Questo rimuove e modifica le voci dell'indice in corrisponde all'albero di lavoro, ma non aggiunge nuovi file. Se non viene fornito <pathspec> quando viene utilizzata l'opzione -u, tutti i file tracciati nell'intero albero di lavoro vengono aggiornati (le vecchie versioni di Git utilizzate per limitare l'aggiornamento alla directory corrente e le sue sottodirectory). "
HEDMON,

92

Sii molto cauto git rm .; potrebbe rimuovere più di quanto desideri. Certo, puoi recuperare, ma è più semplice non doverlo fare.

Il più semplice sarebbe:

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

Non è possibile utilizzare i caratteri jolly della shell perché i file non esistono, ma è possibile utilizzare (almeno in Bash):

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

Oppure considera:

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

Questo prende l'output di git status, non stampa nulla per impostazione predefinita ( sed -n), ma sulle righe che iniziano # deleted:, si elimina #e deleted:e stampa ciò che rimane; xargsraccoglie gli argomenti e li fornisce a un git rmcomando. Funziona con qualsiasi numero di file indipendentemente dalla somiglianza (o dissomiglianza) nei nomi.


6
È possibile utilizzare i caratteri jolly (anche se potrebbe essere necessario sfuggire loro), e git corrisponderanno ai percorsi nell'indice, non solo quelli in albero di lavoro, quindi non importa che non esistono sul filesystem.
Ben James,

109
git diff --diff-filter=D --name-only -z | xargs -0 git rmè un approccio più affidabile rispetto al tentativo di analizzare git statusche è orientato all'utente e non è garantito che sia stabile rispetto alle versioni future.
CB Bailey

@Charles: è sicuramente meglio, ma richiede molte conoscenze su quali opzioni sono disponibili git diff(che non avevo, non avevo mai avuto bisogno prima). Grazie!
Jonathan Leffler

8
Nota che esiste anche "git ls-files --deleted"
Petr Gladkikh,

1
così, ha git ls-files --deleted | xargs git rmfatto il trucco per me.
fiacobelli,

50

Un'altra versione alla risposta di ByScripts è

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

Questo rimuoverà SOLO i file cancellati da git.

Potrebbe anche essere usato per aggiungere SOLO file modificati.

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

Questi comandi funzionano anche su gitbash per Windows.


2
Inestimabile, lo git ls-filesstato cancellato o modificato è molto utile.
Mario Peshev,

1
Il comportamento di 'git add --update (or -u)'senza argomento path da una sottodirectory dell'albero cambierà in Git 2.0 e non dovrebbe più essere usato. Per aggiungere contenuto per l'intero albero, eseguire: git add --update :/ (o git add -u: /) Per limitare il comando alla directory corrente, eseguire: git add --update . (o git add -u.) Con la versione Git corrente, il comando è limitato al directory corrente
Ans

1
Qualche idea su come gestire i percorsi con spazi al loro interno? Esempio: src/my spaced directory/myfile. Questo può essere gestito individualmente, ma come può essere gestito usando i comandi in questa risposta?
Muhammad Gelbana,

35

Aggiorna tutte le modifiche apportate:

git add -u

I file eliminati dovrebbero passare da non in scena (di solito di colore rosso) a in scena (verde). Quindi impegnarsi a rimuovere i file eliminati:

git commit -m "note"

1
Merita il badge populista.
Giovanni

1
Questa è di gran lunga la soluzione migliore. Nessun hack di scripting, nessun processo lungo, solo una bandiera per dire a git di aggiornare il suo indice in modo approfondito.
Ron Dahlgren,

Brillante! Mi ha salvato dal dover digitare più di 20 percorsi di file. Grazie!
Allardbrain,

12

La soluzione migliore se non ti interessa la gestione temporanea dei file modificati è quella di usarla git add -ucome indicato da mshameers e / o pb2q .

Se vuoi solo rimuovere i file cancellati, ma non metterne in scena quelli modificati, penso che dovresti usare l' ls-filesargomento con il--deleted opzione (non è necessario usare regex o altri argomenti / opzioni complessi):

git ls-files --deleted | xargs git rm

1
git add -Arisolve questo problema ... nel caso in cui qualcuno volesse saperlo in futuro. controlla la risposta qui sotto
Ja8zyjits

8

Sì, git rm <filename>metterà in scena lo stato cancellato di un file, dove <filename>potrebbe essere un modello glob:

$ 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
#       ...

Quindi, puoi impegnarti.

git commit -a lo farà in una volta sola, se vuoi.

È inoltre possibile utilizzare git add -uper mettere in scena tutte le modifiche, inclusi tutti i file eliminati, quindi eseguire il commit.


così rm. (punto e basta) cancellarli subito?
Shin

quindi basta git rm rimuoverà tutto in una volta?
Shin

1
È possibile utilizzare un modello in stile glob per rimuovere più file; Ho aggiornato la mia risposta per mostrare un esempio.
Ben James,

5
Sembra git add -uesattamente quello che stiamo cercando: se fai molte eliminazioni, quindi vuoi commettere tutte le eliminazioni, quello sembra essere il modo più semplice e più 'standard' (cioè, senza globs specifici del caso o shell complesse che analizzano in xargs). C'è un motivo per cui non vorremmo usarlo, oltre al fatto che aggiunge tutte le modifiche contemporaneamente?
trisweb,

7

Quando ho molti file che ho eliminato che non sono stati messi in scena per il commit, puoi git rmfarli tutti in uno spettacolo con:

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

Come menzionato nella domanda, fai attenzione git rm.


5

Prova questo:

 git rm `git ls-files -d`

Ciò ha risolto il mio problema di mettere in scena solo script cancellati (usando bash)
Mariano Argañaraz,

3

Puoi usare

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

Dopo aver eliminato i file manualmente.


1
O in modo identico ma più conciso: git commit -am "rimuovi file"
BradChesney79,

3

È possibile creare uno script di shell che rimuoverà tutti i file durante l'esecuzione:

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

Lo script creato è remove.she contiene l'elenco completo dei git rmcomandi.


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


2

Se vuoi eliminarli tutti usando "git rm". Questo è ciò che faccio:

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

Questa query elenca tutti i file che sono stati rimossi e li elimina dal tuo repository git. Spero che sia d'aiuto.



1

Ho avuto questo problema con i file fantasma che comparivano nel mio repository dopo averli cancellati e mi sono imbattuto in questo preciso comando!

git add -A

È essenzialmente uguale git add -ae git add -ucombinato, ma fa distinzione tra maiuscole e minuscole. L'ho preso da questo fantastico link (questo link punta alla versione su archive.org ora, perché l'originale è stato convertito in una pagina di spam / phishing a partire da giugno 2016)


0

Ecco come rilevare i file eliminati e organizzare la loro eliminazione come parte del prossimo commit. Tutte le soluzioni su questo thread hanno meriti diversi. Questa seguente soluzione affronta in modo specifico il problema dei nomi dei file con spazi al loro interno.

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

assicurati di testarlo con l'opzione --dry-run di git prima di eseguirlo con il seguente:

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

spiegazione:

git status --porcelain

Questo stampa qualcosa come D "/ percorso di una cartella / percorso di un file" che accade solo quando ci sono spazi nei nomi dei percorsi

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

abbina solo le righe che iniziano con "D"

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

rimuovere "D" dalla parte anteriore di ogni stringa

tr -d '"'

rimuovere eventuali virgolette

xargs -I {} git rm '{}'

definire le variabili del nome file come {} eseguire il nome file sotto git rm racchiuso tra virgolette singole per assicurarsi che supporti i nomi file con spazi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.