Kann wegen der großen Datei, die ich bereits gelöscht habe, nicht auf GitHub pushen

270

Derzeit habe ich

  1. Leeres GitHub-Repo
  2. SSH Server Repo (Haupt)
  3. Lokales Repo

Das SSH-Server-Repo war das aktuellste Repo (Produktionsstandort), daher habe ich einen Git-Klon von dort nach lokal erstellt. Ich habe dann versucht, ein git pushGitHub zu machen.

Alles lief in Ordnung, aber dann stand etwas darüber, dass filename.gz für GitHub zu groß ist. Ich brauchte diese Datei nicht, also führte ich mehrere Git-Befehle aus, um sie aus dem Git-Cache zu entfernen, und schob sie dann zurück zum SSH-Server.

Ich sehe die große Datei lokal nicht, aber sie befindet sich immer noch auf dem SSH-Server, obwohl git diffnichts zurückgegeben wird und git push "Alles ist auf dem neuesten Stand" zurückgibt - und obwohl die Datei im lokalen Repo nicht sichtbar ist, wenn ich versuche, auf zu pushen GitHub Ich bekomme immer noch Fehler darüber

remote: Fehler: Datei fpss.tar.gz ist 135,17 MB; Dies überschreitet die Dateigrößenbeschränkung von GitHub von 100 MB

Ich habe die in der GitHub-Hilfe aufgeführten Schritte unter "Beheben des Problems" ausgeführt. Sollte das nicht genug gewesen sein?

Wie befindet sich die Datei noch im Äther, wenn sie nicht lokal ist oder in git status / diff / push aufgeführt ist?

Kevin W.
quelle
2
Die Datei befindet sich noch im Verlauf. Sie müssen den Verlauf zerstören, möglicherweise indem Sie die Commits quetschen, mit denen die Datei hinzugefügt und entfernt wurde.
Shahbaz
@ Shahbaz Ich habe die auf dieser Seite aufgeführten Schritte unter "Beheben des Problems" ausgeführt. Sollte das nicht genug gewesen sein? help.github.com/articles/working-with-large-files
Kevin W.
Der Befehl dort ist weiter fortgeschritten als meine Kenntnisse über Git, daher kann ich es nicht wirklich sagen. Wie auch immer, wenn git log -- the_big_fileSie etwas zurückgeben, ist die Datei immer noch im Verlauf.
Shahbaz
@ Shahbaz, der nichts zurückgibt> <
Kevin W.
Könnte es sein, dass Sie auch andere Zweige verschieben, in denen die Datei vorhanden ist? Wenn sich die Datei noch auf dem Server befindet, warum sollte dann git pushalles auf dem neuesten Stand sein? Da Sie die Geschichte geändert haben, hätte es sich beschweren müssen, dass der Push nicht möglich ist und dass Sie ihn erzwingen müssten.
Shahbaz

Antworten:

443

Sie können verwenden

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

Dadurch wird alles im Verlauf dieser Datei gelöscht. Das Problem ist, dass die Datei im Verlauf vorhanden ist.

Dieser Befehl ändert die Hashes Ihrer Commits, was insbesondere bei freigegebenen Repositorys ein echtes Problem sein kann. Es sollte nicht durchgeführt werden, ohne die Konsequenzen zu verstehen.

MacGyver
quelle
22
Hat für mich funktioniert, aber ich musste es 'erzwingen': git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file / dir>' -f HEAD
alexoviedo999
30
Dieser Befehl ändert die Hashes Ihrer Commits, was insbesondere bei freigegebenen Repositorys ein echtes Problem sein kann. Es sollte nicht durchgeführt werden, ohne die Konsequenzen zu verstehen.
Chris
6
Sollen Sie <Datei / Verzeichnis> durch den Namen der Datei oder des Verzeichnisses ersetzen, die bzw. das das Problem verursacht?
David Rhoden
12
Beachten Sie, dass Sie, wenn Sie diese Änderungen auf ALLE Zweige anwenden möchten, ein --allFlag anstelle vonHEAD
Nick Spreitzer
9
Ich 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

Ich fand Quetschen nützlicher als filter-branch. Ich habe folgendes gemacht:

  1. Löschen Sie lokal große Dateien.
  2. Übernehmen Sie die lokalen Löschvorgänge.
  3. Soft-Reset zurück X Anzahl der Commits (für mich waren es 3) : git reset --soft HEAD~3.
  4. Dann alle Änderungen zusammen erneut festschreiben (AKA-Kürbis) git commit -m "New message for the combined commit"
  5. Push Squashed Commit.

Sonderfall (von Benutzer @lituo): Wenn oben nicht funktioniert, haben Sie möglicherweise diesen Fall. Commit 1 enthielt die große Datei, und der Push von Commit 1 schlug aufgrund eines Fehlers bei großen Dateien fehl. Commit 2 entfernte die große Datei um,git rm --cached [file_name]aber der PushvonCommit 2 schlug immer noch fehl. Sie können die gleichen Schritte wie oben ausführen, aber anstatt zu verwendenHEAD~3, verwenden SieHEAD~2.

Aber ich bin keine Wrapper-Klasse
quelle
2
Arbeitete für mich, musste nur die Änderungen aus den drei Commits wieder in meinem lokalen Repository zusammenführen, bevor der Squash-Push funktionierte.
dasWesen
5
Dies ist viel besser als die Top-Antwort. Die Top-Antwort bringt Ihre gesamte Commit-Historie durcheinander.
manic.coder
Habe mein Problem nicht behoben
Hirak Sarkar
3
Dies ist bei weitem die einzige Antwort, die große nicht festgeschriebene oder festgeschriebene Dateien behebt, ohne das Repository vollständig zu zerstören! Upvoted, damit es nach oben gehen kann :-)
Ælex
1
@ aber ich bin keine Wrapper-Klasse: Vielen Dank! das hat wie ein Zauber funktioniert :)
POOJA GUPTA
61

Folgendes fand ich sehr hilfreich, wenn Sie bereits mit Ihrem Repo herumgespielt haben, bevor Sie um Hilfe gebeten haben. Erster Typ:

git status

Danach sollten Sie etwas in der Art von sehen

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

Der wichtige Teil sind die "2 Commits"! Von hier aus geben Sie Folgendes ein:

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

Für das obige Beispiel würde man also Folgendes eingeben:

git reset HEAD~2

Nachdem Sie das eingegeben haben, sollte Ihr "Git-Status" lauten:

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

nothing to commit, working tree clean

Von dort aus können Sie die große Datei löschen (vorausgesetzt, Sie haben dies noch nicht getan), und Sie sollten in der Lage sein, alles erneut festzuschreiben, ohne Ihre Arbeit zu verlieren.
Ich weiß, dass dies keine ausgefallene Antwort ist, aber ich hoffe, es hilft!

Shreya
quelle
11
Gewinner. Einfache, saubere, effektive und von Git gebaute Lösung. Liebe antwortet so.
Reece Daniels
3
Dies ist die beste Lösung, die es gibt.
Wrahool
40

Wenn die Datei mit zugesetztem Ihre letzte begehen , und Sie haben nicht auf die Remote - Repository geschoben , können Sie die Datei löschen und ändern die begehen, Genommen von hier :

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"
BlueMoon93
quelle
1
Diese Lösung wird nicht funktionieren, da die Datei nicht mehr im Git-Index ist (sie ergibt sich als untrackedDateiliste um git status.
Loretoparisi
Nichts passiert. Nachdem dies angewendet wurde, reduzierte es die Gesamtzahl der Dateien, aber nachdem der Prozess zu 99% angezeigt wurde, blieb es wieder hängen. Irgendein Vorschlag, was mir fehlt?
CoDe
4
Was bedeutet -CHEAD?
Aerin
1
Was ist, wenn ich dies von einem bestimmten Commit aus versuchen möchte - nicht vom allerletzten Commit? Ich habe es versucht, git rm --cached giant_file commit_idaber es hat nicht funktioniert :(
Puifais
@puifais Ich würde zum vorherigen Commit zurückkehren, diese Schritte ausführen und dann mit dem aktuellen zusammenführen. Ich bin mir nicht sicher , ob dies der beste Ansatz ist, ich bin nicht ein Git - Experte
BlueMoon93
13

Ich hatte ein ähnliches Problem und habe den obigen Schritt verwendet , um die Datei zu entfernen. Es hat perfekt funktioniert.

Ich habe dann einen Fehler in einer zweiten Datei erhalten, die ich entfernen musste: remote: error: File <path/filename> is 109.99 MB; this exceeds GitHub's file size limit of 100.00 MB

Ich habe den gleichen Schritt versucht und eine Fehlermeldung erhalten: "A previous backup already exists in <path/filename>"

Aus Recherchen auf dieser Website habe ich den Befehl verwendet:git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <path/filename>" --prune-empty --tag-name-filter cat -- --all

Hat super funktioniert und die großen Dateien wurden entfernt.

Unglaublicherweise schlug der Push immer noch mit einem weiteren Fehler fehl: error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 104 fatal: The remote end hung up unexpectedly

Dies habe ich behoben, indem ich die .git-Konfigurationsdatei direkt geändert habe - postBuffer = 999999999

Danach ging der Push durch!

Andre Odendaal
quelle
1
Ein zusätzliches Problem, mit dem ich beim Entfernen einer großen Datei (wie oben) zu kämpfen hatte, war, dass einer der Ordner ein Hash-Zeichen enthielt. Dies verursachte überhaupt keine Probleme für den normalen Git-Betrieb, jedoch musste git rmich den vollständigen Repository-Pfadnamen für die Datei
angeben
das hat auch bei mir funktioniert. Ich habe den reset hardSchritt am Ende der Seite mit einem einfachen Druck vermieden . czettner.com/2015/07/16/…
Monte Hayward
Dies funktionierte, nachdem auch 'git push -f origin' ausgeführt wurde
kezzos
12

Warum lehnt GitHub mein Repo ab, obwohl ich die große Datei gelöscht habe?

Git speichert den vollständigen Verlauf Ihres Projekts. Selbst wenn Sie eine Datei aus Ihrem Projekt "löschen", enthält das Git-Repo eine Kopie der Datei im Verlauf und wenn Sie versuchen, in ein anderes Repository (wie eines, das bei gehostet wird) zu pushen GitHub), dann erfordert Git, dass das Remote-Repo denselben Verlauf hat wie Ihr lokales Repo (dh dieselben großen Dateien in seinem Verlauf).

Wie kann ich GitHub dazu bringen, mein Repo anzunehmen?

Sie müssen den Git-Verlauf Ihres Projekts lokal bereinigen, die unerwünschten großen Dateien aus dem gesamten Verlauf entfernen und anschließend nur den "bereinigten" Verlauf verwenden. Die Git-Commit-IDs der betroffenen Commits ändern sich.

Wie bereinige ich große Dateien aus meinem Git-Repo?

Das beste Tool zum Bereinigen unerwünschter großer Dateien aus dem Git-Verlauf ist der BFG Repo-Cleaner - eine einfachere und schnellere Alternative zum git-filter-branchEntfernen unerwünschter Dateien aus dem Git-Verlauf.

Befolgen Sie sorgfältig die Gebrauchsanweisung , der Kern ist genau dies:

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

Alle Dateien mit einer Größe von mehr als 100 MB (die nicht in Ihrem letzten Commit enthalten sind) werden aus dem Verlauf Ihres Git-Repositorys entfernt. Sie können dann git gcdie toten Daten entfernen:

$ git gc --prune=now --aggressive

Das BFG ist in der Regel mindestens 10-50x schneller als das Laufen git-filter-branchund im Allgemeinen viel einfacher zu bedienen.

Vollständige Offenlegung: Ich bin der Autor des BFG Repo-Cleaner.

Roberto Tyley
quelle
1
Mein Fall hatte zusätzliche Komplikationen, die ein Quetschen verhinderten. Das BFG-Tool hat super funktioniert. Vielen Dank.
Dantopa
Dies ist eine phänomenale Lösung
SexualPotatoes
4

Ich habe das gleiche Problem und keine der Antworten funktioniert für mich. Ich habe durch die folgenden Schritte gelöst:

1. Finden Sie heraus, welche Commits die große Datei enthalten

git log --all -- 'large_file`

Das unterste Commit ist das älteste Commit in der Ergebnisliste.

2. Finden Sie die kurz vor der ältesten.

git log

Angenommen, Sie haben:

commit 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

3. Git Rebase

git rebase -i 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

Tipps :

  1. Listenpunkt
  2. Ich wähle nur dropfür die Commits enthält die große Datei.
  3. Während der Rebase können Konflikte auftreten, die behoben und git rebase --continuefortgesetzt werden, bis Sie fertig sind.
  4. Wenn während der Rebase etwas schief gelaufen ist, verwenden Sie diese git rebase --abort, um sie abzubrechen.
William Hu
quelle
4

Ich habe alle oben genannten Methoden ausprobiert, aber keine davon funktioniert für mich.

Dann habe ich meine eigene Lösung gefunden.

  1. Zunächst benötigen Sie ein sauberes, aktuelles lokales Repo. Lösche alle verdammt großen Dateien.

  2. Erstellen Sie nun einen neuen Ordner AUSSERHALB Ihres Repo-Ordners und verwenden Sie "Git create repository here", um daraus ein neues Git-Repository zu machen. Nennen wir es new_local_repo. Das ist es! Alle oben genannten Methoden besagten, dass Sie die Historie bereinigen müssen ... nun, ich habe es satt, lassen Sie uns ein neues Repo erstellen, das überhaupt keine Historie hat!

  3. Kopieren Sie die Dateien von Ihrem alten, beschissenen lokalen Repo in das neue, schöne Repo. Beachten Sie, dass das grüne Logo auf dem Ordnersymbol verschwindet. Dies ist vielversprechend, da dies ein neues Repo ist!

  4. Übertragen Sie auf den lokalen Zweig und drücken Sie dann auf den neuen Remote-Zweig. Nennen wir es new_remote_branch. Wenn Sie nicht wissen, wie Sie von einem neuen lokalen Repo aus pushen können, googeln Sie es.

  5. Glückwunsch! Sie haben Ihren sauberen, aktuellen Code an GitHub gesendet. Wenn Sie den Remote-Hauptzweig nicht mehr benötigen, können Sie Ihre new_remote_branch als neuen Hauptzweig festlegen. Wenn Sie nicht wissen, wie es geht, googeln Sie es.

  6. Letzter Schritt, es ist Zeit, das beschissene alte lokale Repo zu löschen. In Zukunft verwenden Sie nur das new_local_repo.

Shuaibin Chang
quelle
1

Die Lösung, um die großen Dateien / Ordner im Arbeitsordner zu halten

Dies ist die Zeile, mit der das hier gestellte Problem gelöst wurde (aus Antwort 1):

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

Dieser Befehl löscht auch die Datei / das Verzeichnis, wenn sich die Datei / das Verzeichnis im Arbeitsbaum befindet.

Wenn Sie die Datei / den Ordner im Arbeitsbaum behalten möchten, schlage ich die folgenden Schritte vor.

  1. Nach diesem Fehler ausführen git reset HEAD^
  2. Fügen Sie die betreffende Datei / den betreffenden Ordner in die Datei `` .gitignore``` ein.

  3. Gehen Sie wie gewohnt vor git add ., um möglicherweise andere Dateien / Ordner zu erfassen, müssen jedoch Dateien erfassen .gitignore. Weiter ist git commit -m"message"und endlichgit push origin <branch_name>

Kiprono Elijah Koech
quelle
0

das hat bei mir funktioniert. Dokumentation von github Squashing Git Commits git reset origin / master

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

Dokumentation finden Sie hier

Njoroge Mathu
quelle
0

Ich füge der ersten Antwort hinzu.

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

Es wird einen Zusammenführungskonflikt von Ursprung / Master geben.

Ihr Zweig und "Ursprung / Master" sind unterschiedlich und haben jeweils 114 bzw. 109 verschiedene Commits. (Verwenden Sie "git pull", um den Remote-Zweig mit Ihrem zusammenzuführen.)

Bitte führen Sie dies aus

Git Reset - Hard Origin / Master

Es wird alle meine inszenierten und nicht inszenierten Änderungen wegwerfen, alles in meiner aktuellen lokalen Niederlassung vergessen und es genau so machen wie origin / master.

RAHUL KUMAR
quelle
0

Ich bin also auf eine bestimmte Situation gestoßen: Ich habe ein Repository aus gitlab geklont, das eine Datei mit mehr als 100 MB enthielt, aber irgendwann im Git-Verlauf entfernt wurde. Als ich später ein neues privates Github-Repo hinzufügte und versuchte, auf das neue Repo zu pushen, bekam ich den berüchtigten Fehler "Datei zu groß". Zu diesem Zeitpunkt hatte ich keinen Zugriff mehr auf das ursprüngliche Gitlab-Repo. Ich konnte jedoch weiterhin mithilfe bfg-repo-cleanereines lokalen Repositorys auf meinem Computer auf das neue private Github-Repo zugreifen :

$ 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
Donato
quelle
0

Manchmal wird die Datei im Tracking-Verlauf gespeichert. Führen Sie die folgenden Schritte aus:

  1. git commitWenn der Erstellungsmodus mit der aufgelisteten großen Datei angezeigt wird, gehen Sie wie folgt vor :
  2. git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch filename' HEAD. In Ihrer Konsole sollte eine Reihe von Umschreibungen angezeigt werden, die mit Folgendem enden:

    rm 'Dateiname' und

    Die letzte Zeile Ref wurde neu geschrieben.

Es ist fertig.

Baum DR
quelle