Git – Unterschied zwischen ‘unverändert annehmen’ und ‘Arbeitsbaum überspringen’

Lesezeit: 10 Minuten

Git Unterschied zwischen unverandert annehmen und Arbeitsbaum uberspringen
ckb

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?

  • 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

1646902092 759 Git Unterschied zwischen unverandert annehmen und Arbeitsbaum uberspringen
Borealis

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.

  • Eine kleine Notiz, um ein paar Sekunden beim Suchen und Lesen zu sparen. Abbrechen --skip-worktree Effekte und Unset das Flag gibt es --no-skip-worktree Möglichkeit. Funktioniert genau so. Dies ist nützlich, falls eine Hand ausgerutscht ist und falsche Dateien markiert wurden, oder wenn sich die Umstände geändert haben und zuvor übersprungene Dateien nicht mehr ignoriert werden sollen.

    – drdaeman

    7. August 2015 um 16:00 Uhr

  • Um meine eigene Frage oben zu beantworten, der Unterschied zwischen der Verwendung von --skip-worktree und das .git/info/exclude Datei ist, dass Ersteres auch für Dateien funktioniert, die derzeit verfolgt werden. .git/info/excludewie .gitignoreverhindert nur das versehentliche Hinzufügen von nicht nachverfolgten Dateien zum Index, aber keine Änderungen an bereits nachverfolgten Dateien.

    – LinusR

    21. Oktober 2015 um 21:16 Uhr

  • Kann dies auf die Fernbedienung übertragen und von allen Klonen beibehalten werden?

    – CMCDragonkai

    31. März 2016 um 16:01 Uhr

  • Leider beides: --skip-worktree und --assume-unchanged Erlauben Sie keinen Wechsel zu einem anderen Zweig. Ich bekomme den Fehler: Your local changes to the following files would be overwritten by checkout. Details hier

    – Eugen Konkow

    2. Juni 2018 um 11:20 Uhr

  • Nur die Verwendunggnädige Frau: git update-index --skip-worktree <file_name>

    – Rufin

    2. August 2018 um 13:21 Uhr

Git Unterschied zwischen unverandert annehmen und Arbeitsbaum uberspringen
VonC

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

  • Die Datei wird sowohl im lokalen Repository als auch im Upstream geändert und versucht trotzdem, sie zu ziehen
    git stash
    git pull

    Verwenden skip-worktree bedeutet etwas zusätzliche manuelle Arbeit, aber zumindest würden Sie keine Daten verlieren, wenn Sie lokale Änderungen hätten.

    • Datei mit assume-unchanged flag: Verwirft alle lokalen Änderungen ohne Möglichkeit, sie wiederherzustellen. Der Effekt ist wie ‘git reset --hard‘. ‘git pull‘ Anruf wird erfolgreich sein
    • Datei mit skip-worktree flag: Stash würde nicht funktionieren skip-worktree Dateien. ‘git pull‘ wird mit dem gleichen Fehler wie oben fehlschlagen. Der Entwickler ist gezwungen, manuell zurückzusetzen skip-worktree Flag, um das Fehlschlagen verstauen und vervollständigen zu können pull.

  • 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.

  • Mit lokaler Datei geändert
    git reset --hard

    Git berührt nicht skip-worktree Datei und spiegelt die Realität wider (die versprochene unveränderte Datei wurde tatsächlich geändert) für assume-unchanged Datei.

    • Datei mit assume-unchanged Flag: Dateiinhalt wird zurückgesetzt. Flag wird zurückgesetzt auf H (von h).
    • Datei mit skip-worktree Flag: Dateiinhalt ist intakt. Flagge bleibt gleich.

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.

  • Wenn Sie skip-worktree für eine Datei und die Upstream-Änderungen haben, erhalten Sie beim Pull-Versuch “Please commit or stash”, obwohl der Git-Status die Datei nicht als geändert meldet. Wie können Sie dies vermeiden, damit die lokalen Änderungen bestehen bleiben, während die Leute mit den Produktionseinstellungen am Ursprung herumspielen?

    – GreenAsJade

    11. Dezember 2014 um 23:28 Uhr

  • @GreenAsJade nicht sicher: Das wäre eine gute Frage für sich (mit einem Link zurück zu dieser). Ich nehme an, Sie würden eine ähnliche Nachricht mit erhalten assume-unchanged anstatt skip-worktree.

    – VonC

    12. Dezember 2014 um 6:54 Uhr

  • Ja, das kann ich bestätigen. Es bedeutet, dass es immer noch sehr schwierig ist, eine lokale Datei zu haben, die Sie einfach anders als den Ursprung verwalten möchten.

    – GreenAsJade

    12. Dezember 2014 um 7:02 Uhr

  • @GreenAsJade scheint uralt zu sein. Besteht die Möglichkeit, es mit einer 2.2.x zu testen?

    – VonC

    12. Dezember 2014 um 7:08 Uhr


  • @VonC wie man beide löst assume-changed & skip-worktree zum git pull oder rebasebeide werden wirft bitte festschreiben oder verstauen eben git status zeigt nichts

    – mochadwi

    22. Juni 2019 um 4:40 Uhr

987180cookie-checkGit – Unterschied zwischen ‘unverändert annehmen’ und ‘Arbeitsbaum überspringen’

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy