it-swarm.com.de

Git: So entfernen Sie Dateien aus dem Index, ohne Dateien aus einem Repository zu löschen

Wenn Sie verwenden

git rm --cached myfile

es wird nicht aus dem lokalen Dateisystem gelöscht, was das Ziel ist. Wenn Sie die Datei jedoch bereits versioniert und festgeschrieben, in ein zentrales Repository gepusht und vor der Verwendung des Befehls in ein anderes Repository gezogen haben, wird die Datei von diesem System gelöscht.

Gibt es eine Möglichkeit, die Datei einfach von der Versionierung zu entfernen, ohne sie aus einem Dateisystem zu löschen?

Edit: Klar, hoffe ich.

148
Fletcher Moore

Ich glaube nicht, dass ein Git-Commit eine Absicht aufzeichnen kann, z. B. „Diese Datei nicht mehr verfolgen, aber nicht löschen“.

Um eine solche Absicht in Kraft zu setzen, ist ein Eingriff außerhalb von Git in Repositorys erforderlich, in denen ein Commit (bei dem ein Commit ausgeführt wird oder das Rebase erneut durchgeführt wird) und die Datei gelöscht wird.


Kopie speichern, Löschen anwenden, Wiederherstellen

Am einfachsten ist es wahrscheinlich, den nachgeschalteten Benutzern zu sagen, dass sie eine Kopie der Datei speichern, den Löschvorgang ausführen und dann die Datei wiederherstellen. Wenn sie über Rebase ziehen und Änderungen an der Datei durchführen, werden sie dies tun Konflikte bekommen. Um solche Konflikte aufzulösen, verwenden Sie git rm foo.conf && git rebase --continue (falls sich das Konflikt-Commit außer den Änderungen an der entfernten Datei geändert hat) oder git rebase --skip (wenn das Konflikt-Commit nur in die entfernte Datei geändert wurde).

Wiederherstellen der Datei nach dem Ziehen eines Commits, der sie löscht

Wenn das Löschungs-Commit bereits ausgeführt wurde, können Sie die vorherige Version der Datei weiterhin mit git show wiederherstellen:

git show @{1}:foo.conf >foo.conf

Oder mit git checkout (pro Kommentar von William Pursell; aber vergessen Sie nicht, es aus dem Index zu entfernen!):

git checkout @{1} -- foo.conf && git rm --cached foo.conf

Wenn sie seit dem Löschen Ihrer Löschaktion andere Aktionen ausgeführt haben (oder mit rebase in einen abgelösten HEAD ziehen), benötigen sie möglicherweise etwas anderes als @{1}. Sie könnten git log -g verwenden, um das Commit zu finden, bevor Sie Ihre Löschung durchgeführt haben.


In einem Kommentar erwähnen Sie, dass es sich bei der Datei, die Sie "entpacken, aber beibehalten" möchten, um eine Art Konfigurationsdatei handelt, die zum Ausführen der Software (direkt aus einem Repository) erforderlich ist.

Datei als "Standard" beibehalten und manuell/automatisch aktivieren

Wenn es nicht völlig inakzeptabel ist, den Inhalt der Konfigurationsdatei weiterhin im Repository zu verwalten, können Sie die verfolgte Datei möglicherweise von (z. B. foo.conf in foo.conf.default) umbenennen und Ihre Benutzer nach dem Anwenden des Umbenennen-Commits ..__ anweisen, cp foo.conf.default foo.conf. Wenn die Benutzer bereits vorhandene Teile des Repositorys verwenden (z. B. ein Skript oder ein anderes durch Inhalt im Repository konfiguriertes Programm (z. B. Makefile oder ähnliches)), um Ihre Software zu starten bzw. bereitzustellen, können Sie einen Standardmechanismus in den Startvorgang einbauen/Bereitstellungsprozess:

test -f foo.conf || test -f foo.conf.default &&
    cp foo.conf.default foo.conf

Mit einem solchen Standardmechanismus sollten Benutzer in der Lage sein, ein Commit aufzurufen, das foo.conf in foo.conf.default umbenennt, ohne dass zusätzliche Arbeiten erforderlich sind ..__ Sie müssen außerdem keine Konfigurationsdatei manuell kopieren, wenn Sie zusätzliche Installationen/Repositorys vornehmen in der Zukunft.

Umschreibung der Historie erfordert sowieso manuelle Intervention…

Wenn es nicht akzeptabel ist, den Inhalt im Repository zu verwalten, sollten Sie ihn wahrscheinlich mit etwas wie git filter-branch --index-filter … ..__ vollständig aus der Historie entfernen. Dies bedeutet, dass die Historie neu geschrieben wird, was einen manuellen Eingriff für jeden Zweig/Repository erfordert (Siehe Abschnitt "Wiederherstellen von Upstream-Rebase" in der Manpage git rebase ) . Die für Ihre Konfigurationsdatei erforderliche Sonderbehandlung wäre nur ein weiterer Schritt, den Sie beim Wiederherstellen nach dem Überschreiben ausführen müssen:

  1. Speichern Sie eine Kopie der Konfigurationsdatei.
  2. Erholen Sie sich von der Umschreibung.
  3. Stellen Sie die Konfigurationsdatei wieder her.

Ignorieren Sie es, um ein erneutes Auftreten zu verhindern

Unabhängig von der von Ihnen verwendeten Methode möchten Sie wahrscheinlich den Konfigurationsdateinamen in eine .gitignore-Datei im Repository einschließen, sodass niemand wieder versehentlich git add foo.conf wieder verwendet werden kann (dies ist möglich, erfordert jedoch -f--force) . Wenn Sie mehr als eine haben Konfigurationsdatei können Sie erwägen, sie alle in ein einziges Verzeichnis zu verschieben und das Ganze zu ignorieren (mit "verschieben" meine ich die Position, an der das Programm seine Konfigurationsdateien erwartet, und die Benutzer (oder den Start-/Bereitstellungsmechanismus). Wenn Sie die Dateien an einen neuen Speicherort kopieren oder verschieben möchten, möchten Sie nicht, dass _/git mv eine Datei in einem Verzeichnis ablegt, das Sie ignorieren werden.

108
Chris Johnsen

Hatte dasselbe Problem diese Woche, als ich aus Versehen einen Fehler begangen hatte, und dann versuchte, eine Builddatei aus einem gemeinsam genutzten Repository zu entfernen.

http://gitready.com/intermediate/2009/02/18/temporarily-ignoring-files.html

hat für mich gut funktioniert und bisher nicht erwähnt.

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

Um die gewünschte Datei aus der Versionskontrolle zu entfernen, verwenden Sie alle anderen Befehle wie gewohnt.

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

Wenn Sie es jemals wieder einsetzen wollten.

Edit: siehe Kommentare von Chris Johnsen und KPM, dies funktioniert nur lokal und die Datei bleibt für andere Benutzer unter Versionskontrolle, wenn sie dies nicht auch tun. Die akzeptierte Antwort gibt vollständigere/korrekte Methoden an, um damit umzugehen. Bei Verwendung dieser Methode auch einige Hinweise aus dem Link:

Offensichtlich gibt es eine Reihe von Vorbehalten, die damit ins Spiel kommen. Wenn Sie die Datei direkt hinzufügen, wird sie dem Index hinzugefügt .. _. Wenn Sie ein Commit mit diesem Flag zusammenführen, schlägt die Zusammenführung fehl elegant, damit Sie es manuell handhaben können.

85
Tom Power

Um die Datei aus dem Index zu entfernen, verwenden Sie:

git reset myfile

Dies sollte sich nicht auf Ihre lokale Kopie oder die von anderen Personen auswirken.

30
Armand

Versuchen Sie nach dem Ausführen des Befehls git rm --cached, myfile zur .gitignore-Datei hinzuzufügen (erstellen Sie eine, falls diese nicht vorhanden ist). Dies sollte git anweisen, myfile zu ignorieren.

Die .gitignore-Datei ist versioniert, Sie müssen sie also festschreiben und in das Remote-Repository übertragen.

15
awgy
  1. git rm --cached remove_file
  2. füge die datei zu gitignore hinzu
  3. git add .gitignore
  4. git commit -m "Excluding"
  5. Habe Spaß ;)

Meine Lösung ist, die andere Arbeitskopie zu ziehen und dann zu tun:

git log --pretty="format:" --name-only -n1 | xargs git checkout HEAD^1

besagt, dass alle Dateipfade im neuesten Kommentar abgerufen und vom übergeordneten Element von HEAD ausgecheckt werden. Job erledigt.

1
Tom Viner

Die oben genannten Lösungen funktionieren in den meisten Fällen einwandfrei. Wenn Sie jedoch auch alle Spuren dieser Datei entfernen möchten (z. B. vertrauliche Daten wie Kennwörter), möchten Sie sie auch als Datei aus Ihrem gesamten Commit-Verlauf entfernen konnte immer noch von dort abgerufen werden.

Hier ist eine Lösung, die alle Spuren der Datei aus dem gesamten Festschreibungsverlauf entfernt, als ob sie nie existiert hätte, die Datei jedoch auf Ihrem System erhalten bleibt.

https://help.github.com/articles/remove-sensitive-data/

Sie können tatsächlich mit Schritt 3 fortfahren, wenn Sie sich in Ihrem lokalen Git-Repository befinden und keinen Testlauf durchführen müssen. In meinem Fall brauchte ich nur die Schritte 3 und 6, da ich bereits meine .gitignore-Datei erstellt hatte und sich im Repository befand, an dem ich arbeiten wollte.

Um Ihre Änderungen anzuzeigen, müssen Sie möglicherweise den GitHub-Stamm Ihres Repositorys aufrufen und die Seite aktualisieren. Navigieren Sie dann durch die Links, um zu einem alten Commit zu gelangen, in dem sich die Datei einmal befunden hat, um zu sehen, dass sie jetzt entfernt wurde. Wenn Sie einfach die alte Commit-Seite aktualisieren, wurde die Änderung für mich nicht angezeigt.

Es sah auf den ersten Blick einschüchternd aus, war aber wirklich einfach und funktionierte wie ein Zauber! :-)

0
SherylHohman