Impossibile inviare a GitHub a causa del file di grandi dimensioni che ho già eliminato


272

Attualmente ho

  1. Vuoto repository GitHub
  2. Repository server SSH (principale)
  3. Repo locale

Il repository di server SSH era il repository più aggiornato (sito di produzione), quindi da lì ho eseguito un clone Git in locale. Ho quindi provato a fare un git pushGitHub.

Tutto è andato bene ma poi ha detto qualcosa sul nome di file.gz essendo troppo grande per GitHub. Non avevo bisogno di questo file, quindi ho eseguito diversi comandi Git per eliminarlo dalla cache di Git, quindi ho inviato nuovamente al server SSH.

Non vedo il file di grandi dimensioni localmente ma è ancora sul server SSH anche se git diffnon restituisce nulla e git push restituisce "Tutto è aggiornato" - E anche se il file non è visibile nel repository locale quando provo a eseguire il push in GitHub Ottengo ancora errori al riguardo

remoto: errore: il file fpss.tar.gz è 135,17 MB; questo supera il limite della dimensione del file di GitHub di 100 MB

Ho seguito i passaggi in "risoluzione del problema" elencati nella guida di GitHub, quindi non sarebbe bastato?

In che modo il file è ancora nell'etere quando non è locale o elencato in git status / diff / push?


2
Il file è ancora lì nella cronologia. Devi distruggere la cronologia, possibilmente schiacciando i commit che hanno aggiunto e rimosso il file.
Shahbaz,

@Shahbaz Ho seguito i passaggi indicati in "risoluzione del problema" elencati in questo sito ... non sarebbe bastato? help.github.com/articles/working-with-large-files
Kevin W.

Il comando è più avanzato della mia conoscenza di git, quindi non posso davvero dirlo. Ad ogni modo, se git log -- the_big_fileti restituisce qualcosa, il file è ancora nella cronologia.
Shahbaz,

@Shahbaz che non restituisce nulla> <
Kevin W.

Potrebbe essere che stai spingendo anche altri rami in cui esiste il file? Inoltre, se il file è ancora sul server, perché dovrebbe git pushdire che tutto è aggiornato? Da quando hai cambiato la storia, avrebbe dovuto lamentarsi del fatto che la spinta non è possibile e che dovresti forzarla.
Shahbaz,

Risposte:


446

Puoi usare

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

Ciò eliminerà tutto nella cronologia di quel file. Il problema è che il file è presente nella cronologia.

Questo comando modifica gli hash dei tuoi commit che possono essere un vero problema, specialmente sui repository condivisi. Non dovrebbe essere eseguito senza comprendere le conseguenze.


23
Ha funzionato per me ma ho dovuto 'forzarlo': git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file / dir>' -f HEAD
alexoviedo999

30
Questo comando modifica gli hash dei tuoi commit che possono essere un vero problema, specialmente sui repository condivisi. Non dovrebbe essere eseguito senza comprendere le conseguenze.
Chris,

6
Dovresti sostituire <file / dir> con il nome del file o della directory che causa il problema?
David Rhoden,

12
Nota che se vuoi applicare queste modifiche a TUTTI i rami, devi usare una --allbandiera invece diHEAD
Nick Spreitzer,

9
Ricevo:Rewrite 657560fa18c030bcfac9132ce1c3541e84a5bc2c (1/10) (0 seconds passed, remaining 0 predicted) /usr/lib/git-core/git-filter-branch: 1: eval: Syntax error: end of file unexpected
João Abrantes,

68

Ho trovato più utile di schiacciarefilter-branch . Ho fatto quanto segue:

  1. Elimina localmente file di grandi dimensioni.
  2. Commettere le eliminazioni locali.
  3. Soft reset dei numeri di nuovo X di commit (per me è stato 3): git reset --soft HEAD~3.
  4. Quindi raccomandare tutte le modifiche insieme (AKA squash) git commit -m "New message for the combined commit"
  5. Push commit schiacciato.

Caso speciale (dall'utente @lituo): se sopra non funziona, allora potresti avere questo caso. Commit 1 includeva il file di grandi dimensioni e il push di Commit 1 non è riuscito a causa di un errore di file di grandi dimensioni. Commit 2 ha rimosso il file di grandi dimensionigit rm --cached [file_name]ma il push di Commit 2 non è ancora riuscito. Puoi seguire gli stessi passaggi sopra ma invece di usareHEAD~3, usaHEAD~2.


2
Ha funzionato per me, ho dovuto riunire nuovamente le modifiche dei tre commit nel mio repository locale prima che la compressione dello squash funzionasse.
dasWesen,

5
Questo è MOLTO meglio della risposta migliore. La risposta migliore rovina l'intera cronologia dei commit.
manic.coder

Non ho risolto il mio problema
Hirak Sarkar il

3
Questa è di gran lunga l'unica risposta che corregge file di grandi dimensioni, non impegnati o sottoposti a commit, senza modificare completamente l'archivio del repository! Eseguito l'upgrade in modo che possa spostarsi verso l'alto :-)
Ælex

1
@ma non sono una classe wrapper: grazie mille! questo ha funzionato come un incanto :)
POOJA GUPTA il

63

Ecco qualcosa che ho trovato molto utile se hai già fatto casini con il tuo repository prima di chiedere aiuto. Primo tipo:

git status

Dopo questo, dovresti vedere qualcosa sulla falsariga di

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

La parte importante è il "2 commit"! Da qui, vai avanti e digita:

git reset HEAD~<HOWEVER MANY COMMITS YOU WERE BEHIND>

Quindi, per l'esempio sopra, si dovrebbe digitare:

git reset HEAD~2

Dopo averlo digitato, il tuo "stato git" dovrebbe dire:

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Da lì, puoi eliminare il file di grandi dimensioni (supponendo di non averlo già fatto) e dovresti essere in grado di ripetere il commit di tutto senza perdere il lavoro.
So che questa non è una risposta super fantasiosa, ma spero che ti aiuti!


11
Vincitore. Soluzione semplice, pulita, efficace e git. L'amore risponde così.
Reece Daniels,

3
questa è la migliore soluzione che ci sia.
wrahool,

40

Se il file è stato aggiunto con il commit più recente e non è stato eseguito il push nel repository remoto , è possibile eliminare il file e modificare il commit, preso da qui :

git rm --cached giant_file
    # Stage "giant_file" for removal with "git rm"
    # Leave it on disk with "--cached". if you want to remove it from disk
    # then ignore the "--cached" parameter
git commit --amend -CHEAD
    # Commit the current tree without the giant file using "git commit"
    # Amend the previous commit with your change "--amend" 
    # (simply making a new commit won't work, as you need
    # to remove the file from the unpushed history as well)
    # Use the log/authorship/timestamp of the last commit (the one we are
    # amending) with "-CHEAD", equivalent to --reuse-message=HEAD
git push
    # Push our rewritten, smaller commit with "git push"

1
Questa soluzione non funzionerà poiché il file non è più nell'indice git (risulta come untrackedelenco di file su git status.
Loretoparisi,

Non sta succedendo niente. Dopo averlo applicato, ha ridotto il numero totale di file, ma dopo aver mostrato il processo al 99% si è bloccato di nuovo. Qualche suggerimento su cosa mi sto perdendo?
CoDe

4
cosa significa -CHEAD?
Aerin,

1
E se volessi provare questo da un commit specifico, non dall'ultimo commit? Ci ho provato git rm --cached giant_file commit_idma non ha funzionato :(
puifais il

@puifais Vorrei tornare al commit precedente, fare questi passaggi e quindi unirmi a quello corrente. Non sono sicuro che questo sia l'approccio migliore, non sono un esperto di Git
BlueMoon93,

13

Ho avuto un problema simile e ho usato il passaggio sopra per rimuovere il file. Ha funzionato perfettamente.

Ho quindi ricevuto un errore su un secondo file che dovevo rimuovere: remote: error: File <path/filename> is 109.99 MB; this exceeds GitHub's file size limit of 100.00 MB

Ho provato lo stesso passaggio, ho ricevuto un errore: "A previous backup already exists in <path/filename>"

Dalla ricerca su questo sito web ho usato il comando:git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <path/filename>" --prune-empty --tag-name-filter cat -- --all

Ha funzionato alla grande e i file di grandi dimensioni sono stati rimossi.

Incredibilmente, la spinta non è riuscita con un altro errore: error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 104 fatal: The remote end hung up unexpectedly

Questo ho risolto modificando direttamente il file di configurazione .git - postBuffer = 999999999

Dopo di che la spinta è passata!


1
un ulteriore problema che ho dovuto affrontare per rimuovere un file di grandi dimensioni (come sopra) era che una delle cartelle conteneva un carattere hash #. Ciò non ha causato alcun problema per la normale operazione git, tuttavia per il fatto che git rmavevo bisogno di dare il nome completo del percorso del repository per il file e di sfuggire al # con una barra rovesciata per farlo funzionare
jacanterbury,

questo ha funzionato anche per me. Ho evitato il reset hardpassaggio in fondo alla pagina con una semplice spinta. czettner.com/2015/07/16/…
Monte Hayward

Funzionava anche dopo aver eseguito 'git push -f origin'
kezzos il

12

Perché GitHub rifiuta il mio repository, anche dopo aver eliminato il file di grandi dimensioni?

Git memorizza la cronologia completa del tuo progetto, quindi anche se "elimini" un file dal tuo progetto, il repository Git ha ancora una copia del file nella sua cronologia e se provi a passare a un altro repository (come uno ospitato su GitHub) quindi Git richiede che il repository remoto abbia la stessa cronologia del repository locale (ovvero gli stessi file di grandi dimensioni nella sua cronologia).

Come posso ottenere GitHub per accettare il mio repository?

È necessario ripulire la cronologia Git del progetto localmente, rimuovendo i file di grandi dimensioni indesiderati da tutta la cronologia, quindi utilizzare solo la cronologia "pulita" in futuro. Gli ID di commit Git dei commit interessati cambieranno.

Come pulisco i file di grandi dimensioni dal mio repository Git?

Lo strumento migliore per eliminare file di grandi dimensioni indesiderati dalla cronologia di Git è BFG Repo-Cleaner : è un'alternativa più semplice e veloce a quella git-filter-branchappositamente progettata per rimuovere file indesiderati dalla cronologia di Git.

Seguire attentamente le istruzioni per l' uso , la parte fondamentale è proprio questa:

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

Qualsiasi file di dimensioni superiori a 100 MB (che non sono nel tuo ultimo commit) verrà rimosso dalla cronologia del tuo repository Git. È quindi possibile utilizzare git gcper pulire i dati morti:

$ git gc --prune=now --aggressive

Il GGG è in genere almeno 10-50 volte più veloce della corsa git-filter-branche generalmente molto più facile da usare.

Informativa completa: sono l'autore del Repo-Cleaner di BFG.


1
Il mio caso aveva ulteriori complicazioni che impedivano di schiacciare. Lo strumento BFG ha funzionato alla grande. Grazie.
dantopa,

Questa è una soluzione fenomenale
Patate sessuali

5

Ho provato tutti i metodi sopra indicati, ma nessuno di questi funziona per me.

Poi ho trovato la mia soluzione.

  1. Prima di tutto, hai bisogno di un repository locale pulito e aggiornato. Elimina tutti i fottuti file di grandi dimensioni.

  2. Ora crea una nuova cartella ESTERNA dalla tua cartella repository e usa "Git crea repository qui" per renderlo un nuovo repository Git, chiamiamolo new_local_repo. Questo è! Tutti i suddetti metodi hanno detto che devi pulire la storia ... beh, sono stufo di questo, creiamo un nuovo repository che non ha alcuna storia!

  3. Copia i file dal tuo vecchio repository locale incasinato nel nuovo, bellissimo repository. Si noti che il logo verde sull'icona della cartella scompare, questo è promettente perché si tratta di un nuovo repository!

  4. Effettuare il commit nella succursale locale e quindi spingere nella nuova succursale remota. Chiamiamolo new_remote_branch. Se non sai come effettuare il push da un nuovo repository locale, cercalo su Google.

  5. Congratulazioni! Hai inviato il tuo codice pulito e aggiornato a GitHub. Se non hai più bisogno del ramo master remoto, puoi creare il tuo new_remote_branch come nuovo ramo master. Se non sai come farlo, cercalo su Google.

  6. Ultimo passo, è tempo di cancellare il vecchio repository locale incasinato. In futuro utilizzerai solo new_local_repo.


4

Ho avuto lo stesso problema e nessuna delle risposte funziona per me. Ho risolto i seguenti passi:

1. Trova quali commit contengono il file di grandi dimensioni

git log --all -- 'large_file`

Il commit in basso è il commit più vecchio nell'elenco dei risultati.

2. Trova quello appena prima del più vecchio.

git log

Supponiamo che tu abbia:

commit 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

3. Git rebase

git rebase -i 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

Suggerimenti :

  1. Voce di elenco
  2. Ho solo scelto dropper il commit contiene il file di grandi dimensioni.
  3. Potresti incontrare conflitti durante rebase risolverli e utilizzare git rebase --continueper continuare fino a quando non lo finisci.
  4. Se qualcosa è andato storto durante il rebase usa git rebase --abortper annullarlo.


1

La soluzione per mantenere i file / le cartelle di grandi dimensioni all'interno della cartella di lavoro

Questa è la linea che ha funzionato per risolvere il problema qui richiesto (dalla risposta 1):

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

Questo comando elimina anche il file / dir se il file / dir si trova nell'albero di lavoro.

Se si desidera mantenere il file / la cartella all'interno dell'albero di lavoro, propongo di seguire i seguenti passi.

  1. Dopo quell'esecuzione dell'errore git reset HEAD^
  2. Aggiungi il file / la cartella in questione nel file `` .gitignore```.

  3. Procedere come di consueto git add .che potrebbe acquisire altri file / cartelle ma deve acquisire il .gitignorefile. Il prossimo è git commit -m"message"e finalmentegit push origin <branch_name>


0

questo ha funzionato per me. documentazione da github Squashing Git Commette git reset origin / master

git checkout master && git pull;
git merge feature_branch;
git add . --all;
git commit -m "your commit message"

trova la documentazione qui


0

Quindi ho riscontrato una situazione particolare: ho clonato un repository da gitlab, che conteneva un file più grande di 100 mb, ma è stato rimosso ad un certo punto nella storia di git. Successivamente, quando ho aggiunto un nuovo repository privato github e ho provato a inviare il nuovo repository, ho ricevuto il famigerato errore "file troppo grande". A questo punto, non avevo più accesso al repository gitlab originale. Tuttavia, sono stato ancora in grado di eseguire il push sul nuovo repository github privato utilizzando bfg-repo-cleanerun repository LOCAL sulla mia macchina:

$ cd ~
$ curl https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar > bfg.jar
$ cd my-project
$ git gc
$ cd ../
$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-project
$ cd my-project
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git remote -v # confirm origin is the remote you want to push to
$ git push origin master

0

A volte il file viene conservato nella cronologia di monitoraggio, prova i seguenti passaggi:

  1. git commit, Se visualizzi la modalità di creazione con il file di grandi dimensioni elencato, quindi esegui:
  2. git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch filename' HEAD. Dovresti vedere un mucchio di riscritture mostrato nella tua console che termina con:

    rm 'nome file' e

    l'ultima riga Ref è stata riscritta.

E 'fatto.


-1

Sto aggiungendo alla prima risposta.

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

Ci saranno alcuni conflitti di unione tra origin / master.

La tua filiale e 'origine / padrone' sono divergenti e hanno rispettivamente 114 e 109 diversi commit ciascuno. (usa "git pull" per unire il ramo remoto al tuo)

Si prega di eseguire questo

git reset --hard origin / master

Getterà via tutte le mie modifiche organizzate e non messe in scena, dimenticherà tutto sul mio attuale ramo locale e lo farà esattamente come origin / master.

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.