Come far dimenticare a Git un file che è stato rintracciato ma che si trova ora in .gitignore?


5404

C'è un file che è stato monitorato da git, ma ora il file è .gitignorenell'elenco.

Tuttavia, quel file continua a comparire git statusdopo essere stato modificato. Come costringi gita dimenticartene completamente?


16
git clean -Xsembra simile, ma non si applica in questa situazione (quando i file sono ancora tracciati da Git). Sto scrivendo questo per chiunque cerchi una soluzione per non seguire la strada sbagliata.
imz - Ivan Zakharyaschev,

35
L'unica vera risposta a questo è in basso, vedi git update-index --assume-unchanged. Questa soluzione 1) mantiene il file sul server (indice), 2) consente di modificarlo liberamente localmente.
Qwerty,

8
Devi usare --skip-worktree, vedi: stackoverflow.com/questions/13630849/…
Doppelganger

77
Una domanda importante è: il file dovrebbe rimanere nel repository o no? Ad esempio, se qualcuno di nuovo clona il repository, dovrebbe ottenere il file o no? Se SÌ, allora git update-index --assume-unchanged <file>è corretto e il file rimarrà nel repository e le modifiche non verranno aggiunte con git add. Se NO (ad esempio era un file di cache, file generato ecc.), Lo git rm --cached <file>rimuoverà dal repository.
Martin,

9
@Martin @Qwerty Ognuno dovrebbe smettere di avvisare per --assume-unchangedquale sia la prestazione per impedire a git di controllare lo stato dei file tracciati di grandi dimensioni, ma preferisce --skip-worktreequale è per i file tracciati modificati che l'utente non vuole più impegnare. Vedi stackoverflow.com/questions/13630849/…
Philippe

Risposte:


5707

.gitignoreimpedirà add -fche i file non tracciati vengano aggiunti (senza un ) all'insieme di file tracciati da git, tuttavia git continuerà a tenere traccia di tutti i file già tracciati.

Per interrompere il tracciamento di un file è necessario rimuoverlo dall'indice. Questo può essere ottenuto con questo comando.

git rm --cached <file>

Se si desidera rimuovere un'intera cartella, è necessario rimuovere tutti i file in essa ricorsivamente.

git rm -r --cached <folder>

La rimozione del file dalla revisione principale avverrà al prossimo commit.

ATTENZIONE: Sebbene ciò non rimuoverà il file fisico dal tuo locale, rimuoverà i file dalle altre macchine degli sviluppatori sul prossimo git pull.


55
il processo che ha funzionato per me è stato 1. commit prima delle modifiche in sospeso 2. git rm --cached <file> e commit di nuovo 3. aggiungi il file a .gitignore, controlla con lo stato git e commetti di nuovo
mataal

117
Aggiunta molto importante. Se il file che viene ignorato verrebbe modificato (ma nonostante ciò non dovrebbe essere eseguito il commit), dopo la modifica e l'esecuzione git add .verrà aggiunto all'indice. E il prossimo commit lo impegnerebbe nel repository. Per evitarlo, esegui subito dopo che quel mataal disse un altro comando:git update-index --assume-unchanged <path&filename>
Dao,

32
Il metodo di @AkiraYamamoto ha funzionato bene anche per me. Nel mio caso ho soppresso l'output poiché il mio repository aveva migliaia di file:git rm -r -q --cached .
Aaron Blenkush,

85
Questo eliminerà il file su git pullperò.
Petr Peller,

22
git rm --cached <file> rimuove semplicemente il file dal repository, git update-index --assume-invariato <file> file non mostrato nelle modifiche non messe in scena e non effettua pull nuove modifiche. Ma voglio GIT SOLO IGNORARE IL CONTENUTO DEL FILE PER FAVORE
Igor Semin

2610

La serie di comandi di seguito rimuoverà tutti gli elementi dall'indice Git (non dalla directory di lavoro o dal repository locale), quindi aggiorna l'indice Git, rispettando git ignora. PS. Indice = cache

Primo:

git rm -r --cached . 
git add .

Poi:

git commit -am "Remove ignored files"

O one-liner:

git rm -r --cached . && git add . && git commit -am "Remove ignored files"

197
Per evidenziare la differenza tra questa risposta e quella accettata: utilizzando questi comandi non è necessario conoscere effettivamente i file interessati. (Immagina una directory temporanea con molti file casuali che dovrebbero essere cancellati dall'indice).
Ludwig,

53
Come la risposta accettata. I file verranno eliminati git pull.
Petr Peller,

73
Sarebbe bello avere questo come comando git standard. Qualcosa del genere git rmignored.
Berik,

12
@gudthing -r sta per "ricorsivo"
Mark

14
Con questo potresti finire per aggiungere altri file inutili che non sono attualmente presenti .gitignore. Il che può essere difficile da scoprire se dipende da quanto git statusè il tuo rumore dopo questo comando. Un comando che rimuove solo i file appena ignorati sarebbe meglio. Ecco perché preferisco la risposta di
Soft

1122

git update-index fa il lavoro per me:

git update-index --assume-unchanged <file>

Nota: questa soluzione è in realtà indipendente .gitignorepoiché gitignore è solo per file non tracciati.

modifica: da quando è stata pubblicata questa risposta, è stata creata una nuova opzione che dovrebbe essere preferita. Dovresti usare --skip-worktreequale è per i file tracciati modificati che l'utente non vuole più impegnare e mantenere le --assume-unchangedprestazioni per impedire a git di controllare lo stato dei file tracciati di grandi dimensioni. Vedi https://stackoverflow.com/a/13631525/717372 per maggiori dettagli ...

git update-index --skip-worktree <file>

173
Questa è la vera risposta. In realtà fantastico, molto semplice, non inquina git statuse in realtà molto intuitivo. Grazie.
Pablo Olmos de Aguilera C.,

4
Ho optato per la rm [...] .soluzione abbastanza buona , poiché almeno potevo capire come funzionasse. Non ho trovato un'ottima documentazione su cosa fare update-indexe cosa --assume-unchangedfare. Qualcuno può aggiungere come questo rispetto all'altro, in quanto vorrei rimuovere tutti i file che sarebbero stati ignorati? (O un link per chiarire la spiegazione?)
Brady Trainor

25
git update-index --assume-unchanged <path> …farà in modo che git ignori le modifiche nei percorsi specificati, indipendentemente da .gitignore. Se si estrae da un telecomando e quel telecomando ha modificato questo percorso, git fallirà l'unione con un conflitto e sarà necessario unire manualmente. git rm --cached <path> …farà in modo che git smetta di tracciare quel percorso. Se non aggiungi il percorso .gitignore, vedrai il percorso in futuro git status. La prima opzione ha meno rumore nella cronologia del commit di git e consente di distribuire in futuro le modifiche al file "ignorato".
ManicDee,

26
Sono abbastanza confuso su come questa non sia la risposta accettata. La risposta accettata qui chiaramente non risponde alla domanda effettiva che viene posta. Questa risposta ignora le modifiche al file che si trova nel repository senza rimuoverlo dal repository.
Dave Cooper,

11
Questa risposta sarebbe molto più utile se spiegasse esattamente cosa fa il comando dato, ad esempio come è diverso dalle altre soluzioni suggerite.
LarsH,

283
git ls-files --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

Questo prende l'elenco dei file ignorati e li rimuove dall'indice, quindi esegue il commit delle modifiche.


7
Se devi rimuoverli anche dalla directory di lavoro, esegui semplicemente git ls-files --ignored --exclude-standard | xargs git rm . Credo che questa risposta sia la migliore! Perché è molto chiaro, in modo Unix, e fa la cosa desiderata in modo diretto, senza comporre gli effetti collaterali di altri comandi più complessi.
imz - Ivan Zakharyaschev,

6
Bella risposta; tuttavia, il comando fallirà se si hanno percorsi con spazi nel mezzo, ad esempio: "My dir / my_ignored_file.txt"
David Hernandez,

8
git ls-files --ignored --exclude-standard | sed 's /.*/"&"/' | xargs git rm --cached
David Hernandez,

3
git rmsi lamenterà se ls-filesnon corrisponde a nulla. Utilizzare xargs -r git rm ...per dire di xargsnon eseguire git rmse nessun file corrisponde.
Wolfgang,

10
Sarebbe meglio usare \ 0 come separatore:git ls-files --ignored --exclude-standard -z|xargs -0 git rm --cached
Nils-o-mat

83

Uso sempre questo comando per rimuovere quei file non tracciati. Uscita pulita a una riga, stile Unix:

git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

Elenca tutti i file ignorati, sostituisce ogni riga di output con una riga tra virgolette invece di gestire percorsi con spazi interni e passa tutto git rm -r --cachedper rimuovere i percorsi / file / directory dall'indice.


3
Ottima soluzione! Ha funzionato perfettamente e sembra più corretto che rimuovere tutti i file e aggiungerli di nuovo.
Jon Catmull,

5
Anch'io ho trovato questo "più pulito". Potrebbe essere ovvio, ma solo eseguendo la prima parte, git ls-files --ignored --exclude-standardda solo ti consente di capire / verificare quali file il tuo nuovo .gitignoresta per escludere / rimuovere, prima di andare avanti ed eseguire la finale git rm.
JonBrave,

Attenzione, fallisce sui nomi dei file con alcuni caratteri "cattivi", ad es \n. Ho pubblicato la mia soluzione per soddisfare questo.
JonBrave,

3
Un altro avvertimento: al pull, questo causerà l'eliminazione del file nelle directory di lavoro degli altri, giusto?
LarsH,

provato, ma non ha funzionato per me: sed: 1: "s/.*/": unterminated substitute in regular expressionin un comando filtro-ramo su un repository con spazi. (Sembrava funzionare al di fuori del ramo del filtro però). Ho usato invece git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cacheddalla risposta di @ JonBrave .
goofology il

71

spostalo, commettilo, quindi spostalo di nuovo dentro. Questo ha funzionato per me in passato. Probabilmente esiste un modo "gittoso" per raggiungere questo obiettivo.


2
Funzionava alla grande se si desidera ignorare un mucchio di file che non erano stati precedentemente ignorati. Anche se come hai detto, probabilmente c'è un modo migliore per farlo.
Oskar Persson,

Questo è esattamente quello che ho fatto. Basta spostare i file in una cartella fuori da git, quindi fare "git add.", "Git commit". (Ciò ha rimosso i file) quindi aggiungere gitignore, facendo riferimento ai file / cartelle, impegnarsi nuovamente per aggiungere il file gitignore a git, quindi copiare / tornare indietro nelle cartelle e dovrebbero essere ignorati. NB: sembrerà che i file siano stati eliminati da GIT, quindi probabilmente li rimuoveranno da altri checkout / pull, come menzionato nelle soluzioni sopra, ma poiché si stanno facendo copie di essi inizialmente, questo non è un problema IMHO. fai solo sapere al resto della squadra ...
Del

Questo è il modo più semplice per eliminare le cartelle errate.
Martlark,

2
Sembra essere l'unico modo che posso vedere. È un enorme bug (non 'funzionalità') in git che non appena aggiungi un file / cartella a .gitignore, non ignora quel file da quel punto in poi - per sempre - ovunque.
JosephK,

Questo ha funzionato dopo che li avevo aggiunti, e poi dopo il fatto li
ho

66

Se non riesci git rma tracciare un file perché altre persone potrebbero averne bisogno (avviso, anche se tu git rm --cached , quando qualcun altro riceve questa modifica, i suoi file verranno eliminati nel loro filesystem). Questi vengono spesso eseguiti a causa di sostituzioni dei file di configurazione, credenziali di autenticazione, ecc. Consultare https://gist.github.com/1423106 per sapere come le persone hanno risolto il problema.

Riassumere:

  • Chiedi alla tua applicazione di cercare un file ignorato config-overide.ini e utilizzalo sul file di configurazione config.ini (o, in alternativa, cerca ~ / .config / myapp.ini o $ MYCONFIGFILE)
  • Commettere il file config-sample.ini e ignorare il file config.ini, fare in modo che uno script o simile copi il file se necessario.
  • Prova ad usare gitattributes clean / smudge magic per applicare e rimuovere le modifiche per te, ad esempio sfumare il file di configurazione come checkout da un ramo alternativo e pulire il file di configurazione come checkout da HEAD. Questa è roba difficile, non la consiglio per l'utente inesperto.
  • Mantenere il file di configurazione su un ramo di distribuzione ad esso dedicato che non viene mai unito al master. Quando vuoi distribuire / compilare / test ti unisci a quel ramo e ottieni quel file. Questo è essenzialmente l'approccio sfumato / pulito, tranne per l'uso di politiche di unione umana e moduli extra-git.
  • Anti-ricomposizione: non usare supposta invariata, finirà solo in lacrime (perché avere mentire con se stesso causerà cose brutte, come se il tuo cambiamento venisse perso per sempre).

7
git non rimuoverebbe il file, se fosse sporco al momento della cancellazione. E se non è sporco, recuperare il file sarebbe facile come git checkout <oldref> -- <filename>- ma poi verrebbe estratto e ignorato.
amenthes,

Per quanto riguarda la tua ultima nota (circa --assume-unchanged): o questo è un culto del carico e dovrebbe essere respinto, oppure puoi spiegare perché (di cui sono convinto) e diventa utile.
RomainValeri,

57

Usalo quando:

1. Volete decomprimere molti file o

2. Hai aggiornato il tuo file gitignore

Link alla fonte: http://www.codeblocq.com/2016/01/Untrack-files-already-added-to-git-repository-based-on-gitignore/

Supponiamo che tu abbia già aggiunto / eseguito il commit di alcuni file nel tuo repository git e poi li aggiungi al tuo .gitignore; questi file saranno ancora presenti nell'indice del repository. Questo articolo vedremo come sbarazzarsi di loro.

Passaggio 1: eseguire il commit di tutte le modifiche

Prima di procedere, assicurati che tutte le modifiche siano impegnate, incluso il tuo file .gitignore.

Passaggio 2: rimuovere tutto dal repository

Per cancellare il repository, utilizzare:

git rm -r --cached .
  • rm è il comando di rimozione
  • -r consentirà la rimozione ricorsiva
  • –Cached rimuoverà solo i file dall'indice. I tuoi file saranno ancora lì.

Il rmcomando può non perdonare. Se desideri provare cosa fa prima, aggiungi il flag -no --dry-runper testare le cose.

Passaggio 3: aggiungere nuovamente tutto

git add .

Passaggio 4: impegno

git commit -m ".gitignore fix"

Il tuo repository è pulito :)

Spingi le modifiche sul telecomando per vedere le modifiche efficaci anche lì.


1
Non eliminerà i file dal repository remoto? Cosa succede se voglio mantenere i file sia nel repository locale che in quello remoto ma facendo in modo che git "dimentichi" di loro?
Avishay28,

AFAIK questo non eliminerà i file dalla cronologia perché non stiamo usando alcun comando di modifica della cronologia (correggimi se sbaglio). Questo aggiunge solo un nuovo commit eliminando i file ignorati in gitignore da git. Questi file saranno presenti in gli impegni storici
Dheeraj Bhaskar

49

Ho realizzato questo usando git filter-branch . Il comando esatto che ho usato è stato preso dalla pagina man:

ATTENZIONE : questo eliminerà il file da tutta la tua cronologia

git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD

Questo comando ricrea l'intera cronologia del commit, eseguendo git rmprima di ogni commit e quindi eliminerà il file specificato. Non dimenticare di eseguire il backup prima di eseguire il comando poiché andrà perso.


9
Ciò modificherà tutti gli ID di commit, interrompendo così le fusioni dai rami all'esterno della copia del repository.
bdonlan,

19
ATTENZIONE: questo eliminerà il file da tutta la tua cronologia. Questo era ciò che stavo cercando, tuttavia, per rimuovere un file completamente non necessario e di grandi dimensioni (output che non avrebbe mai dovuto essere commesso) che è stato impegnato molto tempo fa nella cronologia delle versioni.
zebediah49,

48

Cosa non ha funzionato per me

(Sotto Linux), volevo usare i post qui suggerendo l' ls-files --ignored --exclude-standard | xargs git rm -r --cachedapproccio. Tuttavia, (alcuni dei) file da rimuovere avevano una nuova riga / LF / incorporata \nnei loro nomi. Nessuna delle soluzioni:

git ls-files --ignored --exclude-standard | xargs -d"\n" git rm --cached
git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm -r --cached

far fronte a questa situazione (ottenere errori sui file non trovati).

Quindi offro

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached
git commit -am "Remove ignored files"

Questo utilizza l' -zargomento per ls-files e l' -0argomento per xargs per soddisfare in modo sicuro / corretto caratteri "cattivi" nei nomi dei file.

Nella pagina di manuale git-ls-files (1) , afferma:

Quando l'opzione -z non viene utilizzata, i caratteri TAB, LF e barra rovesciata nei nomi dei percorsi sono rappresentati rispettivamente come \ t, \ n e \\.

quindi penso che la mia soluzione sia necessaria se i nomi dei file contengono uno di questi caratteri.


1
Per me questa è la soluzione migliore. Ha prestazioni molto migliori di a git add .. Contiene anche i migliori miglioramenti da alcuni commenti sopra.
Nils-o-mat,

Puoi aggiungere in seguito thSoft git commit -am "Remove ignored files"alla tua risposta? Le tue risposte combinate mi hanno fatto
capire le

Non capisco lo scopo di git commit -a. Per me git rm --cachedinfluenza esattamente l'indice, quindi non c'è bisogno di mettere in scena i file dopo ...
Jean Paul,

23
  1. Aggiorna il tuo .gitignorefile - ad esempio, aggiungi una cartella in cui non desideri monitorare .gitignore.

  2. git rm -r --cached .- Rimuovere tutti i file tracciati, compresi quelli desiderati e indesiderati. Il tuo codice sarà al sicuro finché avrai salvato localmente.

  3. git add .- Tutti i file verranno aggiunti nuovamente, tranne quelli in .gitignore.


Punta del cappello a @AkiraYamamoto per indicarci nella giusta direzione.


1
Che ne dici di effettuare il downgrade a causa del fatto che in realtà non funzionerà perché hai bisogno di -r per eseguire rm in modo ricorsivo comunque :) (Qualcuno non ha copiato correttamente)
Aran Mulholland,

1
Avvertenza: questa tecnica in realtà non fa in modo che git ignori il file, ma in realtà fa sì che git elimini il file. Ciò significa che se si utilizza questa soluzione, ogni volta che qualcun altro esegue un pull git, il file verrà eliminato. Quindi non è in realtà ignorato. Vedi la soluzione che suggerisce git update-index --assume-invariato invece per una soluzione alla domanda originale.
or

16

Penso che forse git non può assolutamente dimenticare il file a causa della sua concezione ( sezione "Istantanee, Non differenze" ).

Questo problema è assente, ad esempio, quando si utilizza CVS. CVS memorizza le informazioni come un elenco di modifiche basate su file. Le informazioni per CVS sono un insieme di file e le modifiche apportate a ciascun file nel tempo.

Ma in Git ogni volta che ti impegni, o salvi lo stato del tuo progetto, fondamentalmente scatta una foto di come appaiono tutti i tuoi file in quel momento e memorizza un riferimento a quella istantanea. Quindi, se hai aggiunto il file una volta, sarà sempre presente in quella istantanea.

Questi 2 articoli mi sono stati utili:

git assume-immutato vs skip-worktree e Come ignorare le modifiche nei file tracciati con Git

Basandomi su di esso faccio quanto segue, se il file è già tracciato:

git update-index --skip-worktree <file>

Da questo momento tutte le modifiche locali in questo file verranno ignorate e non andranno in remoto. Se il file viene modificato sul telecomando, si verificherà un conflitto, quando git pull. Stash non funzionerà. Per risolverlo, copia il contenuto del file in un luogo sicuro e segui questi passaggi:

git update-index --no-skip-worktree <file>
git stash
git pull 

Il contenuto del file verrà sostituito dal contenuto remoto. Incolla le modifiche da un luogo sicuro a un file ed esegui di nuovo:

git update-index --skip-worktree <file>

Se tutti, che lavorano con il progetto, si esibiranno git update-index --skip-worktree <file>, i problemi con pulldovrebbero essere assenti. Questa soluzione è OK per i file di configurazione, quando ogni sviluppatore ha la propria configurazione di progetto.

Non è molto conveniente farlo ogni volta, quando il file è stato modificato su remoto, ma può proteggerlo dalla sovrascrittura da contenuto remoto.


16

Esegui i seguenti passaggi in serie, starai bene.

1. rimuovere i file aggiunti erroneamente dalla directory / archiviazione . È possibile utilizzare il comando "rm -r" (per linux) o eliminarli sfogliando le directory. Oppure spostali in un'altra posizione sul tuo PC. [Potrebbe essere necessario chiudere l'IDE se in esecuzione per lo spostamento / rimozione ]

2.aggiungi i file / le directory da gitignorearchiviare ora e salvali .

3. ora rimuoverli dalla cache di Git usando questi comandi (se ci sono più di una directory, rimuoverli uno per uno emettendo ripetutamente questo comando)

git rm -r --cached path-to-those-files

4. ora fai un commit e premi , usa questi comandi. Questo rimuoverà quei file da git remote e farà smettere a git di tracciare quei file.

git add .
git commit -m "removed unnecessary files from git"
git push origin

13

La risposta copia / incolla è git rm --cached -r .; git add .; git status

Questo comando ignorerà i file che sono già stati sottoposti a commit in un repository Git ma ora li abbiamo aggiunti .gitignore.


9

La risposta di Matt Fear è stata l'IMHO più efficace. Quello che segue è solo uno script di PowerShell per coloro che usano Windows per rimuovere solo i file dal loro repository git che corrispondono al loro elenco di esclusioni.

# Get files matching exclusionsfrom .gitignore
# Excluding comments and empty lines
$ignoreFiles =  gc .gitignore | ?{$_ -notmatch  "#"} |  ?{$_ -match  "\S"} | % {
                    $ignore = "*" + $_ + "*"
                    (gci -r -i $ignore).FullName
                }
$ignoreFiles = $ignoreFiles| ?{$_ -match  "\S"}

# Remove each of these file from Git 
$ignoreFiles | % { git rm $_}

git add .

In quale situazione questo elenco di file non sarà uguale al --cache ricorsivo?
John Zabroski,

8

Sposta o copia il file in un luogo sicuro, in modo da non perderlo. Quindi git rm il file e commit. Il file verrà comunque visualizzato se si ripristina uno di quei commit precedenti o un altro ramo in cui non è stato rimosso. Tuttavia, in tutti i commit futuri, il file non verrà più visualizzato. Se il file si trova in git ignore, puoi spostarlo di nuovo nella cartella e git non lo vedrà.


34
git rm --cachedrimuoverà il file dall'indice senza eliminarlo dal disco, quindi non è necessario spostarlo / copiarlo
bdonlan

7

L'uso del git rm --cachedcomando non risponde alla domanda originale:

Come forzate gita dimenticare completamente [un file]?

In realtà, questa soluzione farà sì che il file da cancellati in ogni altra istanza del repository durante l'esecuzione di una git pull!

Il modo corretto di forzare git a dimenticare un file è documentato da GitHub qui .

Consiglio di leggere la documentazione, ma sostanzialmente:

git fetch --all
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch full/path/to/file' --prune-empty --tag-name-filter cat -- --all
git push origin --force --all
git push origin --force --tags
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

basta sostituire full/path/to/filecon il percorso completo del file. Assicurati di aver aggiunto il file al tuo .gitignore.

Dovrai anche consentire (temporaneamente) push non avanzati al repository , poiché stai modificando la cronologia git.


5

Il BFG è specificamente progettato per rimuovere dati indesiderati come file di grandi dimensioni o password dai repository Git, quindi ha un semplice flag che rimuoverà qualsiasi grande file storico (non-nel-tuo-attuale-commit): '--strip-blobs- più grande di'

$ java -jar bfg.jar --strip-blobs-bigger-than 100M

Se desideri specificare i file per nome, puoi farlo anche tu:

$ java -jar bfg.jar --delete-files *.mp4

Il GGG è 10-1000 volte più veloce del ramo del filtro git e generalmente molto più facile da usare - controlla le istruzioni e gli esempi completi di utilizzo per maggiori dettagli.

Fonte: https://confluence.atlassian.com/bitbucket/reduce-repository-size-321848262.html


5

Se non vuoi usare la CLI e stai lavorando su Windows, una soluzione molto semplice è usare TortoiseGit , ha l'azione "Elimina (mantieni locale)" nel menu che funziona bene.


5

Mi è piaciuta la risposta di JonBrave ma ho abbastanza directory di lavoro abbastanza disordinate che commettono -a mi spaventa un po ', quindi ecco cosa ho fatto:

git config --global alias.exclude-ignored '! git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached && git ls-files -z --ignored --exclude-standard | xargs -0 git stage && git stage .gitignore && git commit -m "nuovo gitignore e rimuovi i file ignorati dall'indice" '

abbattendolo:

git ls-files -z --ignored --exclude-standard | xargs -0 git rm -r --cached 
git ls-files -z --ignored --exclude-standard | xargs -0 git stage 
git stage .gitignore 
git commit -m "new gitignore and remove ignored files from index"
  • rimuove i file ignorati dall'indice
  • stage .gitignore e i file che hai appena rimosso
  • commettere

4

Questo non è più un problema nell'ultimo git (v2.17.1 al momento della scrittura).

Il .gitignoreinfine ignora cingolato-but-file eliminati. Puoi testarlo tu stesso eseguendo il seguente script. La git statusdichiarazione finale dovrebbe riportare "niente da impegnare".

# Create empty repo
mkdir gitignore-test
cd gitignore-test
git init

# Create a file and commit it
echo "hello" > file
git add file
git commit -m initial

# Add the file to gitignore and commit
echo "file" > .gitignore
git add .gitignore
git commit -m gitignore

# Remove the file and commit
git rm file
git commit -m "removed file"

# Reintroduce the file and check status.
# .gitignore is now respected - status reports "nothing to commit".
echo "hello" > file
git status

Sono contento che adesso Git lo faccia. Tuttavia, l'OP stava chiedendo di non tenere traccia delle modifiche nei file presenti in .gitignore, i file non eliminati che mostravano ancora uno stato.
mrturtle,

2

In caso di già commesso DS_Store:

find . -name .DS_Store -print0 | xargs -0 git rm --ignore-unmatch

Ignorali con:

echo ".DS_Store" >> ~/.gitignore_global
echo "._.DS_Store" >> ~/.gitignore_global
echo "**/.DS_Store" >> ~/.gitignore_global
echo "**/._.DS_Store" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global

Infine, fai un commit!


2

Soprattutto per i file basati su IDE, utilizzo questo:

Ad esempio lo slnx.sqlite, me ne sono appena liberato completamente come segue:

git rm {PATH_OF_THE_FILE}/slnx.sqlite -f
git commit -m "remove slnx.sqlite"

Tieni a mente che alcuni di questi file memorizzano alcune impostazioni e preferenze dell'utente locale per i progetti (come i file che hai aperto). Quindi ogni volta che navighi o apporti alcune modifiche al tuo IDE, quel file viene modificato e quindi viene verificato e visualizzato in quanto vi sono modifiche non impegnate.


2

La risposta accettata non "fa dimenticare a Git " un file ... "(storicamente). Fa solo in modo che git ignori il file nel presente / futuro.

Questo metodo fa in modo che git dimentichi completamente i file ignorati ( passati / presenti / futuri), ma non elimina nulla dalla directory di lavoro (anche quando viene estratto nuovamente da remoto).

Questo metodo richiede l'utilizzo di /.git/info/exclude(preferito) O un preesistente .gitignore in tutti i commit che hanno file da ignorare / dimenticare. 1

Tutti i metodi per applicare git ignorano il comportamento dopo il fatto riscrivendo efficacemente la storia e quindi hanno conseguenze significative per qualsiasi repository pubblico / condiviso / collaborativo che potrebbe essere tirato dopo questo processo. 2

Consiglio generale: inizia con un repository pulito - tutto impegnato, nulla in sospeso nella directory o nell'indice di lavoro ed esegui un backup !

Inoltre, i commenti / la cronologia delle revisioni di questa risposta ( e la cronologia delle revisioni di questa domanda ) possono essere utili / illuminanti.

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch

git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch

git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --prune-empty flag in the following command
#this command must be run on each branch

git commit -m "ignored index"

#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits.  If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command

git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all

#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch

git ls-files --other --ignored --exclude-standard

Infine, segui il resto di questa guida di GitHub (a partire dal passaggio 6) che include importanti avvertenze / informazioni sui comandi seguenti .

git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now

Altri sviluppatori che eseguono il pull dal repository remoto ora modificato dovrebbero eseguire un backup e quindi:

#fetch modified remote

git fetch --all

#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed

git reset FETCH_HEAD

Le note

1 Poiché /.git/info/excludepuò essere applicato a tutti i commit storici usando le istruzioni sopra, forse i dettagli su come ottenere un .gitignorefile nei commit storici che ne hanno bisogno vanno oltre lo scopo di questa risposta. Volevo un vero .gitignoreessere nel root commit, come se fosse la prima cosa che ho fatto. Ad altri potrebbe non interessarsi poiché /.git/info/excludepuò realizzare la stessa cosa indipendentemente da dove .gitignoreesiste nella cronologia del commit, e riscrivere chiaramente la storia è un argomento molto delicato, anche se consapevole delle conseguenze .

FWIW, i potenziali metodi possono includere git rebaseo un git filter-branchcopia di un esterno .gitignore in ciascun commit, come le risposte a questa domanda

2 L'applicazione forzata di git ignora il comportamento dopo aver eseguito il commit dei risultati di un git rm --cachedcomando autonomo può comportare la cancellazione di file appena ignorata nei pull futuri dal telecomando forzato. Il --prune-emptyflag nel git filter-branchcomando seguente evita questo problema rimuovendo automaticamente il precedente commit solo indice "elimina tutti i file ignorati". Riscrivere la storia di Git cambia anche gli hash di commit, che causeranno il caos su futuri pull da repository pubblici / condivisi / collaborativi. Si prega di comprendere appieno le ramificazioni prima di fare questo a tale repo. Questa guida di GitHub specifica quanto segue:

Di 'ai tuoi collaboratori di rifare , non unire, tutti i rami che hanno creato dalla tua vecchia storia (contaminata) del repository. Un commit di merge potrebbe reintrodurre una parte o tutta la storia contaminata che hai appena avuto il disturbo di eliminare.

Soluzioni alternative che non influiscono sul repository remoto sono git update-index --assume-unchanged </path/file>o git update-index --skip-worktree <file>, esempi dei quali sono disponibili qui .


0

Se qualcuno ha problemi con Windows e vuoi ignorare l'intera cartella, "cd" desidera la "cartella" e fare "Git Bash Here".

git ls-files -z | xargs -0 git update-index --assume-unchanged

0

Nel mio caso qui, avevo diversi file .lock in diverse directory che dovevo rimuovere. Ho eseguito il seguente e ha funzionato senza dover andare in ogni directory per rimuoverli:

git rm -r --cached **/*.lock

In questo modo è andato in ogni cartella sotto la 'radice' di dove mi trovavo ed escluso tutti i file che corrispondevano al modello.

Spero che questo aiuti gli altri!

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.