Rimuovere un file da un repository Git senza eliminarlo dal filesystem locale


3048

Il mio commit iniziale conteneva alcuni file di registro. Ho aggiunto *logal mio .gitignoree ora voglio rimuovere i file di registro dal mio repository.

git rm mylogfile.log

rimuoverà un file dal repository, ma lo rimuoverà anche dal file system locale.

Come posso rimuovere questo file dal repository senza eliminare la mia copia locale del file?



14
Vale la pena notare che la risposta più votata è pericolosa per alcuni. Se si utilizza un repository remoto rispetto a quando si esegue il push del proprio locale, estrarre altrove quei file rimossi da Git . Verranno eliminati . Questo è menzionato in una delle risposte ma non commentato.
RichieHH,

Risposte:


4355

Dal file man :

Quando --cachedviene fornito, il contenuto in fasi deve corrispondere alla punta del ramo o al file sul disco, consentendo di rimuovere il file solo dall'indice.

Quindi, per un singolo file:

git rm --cached mylogfile.log

e per una singola directory:

git rm --cached -r mydirectory

151
Facilmente perso perché non è così esplicativo come svn rm --keep-local.
Martin,

114
Ma come conservo i file sui server remoti? Questo mantiene il mio locale, ma se spingo e tiro da un altro server, il file viene eliminato. Ho anche aggiunto un .gitignore per il file, ma viene comunque rimosso
spankmaster79

6
Questo rimuove ancora i file git pullse sei dietro il commit dopogit rm
Petr Peller

9
Vale la pena notare che, dopo aver eseguito il comando nella risposta, è necessario utilizzare git commit -m "Commit message"e git push. Se hai altre modifiche organizzate (verifica con git status), anche queste verranno impegnate in questo momento.
Sinjai,

9
Dal momento che questa è la risposta più accettata e non funziona, ciò che viene richiesto, dirò cosa faccio. Uso il comando git rm --cached mylogfile.loged elimino il file dal repository. Per evitare di perdere il file sul sistema produttivo, eseguo un backup del file e lo tiro dopo. Il file viene eliminato come indicato in precedenza e deve essere copiato dal backup. Questo è piuttosto un dolore, ma non ho trovato una soluzione migliore per questo problema.
Marcel Grolms il

275

Per rimuovere un'intera cartella dal repository (come i file Resharper), procedere come segue:

git rm -r --cached folderName

Avevo eseguito il commit di alcuni file resharper e non volevo che persistessero per altri utenti del progetto.


13
Solo una nota aggiuntiva per i futuri visitatori: non utilizzare una GUI per "Sincronizzare" il commit con il repository. Ciò riporterà i file nel repository locale. Devi fare un Git Push repo branchper rimuovere effettivamente i file dal telecomando.
RubberDuck,

211

Puoi anche rimuovere i file dal repository in base al tuo .gitignore senza eliminarli dal file system locale:

git rm --cached `git ls-files -i -X .gitignore`

O, in alternativa, su Windows Powershell:

git rm --cached $(git ls-files -i -X .gitignore)

7
Non funziona su Windows. git ls-files -i -X ​​.gitignore funziona, ma non so come inviare i file a 'git rm'. Sai come farlo?
Erik Z,

17
Funziona su Windows se usi Git Bash invece di cmd-console
Andreas Zita il

17
Ama questo. Ha funzionato tranne che avevo alcuni file che finivano per avere spazi nel nome del file. Ho modificato la soluzione qui per questo: git ls-files -i -X .gitignore | xargs -I{} git rm --cached "{}". Ti preghiamo di considerare di modificare o aggiungere questa soluzione alla risposta qui, perché è un ottimo strumento per avere ...
mpettis

Non ho provato ma dovrebbe essere testato rimuoverà anche i file come .gitkeepche conserva una cartella vuota nel repository. Per esempio. .gitignorecontenere cartella uploadse repository è costretto a tenere traccia di .gitkeep. Rimuovendo tutto dal repository sottostante uploadsverrà rimosso anche .gitkeep.
Vladimir Vukanac,

Questo suggerimento ha funzionato perfettamente in PowerShell: git rm --cached $ (git ls-files -i -X ​​.gitignore)
geekandglitter

89

Secondo la mia risposta qui: /programming/6313126/how-to-remove-a-directory-in-my-github-repository

Per rimuovere cartella / directory o file solo dal repository git e non dal locale, provare 3 semplici passaggi.


I passaggi per rimuovere la directory

git rm -r --cached File-or-FolderName
git commit -m "Removed folder from repository"
git push origin master

I passaggi per ignorare quella cartella nei prossimi commit

Per ignorare quella cartella dai prossimi commit, crea un file nella radice chiamato .gitignore e inseriscici il nome. Puoi metterne quanti ne vuoi

Il file .gitignore sarà simile a questo

/FolderName

rimuovi directory


@gaurav felice che mi sia stato d'aiuto!
eirenaios,

69

Inoltre, se hai eseguito il commit di dati sensibili (ad esempio un file contenente password), dovresti eliminarli completamente dalla cronologia del repository. Ecco una guida che spiega come farlo: http://help.github.com/remove-sensitive-data/


13
Questa risposta dovrebbe includere i comandi richiesti per completare questa attività invece di collegarsi a un altro sito Web.
Florian Lemaitre,

1
Vorrei anche notare che ho trovato l'uso dello strumento di pulizia repository git bfg più facile e veloce.
Lubed Up Slug,

64

Una soluzione più generica:

  1. Modifica .gitignorefile.

    ECHO mylogfile.log >> .gitignore

  2. Rimuovi tutti gli elementi dall'indice.

    git rm -r -f --cached .

  3. Ricostruisci indice.

    git add .

  4. Effettua nuovo commit

    git commit -m "Removed mylogfile.log"


2
Questo eliminerà effettivamente il file?
Mr_and_Mrs_D,

6
Da GitHub? NO. Se hai già spinto su github non lo rimuoverà dal sito. Ma aggiornerà il tuo repository git locale.
mAsT3RpEE

5
Il commento che hai eliminato è stato effettivamente più eliminato :) Il problema con la soluzione rm --cashedè che alla fine eliminerà il file quando uno tira, giusto? E questo non è ciò che la gente vuole quando dice "Rimuovi un file dal repository senza eliminarlo dal filesystem locale ". Ora, perché la soluzione sopra accettata è al di là di me - probabilmente l'OP stava lavorando da solo e non ha mai tirato? Boh. Capisco il problema "una volta spinto sempre lì" ofc
Mr_and_Mrs_D

Non credo che esista una soluzione al 100% a meno che non si chieda a Github stesso. Per ora atteniti a questo. Copia il file, aggiungi a gitignore, esegui git rm -r, esegui il commit, spingi, ripristina il file. Sei riuscito a trovare un'altra soluzione?
mAsT3RpEE

9
Il mio problema non è github - è che il file verrà effettivamente eliminato dai colleghi quando tirano . Io non voglio che il file da cancellare. Questo mi ha causato enormi problemi in passato. Quindi mi chiedevo se esiste davvero una soluzione che non cancella davvero il file. Vedi anche il commento nella risposta accettata: stackoverflow.com/questions/1143796/…
Mr_and_Mrs_D

24

Git ti consente di ignorare quei file assumendo che siano invariati. Questo viene eseguito eseguendo il git update-index --assume-unchanged path/to/file.txtcomando. Una volta contrassegnato un file come tale, git ignorerà completamente qualsiasi modifica su quel file; non verranno visualizzati quando si esegue git status o git diff, né verranno mai impegnati.

(Da https://help.github.com/articles/ignoring-files )

Quindi, non eliminarlo, ma ignorare le modifiche per sempre. Penso che questo funzioni solo localmente, quindi i collaboratori possono ancora vedere le modifiche a meno che non eseguano lo stesso comando di cui sopra. (Devo comunque verificarlo.)

Nota: questo non risponde direttamente alla domanda, ma si basa su domande di follow-up nei commenti delle altre risposte.


2
Lo faccio, ma vedo che il file può essere sovrascritto se qualcun altro lo modifica nel repository.
AlxVallejo,

17

Se si desidera semplicemente annullare la traccia di un file e non eliminarlo dal repository locale e remoto, utilizzare questo comando:

git update-index --assume-unchanged  file_name_with_path

2
Sebbene questa sia una buona risposta, è importante notare che questo non "toglie la traccia" a un file, nel senso che le persone di solito usano quella parola con Git, dove un file non tracciato è uno che non è nella cronologia del repository e non è mai stato . Ciò che fa questa risposta è mantenere il file nel repository ma impedire a Git di notare che sono state apportate modifiche ad esso. Ciò ha alcune differenze significative - soprattutto, il file è ancora presente per gli altri, e se qualcun altro lo modifica e lo tiri, la tua copia locale può essere sovrascritta senza conferma.
Soren Bjornstad,

8

Le risposte sopra non hanno funzionato per me. Ho usato filter-branchper rimuovere tutti i file impegnati.

Rimuovi un file da un repository git con:

git filter-branch --tree-filter 'rm  file'

Rimuovi una cartella da un repository git con:

git filter-branch --tree-filter 'rm -rf directory'

Ciò rimuove la directory o il file da tutti i commit.

È possibile specificare un commit utilizzando:

git filter-branch --tree-filter 'rm -rf directory' HEAD

O un intervallo:

git filter-branch --tree-filter 'rm -rf vendor/gems' t49dse..HEAD

Per inviare tutto al telecomando, puoi fare:

git push origin master --force

2
Questo combinato con git rm -r --cached NAMEè il trucco per rimuoverlo dal tuo repository git locale e impedire che colpisca chiunque tira più tardi (eliminando la cronologia del file o della directory da git.)
notbad.jpeg

1
Questo riscrive la storia di Git e dovresti spingere - forza dopo, questo è un po 'fuori portata con la domanda che immagino. Su un famoso repository pubblico non puoi semplicemente cambiare la linea della cronologia in questo modo poiché tutti coloro che hanno già clonato il repository potrebbero avere problemi durante il pull.
Guillaume Perrot

0

Ignora i file, rimuovi i file da git, aggiorna git (per la rimozione).

Nota: questo non riguarda la cronologia delle informazioni sensibili.

Questo processo prende sicuramente una certa comprensione di ciò che sta succedendo con Git. Con il passare del tempo, acquisito ciò, ho imparato a fare processi come:

1) Ignora i file

  • Aggiungi o aggiorna il progetto .gitignoreper ignorarli: in molti casi come il tuo, la directory principale, ad esempio, log/sarà la regex da utilizzare.
  • impegnarsi e spingere quel .gitignorecambiamento di file (non sono sicuro che push abbia bisogno di attenzione, nessun danno se fatto).

2) Rimuovere i file da git (solo).

  • Ora rimuovi i file da git (solo) con git remove --cached some_dir/
  • Controlla che rimangano ancora localmente (dovrebbero!).

3) Aggiungi e apporta tale modifica (essenzialmente si tratta di una modifica per "aggiungere" l'eliminazione di elementi, nonostante il comando "aggiungi" altrimenti confuso!)

  • git add .
  • git commit -m"removal"
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.