Freigeben über


Entfernen einer großen Binärdatei aus Ihrem Git-Verlauf zum Verwalten der Größe von geklonten Repositorys

Azure DevOps Services | Azure DevOps Server | Azure DevOps Server 2022

Git ist ein beliebtes Repository für verteilten Quellcode (Repo), mit dem Benutzer auch dann mit dem kompletten Repository arbeiten können, wenn sie offline sind. Die Vorteile von Git sind gut dokumentiert, aber was passiert, wenn Sie das Rollback der Uhr auf dem primären Repository ausführen müssen? Dies ist nicht intuitiv und erfordert erhöhte Berechtigungen. Diese Anforderung wird für etwas erwartet, das sich auf jeden einzelnen Benutzer des Repositorys auswirkt.

Wie können Sie das zentrale Repository sicher zurücksetzen?

Problemszenario

Stellen Sie sich vor, Sie übernehmen eine große Datei, z. B. ein Video, auf Ihren Git-Server. In einem herkömmlichen Quellcodesystem ist es praktisch, alles an einer zentralen Stelle zu speichern und dann die benötigten Elemente nach unten zu ziehen. Bei Git wird das gesamte Repository auf den lokalen Computer jedes Benutzers geklont. Bei einer großen Datei muss jeder einzelne Benutzer des Projekts auch die großen Dateien herunterladen.

Bei jeder nachfolgenden großen Datei, die auf den Server zugesichert wird, wächst das Problem nur. Das Repository wird zu groß, um für seine Benutzer effizient zu sein. Selbst wenn Sie die große Datei aus Ihrem lokalen Repository entfernen und erneut übermitteln, ist die Datei weiterhin im Verlauf des Repositorys vorhanden. Daher wird die Datei weiterhin im Rahmen des Verlaufs auf den lokalen Computer aller Benutzer heruntergeladen.

Screenshot des Dialogfelds

Fügen Sie dem lokalen Repository eine große Datei hinzu.

Screenshot, der server- und lokale Repositorys mit einer Kopie der großen Videodateien zeigt.

Nachdem Sie einen Commit aus dem lokalen Repository ausgeführt haben, verfügt der Server auch über die große Datei.

Repository einfrieren

Um das Problem eines großen Repositorys zu beheben, müssen Sie an der Quelle beginnen. In diesem Szenario ist die Quelle das Server-Repository. Bitten Sie das Team, den Push an das Repository zu beenden. Wenn während dieses Prozesses mehr Pushes auftreten, müssen Sie diese berücksichtigen, damit keine Daten verloren gehen.

Von Bedeutung

Mit den folgenden Schritten wird das Video aus Ihrem Branch-Verlauf entfernt, bleibt jedoch im Repository-Verlauf vorhanden, wenn Sie Ihr Repository aus Azure Repos klonen. Durch das Entfernen der Dateien aus dem Verzweigungsverlauf wird verhindert, dass die Dateien aktualisiert werden, wodurch eine andere Version der großen Datei in Ihrem Repository erstellt wurde.

Erfahren Sie mehr über das Verwalten großer Dateien in Git. Eine Erläuterung und Problemumgehung für dieses Verhalten, wenn Sie Azure Repos Git-Repositorys verwenden, finden Sie unter Warum gibt das Klonen von Visual Studio Team Services alte nicht referenzierte Objekte zurück?.

Rebase ausführen und erzwungener Push

Wenn niemand anderes im Team Änderungen am Repository vorgenommen hat, die in der Regel durch einen Push auftreten, können Sie die einfache Route nutzen. Im Wesentlichen gestalten Sie ihr lokales Repository so, wie es aussehen soll (d. a. ohne die große Datei). Anschließend erzwingen Sie die Änderungen am Server.

Möglicherweise müssen Sie Ihr lokales Repository klonen oder beheben, bevor Sie mit dieser Arbeit beginnen. Dieser Vorgang kann zu verlorenen Arbeiten oder Änderungen führen, also gehen Sie vorsichtig vor.

Standardmäßig können Sie lokale Projektdateien ändern und Änderungen an den Server pushen, sie können jedoch keine Vorgänge auf Serverebene ausführen, z. B. löschen oder neubasieren. Um fortzufahren, benötigen Sie Force-Push-Berechtigungen (bevorzugt) oder Administratorberechtigungen für das Repository. Wenden Sie sich an Ihren Projektadministrator, um diese Berechtigungen anzufordern, oder bitten Sie jemanden, der sie bereits zur Hilfe hat. Weitere Informationen finden Sie unter Festlegen von Git-Repositoryberechtigungen.

Screenshot der Befehlsaufforderung - git push --force-Berechtigungen.

Als Nächstes müssen Sie das Repository neu erstellen.

  1. Benutzen Sie git log, um die SHA-Hashwerte (Secure Hash Algorithm) der neuesten Commits zu finden. Sie benötigen diese Informationen in einem Moment, da Sie den letzten guten Commit kennen müssen. Sie können diese Informationen abrufen, indem Sie eine Git-Eingabeaufforderung öffnen und Folgendes eingeben:

    git log

    Alternativ können Sie den SHA-Hash aus dem Anzeigen des Verzweigungsverlaufs im Visual Studio-Team-Explorer abrufen.

    Screenshot der Option

  2. Öffnen Sie eine Git-Eingabeaufforderung.

    Screenshot der Aktion

  3. Suchen Sie die SHA-Hashnummer von Interesse.

    Screenshot der Eingabeaufforderung für den Video-Commit.

    Sie benötigen das SHA, das mit 25b4 beginnt.

    Denken Sie daran, dass Git Zeiger verwendet, um zu bestimmen, wo sich der Kopf oder die aktuelle Verzweigung im Repository befindet. Der Status des Repositorys, an dem Sie interessiert sind, befindet sich an einem bestimmten Punkt in der Vergangenheit.

  4. Verwenden Sie git rebase den Befehl, um in der Zeit zurückzugehen und den vorherigen Zustand zum neuen aktuellen Zustand zu machen:

    git rebase -i <SHA hash of desired new current branch>

    Screenshot der Verwendung der Rebase zum Entfernen der Videodatei.

    Der -i Schalter bietet zusätzliche Sicherheit, da er den Verlauf in einem Editor anzeigt. (In diesem Artikel wird eine Implementierung von Git verwendet, die den klassischen Vi-Editor in der Befehlszeile in Windows aufführt. Sie erinnern sich vielleicht daran, wenn Sie mit einem Unix-basierten System gearbeitet haben.)

  5. In diesem Beispiel geben Sie Folgendes ein:

    git rebase -i 25b4

  6. Nachdem der Editor angezeigt wurde, entfernen Sie alle Zeilen mit Ausnahme der pick Verzweigung, die Sie als neuen Hauptzweig behalten möchten. Wenn alles korrekt aussieht, geben Sie :w\<enter\> in vi ein, um zu speichern, oder geben Sie !q\<enter\> ein, um ohne zu speichern zu beenden.

    Screenshot, der die Eingabeaufforderung zeigt – Git rebase -i 25b4 pick-Befehl.

    Ändern Sie die nicht mehr gewünschten Zeilen.

    Screenshot der Eingabeaufforderung - git rebase -i 25b4 drop-Befehl.

  7. Ändern Sie pick in drop wie gezeigt. Geben Sie dann \ (in vi) zum Speichern ein, und geben Sie \ ein, um das Rebase zu starten.

    Geben Sie jetzt erneut ein git log . Die vergehende Verzweigung sollte nicht im Protokoll vorhanden sein. Falls ja, sind Sie bereit für den letzten Schritt, der Projektadministratorberechtigungen erfordert:

    git log

    Screenshot, der lokale und Server-Repositorys nach dem Rebase zeigt.

    Der Commit für das große Video ist jetzt aus dem lokalen Repository verschwunden.

  8. Geben Sie den folgenden Befehl ein:

    git push --force

    Screenshot der Befehlszeile - Git push --force.

    Screenshot, der das Ergebnis der Eingabeaufforderung anzeigt - git push --force.

    Dieser Befehl zwingt Ihr Repo dazu, das Repo auf dem Server zu überschreiben.

    Verwenden Sie diesen Befehl mit Vorsicht, da Sie auf einfache Weise Daten auf dem Server verlieren können.

    Screenshot eines Force Pushs, der zeigt, welche Inhalte beibehalten werden sollen, ohne die große Videodatei.

Sie müssen sich beim Server authentifizieren, damit diese Aktion funktioniert.

Wenn Sie Azure Repos verwenden, müssen Sie möglicherweise eine alternative Anmeldeinformation einrichten, die keine Sonderzeichen verwendet. Ein Beispiel ist das At-Symbol (@) in einer E-Mail-Adresse. Befolgen Sie dazu die Anweisungen in der Authentifizierung mit Azure Repos.

Nun ist der Branch dauerhaft vom Server gelöscht. Nachfolgende Klonen und Synchronisierungen von Teammitgliedern laden nicht die großen Dateien herunter, die Sie entfernen wollten. Benutzer müssen vom Server nach unten ziehen, um sicherzustellen, dass sie mit dem neuen Server-Repositorystatus synchronisiert sind.

Wenn Benutzer neuere Commits haben

Wenn andere Benutzer einen Commit an das Server-Repository übertragen haben, haben Sie eine weitere Überlegung. Sie möchten den Branch entfernen, der die großen Dateien enthält, dabei aber keine Änderungen verlieren, die das Team vorgenommen hat. Um diese Situation zu beheben, schauen Sie sich beim Öffnen des Editors als Teil der Neubasierung sorgfältig die Commits an. Stellen Sie sicher, dass die Commits, die Sie beibehalten möchten, in den pick Zeilen aufgeführt sind. Löschen Sie diejenigen, die Sie entfernen möchten, z. B. wo eine große Datei hinzugefügt wurde.

Nach dem Rebasen müssen die anderen Benutzer im Team auch erneut rebasen, damit jeder über eine konsistente Kopie des Server-Repositories besitzt. Diese Arbeit ist für jeden mühsam, und Sie möchten es vermeiden. Wenn Sie eine Push-Benachrichtigung entfernen müssen, sollten Sie sich mit dem Team abstimmen. Weitere Informationen zum Thema Rebasing finden Sie unter Git Branching – Rebasing.

Der Schlüssel besteht darin, sicherzustellen, dass Sie die gewünschten Commits kennen und die commits, die Sie nicht möchten. Studieren Sie die git log oder die Historie in Ihrer integrierten Entwicklungsumgebung (z. B. Visual Studio). Notieren Sie sich sorgfältig die SHA-Hashes, die beibehalten werden sollen, und die zu entfernenden Hashes.

In Szenarien, in denen die große Datei alt ist und nachfolgende Verzweigungen und Zusammenführungen vorhanden waren, können Sie die Datei möglicherweise mithilfe der git filter-branch Option entfernen. Weitere Informationen finden Sie unter Entfernen vertraulicher Daten aus einem Repository.

Überlegungen zu bewährten Methoden

Stellen Sie sicher, dass große Dateien außerhalb des Haupt-Repositorys bleiben, um Teammitglieder vor zusätzlicher Arbeit zu bewahren. Hier sind einige bewährte Praktiken, die das Team im Auge behalten sollte.

Zu erledigende Dinge

  • Änderungen häufig festschreiben. Sie können sie später jederzeit mit einem Squash oder einem Rebase korrigieren.
  • Verwenden Sie Verzweigungen, um Ihre Änderungen zu isolieren. Filialen sind billig und privat, und die Zusammenführung ist einfach. Sie können auch Änderungen an einem Branch sichern, indem Sie sie an den Server übertragen.
  • Verwenden Sie beim Veröffentlichen von Themenzweigen eine Benennungskonvention. Geben Sie der Verzweigung users/<alias>/<branchname>einen Namen. Dieser Name hilft, Ihre Filialen zu gruppieren und es anderen leicht zu machen, den Besitzer zu identifizieren.
  • Denken Sie daran, Ihre Änderungen zu pushen. Verwenden Sie Commit != Checkin und (Commit + Push) == Checkin.
  • Erwägen Sie die Verwendung .gitignore für große Binärdateien, damit sie dem Repository nicht hinzugefügt werden. Weitere Informationen finden Sie unter Ignorieren von Dateien.
  • Erwägen Sie die Verwendung der NuGet- oder Team Foundation Server-Versionssteuerung zum Speichern ihrer großen Binärdateien.

Zu vermeidende Dinge

  • Kein Rebase nach dem Pushen. Das Neubasieren von pushed Commits in Git kann schlecht sein, da alle anderen Personen im Repository gezwungen werden, ihre lokalen Änderungen zu rebasen. Teammitglieder sind möglicherweise nicht glücklich, wenn sie diese Aufgabe ausführen müssen. Das Neubasieren von gepushten Commits auf Ihrem persönlichen Branch ist kein Problem, es sei denn, andere Personen ziehen diese Commits.
  • Kommitten Sie keine Binärdateien in Ihr Repository. Git komprimiert keine Binärdateien so, wie dies bei der Team Foundation-Versionskontrolle der Fall ist. Da alle Repositorien über den gesamten Verlauf verfügen, bedeutet das Einpflegen von Binärdateien eine dauerhafte Aufblähung des Speicherplatzes.

Zusammenfassung

Manchmal werden unerwünschte Elemente, z. B. große Dateien, einem Repository hinzugefügt und müssen entfernt werden, um das Repository sauber und leicht zu halten. Sie können diese Aufgabe ausführen, indem Sie Ihr lokales Repository in der gewünschten Reihenfolge abrufen. Verwenden Sie den git rebase Befehl, und verwenden Sie dann den git push --force Befehl, um das Server-Repository mit Ihrem lokalen Repository zu überschreiben.