Ich habe lokale Änderungen an einer Datei, die ich nicht in mein Repository übertragen möchte. Es ist eine Konfigurationsdatei zum Erstellen der Anwendung auf einem Server, aber ich möchte lokal mit anderen Einstellungen erstellen. Natürlich wird die Datei immer angezeigt, wenn ich ‘git status’ als etwas zu inszenierendes mache. Ich möchte diese spezielle Änderung ausblenden und nicht festschreiben. Ich werde keine weiteren Änderungen an der Datei vornehmen.
Zur Verdeutlichung ist die Verwendung von .gitignore nicht das, was ich möchte, da dies nur verhindert, dass neue Dateien hinzugefügt werden. Ich möchte Änderungen an einer Datei ignorieren, die sich bereits im Repository befindet.
Nach einigem Suchen sehe ich 2 Möglichkeiten: assume-unchanged
und skip-worktree
. Eine vorherige Frage hier spricht über sie, erklärt aber nicht wirklich ihre Unterschiede.
Wie unterscheiden sich die beiden Befehle? Warum sollte jemand das eine oder das andere verwenden?
Sie wollen skip-worktree
.
assume-unchanged
ist für Fälle gedacht, in denen es teuer ist, zu überprüfen, ob eine Gruppe von Dateien geändert wurde; Wenn Sie das Bit setzen, git
(natürlich) davon aus, dass die Dateien, die diesem Teil des Index entsprechen, in der Arbeitskopie nicht geändert wurden. So vermeidet es ein Durcheinander stat
Anrufe. Dieses Bit geht immer dann verloren, wenn sich der Eintrag der Datei im Index ändert (also wenn die Datei stromaufwärts geändert wird).
skip-worktree
ist mehr als das: sogar wo git
weiß dass die Datei geändert wurde (oder geändert werden muss durch a reset --hard
oder ähnliches), wird es so tun, als ob es nicht so wäre, und stattdessen die Version aus dem Index verwenden. Dies bleibt bestehen, bis der Index verworfen wird.
Hier finden Sie eine gute Zusammenfassung der Auswirkungen dieses Unterschieds und der typischen Anwendungsfälle: http://fallengamer.livejournal.com/93321.html .
Aus diesem Artikel:
--assume-unchanged
geht davon aus, dass ein Entwickler sollte nicht eine Datei ändern. Diese Flagge ist für gedacht verbessernde Leistung für sich nicht ändernde Ordner wie SDKs.
--skip-worktree
ist nützlich, wenn Sie git anweisen, eine bestimmte Datei niemals zu berühren, weil Entwickler sollte ändern Sie es. Zum Beispiel, wenn das Haupt-Repository Upstream einige produktionsbereite Hosts enthält Konfigurationsdateien und Sie möchten nicht versehentlich Änderungen an diesen Dateien vornehmen, --skip-worktree
ist genau das, was Sie wollen.
Notiz: gefallener Spieler hat 2011 einige Tests durchgeführt (sie könnten also veraltet sein), und hier sind seine Ergebnisse:
Operationen
- Die Datei wird sowohl im lokalen Repository als auch im Upstream geändert
git pull
:
Git behält trotzdem lokale Änderungen bei.
So würden Sie nicht versehentlich Daten verlieren, die Sie mit einem der Flags markiert haben.
- Datei mit
assume-unchanged
Flag: Git würde die lokale Datei nicht überschreiben. Stattdessen würde es Konflikte und Ratschläge zu deren Lösung ausgeben
- Datei mit
skip-worktree
Flag: Git würde die lokale Datei nicht überschreiben. Stattdessen würde es Konflikte und Ratschläge zu deren Lösung ausgeben
- Keine lokalen Änderungen, Upstream-Datei geändert
git pull
Beide Flags würden Sie nicht daran hindern, Upstream-Änderungen zu erhalten. Git erkennt, dass Sie kaputt gegangen sind assume-unchanged
Versprechen und beschließt, die Realität widerzuspiegeln, indem er die Flagge zurücksetzt.
- Datei mit
assume-unchanged
flag: Inhalt wird aktualisiert, Flag geht verloren.
‘git ls-files -v
‘ würde zeigen, dass das Flag geändert wurde H
(von h
).
- Datei mit
skip-worktree
flag: Inhalt wird aktualisiert, Flag bleibt erhalten.
‘git ls-files -v
“ würde dasselbe zeigen S
Flagge wie vor der pull
.
Er fügt die folgende Analyse hinzu:
-
Es sieht aus wie skip-worktree
ist sehr bemüht, Ihre lokalen Daten zu erhalten. Aber es hindert Sie nicht daran, Upstream-Änderungen zu erhalten, wenn es sicher ist. Außerdem setzt Git das Flag nicht zurück pull
.
Aber das Ignorieren des ‘reset --hard
“-Befehl könnte zu einer bösen Überraschung werden für einen Entwickler.
-
Assume-unchanged
Flagge könnte auf der verloren gehen pull
Der Betrieb und die lokalen Änderungen in solchen Dateien scheinen für git nicht wichtig zu sein.
Sehen:
Er schließt:
Eigentlich ist keines der Flags intuitiv genug.
-
assume-unchanged
geht davon aus, dass ein Entwickler eine Datei nicht ändern sollte. Wenn eine Datei geändert wurde – dann ist diese Änderung nicht wichtig. Dieses Flag soll die Leistung für sich nicht ändernde Ordner wie SDKs verbessern.
Aber wenn das Versprechen gebrochen wird und eine Datei tatsächlich geändert wird, kehrt git das Flag zurück, um die Realität widerzuspiegeln. Wahrscheinlich ist es in Ordnung, einige inkonsistente Flags in Ordnern zu haben, die im Allgemeinen nicht geändert werden sollen.
-
Andererseits skip-worktree
ist nützlich, wenn Sie git anweisen, eine bestimmte Datei niemals anzufassen. Das ist nützlich für eine bereits getrackte Konfigurationsdatei.
Das Upstream-Haupt-Repository hostet einige produktionsbereite Konfigurationen, aber Sie möchten einige Einstellungen in der Konfiguration ändern, um lokale Tests durchführen zu können. Und Sie möchten nicht versehentlich die Änderungen in einer solchen Datei überprüfen, um die Produktionskonfiguration zu beeinflussen. In diesem Fall skip-worktree
macht perfekte Szene.
Mit Git 2.25.1 (Feb. 2020) wird das oben erwähnte „Eigentlich keines der Flags ist intuitiv genug“ weiter präzisiert:
Sehen Commit 7a2dc95, begehen 1b13e90 (22. Januar 2020) von Brian m. Carlson (bk2204
).
(Zusammengeführt von Junio C. Hamano — gitster
— in Commit 53a832930. Januar 2020)
(Git-Mailingliste)
doc
: Benutzer davon abhalten, nachverfolgte Dateien zu ignorieren
Unterzeichnet von: Jeff King
Unterzeichnet von: Brian M. Carlson
Es ist durchaus üblich, dass Benutzer die Änderungen an einer Datei ignorieren möchten, die Git verfolgt.
Häufige Szenarien für diesen Fall sind IDE-Einstellungen und Konfigurationsdateien, die im Allgemeinen nicht nachverfolgt werden sollten und möglicherweise mithilfe eines Templating-Mechanismus aus nachverfolgten Dateien generiert werden.
Die Benutzer erfahren jedoch etwas über die Bits „Accept-Unchanged“ und „Skip-Worktree“ und versuchen, sie trotzdem zu verwenden, um dies zu tun.
Das ist problematisch, denn wenn diese Bits gesetzt sind, verhalten sich viele Operationen so, wie der Benutzer es erwartet, aber sie helfen normalerweise nicht, wann git checkout
muss eine Datei ersetzen.
In diesem Fall gibt es kein sinnvolles Verhalten, denn manchmal handelt es sich um wertvolle Daten, wie etwa bestimmte Konfigurationsdateien, und manchmal um irrelevante Daten, die der Benutzer gerne verwerfen würde.
Da dies keine unterstützte Konfiguration ist und Benutzer dazu neigen, die vorhandenen Funktionen für unbeabsichtigte Zwecke zu missbrauchen, was zu allgemeiner Traurigkeit und Verwirrung führtdokumentieren wir das vorhandene Verhalten und die Fallstricke in der Dokumentation für git update-index
damit die Benutzer wissen, dass sie nach alternativen Lösungen suchen sollten.
Lassen Sie uns außerdem eine empfohlene Lösung für den Umgang mit dem häufigen Fall von Konfigurationsdateien bereitstellen, da es bekannte Ansätze gibt, die in vielen Umgebungen erfolgreich verwendet werden.
Die git update-index
Manpage beinhaltet jetzt:
Benutzer versuchen oft, die zu verwenden assume-unchanged
und skip-worktree
Bits, um Git anzuweisen, Änderungen an nachverfolgten Dateien zu ignorieren. Dies funktioniert nicht wie erwartet, da Git bei der Ausführung bestimmter Operationen Arbeitsbaumdateien möglicherweise immer noch mit dem Index vergleicht. Im Allgemeinen bietet Git keine Möglichkeit, Änderungen an nachverfolgten Dateien zu ignorieren, daher werden alternative Lösungen empfohlen.
Wenn die Datei, die Sie ändern möchten, beispielsweise eine Art Konfigurationsdatei ist, kann das Repository eine Beispielkonfigurationsdatei enthalten, die dann in den ignorierten Namen kopiert und geändert werden kann. Das Repository kann sogar ein Skript enthalten, um die Beispieldatei als Vorlage zu behandeln und sie automatisch zu ändern und zu kopieren.
Dieser letzte Teil ist das, was ich einen typischen Content-Filter-Treiber beschreibe, der auf Smudge/Clean-Skripten basiert.
aber kann man nicht alle entfernen und alle hinzufügen, um sie zu “aktualisieren”, wie hier erklärt? http://stackoverflow.com/questions/7075923/… @Grigory
– Daniel Springer
23. Mai 2018 um 0:06 Uhr
Die Datei sollte nicht ignoriert werden, wenn ich die Absicht von OP richtig verstehe. Die Datei muss sich im Repository befinden, aber diese sehr spezifischen Änderungen, die er vorgenommen hat, sollten nicht festgeschrieben werden – zumindest nicht jetzt.
– Simone
28. November 2018 um 14:09 Uhr
Googler: siehe auch Ich werde diese E-Mail-Antwort von Junio Hamano (dem Betreuer von Git) akzeptieren, weil ich denke, dass sie einige Dinge klarer erklärt als die offiziellen Dokumente und als “offizieller” Ratschlag angesehen werden kann
– mehov
12. Mai 2021 um 5:32 Uhr
Interessanter Patch in Arbeit im ersten Quartal 2022: public-inbox.org/git/[email protected]/…
– VonC
10. Januar um 23:55 Uhr