Einrichtung und Konfiguration
Projekte holen und erstellen
Grundlegende Snapshots
Branching und Merging
Projekte teilen und aktualisieren
Inspektion und Vergleich
Patching
Debugging
Externe Systeme
Server-Administration
Anleitungen
- gitattributes
- Konventionen der Kommandozeile
- Tägliches Git
- Häufig gestellte Fragen (FAQ)
- Glossar
- Hooks
- gitignore
- gitmodules
- Revisionen
- Submodule
- Tutorial
- Workflows
- Alle Anleitungen...
Administration
Plumbing-Befehle
- 2.50.1 → 2.52.0 keine Änderungen
-
2.50.0
2025-06-16
- 2.49.1 keine Änderungen
-
2.49.0
2025-03-14
- 2.46.1 → 2.48.2 keine Änderungen
-
2.46.0
2024-07-29
- 2.44.1 → 2.45.4 keine Änderungen
-
2.44.0
2024-02-23
- 2.43.1 → 2.43.7 keine Änderungen
-
2.43.0
2023-11-20
- 2.42.1 → 2.42.4 keine Änderungen
-
2.42.0
2023-08-21
- 2.41.1 → 2.41.3 keine Änderungen
-
2.41.0
2023-06-01
- 2.40.1 → 2.40.4 keine Änderungen
-
2.40.0
2023-03-12
- 2.36.1 → 2.39.5 keine Änderungen
-
2.36.0
2022-04-18
- 2.32.1 → 2.35.8 keine Änderungen
-
2.32.0
2021-06-06
- 2.30.1 → 2.31.8 keine Änderungen
-
2.30.0
2020-12-27
- 2.27.1 → 2.29.3 keine Änderungen
-
2.27.0
2020-06-01
- 2.25.1 → 2.26.3 keine Änderungen
-
2.25.0
2020-01-13
- 2.24.1 → 2.24.4 keine Änderungen
-
2.24.0
2019-11-04
- 2.23.1 → 2.23.4 keine Änderungen
-
2.23.0
2019-08-16
- 2.22.1 → 2.22.5 keine Änderungen
-
2.22.0
2019-06-07
- 2.21.1 → 2.21.4 keine Änderungen
-
2.21.0
2019-02-24
- 2.19.3 → 2.20.5 keine Änderungen
-
2.19.2
2018-11-21
- 2.18.1 → 2.19.1 keine Änderungen
-
2.18.0
2018-06-21
- 2.17.1 → 2.17.6 keine Änderungen
-
2.17.0
2018-04-02
-
2.16.6
2019-12-06
- 2.15.4 keine Änderungen
-
2.14.6
2019-12-06
-
2.13.7
2018-05-22
- 2.12.5 keine Änderungen
-
2.11.4
2017-09-22
-
2.10.5
2017-09-22
-
2.9.5
2017-07-30
- 2.7.6 → 2.8.6 keine Änderungen
-
2.6.7
2017-05-05
-
2.5.6
2017-05-05
-
2.4.12
2017-05-05
- 2.3.10 keine Änderungen
-
2.2.3
2015-09-04
- 2.1.4 keine Änderungen
-
2.0.5
2014-12-17
BESCHREIBUNG
Eine gitattributes Datei ist eine einfache Textdatei, die Pfadnamen Attribute zuweist.
Jede Zeile in einer gitattributes Datei hat das Format
pattern attr1 attr2 ...
Das heißt, ein Muster gefolgt von einer Liste von Attributen, getrennt durch Leerzeichen. Führende und nachfolgende Leerzeichen werden ignoriert. Zeilen, die mit # beginnen, werden ignoriert. Muster, die mit einem Anführungszeichen beginnen, werden im C-Stil zitiert. Wenn das Muster mit dem fraglichen Pfad übereinstimmt, werden die auf der Zeile aufgeführten Attribute dem Pfad zugewiesen.
Jedes Attribut kann für einen gegebenen Pfad einen der folgenden Zustände haben
- gesetzt
-
Der Pfad hat das Attribut mit dem speziellen Wert "true"; dies wird spezifiziert, indem nur der Name des Attributs in der Attributliste aufgeführt wird.
- nicht gesetzt
-
Der Pfad hat das Attribut mit dem speziellen Wert "false"; dies wird spezifiziert, indem der Name des Attributs, dem ein Bindestrich
-vorangestellt ist, in der Attributliste aufgeführt wird. - auf einen Wert gesetzt
-
Der Pfad hat das Attribut mit dem angegebenen String-Wert; dies wird spezifiziert, indem der Name des Attributs gefolgt von einem Gleichheitszeichen
=und seinem Wert in der Attributliste aufgeführt wird. - nicht spezifiziert
-
Kein Muster stimmt mit dem Pfad überein und nichts besagt, ob der Pfad das Attribut hat oder nicht, das Attribut für den Pfad gilt als nicht spezifiziert.
Wenn mehr als ein Muster mit dem Pfad übereinstimmt, überschreibt eine spätere Zeile eine frühere Zeile. Dieses Überschreiben geschieht pro Attribut.
Die Regeln, nach denen das Muster mit Pfaden übereinstimmt, sind dieselben wie in .gitignore Dateien (siehe gitignore[5]), mit wenigen Ausnahmen
-
negative Muster sind verboten
-
Muster, die ein Verzeichnis abgleichen, gleichen nicht rekursiv Pfade innerhalb dieses Verzeichnisses ab (daher ist die Syntax mit dem abschließenden Schrägstrich
pfad/in einer Attributdatei nutzlos; verwenden Sie stattdessenpfad/**)
Wenn Git entscheidet, welche Attribute einem Pfad zugewiesen werden, prüft es die Datei $GIT_DIR/info/attributes (die die höchste Priorität hat), die Datei .gitattributes im selben Verzeichnis wie der fragliche Pfad und seine Elternverzeichnisse bis zum obersten Level des Arbeitsbaums (je weiter das Verzeichnis, das .gitattributes enthält, vom fraglichen Pfad entfernt ist, desto niedriger seine Priorität). Schließlich werden globale und systemweite Dateien berücksichtigt (sie haben die niedrigste Priorität).
Wenn die Datei .gitattributes im Arbeitsbaum fehlt, wird der Pfad im Index als Fallback verwendet. Während des Check-out-Prozesses wird .gitattributes im Index verwendet und dann die Datei im Arbeitsverzeichnis als Fallback.
Wenn Sie nur ein einzelnes Repository beeinflussen möchten (d. h. Dateien Attribute zuzuweisen, die für den Workflow eines Benutzers in diesem Repository spezifisch sind), dann sollten Attribute in der Datei $GIT_DIR/info/attributes platziert werden. Attribute, die versionsgesteuert und an andere Repositories verteilt werden sollen (d. h. Attribute, die für alle Benutzer von Interesse sind), sollten in .gitattributes Dateien abgelegt werden. Attribute, die alle Repositories für einen einzelnen Benutzer beeinflussen sollen, sollten in einer Datei abgelegt werden, die durch die Konfigurationsoption core.attributesFile angegeben ist (siehe git-config[1]). Ihr Standardwert ist $XDG_CONFIG_HOME/git/attributes. Wenn $XDG_CONFIG_HOME entweder nicht gesetzt oder leer ist, wird stattdessen $HOME/.config/git/attributes verwendet. Attribute für alle Benutzer eines Systems sollten in der Datei $(prefix)/etc/gitattributes abgelegt werden.
Manchmal müssen Sie eine Einstellung eines Attributs für einen Pfad auf den Zustand nicht spezifiziert überschreiben. Dies kann durch Auflistung des Attributnamens, dem ein Ausrufezeichen ! vorangestellt ist, geschehen.
RESERVIERTE BUILTIN_* ATTRIBUTE
builtin_* ist ein reservierter Namensraum für integrierte Attributwerte. Alle vom Benutzer definierten Attribute unter diesem Namensraum werden ignoriert und lösen eine Warnung aus.
builtin_objectmode
Dieses Attribut dient zum Filtern von Dateien nach ihren Dateimodus-Bits (40000, 120000, 160000, 100755, 100644). z.B. :(attr:builtin_objectmode=160000). Sie können diese Werte auch mit git check-attr builtin_objectmode -- <datei> überprüfen. Wenn das Objekt nicht im Index ist, gibt git check-attr --cached "unspecified" zurück.
EFFEKTE
Bestimmte Operationen von Git können durch Zuweisung spezifischer Attribute zu einem Pfad beeinflusst werden. Derzeit sind die folgenden Operationen Attribut-bewusst.
Check-out und Check-in
Diese Attribute beeinflussen, wie die im Repository gespeicherten Inhalte in die Arbeitsbaumdateien kopiert werden, wenn Befehle wie git switch, git checkout und git merge ausgeführt werden. Sie beeinflussen auch, wie Git die im Arbeitsbaum vorbereiteten Inhalte bei git add und git commit im Repository speichert.
text
Dieses Attribut kennzeichnet den Pfad als Textdatei, was die Umwandlung von Zeilenenden ermöglicht: Wenn eine passende Datei zum Index hinzugefügt wird, werden die Zeilenenden der Datei im Index auf LF normalisiert. Umgekehrt, wenn die Datei vom Index in das Arbeitsverzeichnis kopiert wird, können ihre Zeilenenden je nach eol-Attribut, der Git-Konfiguration und der Plattform von LF in CRLF umgewandelt werden (siehe Erklärung von eol unten).
- gesetzt
-
Das Setzen des
text-Attributs auf einem Pfad aktiviert die Umwandlung von Zeilenenden beim Check-in und Check-out, wie oben beschrieben. Zeilenenden werden jedes Mal auf LF im Index normalisiert, wenn die Datei eingecheckt wird, auch wenn die Datei zuvor mit CRLF-Zeilenenden zu Git hinzugefügt wurde. - nicht gesetzt
-
Das Nichtsetzen des
text-Attributs auf einem Pfad weist Git an, beim Check-in oder Check-out keine Umwandlung von Zeilenenden zu versuchen. - auf den String-Wert "auto" gesetzt
-
Wenn
textauf "auto" gesetzt ist, entscheidet Git selbst, ob die Datei Text oder Binär ist. Wenn es Text ist und die Datei nicht bereits mit CRLF-Endungen in Git war, werden die Zeilenenden beim Check-in und Check-out wie oben beschrieben umgewandelt. Andernfalls erfolgt keine Umwandlung beim Check-in oder Check-out. - nicht spezifiziert
-
Wenn das
text-Attribut nicht spezifiziert ist, verwendet Git die Konfigurationsvariablecore.autocrlf, um zu bestimmen, ob die Datei umgewandelt werden soll.
Jeder andere Wert führt dazu, dass Git sich so verhält, als wäre text nicht spezifiziert geblieben.
eol
Dieses Attribut kennzeichnet einen Pfad zur Verwendung eines bestimmten Zeilenendungsstils im Arbeitsbaum, wenn er ausgecheckt wird. Es hat nur dann eine Auswirkung, wenn text oder text=auto gesetzt ist (siehe oben), aber die Angabe von eol setzt automatisch text, wenn text nicht spezifiziert war.
- auf den String-Wert "crlf" gesetzt
-
Diese Einstellung wandelt die Zeilenenden der Datei im Arbeitsverzeichnis in CRLF um, wenn die Datei ausgecheckt wird.
- auf den String-Wert "lf" gesetzt
-
Diese Einstellung verwendet dieselben Zeilenenden im Arbeitsverzeichnis wie im Index, wenn die Datei ausgecheckt wird.
- nicht spezifiziert
-
Wenn das
eol-Attribut für eine Datei nicht spezifiziert ist, werden ihre Zeilenenden im Arbeitsverzeichnis durch die Konfigurationsvariablecore.autocrlfodercore.eolbestimmt (siehe die Definitionen dieser Optionen in git-config[1]). Wenntextgesetzt ist, aber keine dieser Variablen, ist der Standardwerteol=crlfunter Windows undeol=lfauf allen anderen Plattformen.
Abwärtskompatibilität mit dem crlf-Attribut
Aus Kompatibilitätsgründen wird das crlf-Attribut wie folgt interpretiert
crlf text -crlf -text crlf=input eol=lf
Zeilenende-Konvertierung
Während Git normalerweise Dateiinhalte unverändert lässt, kann es konfiguriert werden, Zeilenenden im Repository auf LF zu normalisieren und optional bei Check-outs in CRLF umzuwandeln.
Wenn Sie einfach nur CRLF-Zeilenenden in Ihrem Arbeitsbaum haben möchten, unabhängig davon, mit welchem Repository Sie arbeiten, können Sie die Konfigurationsvariable "core.autocrlf" setzen, ohne Attribute zu verwenden.
[core] autocrlf = true
Dies erzwingt keine Normalisierung von Textdateien, stellt aber sicher, dass Textdateien, die Sie in das Repository einführen, beim Hinzufügen normalisierte Zeilenenden auf LF haben und dass Dateien, die bereits im Repository normalisiert sind, normalisiert bleiben.
Wenn Sie sicherstellen möchten, dass Textdateien, die von beliebigen Mitwirkenden in das Repository eingeführt werden, normalisierte Zeilenenden haben, können Sie das text-Attribut für alle Dateien auf "auto" setzen.
* text=auto
Die Attribute ermöglichen eine feingranulare Kontrolle über die Konvertierung der Zeilenenden. Hier ist ein Beispiel, das Git veranlasst, .txt-, .vcproj- und .sh-Dateien zu normalisieren, sicherzustellen, dass .vcproj-Dateien im Arbeitsbaum CRLF und .sh-Dateien LF haben, und zu verhindern, dass .jpg-Dateien unabhängig von ihrem Inhalt normalisiert werden.
* text=auto *.txt text *.vcproj text eol=crlf *.sh text eol=lf *.jpg -text
|
Hinweis
|
Wenn die text=auto-Konvertierung in einem plattformübergreifenden Projekt aktiviert ist, das Push und Pull in ein zentrales Repository verwendet, sollten Textdateien, die CRLFs enthalten, normalisiert werden. |
Aus einem sauberen Arbeitsbaum
$ echo "* text=auto" >.gitattributes $ git add --renormalize . $ git status # Show files that will be normalized $ git commit -m "Introduce end-of-line normalization"
Wenn Dateien, die nicht normalisiert werden sollten, in git status erscheinen, setzen Sie ihr text-Attribut auf "unset", bevor Sie git add -u ausführen.
manual.pdf -text
Umgekehrt können Textdateien, die Git nicht erkennt, manuell für die Normalisierung aktiviert werden.
weirdchars.txt text
Wenn core.safecrlf auf "true" oder "warn" gesetzt ist, prüft Git, ob die Konvertierung für die aktuelle Einstellung von core.autocrlf umkehrbar ist. Bei "true" lehnt Git umkehrbare Konvertierungen ab; bei "warn" gibt Git nur eine Warnung aus, akzeptiert aber eine umkehrbare Konvertierung. Die Sicherheitsmechanismen verhindern solche Konvertierungen für Dateien im Arbeitsbaum, es gibt jedoch einige Ausnahmen. Auch wenn…
-
git add selbst berührt die Dateien im Arbeitsbaum nicht, aber der nächste Check-out würde es tun, also greifen die Sicherheitsmechanismen;
-
git apply zur Aktualisierung einer Textdatei mit einem Patch berührt die Dateien im Arbeitsbaum, aber die Operation betrifft Textdateien und die CRLF-Konvertierung dient der Behebung von Inkonsistenzen bei Zeilenenden, daher greift der Sicherheitsmechanismus nicht;
-
git diff selbst berührt die Dateien im Arbeitsbaum nicht, es wird oft ausgeführt, um die Änderungen zu inspizieren, die Sie als nächstes mit git add hinzufügen möchten. Um potenzielle Probleme frühzeitig zu erkennen, greifen die Sicherheitsmechanismen.
working-tree-encoding
Git erkennt Dateien, die in ASCII oder einer seiner Obermengen (z. B. UTF-8, ISO-8859-1, …) kodiert sind, als Textdateien. Dateien, die in bestimmten anderen Kodierungen (z. B. UTF-16) kodiert sind, werden als Binärdateien interpretiert und folglich verarbeiten integrierte Git-Textverarbeitungswerkzeuge (z. B. git diff) sowie die meisten Git-Web-Frontends die Inhalte dieser Dateien standardmäßig nicht.
In diesen Fällen können Sie Git die Kodierung einer Datei im Arbeitsverzeichnis mit dem Attribut working-tree-encoding mitteilen. Wenn eine Datei mit diesem Attribut zu Git hinzugefügt wird, kodiert Git den Inhalt von der angegebenen Kodierung in UTF-8 um. Schließlich speichert Git den UTF-8-kodierten Inhalt in seiner internen Datenstruktur (genannt "Index"). Beim Check-out wird der Inhalt zurück in die angegebene Kodierung umkodiert.
Bitte beachten Sie, dass die Verwendung des Attributs working-tree-encoding eine Reihe von Fallstricken haben kann
-
Alternative Git-Implementierungen (z. B. JGit oder libgit2) und ältere Git-Versionen (Stand März 2018) unterstützen das Attribut
working-tree-encodingnicht. Wenn Sie sich entscheiden, das Attributworking-tree-encodingin Ihrem Repository zu verwenden, wird dringend empfohlen, sicherzustellen, dass alle Clients, die mit dem Repository arbeiten, es unterstützen.Beispielsweise sind Microsoft Visual Studio-Ressourcendateien (
*.rc) oder PowerShell-Skriptdateien (*.ps1) manchmal in UTF-16 kodiert. Wenn Sie*.ps1-Dateien als UTF-16 deklarieren und Siefoo.ps1mit einemworking-tree-encoding-fähigen Git-Client hinzufügen, dann wirdfoo.ps1intern als UTF-8 gespeichert. Ein Client ohneworking-tree-encoding-Unterstützung checktfoo.ps1als UTF-8-kodierte Datei aus. Dies wird typischerweise zu Problemen für die Benutzer dieser Datei führen.Wenn ein Git-Client, der das Attribut
working-tree-encodingnicht unterstützt, eine neue Dateibar.ps1hinzufügt, dann wirdbar.ps1intern "wie-ist" gespeichert (in diesem Beispiel wahrscheinlich als UTF-16). Ein Client mitworking-tree-encoding-Unterstützung interpretiert die internen Inhalte als UTF-8 und versucht, sie beim Check-out nach UTF-16 umzukodieren. Dieser Vorgang schlägt fehl und verursacht einen Fehler. -
Die Umkodierung von Inhalten in Nicht-UTF-Kodierungen kann Fehler verursachen, da die Konvertierung möglicherweise nicht UTF-8-rundlauf-sicher ist. Wenn Sie vermuten, dass Ihre Kodierung nicht rundlauf-sicher ist, fügen Sie sie zu
core.checkRoundtripEncodinghinzu, damit Git die Rundlaufkodierung prüft (siehe git-config[1]). SHIFT-JIS (japanischer Zeichensatz) ist dafür bekannt, Rundlaufprobleme mit UTF-8 zu haben und wird standardmäßig geprüft. -
Die Umkodierung von Inhalten erfordert Ressourcen, die bestimmte Git-Operationen (z. B. git checkout oder git add) verlangsamen können.
Verwenden Sie das Attribut working-tree-encoding nur, wenn Sie eine Datei nicht in UTF-8-Kodierung speichern können und Git den Inhalt als Text verarbeiten können soll.
Verwenden Sie beispielsweise die folgenden Attribute, wenn Ihre *.ps1-Dateien UTF-16-kodiert mit Byte Order Mark (BOM) sind und Git die automatische Zeilenende-Konvertierung basierend auf Ihrer Plattform durchführen soll.
*.ps1 text working-tree-encoding=UTF-16
Verwenden Sie die folgenden Attribute, wenn Ihre *.ps1-Dateien UTF-16 Little Endian ohne BOM kodiert sind und Git Windows-Zeilenenden im Arbeitsbaum verwenden soll (verwenden Sie UTF-16LE-BOM anstelle von UTF-16LE, wenn Sie UTF-16 Little Endian mit BOM wünschen). Bitte beachten Sie, dass es dringend empfohlen wird, die Zeilenenden explizit mit eol zu definieren, wenn das Attribut working-tree-encoding verwendet wird, um Mehrdeutigkeiten zu vermeiden.
*.ps1 text working-tree-encoding=UTF-16LE eol=crlf
Sie können eine Liste aller auf Ihrer Plattform verfügbaren Kodierungen mit dem folgenden Befehl abrufen
iconv --list
Wenn Sie die Kodierung einer Datei nicht kennen, können Sie den Befehl file verwenden, um die Kodierung zu erraten
file foo.ps1
ident
Wenn das Attribut ident für einen Pfad gesetzt ist, ersetzt Git beim Check-out $Id$ im Blob-Objekt durch $Id:, gefolgt vom 40-stelligen hexadezimalen Blob-Objektnamen, gefolgt von einem Dollarzeichen $. Jede Byte-Sequenz, die mit $Id: beginnt und mit $ in der Arbeitsbaumdatei endet, wird beim Check-in durch $Id$ ersetzt.
filter
Ein filter-Attribut kann auf einen String-Wert gesetzt werden, der einen in der Konfiguration definierten Filtertreiber benennt.
Ein Filtertreiber besteht aus einem clean-Befehl und einem smudge-Befehl, wobei jeder davon optional sein kann. Beim Check-out wird, wenn der smudge-Befehl angegeben ist, der Befehl vom Standard-Input mit dem Blob-Objekt gespeist, und seine Standard-Ausgabe wird verwendet, um die Arbeitsbaumdatei zu aktualisieren. Ebenso wird der clean-Befehl verwendet, um die Inhalte der Arbeitsbaumdatei beim Check-in zu konvertieren. Standardmäßig verarbeiten diese Befehle nur einen einzelnen Blob und beenden sich. Wenn ein langlaufender process-Filter anstelle von clean und/oder smudge-Filtern verwendet wird, kann Git alle Blobs mit einer einzigen Filterbefehl-Invocation für die gesamte Lebensdauer eines einzelnen Git-Befehls verarbeiten, zum Beispiel git add --all. Wenn ein langlaufender process-Filter konfiguriert ist, hat er immer Vorrang vor einem konfigurierten Ein-Blob-Filter. Siehe den unten stehenden Abschnitt für die Beschreibung des Protokolls zur Kommunikation mit einem process-Filter.
Ein Anwendungsfall des Inhaltsfilters ist die Aufbereitung des Inhalts in eine Form, die für die Plattform, das Dateisystem und den Benutzer bequemer zu verwenden ist. Für diese Betriebsart ist die Schlüsselphrase hier "bequemer" und nicht "etwas Unbrauchbares in etwas Brauchbares verwandeln". Mit anderen Worten, die Absicht ist, dass das Projekt auch dann noch nutzbar sein sollte, wenn jemand die Filtertreiberdefinition aufhebt oder kein entsprechendes Filterprogramm hat.
Ein weiterer Anwendungsfall des Inhaltsfilters ist die Speicherung von Inhalten, die nicht direkt im Repository verwendet werden können (z. B. eine UUID, die auf den wahren Inhalt außerhalb von Git verweist, oder verschlüsselte Inhalte), und die Umwandlung in eine brauchbare Form beim Check-out (z. B. Herunterladen des externen Inhalts oder Entschlüsseln des verschlüsselten Inhalts).
Diese beiden Filter verhalten sich unterschiedlich, und standardmäßig wird ein Filter als erster betrachtet, der Inhalte in eine bequemere Form umwandelt. Eine fehlende Filtertreiberdefinition in der Konfiguration oder ein Filtertreiber, der mit einem Fehlerstatus ungleich Null beendet wird, ist kein Fehler, sondern macht den Filter zu einem passiven Passthrough.
Sie können deklarieren, dass ein Filter Inhalte, die an sich unbrauchbar sind, in brauchbare Inhalte umwandelt, indem Sie die Konfigurationsvariable filter.<driver>.required auf true setzen.
Hinweis: Jedes Mal, wenn der Clean-Filter geändert wird, sollte das Repository neu normalisiert werden: $ git add --renormalize .
Beispielsweise würden Sie in .gitattributes dem filter-Attribut für Pfade zuweisen.
*.c filter=indent
Dann würden Sie in Ihrer .git/config oder $HOME/.gitconfig eine "filter.indent.clean"- und "filter.indent.smudge"-Konfiguration definieren, um ein Paar von Befehlen anzugeben, die die Inhalte von C-Programmen modifizieren, wenn die Quelldateien eingecheckt ("clean" wird ausgeführt) und ausgecheckt werden (es wird keine Änderung vorgenommen, da der Befehl "cat" ist).
[filter "indent"] clean = indent smudge = cat
Für beste Ergebnisse sollte clean seine Ausgabe nicht weiter verändern, wenn es zweimal ausgeführt wird ("clean→clean" sollte äquivalent zu "clean" sein), und mehrere smudge-Befehle sollten die Ausgabe von clean nicht verändern ("smudge→smudge→clean" sollte äquivalent zu "clean" sein). Siehe den Abschnitt über Merging unten.
Der "indent"-Filter verhält sich in dieser Hinsicht gut: Er verändert nicht die Eingabe, die bereits korrekt eingerückt ist. In diesem Fall bedeutet das Fehlen eines Smudge-Filters, dass der Clean-Filter seine eigene Ausgabe ohne Veränderung akzeptieren muss.
Wenn ein Filter erfolgreich sein muss, um die gespeicherten Inhalte nutzbar zu machen, können Sie deklarieren, dass der Filter in der Konfiguration erforderlich ist
[filter "crypt"] clean = openssl enc ... smudge = openssl enc -d ... required
Die Sequenz "%f" auf der Filter-Befehlszeile wird durch den Namen der Datei ersetzt, an der der Filter arbeitet. Ein Filter kann dies in der Keyword-Substitution verwenden. Zum Beispiel
[filter "p4"] clean = git-p4-filter --clean %f smudge = git-p4-filter --smudge %f
Beachten Sie, dass "%f" der Name des Pfades ist, an dem gearbeitet wird. Abhängig von der Version, die gefiltert wird, existiert die entsprechende Datei auf der Festplatte möglicherweise nicht oder hat andere Inhalte. Daher sollten Smudge- und Clean-Befehle nicht auf die Datei auf der Festplatte zugreifen, sondern nur als Filter auf die ihnen über die Standardeingabe bereitgestellten Inhalte wirken.
Langlaufender Filterprozess
Wenn der Filterbefehl (ein String-Wert) über filter.<driver>.process definiert wird, kann Git alle Blobs mit einer einzigen Filter-Invocation für die gesamte Lebensdauer eines einzelnen Git-Befehls verarbeiten. Dies wird durch die Verwendung des langlaufenden Prozessprotokolls erreicht (beschrieben in Documentation/technical/long-running-process-protocol.adoc).
Wenn Git auf die erste Datei stößt, die gereinigt oder verschmiert werden muss, startet es den Filter und führt den Handshake durch. Beim Handshake lautet die von Git gesendete Willkommensnachricht "git-filter-client", nur Version 2 wird unterstützt, und die unterstützten Fähigkeiten sind "clean", "smudge" und "delay".
Danach sendet Git eine Liste von "Schlüssel=Wert"-Paaren, die mit einem Flush-Paket abgeschlossen werden. Die Liste enthält mindestens den Filterbefehl (basierend auf den unterstützten Fähigkeiten) und den Pfadnamen der zu filternden Datei relativ zum Repository-Root. Direkt nach dem Flush-Paket sendet Git den Inhalt in null oder mehr pkt-line-Paketen und einem Flush-Paket zur Beendigung des Inhalts. Bitte beachten Sie, dass der Filter keine Antwort senden darf, bevor er den Inhalt und das abschließende Flush-Paket erhalten hat. Beachten Sie auch, dass der "Wert" eines "Schlüssel=Wert"-Paares das "=" Zeichen enthalten kann, während der Schlüssel dieses Zeichen niemals enthalten würde.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000 packet: git> CONTENT packet: git> 0000
Der Filter wird erwartet, mit einer Liste von "Schlüssel=Wert"-Paaren zu antworten, die mit einem Flush-Paket abgeschlossen werden. Wenn der Filter keine Probleme hat, muss die Liste einen "success"-Status enthalten. Direkt nach diesen Paketen wird erwartet, dass der Filter den Inhalt in null oder mehr pkt-line-Paketen und einem abschließenden Flush-Paket sendet. Schließlich wird eine zweite Liste von "Schlüssel=Wert"-Paaren, die mit einem Flush-Paket abgeschlossen wird, erwartet. Der Filter kann den Status in der zweiten Liste ändern oder den Status unverändert lassen mit einer leeren Liste. Bitte beachten Sie, dass die leere Liste ungeachtet dessen mit einem Flush-Paket abgeschlossen werden muss.
packet: git< status=success packet: git< 0000 packet: git< SMUDGED_CONTENT packet: git< 0000 packet: git< 0000 # empty list, keep "status=success" unchanged!
Wenn der Ergebnisinhalt leer ist, wird erwartet, dass der Filter mit einem "success"-Status und einem Flush-Paket antwortet, um den leeren Inhalt zu signalisieren.
packet: git< status=success packet: git< 0000 packet: git< 0000 # empty content! packet: git< 0000 # empty list, keep "status=success" unchanged!
Wenn der Filter den Inhalt nicht verarbeiten kann oder will, wird erwartet, dass er mit einem "error"-Status antwortet.
packet: git< status=error packet: git< 0000
Wenn der Filter während der Verarbeitung einen Fehler auftritt, kann er den Status "error" senden, nachdem der Inhalt (teilweise oder vollständig) gesendet wurde.
packet: git< status=success packet: git< 0000 packet: git< HALF_WRITTEN_ERRONEOUS_CONTENT packet: git< 0000 packet: git< status=error packet: git< 0000
Wenn der Filter den Inhalt nicht verarbeiten kann oder will und auch zukünftige Inhalte für die Lebensdauer des Git-Prozesses nicht verarbeiten kann, wird erwartet, dass er zu jedem Zeitpunkt des Protokolls mit einem "abort"-Status antwortet.
packet: git< status=abort packet: git< 0000
Git stoppt oder startet den Filterprozess weder, wenn der Status "error" / "abort" gesetzt ist. Git setzt jedoch seinen Exit-Code entsprechend dem Flag filter.<driver>.required und ahmt damit das Verhalten des Mechanismus filter.<driver>.clean / filter.<driver>.smudge nach.
Wenn der Filter während der Kommunikation abstürzt oder das Protokoll nicht einhält, wird Git den Filterprozess stoppen und ihn mit der nächsten zu verarbeitenden Datei neu starten. Abhängig vom Flag filter.<driver>.required interpretiert Git dies als Fehler.
Verzögerung
Wenn der Filter die "delay"-Fähigkeit unterstützt, kann Git nach dem Filterbefehl und Pfadnamen das Flag "can-delay" senden. Dieses Flag zeigt an, dass der Filter die Filterung des aktuellen Blobs verzögern kann (z. B. zur Kompensation von Netzwerk-Latenzen), indem er ohne Inhalt, aber mit dem Status "delayed" und einem Flush-Paket antwortet.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> can-delay=1 packet: git> 0000 packet: git> CONTENT packet: git> 0000 packet: git< status=delayed packet: git< 0000
Wenn der Filter die "delay"-Fähigkeit unterstützt, muss er die Befehlsoption "list_available_blobs" unterstützen. Wenn Git diesen Befehl sendet, wird erwartet, dass der Filter eine Liste von Pfadnamen zurückgibt, die zuvor verzögerte Blobs repräsentieren und nun verfügbar sind. Die Liste muss mit einem Flush-Paket gefolgt von einem "success"-Status abgeschlossen werden, der ebenfalls mit einem Flush-Paket abgeschlossen wird. Wenn noch keine Blobs für die verzögerten Pfade verfügbar sind, wird erwartet, dass der Filter die Antwort blockiert, bis mindestens ein Blob verfügbar ist. Der Filter kann Git mitteilen, dass er keine weiteren verzögerten Blobs mehr hat, indem er eine leere Liste sendet. Sobald der Filter mit einer leeren Liste antwortet, hört Git auf zu fragen. Alle Blobs, die Git bis zu diesem Zeitpunkt nicht erhalten hat, gelten als fehlend und führen zu einem Fehler.
packet: git> command=list_available_blobs packet: git> 0000 packet: git< pathname=path/testfile.dat packet: git< pathname=path/otherfile.dat packet: git< 0000 packet: git< status=success packet: git< 0000
Nachdem Git die Pfadnamen erhalten hat, fordert es die entsprechenden Blobs erneut an. Diese Anfragen enthalten einen Pfadnamen und einen leeren Inhaltsabschnitt. Es wird erwartet, dass der Filter den verschmutzten Inhalt auf die übliche Weise wie oben beschrieben zurückgibt.
packet: git> command=smudge packet: git> pathname=path/testfile.dat packet: git> 0000 packet: git> 0000 # empty content! packet: git< status=success packet: git< 0000 packet: git< SMUDGED_CONTENT packet: git< 0000 packet: git< 0000 # empty list, keep "status=success" unchanged!
Beispiel
Eine Demoimplementierung eines langlaufenden Filters finden Sie in contrib/long-running-filter/example.pl im Git-Kern-Repository. Wenn Sie Ihren eigenen langlaufenden Filterprozess entwickeln, können die Umgebungsvariablen GIT_TRACE_PACKET sehr hilfreich für die Fehlersuche sein (siehe git[1]).
Bitte beachten Sie, dass Sie keinen vorhandenen Befehl filter.<driver>.clean oder filter.<driver>.smudge mit filter.<driver>.process verwenden können, da die beiden ersteren ein anderes Interprozesskommunikationsprotokoll als letzteres verwenden.
Interaktion zwischen Check-in/Check-out-Attributen
Im Check-in-Codepfad wird die Arbeitsbaumdatei zuerst mit dem filter-Treiber (falls spezifiziert und der entsprechende Treiber definiert) konvertiert, dann wird das Ergebnis mit ident (falls spezifiziert) und dann schließlich mit text (wiederum, falls spezifiziert und anwendbar) verarbeitet.
Im Check-out-Codepfad wird der Blob-Inhalt zuerst mit text, dann mit ident konvertiert und an filter weitergeleitet.
Zusammenführen von Branches mit unterschiedlichen Check-in/Check-out-Attributen
Wenn Sie einem Dateiatribut hinzugefügt haben, das das kanonische Repository-Format für diese Datei ändert, z. B. durch Hinzufügen eines Clean/Smudge-Filters oder Text/EOL/Ident-Attributen, würde das Zusammenführen von allem, wo das Attribut nicht vorhanden ist, normalerweise zu Merge-Konflikten führen.
Um diese unnötigen Merge-Konflikte zu verhindern, kann Git angewiesen werden, einen virtuellen Check-out und Check-in aller drei Stufen jeder Datei, die einen dreiseitigen Inhalts-Merge benötigt, auszuführen, indem die Konfigurationsvariable merge.renormalize gesetzt wird. Dies verhindert, dass durch die Check-in-Konvertierung verursachte Änderungen zu falschen Merge-Konflikten führen, wenn eine konvertierte Datei mit einer nicht konvertierten Datei zusammengeführt wird.
Solange ein "smudge→clean" dasselbe Ergebnis wie ein "clean" liefert, auch bei bereits "geschmierten" Dateien, löst diese Strategie automatisch alle filterbezogenen Konflikte. Filter, die sich nicht so verhalten, können zusätzliche Merge-Konflikte verursachen, die manuell gelöst werden müssen.
Generierung von Diff-Text
diff
Das Attribut diff beeinflusst, wie Git Diffs für bestimmte Dateien generiert. Es kann Git mitteilen, ob ein textueller Patch für den Pfad generiert werden soll oder ob der Pfad als Binärdatei behandelt werden soll. Es kann auch beeinflussen, welche Zeile im Hunk-Header @@ -k,l +n,m @@ angezeigt wird, Git anweisen, einen externen Befehl zur Generierung des Diffs zu verwenden oder Git anweisen, Binärdateien vor der Generierung des Diffs in ein Textformat zu konvertieren.
- gesetzt
-
Ein Pfad, dem das Attribut
diffzugewiesen ist, wird als Text behandelt, auch wenn er Byte-Werte enthält, die normalerweise nicht in Textdateien vorkommen, wie z. B. NUL. - nicht gesetzt
-
Ein Pfad, dem das Attribut
diffnicht zugewiesen ist, generiertBinaryfilesdiffer(oder einen Binär-Patch, wenn Binär-Patches aktiviert sind). - nicht spezifiziert
-
Ein Pfad, dem das Attribut
diffnicht zugewiesen ist, wird zuerst auf seinen Inhalt untersucht, und wenn es wie Text aussieht und kleiner als core.bigFileThreshold ist, wird es als Text behandelt. Andernfalls würde esBinaryfilesdiffergenerieren. - String
-
Diff wird unter Verwendung des angegebenen Diff-Treibers angezeigt. Jeder Treiber kann eine oder mehrere Optionen angeben, wie im folgenden Abschnitt beschrieben. Die Optionen für den Diff-Treiber "foo" werden durch die Konfigurationsvariablen im Abschnitt "diff.foo" der Git-Konfigurationsdatei definiert.
Definition eines externen Diff-Treibers
Die Definition eines Diff-Treibers erfolgt in gitconfig, nicht in der gitattributes-Datei, daher ist diese Manualpage streng genommen der falsche Ort dafür. Aber…
Um einen externen Diff-Treiber jcdiff zu definieren, fügen Sie Ihrer Datei $GIT_DIR/config (oder $HOME/.gitconfig) einen Abschnitt wie diesen hinzu
[diff "jcdiff"] command = j-c-diff
Wenn Git Ihnen einen Diff für den Pfad mit dem Attribut diff, gesetzt auf jcdiff, anzeigen muss, ruft es den von Ihnen angegebenen Befehl mit der obigen Konfiguration auf, d. h. j-c-diff, mit 7 Parametern, genauso wie das Programm GIT_EXTERNAL_DIFF aufgerufen wird. Weitere Details finden Sie in git[1].
Wenn das Programm bestimmte Änderungen ignorieren kann (ähnlich wie git diff --ignore-space-change), dann setzen Sie auch die Option trustExitCode auf true. Es wird dann erwartet, dass es den Exit-Code 1 zurückgibt, wenn es signifikante Änderungen findet, und 0, wenn nicht.
Festlegen des internen Diff-Algorithmus
Der Diff-Algorithmus kann über den Konfigurationsschlüssel diff.algorithm festgelegt werden, aber manchmal kann es hilfreich sein, den Diff-Algorithmus pro Pfad festzulegen. Man möchte zum Beispiel vielleicht den minimal Diff-Algorithmus für .json-Dateien und den histogram für .c-Dateien verwenden und so weiter, ohne den Algorithmus jedes Mal über die Kommandozeile übergeben zu müssen.
Zuerst wird in .gitattributes das Attribut diff für Pfade zugewiesen.
*.json diff=<name>
Anschließend wird eine Konfiguration "diff.<name>.algorithm" definiert, um den Diff-Algorithmus festzulegen, wählbar aus myers, patience, minimal oder histogram.
[diff "<name>"] algorithm = histogram
Dieser Diff-Algorithmus gilt für die für den Benutzer sichtbare Diff-Ausgabe wie git-diff(1), git-show(1) und wird auch für die --stat-Ausgabe verwendet. Die Merge-Mechanismen verwenden den auf diese Weise festgelegten Diff-Algorithmus nicht.
|
Hinweis
|
Wenn diff.<name>.command für einen Pfad mit dem Attribut diff=<name> definiert ist, wird er als externer Diff-Treiber ausgeführt (siehe oben), und das Hinzufügen von diff.<name>.algorithm hat keine Auswirkung, da der Algorithmus nicht an den externen Diff-Treiber übergeben wird. |
Definieren eines benutzerdefinierten Hunk-Headers
Jede Gruppe von Änderungen (genannt "Hunk") in der textuellen Diff-Ausgabe wird mit einer Zeile der Form vorangestellt
@@ -k,l +n,m @@ TEXT
Dies wird als Hunk-Header bezeichnet. Der "TEXT"-Teil ist standardmäßig eine Zeile, die mit einem Buchstaben, einem Unterstrich oder einem Dollarzeichen beginnt; dies entspricht der Ausgabe von GNU diff -p. Diese Standardauswahl ist jedoch für einige Inhalte nicht geeignet, und Sie können ein benutzerdefiniertes Muster verwenden, um eine Auswahl zu treffen.
Zuerst wird in .gitattributes das Attribut diff für Pfade zugewiesen.
*.tex diff=tex
Dann definieren Sie eine Konfiguration "diff.tex.xfuncname", um einen regulären Ausdruck anzugeben, der auf eine Zeile passt, die Sie als "TEXT" des Hunk-Headers erscheinen lassen möchten. Fügen Sie Ihrem $GIT_DIR/config- oder $HOME/.gitconfig-Datei einen Abschnitt wie diesen hinzu
[diff "tex"]
xfuncname = "^(\\\\(sub)*section\\{.*)$"
Hinweis. Eine einzelne Ebene von Backslashes wird vom Konfigurationsdateiparser verschluckt, sodass Sie die Backslashes verdoppeln müssen; das obige Muster wählt eine Zeile aus, die mit einem Backslash beginnt, und null oder mehr Vorkommen von sub gefolgt von section gefolgt von einer öffnenden Klammer bis zum Ende der Zeile.
Es gibt einige eingebaute Muster, die dies erleichtern, und tex ist eines davon, sodass Sie das oben Genannte nicht in Ihre Konfigurationsdatei schreiben müssen (Sie müssen dies immer noch über den Attributmechanismus mit .gitattributes aktivieren). Die folgenden eingebauten Muster sind verfügbar
-
adageeignet für Quellcode in der Programmiersprache Ada. -
bashgeeignet für Quellcode in der Bourne-Again SHell-Sprache. Deckt eine Obermenge von POSIX Shell-Funktionsdefinitionen ab. -
bibtexgeeignet für Dateien mit BibTeX-kodierten Referenzen. -
cppgeeignet für Quellcode in den Programmiersprachen C und C++. -
csharpgeeignet für Quellcode in der Programmiersprache C#. -
cssgeeignet für Cascading Style Sheets. -
dtsgeeignet für Device Tree (DTS) Dateien. -
elixirgeeignet für Quellcode in der Programmiersprache Elixir. -
fortrangeeignet für Quellcode in der Programmiersprache Fortran. -
fountaingeeignet für Fountain-Dokumente. -
golanggeeignet für Quellcode in der Programmiersprache Go. -
htmlgeeignet für HTML/XHTML-Dokumente. -
javageeignet für Quellcode in der Programmiersprache Java. -
kotlingeeignet für Quellcode in der Programmiersprache Kotlin. -
markdowngeeignet für Markdown-Dokumente. -
matlabgeeignet für Quellcode in den Programmiersprachen MATLAB und Octave. -
objcgeeignet für Quellcode in der Programmiersprache Objective-C. -
pascalgeeignet für Quellcode in den Programmiersprachen Pascal/Delphi. -
perlgeeignet für Quellcode in der Programmiersprache Perl. -
phpgeeignet für Quellcode in der Programmiersprache PHP. -
pythongeeignet für Quellcode in der Programmiersprache Python. -
rubygeeignet für Quellcode in der Programmiersprache Ruby. -
rustgeeignet für Quellcode in der Programmiersprache Rust. -
schemegeeignet für Quellcode in der Programmiersprache Scheme. -
texgeeignet für Quellcode für LaTeX-Dokumente.
Wort-Diff anpassen
Sie können die Regeln, die git diff --word-diff zum Aufteilen von Wörtern in einer Zeile verwendet, anpassen, indem Sie einen geeigneten regulären Ausdruck in der Konfigurationsvariable "diff.*.wordRegex" angeben. In TeX bildet beispielsweise ein Backslash gefolgt von einer Buchstabenfolge einen Befehl, aber mehrere solcher Befehle können ohne dazwischenliegende Leerzeichen hintereinander ausgeführt werden. Um sie zu trennen, verwenden Sie einen regulären Ausdruck in Ihrer $GIT_DIR/config- oder $HOME/.gitconfig-Datei wie folgt:
[diff "tex"]
wordRegex = "\\\\[a-zA-Z]+|[{}]|\\\\.|[^\\{}[:space:]]+"
Für alle im vorherigen Abschnitt aufgeführten Sprachen ist ein integriertes Muster vorhanden.
Text-Diffs von Binärdateien durchführen
Manchmal ist es wünschenswert, die Unterschiede einer textkonvertierten Version von Binärdateien anzuzeigen. Zum Beispiel kann ein Textverarbeitungsdokument in eine ASCII-Textdarstellung konvertiert und der Diff des Textes angezeigt werden. Obwohl diese Konvertierung einige Informationen verliert, ist der resultierende Diff für die menschliche Betrachtung nützlich (kann aber nicht direkt angewendet werden).
Die Konfigurationsoption textconv wird verwendet, um ein Programm für die Durchführung einer solchen Konvertierung zu definieren. Das Programm sollte ein einzelnes Argument entgegennehmen, den Namen einer zu konvertierenden Datei, und den resultierenden Text auf stdout ausgeben.
Um beispielsweise die Diff-Informationen der EXIF-Daten einer Datei anstelle der Binärinformationen anzuzeigen (vorausgesetzt, Sie haben das Exif-Tool installiert), fügen Sie Ihrer $GIT_DIR/config- oder $HOME/.gitconfig-Datei einen Abschnitt wie folgt hinzu:
[diff "jpg"] textconv = exif
|
Hinweis
|
Die Textkonvertierung ist im Allgemeinen eine Einwegkonvertierung; in diesem Beispiel verlieren wir den eigentlichen Bildinhalt und konzentrieren uns nur auf die Textdaten. Das bedeutet, dass die von textconv generierten Diffs *nicht* zum Anwenden geeignet sind. Aus diesem Grund führen nur git diff und die git log-Befehlsfamilie (d. h. log, whatchanged, show) eine Textkonvertierung durch. git format-patch wird diese Ausgabe niemals generieren. Wenn Sie jemandem einen textkonvertierten Diff einer Binärdatei senden möchten (z. B. weil er die von Ihnen vorgenommenen Änderungen schnell vermittelt), sollten Sie ihn separat generieren und als Kommentar *zusätzlich* zum üblichen Binärdiff senden, den Sie möglicherweise senden. |
Da die Textkonvertierung langsam sein kann, insbesondere bei einer großen Anzahl von Konvertierungen mit git log -p, bietet Git einen Mechanismus zum Zwischenspeichern der Ausgabe und zur Verwendung in zukünftigen Diffs. Um das Caching zu aktivieren, setzen Sie die Variable "cachetextconv" in der Konfiguration Ihres Diff-Treibers. Zum Beispiel:
[diff "jpg"] textconv = exif cachetextconv = true
Dies speichert das Ergebnis der Ausführung von "exif" auf jedem Blob unbefristet im Cache. Wenn Sie die textconv-Konfigurationsvariable für einen Diff-Treiber ändern, wird Git den Cache automatisch ungültig machen und den textconv-Filter erneut ausführen. Wenn Sie den Cache manuell ungültig machen möchten (z. B. weil Ihre Version von "exif" aktualisiert wurde und jetzt bessere Ausgaben liefert), können Sie den Cache manuell mit git update-ref -d refs/notes/textconv/jpg entfernen (wobei "jpg" der Name des Diff-Treibers ist, wie im obigen Beispiel).
Wahl zwischen textconv und externem Diff
Wenn Sie Unterschiede zwischen binären oder speziell formatierten Blobs in Ihrem Repository anzeigen möchten, können Sie entweder einen externen Diff-Befehl verwenden oder textconv verwenden, um sie in ein diff-fähiges Textformat zu konvertieren. Welche Methode Sie wählen, hängt von Ihrer genauen Situation ab.
Der Vorteil der Verwendung eines externen Diff-Befehls liegt in der Flexibilität. Sie sind nicht an zeilenorientierte Änderungen gebunden, und die Ausgabe muss auch nicht wie ein einheitlicher Diff aussehen. Sie können Änderungen auf die für Ihr Datenformat am besten geeignete Weise lokalisieren und melden.
Ein textconv ist im Vergleich dazu viel einschränkender. Sie stellen eine Transformation der Daten in ein zeilenorientiertes Textformat bereit, und Git verwendet seine regulären Diff-Tools, um die Ausgabe zu generieren. Es gibt mehrere Vorteile, diese Methode zu wählen:
-
Benutzerfreundlichkeit. Es ist oft viel einfacher, eine binäre in Texttransformation zu schreiben, als Ihren eigenen Diff durchzuführen. In vielen Fällen können vorhandene Programme als textconv-Filter verwendet werden (z. B. exif, odt2txt).
-
Git-Diff-Funktionen. Indem Sie nur den Transformationsschritt selbst durchführen, können Sie immer noch viele von Git's Diff-Funktionen nutzen, einschließlich Farbkodierung, Wort-Diff und kombinierte Diffs für Merges.
-
Caching. Textconv-Caching kann wiederholte Diffs beschleunigen, wie sie beispielsweise beim Ausführen von
gitlog-pausgelöst werden.
Dateien als binär kennzeichnen
Git errät normalerweise korrekt, ob ein Blob Text- oder Binärdaten enthält, indem es den Anfang des Inhalts untersucht. Manchmal möchten Sie seine Entscheidung jedoch überschreiben, entweder weil ein Blob später in der Datei Binärdaten enthält oder weil der Inhalt, obwohl technisch aus Textzeichen bestehend, für einen menschlichen Leser undurchsichtig ist. Beispielsweise enthalten viele Postscript-Dateien nur ASCII-Zeichen, erzeugen aber verrauschte und bedeutungslose Diffs.
Der einfachste Weg, eine Datei als binär zu kennzeichnen, ist das Aufheben des Diff-Attributs in der Datei .gitattributes
*.ps -diff
Dies veranlasst Git, Binary files differ (oder einen Binärpatch, wenn Binärpatches aktiviert sind) anstelle eines regulären Diffs zu generieren.
Manchmal möchte man jedoch auch andere Diff-Treiberattribute angeben. Man möchte zum Beispiel vielleicht textconv verwenden, um Postscript-Dateien in eine ASCII-Darstellung zur menschlichen Betrachtung zu konvertieren, sie aber ansonsten als Binärdateien zu behandeln. Sie können nicht gleichzeitig die Attribute -diff und diff=ps angeben. Die Lösung ist die Verwendung der Konfigurationsoption diff.*.binary
[diff "ps"] textconv = ps2ascii binary = true
Dreiseitigen Merge durchführen
merge
Das Attribut merge beeinflusst, wie drei Versionen einer Datei zusammengeführt werden, wenn während git merge und anderen Befehlen wie git revert und git cherry-pick ein Dateiebenen-Merge erforderlich ist.
- Set
-
Der eingebaute 3-Wege-Merge-Treiber wird verwendet, um die Inhalte auf eine Weise zusammenzuführen, die dem merge-Befehl der
RCS-Suite ähnelt. Dies ist für normale Textdateien geeignet. - Unset
-
Nimmt die Version aus dem aktuellen Branch als vorläufiges Merge-Ergebnis und erklärt, dass der Merge Konflikte aufweist. Dies ist für Binärdateien geeignet, die keine gut definierte Merge-Semantik haben.
- Unspezifiziert
-
Standardmäßig wird derselbe eingebaute 3-Wege-Merge-Treiber verwendet, wie wenn das Attribut
mergegesetzt ist. Die Konfigurationsvariablemerge.defaultkann jedoch einen anderen Merge-Treiber benennen, der für Pfade verwendet wird, für die das Attributmergeunspezifiziert ist. - String
-
Ein 3-Wege-Merge wird unter Verwendung des angegebenen benutzerdefinierten Merge-Treibers durchgeführt. Der eingebaute 3-Wege-Merge-Treiber kann explizit spezifiziert werden, indem "text" als Treiber angefordert wird; der eingebaute Treiber "take the current branch" kann mit "binary" angefordert werden.
Eingebaute Merge-Treiber
Es gibt einige eingebaute Low-Level-Merge-Treiber, die über das Attribut merge angefordert werden können.
- text
-
Normaler 3-Wege-Datei-Merge für Textdateien. Konfliktregionen werden mit Konfliktmarkierungen <<<<<<<,
=======und >>>>>>> gekennzeichnet. Die Version aus Ihrem Branch erscheint vor dem=======-Marker, und die Version aus dem zusammengeführten Branch erscheint nach dem=======-Marker. - binary
-
Behält die Version aus Ihrem Branch im Arbeitsverzeichnis, lässt den Pfad jedoch im konfliktbehafteten Zustand, damit der Benutzer ihn lösen kann.
- union
-
Führt einen 3-Wege-Datei-Merge für Textdateien durch, nimmt aber Zeilen aus beiden Versionen anstelle von Konfliktmarkierungen. Dies neigt dazu, die hinzugefügten Zeilen in der resultierenden Datei in zufälliger Reihenfolge zu hinterlassen, und der Benutzer sollte das Ergebnis überprüfen. Verwenden Sie dies nicht, wenn Sie die Implikationen nicht verstehen.
Einen benutzerdefinierten Merge-Treiber definieren
Die Definition eines Merge-Treibers erfolgt in der Datei .git/config, nicht in der Datei gitattributes. Streng genommen ist diese Manpage also der falsche Ort, um darüber zu sprechen. Aber trotzdem...
Um einen benutzerdefinierten Merge-Treiber filfre zu definieren, fügen Sie Ihrer $GIT_DIR/config- oder $HOME/.gitconfig-Datei einen Abschnitt wie diesen hinzu:
[merge "filfre"] name = feel-free merge driver driver = filfre %O %A %B %L %P recursive = binary
Die Variable merge.*.name gibt dem Treiber einen lesbaren Namen.
Der Wert der Variable merge.*.driver wird verwendet, um einen Befehl zu erstellen, der mit der Version des gemeinsamen Vorfahren (%O), der aktuellen Version (%A) und der Version des anderen Branches (%B) ausgeführt wird. Diese drei Platzhalter werden durch die Namen temporärer Dateien ersetzt, die die Inhalte dieser Versionen enthalten, wenn die Befehlszeile erstellt wird. Zusätzlich wird %L durch die Größe der Konfliktmarker (siehe unten) ersetzt.
Es wird erwartet, dass der Merge-Treiber das Ergebnis des Merges in der mit %A benannten Datei hinterlässt, indem er sie überschreibt, und mit Null-Status beendet wird, wenn er sie sauber zusammenführen konnte, oder mit einem Nicht-Null-Status, wenn es Konflikte gab. Wenn der Treiber abstürzt (z. B. durch SEGV beendet wird), wird erwartet, dass er mit einem Nicht-Null-Status größer als 128 beendet wird, und in diesem Fall führt der Merge zu einem Fehler (was sich von der Erzeugung eines Konflikts unterscheidet).
Die Variable merge.*.recursive gibt an, welcher andere Merge-Treiber verwendet werden soll, wenn der Merge-Treiber für einen internen Merge zwischen gemeinsamen Vorfahren aufgerufen wird, wenn es mehr als einen gibt. Wenn sie nicht angegeben ist, wird der Treiber selbst sowohl für den internen Merge als auch für den endgültigen Merge verwendet.
Der Merge-Treiber kann den Pfadnamen, in dem das zusammengeführte Ergebnis gespeichert wird, über den Platzhalter %P erfahren. Die Konfliktbeschriftungen für den gemeinsamen Vorfahren, den lokalen Head und den anderen Head können über %S, %X und %Y übergeben werden.
conflict-marker-size
Dieses Attribut steuert die Länge der Konfliktmarker, die in der Arbeitsbaumdatei während eines konfliktreichen Merges hinterlassen werden. Nur eine positive Ganzzahl hat eine sinnvolle Auswirkung.
Zum Beispiel kann diese Zeile in .gitattributes verwendet werden, um der Merge-Mechanik mitzuteilen, viel längere (anstelle der üblichen 7-Zeichen-langen) Konfliktmarker zu hinterlassen, wenn das Zusammenführen der Datei Documentation/git-merge.adoc zu einem Konflikt führt.
Documentation/git-merge.adoc conflict-marker-size=32
Überprüfung von Whitespace-Fehlern
whitespace
Die Konfigurationsvariable core.whitespace ermöglicht es Ihnen, zu definieren, was diff und apply für alle Pfade im Projekt als Whitespace-Fehler betrachten sollen (siehe git-config[1]). Dieses Attribut gibt Ihnen eine feinere Kontrolle pro Pfad.
- Set
-
Beachten Sie alle Arten potenzieller Whitespace-Fehler, die Git bekannt sind. Die Tabulatorbreite wird dem Wert der Konfigurationsvariable
core.whitespaceentnommen. - Unset
-
Nichts als Fehler betrachten.
- Unspezifiziert
-
Verwenden Sie den Wert der Konfigurationsvariable
core.whitespace, um zu entscheiden, was als Fehler zu betrachten ist. - String
-
Geben Sie eine durch Kommas getrennte Liste gängiger Whitespace-Probleme an, die in demselben Format wie die Konfigurationsvariable
core.whitespacebeachtet werden sollen.
Archiv erstellen
export-ignore
Dateien und Verzeichnisse mit dem Attribut export-ignore werden nicht zu Archivdateien hinzugefügt.
export-subst
Wenn das Attribut export-subst für eine Datei gesetzt ist, erweitert Git beim Hinzufügen dieser Datei zu einem Archiv mehrere Platzhalter. Die Ersetzung hängt von der Verfügbarkeit einer Commit-ID ab, d. h., wenn git-archive[1] anstelle eines Commits oder Tags einen Baum erhalten hat, erfolgt keine Ersetzung. Die Platzhalter sind dieselben wie für die Option --pretty=format: von git-log[1], außer dass sie wie folgt eingekapselt werden müssen: $Format:PLACEHOLDERS$ in der Datei. Z. B. wird der String $Format:%H$ durch den Commit-Hash ersetzt. Es wird jedoch nur ein %(describe)-Platzhalter pro Archiv erweitert, um Denial-of-Service-Angriffe zu vermeiden.
Dateien in GUI-Tools anzeigen
encoding
Der Wert dieses Attributs gibt die Zeichenkodierung an, die von GUI-Tools (z. B. gitk[1] und git-gui[1]) zur Anzeige des Inhalts der betreffenden Datei verwendet werden soll. Beachten Sie, dass gitk[1] aus Leistungsgründen dieses Attribut nicht verwendet, es sei denn, Sie aktivieren manuell Dateikodierungen in seinen Optionen.
Wenn dieses Attribut nicht gesetzt ist oder einen ungültigen Wert hat, wird stattdessen der Wert der Konfigurationsvariable gui.encoding verwendet (siehe git-config[1]).
MAKRO-ATTRIBUTE VERWENDEN
Sie möchten keine End-of-Line-Konvertierungen oder Text-Diffs für eine Binärdatei, die Sie verfolgen, anwenden. Sie müssten zum Beispiel angeben:
*.jpg -text -diff
aber das kann umständlich werden, wenn Sie viele Attribute haben. Mit Makro-Attributen können Sie ein Attribut definieren, das beim Setzen gleichzeitig eine Reihe anderer Attribute setzt oder aufhebt. Das System kennt ein eingebautes Makro-Attribut, binary
*.jpg binary
Das Setzen des "binary"-Attributs hebt auch die "text"- und "diff"-Attribute wie oben auf. Beachten Sie, dass Makro-Attribute nur "gesetzt" werden können, obwohl das Setzen eines Makros den Effekt haben kann, andere Attribute zu setzen oder aufzuheben oder sogar andere Attribute in den "Unspecified"-Zustand zurückzusetzen.
MAKRO-ATTRIBUTE DEFINIEREN
Benutzerdefinierte Makro-Attribute können nur in Top-Level-gitattributes-Dateien ($GIT_DIR/info/attributes, die Datei .gitattributes auf der obersten Ebene des Arbeitsverzeichnisses oder die globalen oder systemweiten gitattributes-Dateien) definiert werden, nicht in .gitattributes-Dateien in Unterverzeichnissen des Arbeitsverzeichnisses. Das eingebaute Makro-Attribut "binary" entspricht
[attr]binary -diff -merge -text
ANMERKUNGEN
Git folgt keinen symbolischen Links beim Zugriff auf eine .gitattributes-Datei im Arbeitsverzeichnis. Dies hält das Verhalten konsistent, wenn die Datei aus dem Index oder einem Baum im Gegensatz zum Dateisystem zugegriffen wird.
BEISPIELE
Wenn Sie diese drei gitattributes-Dateien haben
(in $GIT_DIR/info/attributes) a* foo !bar -baz (in .gitattributes) abc foo bar baz (in t/.gitattributes) ab* merge=filfre abc -foo -bar *.c frotz
werden die für den Pfad t/abc angegebenen Attribute wie folgt berechnet:
-
Durch die Untersuchung von
t/.gitattributes(die sich im selben Verzeichnis wie der fragliche Pfad befindet) stellt Git fest, dass die erste Zeile übereinstimmt. Das Attributmergewird gesetzt. Es stellt auch fest, dass die zweite Zeile übereinstimmt, und die Attributefooundbarwerden aufgehoben. -
Dann wird
.gitattributes(das sich im übergeordneten Verzeichnis befindet) untersucht, und es wird festgestellt, dass die erste Zeile übereinstimmt, aber die Dateit/.gitattributesbereits entschieden hat, wie die Attributemerge,fooundbardiesem Pfad zugewiesen werden sollen, sodassfooundbaraufgehoben bleiben. Das Attributbazwird gesetzt. -
Schließlich wird
$GIT_DIR/info/attributesuntersucht. Diese Datei wird verwendet, um die Einstellungen im Baum zu überschreiben. Die erste Zeile ist eine Übereinstimmung, undfoowird gesetzt,barwird in den unspezifizierten Zustand zurückversetzt, undbazwird aufgehoben.
Als Ergebnis wird die Attributzuweisung an t/abc wie folgt:
foo set to true bar unspecified baz set to false merge set to string value "filfre" frotz unspecified
GIT
Teil der git[1] Suite