git ignorieren vs. ausschließen vs. annehmen-unverändert

73

Ich habe die Dokumentation dazu mehrmals gelesen und verstehe die Unterschiede zwischen diesen verschiedenen Befehlen immer noch nicht vollständig. Vielleicht bin ich es nur, aber die Dokumentation könnte klarer sein:

http://git-scm.com/docs/gitignore

https://help.github.com/articles/ignoring-files

Darüber hinaus scheinen viele Kommentare zu diesem Thema die Wörter "indexiert", "engagiert", "verfolgt" etwas locker zu verwenden, was die Unterschiede zwischen diesen drei weniger deutlich macht.

Mein derzeitiges (zugegebenermaßen begrenztes) Verständnis:

  • Übereinstimmende Dateien werden in .gitignoreZukunft nicht mehr verfolgt. (Obwohl sie möglicherweise zuvor verfolgt wurden.) Dies bedeutet, dass sie niemals in einer zukünftigen git statusListe als geändert angezeigt werden . Zukünftige Änderungen werden jedoch weiterhin mit Remote-Repos synchronisiert . Mit anderen Worten, die Dateien sind immer noch "indiziert", aber sie werden nicht "verfolgt". Da sich eine .gitignoreDatei im Projektverzeichnis befindet, kann die Datei selbst versioniert werden.

  • Übereinstimmende Dateien .git/info/excludewerden ebenfalls nicht "verfolgt". Darüber hinaus werden diese Dateien niemals remote synchronisiert und daher von keinem anderen Benutzer in irgendeiner Form gesehen. Diese Dateien sollten Dateien sein, die für den Editor oder den Workflow eines einzelnen Benutzers spezifisch sind. Da es sich im .git Verzeichnis befindet, kann die excludeDatei selbst nicht versioniert werden.

  • Dateien, die darauf assume-unchangedausgeführt wurden, werden auch nicht in git statusoder angezeigt git diff. Dies scheint insofern ähnlich zu sein exclude, als diese Dateien weder "indiziert" noch "verfolgt" werden. Die letzte Version der Datei, die zuvor festgeschrieben wurde, assume-unchangedbleibt jedoch für alle Benutzer im Repo sichtbar.

Meine Fragen:

  1. Ist die obige Interpretation korrekt? Bitte korrigieren Sie mich.

  2. Wenn eine Datei bereits in einem Commit war, was ist der funktionale Unterschied zwischen dem Abgleichen .excludeund dem Ausführen assume-unchangeddarauf? Warum sollte man einen Ansatz einem anderen vorziehen?

  3. Mein grundlegender Anwendungsfall ist, dass ich vermeiden möchte, Unterschiede in kompilierten Dateien zu sortieren, diese kompilierten Dateien jedoch weiterhin mit den Quelldateien synchronisieren möchte. Wird eine gitignoreD-Datei noch gepusht? Wenn nicht, wie wird die endgültige Bereitstellung der kompilierten Dateien verwaltet?

Vielen Dank im Voraus für jede Hilfe.

Ben
quelle

Antworten:

100

Ich werde diese per E-Mail gesendete Antwort von Junio ​​Hamano (dem Betreuer von Git) akzeptieren, da sie meiner Meinung nach einige Dinge klarer erklärt als die offiziellen Dokumente und als "offizieller" Ratschlag angesehen werden kann:

Der .gitignore und .git / info / exclude sind die beiden Benutzeroberflächen, die denselben Mechanismus aufrufen. In-Tree .gitignore sollen unter den Projektmitgliedern geteilt werden (dh jeder, der an dem Projekt arbeitet, sollte die Pfade, die mit dem dortigen Ignoriermuster übereinstimmen, als Cruft betrachten). Auf der anderen Seite ist .git / info / exclude für persönliche Ignoriermuster gedacht (dh Sie betrachten sie während der Arbeit am Projekt als Cruft).

Angenommen, unverändert sollte nicht für einen Ignoriermechanismus missbraucht werden. Es ist "Ich weiß, dass meine Dateisystemoperationen langsam sind. Ich verspreche Git, dass ich diese Pfade nicht ändern werde, indem ich sie mit diesem Bit mache - auf diese Weise muss Git nicht jedes Mal überprüfen, ob ich dort etwas geändert habe." Ich frage nach 'Git Status' Ausgabe ". Es bedeutet nichts anderes als das. Insbesondere ist es kein Versprechen von Git, dass Git immer davon ausgeht, dass diese Pfade unverändert sind. Wenn Git feststellen kann, dass sich ein Pfad, der als unverändert markiert ist, geändert hat, ohne dass zusätzliche lstat (2) -Kosten anfallen, behält es sich das Recht vor berichten , dass der Pfad wurde modifiziert (als Ergebnis „GIT -a commit“ frei ist , dass die Änderung zu bestätigen).

Ben
quelle
5
"indem du sie mit diesem Bit machst - so"? was bedeutet das?
Blaue Wolken
3
@BlueClouds, nach "so" steht ein Komma, da dies der Beginn eines neuen Gedankens ist. Ich vermute, dass "sie mit diesem Bit machen" "Markierung" bedeuten sollte und bezieht sich auf das Flag "unverändert annehmen" als "Bit" - ich würde mir vorstellen, dass diese Markierung nur ein Bit Speicherplatz benötigt, da es sich um einen Binärzustand handelt. Ich gebe zu, dass dies teilweise eine Vermutung ist, aber ich habe keine Schwierigkeiten, die Antwort zu verstehen, also hilft es Ihnen vielleicht.
Wildcard
@Wildcard Ich muss BlueClouds zustimmen: Ich habe Schwierigkeiten zu verstehen, was "Bit --- das" auch bedeutet. Sie wissen wahrscheinlich mehr über die Interna von git, damit Sie diese Lücken füllen können, aber für viele andere, einschließlich mich, ist es immer noch ein zufälliges Durcheinander von Magie.
Suncat2000
2
Leute, es gab einen Tippfehler in der Arbeit markingund es wurde "machen". Alles was es bedeutet ist, dass es ein Flag gibt, das git pro Datei behält, und dieses Flag kann mit diesem Installationsbefehl gesetzt und zurückgesetzt werden.
Leonid Usov
Beachten Sie außerdem, dass dieses Flag im Index beibehalten wird und sein Wert nach Vorgängen verloren geht, bei denen Ihr Index zurückgesetzt wird. Weitere Informationen finden Sie in der Antwort auf [this) [ stackoverflow.com/a/13631525/5171225]
Leonid Usov,
12

Zusätzlich zu Junio Hamano der Antwort , Git 2.3.0 ( im Februar 2015) jetzt entfernt von der gitignoreDokumentation

Verwenden Sie ' git update-index --assume-unchanged' , um nicht festgeschriebene Änderungen in einer bereits verfolgten Datei zu ignorieren .

Siehe Commit 936d2c9 von Michael J Gruber ( mjg) :

gitignore.txt: nicht vorschlagen assume-unchanged

git-update-index --assume-unchangedwar nie dazu gedacht, Änderungen an verfolgten Dateien zu ignorieren ( nur um einige Statistiken zu schonen ).
Schlagen Sie es also nicht als Mittel vor, um dies zu erreichen.

VonC
quelle
5

Hoffentlich werden nicht zu viele Informationsquellen nachverfolgt, indiziert und lose gebunden, da sie alle unterschiedlich und aussagekräftig sind.

  • Indiziert bedeutet, dass sich die Datei im Git-Index befindet. Irgendwann in der Vergangenheit hat jemand git addeinen Befehl oder einen gleichwertigen Befehl für die Datei. Die Datei wird nachverfolgt und kann auch festgeschrieben werden.
  • Verfolgt bedeutet, dass Git die Datei auf Änderungen überwacht. Jede festgeschriebene Datei oder eine beliebige Datei im Index wird nachverfolgt.
  • Festgeschrieben bedeutet, dass sich die Datei im Verlauf von git befindet. Es gibt mindestens einen Prüfpunkt für diese Datei. Sie können zu jeder festgeschriebenen Version der Datei zurückkehren.

Nun an die Grenze meines eigenen Wissens. Ich bin mir bei dieser Definition nicht sicher, aber das ist mein Verständnis. froh darüber korrigiert zu werden:

Wenn eine indizierte Datei festgeschrieben wird, befindet sie sich nicht mehr im Index. Wenn es das nächste Mal geändert (oder gelöscht) wird, befindet es sich wieder im Index. Der Index ist die Summe aller nachverfolgten Dateien, die sich von den festgeschriebenen Dateien unterscheiden .

Der Index wird auch als Cache oder Staging-Bereich bezeichnet.

Weiter zu Ihrer Hauptfrage. .git / info / exclude ist dasselbe wie .gitignore, nur eine niedrigere Priorität und nicht im Repository (also nicht festgeschrieben und freigegeben). Beides wirkt sich nicht auf bereits verfolgte Dateien aus. Beide betreffen Dateien, die derzeit nicht verfolgt werden. Aktualisieren von .gitignore nach git addoder git commitzu spät; git verfolgt die Datei bereits und .gitignore hat keinen Einfluss darauf.

Angenommen, unverändert betrifft nur nachverfolgte Dateien und ist daher vollständig von .gitignore getrennt. Es kann vorübergehend so tun, als ob die Datei nicht verfolgt und ignoriert wird (aber es muss und kann auch nichts anderes als normales Verhalten tun). Wie in anderen Antworten erwähnt, wird dies nicht zum Ignorieren von Änderungen an Dateien verwendet, sondern nur zum potenziellen Vermeiden von Dateisystemoperationen auf langsamen Dateisystemen.

Betreff: Punkt 3: Sie sollten git keine kompilierten Dateien hinzufügen. Kompilieren Sie Ihre Dateien in ein anderes Verzeichnis, in dem sich Ihre Quelle befindet, und ignorieren Sie das gesamte Verzeichnis. Bündeln Sie Ihre kompilierten Dateien in einer Bibliothek und fügen Sie sie einem Artefakt-Repository hinzu, aber fügen Sie sie nicht in git ein.

Paul Hicks
quelle
1

Ich denke, der Unterschied zwischen .gitignore und Annahme-unverändert ist

  1. .gitignore kann mit anderen Personen im Team geteilt werden, muss jedoch für jedes Mitglied einzeln konfiguriert werden.

  2. Angenommen, unverändert sind verfolgte Dateien. Es ist sehr nützlich, wenn eine Datei Konfigurationsinformationen enthält, diese jedoch vom Team geändert werden können. Wenn eine Datei als unverändert angenommen, aber von anderen Personen geändert und in das Remote-Repository verschoben wird, erinnert git daran, wenn versucht wird, von der Remote zu ziehen.

Gast
quelle