Deaktivieren Sie Git EOL Conversions

100

Ich versuche, git dazu zu bringen, keinerlei Zeilenenden für irgendeine Operation zu ändern. Leider scheint es egal zu sein, was passiert. Ich habe es auf den folgenden Testfall reduziert, der so viele verschiedene Mechanismen zum Deaktivieren dieses Verhaltens enthält, wie ich finden konnte.


  • Beginnen Sie mit zwei Maschinen (Windows-Computer = A, Linux-Computer = B)
  • Auf beiden Maschinen: git config --global core.autocrlf false
  • Auf beiden Maschinen: git config --global core.eol crlf(nur für den Fall)

  • Erstellen Sie ein neues Repository für A. Aus einem leeren Ordner:
    • git init --shared(dann das erstellte .gitVerzeichnis einblenden )
    • Erstellen Sie eine neue Datei .gitignoreim Repository
    • Erstellen Sie eine neue Datei .gitattributesim Repository mit der einzelnen Zeile:* -text
    • git add ., dann um git commit -m "initial commit"zu umgehen, zB dies .
    • git branch master_recv
    • Fernbedienungen hinzufügen
  • Erstellen Sie eine neue Datei document.txtim Repository, die CRLF enthält
  • Commit: git add -Adanngit commit -m "<something>"
  • Beachten Sie, dass A document.txtnoch CRLF enthält (und wenn Sie es löschen und mit zurücksetzen, wird --harddie Version mit CRLF zurückgegeben)

  • SCP das gesamte Verzeichnis auf Computer B.
  • Fügen Sie eine neue Datei new filemit CRLF hinzu
  • Commit: git add -Adanngit commit -m "<something>"
  • Beachten Sie, dass sowohl B document.txtals auch B new fileweiterhin CRLF enthalten

  • Ziehe B's Master zu A: git pull <remote> master:master_recv
  • A's document.txthat sich in LF geändert. Die hinzugefügte Datei new fileenthält auch LF.

Das Problem tritt nicht auf, wenn B ein Windows-Computer ist.

imallett
quelle
War schon core.autocrlf immer falsch? Klingt es so, als hätten Sie bereits \nZeilenenden in Ihrem Repository? Es gibt keine Einstellung, die \nin Ihrem Repository \r\nin Ihrem Arbeitsverzeichnis geändert werden kann .
Edward Thomson
Es wurde nicht immer festgelegt (z. B. als das Repo ursprünglich erstellt wurde). Es sollten jedoch noch keine CR-Zeilenenden im Repo vorhanden sein. Auch hier möchte ich nicht, dass irgendwelche Änderungen vorgenommen werden.
Imallett
Ich frage, weil Ihr Setup Ihre Zeilenenden als CRLF beibehalten sollte . Könnten Sie eine Datei mit ihrer Objekt-ID nur für meine (zugegebenermaßen wahrscheinlich ärgerliche) Bearbeitung in Ihrem Repository veröffentlichen ?
Edward Thomson
@ EdwardThomson wie meinst du das? Das Repo ist nicht öffentlich (da der Linux-Computer nicht öffentlich ist). Ich gehe davon aus, dass Sie eine Beispieldatei möchten. Siehe Bearbeiten.
Imallett
Ja, ich stimme zu, dass diese Datei CRLF-Zeilenenden hat. Können Sie eines klarstellen: Sie haben erwähnt, dass sich die Zeilenumbrüche der Windows-Maschine in CR ändern! Sicher war das ein Tippfehler, oder bekommen Sie wirklich Wagenrücklauf-Endungen im Mac OS 9-Stil?
Edward Thomson

Antworten:

74

In Ihrem Projekt sollte sich eine .gitattributesDatei befinden. Meistens sollte es wie folgt aussehen (oder dieser Screenshot ):

# Handle line endings automatically for files detected as text 
# and leave all files detected as binary untouched.
* text=auto

# Never modify line endings of our bash scripts
*.sh -crlf

#
# The above will handle all files NOT found below
#
# These files are text and should be normalized (Convert crlf => lf)
*.css           text
*.html          text
*.java          text
*.js            text
*.json          text
*.properties    text
*.txt           text
*.xml           text

# These files are binary and should be left untouched
# (binary is macro for -text -diff)
*.class         binary
*.jar           binary
*.gif           binary
*.jpg           binary
*.png           binary

Wechseln Sie * text=autozu * text=false, um die automatische Behandlung zu deaktivieren (siehe Screenshot ).

So was:

Geben Sie hier die Bildbeschreibung ein

Wenn Ihr Projekt keine .gitattributes-Datei hat, werden die Zeilenenden durch Ihre Git-Konfigurationen festgelegt. Gehen Sie folgendermaßen vor, um Ihre Git-Konfigurationen zu ändern:

Gehen Sie zur Konfigurationsdatei in diesem Verzeichnis:

1) C: \ ProgramData \ Git \ config

2) Öffnen Sie die Konfigurationsdatei in Notepad ++ (oder einem beliebigen Texteditor).

3) Ändern Sie "autocrlf =" in false.

Geben Sie hier die Bildbeschreibung ein

Gen
quelle
31
Warum Bilder anstelle von Code-Tags verwenden? Sehr unpraktisch
Clint
31
Weil ich dem Bild ein großes rotes Kästchen hinzufügen kann, um Dinge hervorzuheben.
Gene
21
Mit * text=falsewird der Text nicht deaktiviert: Der Text wird auf den Zeichenfolgenwert false gesetzt. Dies hat den gleichen Effekt, als würde Text nicht spezifiziert (nicht speziell nicht gesetzt). Die Verwendung * -textgibt ihm die spezielle Einstellung "Nicht gesetzt". Wenn Sie das Textattribut in einem Pfad deaktivieren, wird git angewiesen, beim Ein- oder Auschecken keine Zeilenende-Konvertierung zu versuchen.
JustAMartin
Vielen Dank an @Gene für diese Antwort. Das hat mich den ganzen Tag verrückt gemacht und dieses hat es für mich gelöst!
LeopardSkinPillBoxHat
7
Es tut mir leid zu sagen, dass ich mich für diese Antwort nicht bedanken kann. Es hat mich einen halben Tag gekostet, herauszufinden, dass jemand den irreführenden Rat befolgt hat. Wie @JustAMartin hervorhob, * text=falsehat dies keine Wirkung. Bitte korrigieren Sie die Antwort!
Paul B.
47

Eine einfache Lösung ist:

  • Stellen Sie sicher, dass core.autocrlf für alle Repos auf false gesetzt ist :
    git config --global core.autocrlf false
  • Klonen Sie Ihr Repo erneut und überprüfen Sie, ob keine EOL-Konvertierung durchgeführt wurde.
  • oder, seit Git 2.16 (Q1 2018) , behalten Sie Ihr aktuelles Repo und machen Sie agit add --renormalize .

Wenn Konvertierungen automatisch durchgeführt werden, bedeutet dies, dass im Repo eine .gitattributes core.eolDirektive vorhanden ist.

Überprüfen Sie mit Git 2.8+ (März 2016) , ob es noch eine EOL-Transformation gibt mit:

git ls-files --eol
VonC
quelle
2
NUR autocrlfHEUTE NICHT VERWENDEN ! nicht gesetzt autocrlfist gleichbedeutend mit false. Sie blieben hinter den trendigen Bewegungen in Git
Lazy Badger
1
Wie oben hatte ich dies versucht (obwohl nicht mit der globalen Flagge), und es funktionierte nicht. Git-Version ist 1.8.5.2.
Imallett
@ IanMallett "An diesem Punkt scheint es, dass der Linux-Computer noch CRLF hat": Es wird, bis Sie seinen Inhalt wieder normalisieren oder ihn klonen (wie Sie es unter Windows getan haben)
VonC
11

Ich habe es herausgefunden. Es scheint, dass das SCP-Programm die Zeilenenden konvertiert hat. Ich bemerkte dies, als ich versuchte, absichtlich eine Datei mit LF-Endungen zu erstellen und dann feststellte, dass sie beim Herunterladen als CRLF angezeigt wurde.

Da dies die Lösung für mich war, akzeptiere ich diese Antwort, aber die Menschen der Zukunft sollten sich für eine allgemeinere Lösung auch auf die anderen Antworten beziehen.

imallett
quelle
1
Guter Fang, genauer als meine Antwort. +1
VonC
4

Aus dem Thema "Effekte" der gitattributes (5) Handbuchseite

text

Dieses Attribut aktiviert und steuert die Normalisierung am Zeilenende. Wenn eine Textdatei normalisiert wird, werden ihre Zeilenenden im Repository in LF konvertiert. Verwenden Sie das eolAttribut für eine einzelne Datei und die core.eol Konfigurationsvariable für alle Textdateien , um zu steuern, welcher Zeilenendestil im Arbeitsverzeichnis verwendet wird .

Set

Durch Festlegen des Textattributs für einen Pfad wird die Normalisierung am Zeilenende aktiviert und der Pfad als Textdatei markiert. Die Konvertierung am Zeilenende erfolgt ohne Erraten des Inhaltstyps.

Unset Wenn Sie das Textattribut für einen Pfad deaktivieren, wird Git angewiesen, beim Ein- oder Auschecken keine Zeilenende-Konvertierung zu versuchen.

core.autocrlfin neuem (1.7.2+) Git nicht verwendet, core.eolund korrekte Einstellung | Deaktivierung des Textattributs wird als zuverlässiger angesehen

Fauler Dachs
quelle
In der .gitattributesDatei hatte ich allerdings explizit alles als Text deaktiviert, oder? Außerdem sehe ich es nicht mit der Option, dass es keine Konvertierung durchführt (obwohl dies crlfmöglicherweise keine Auswirkungen hat).
Imallett
6
Wichtige Sache, die oft verwirrt wird - textum die Konvertierung aufzuheben und zu verhindern, sollten Sie .gitattributes auf * -text und nicht auf setzen * text=false. falseist kein gültiger Wert für textattribute - git erkennt ihn nicht und greift stattdessen auf die Standardeinstellung für autocrlf zurück. Nachdem textSie den Wert geändert haben, müssen Sie alle Dateien von Ihrem lokalen Repo sichern, ein Commit durchführen, dann die Dateien mit dem richtigen Zeilenende nach Bedarf wiederherstellen und sie wieder festschreiben. Dann wird Ihr Zeilenende nie wieder von git geändert.
JustAMartin