Git unter Windows: Was bedeuten die crlf-Einstellungen?

73

Ich verstehe die Komplexität der CrLf-Einstellungen in git nicht : core.autocrlf,core.safecrlf

Ich entwickle ein plattformübergreifendes Projekt in einem Team und möchte, dass sowohl Windows- als auch Linux-Entwickler zusammenarbeiten können, ohne dass Git-Markierungsdateien nur aufgrund des Zeilenendstils als geändert markiert werden.

Was bedeuten die verschiedenen Einstellungen? Welche Konsequenzen hätte die Auswahl einer der Optionen? Und was wäre die beste Lösung für meinen Fall?

Ja, ich bin mir dieser Frage bewusst und die Antworten dort waren nicht aufschlussreich und daher nicht hilfreich.

Jonathan
quelle
Beispiel für eine autocrlf-Nebenwirkung: stackoverflow.com/questions/2016404/…
VonC
Nur damit Sie sich wohler fühlen: Niemand tut es voll und ganz :)
eckes

Antworten:

97

Die drei Werte für autocrlf:

  • true- Wenn Inhalt in das Repository gelangt (festgeschrieben wird), werden seine Zeilenenden in LF konvertiert, und wenn Inhalt aus dem Repository kommt (ausgecheckt wird), werden die Zeilenenden in CRLF konvertiert. Dies ist im Allgemeinen für ahnungslose Windows-Benutzer / Editoren gedacht. Unter der Annahme, dass ein Editor (oder Benutzer) Dateien mit CRLF-Endungen erstellen wird und ausflippt, wenn normale LF-Endungen angezeigt werden, Sie jedoch LF-Endungen im Repo möchten, wird dies Sie hoffentlich abdecken. Es ist jedoch möglich, dass etwas schief geht. In den verknüpften Fragen finden Sie Beispiele für falsche Zusammenführungskonflikte und Berichte über geänderte Dateien.

  • input- Wenn Inhalte in das Repository gelangen, werden ihre Zeilenenden in LF konvertiert, aber der Inhalt bleibt auf dem Weg nach draußen unberührt. Dies liegt im Wesentlichen im selben Bereich wie trueunter der Annahme, dass die Editoren tatsächlich korrekt mit LF-Endungen umgehen können. Sie schützen sich nur vor der Möglichkeit, versehentlich eine Datei mit CRLF-Endungen zu erstellen.

  • false- git befasst sich überhaupt nicht mit Zeilenenden. Es liegt an dir. Dies ist, was viele Leute empfehlen. Wenn mit dieser Einstellung die Zeilenenden einer Datei durcheinander gebracht werden sollen, müssen Sie sich dessen bewusst sein, sodass Zusammenführungskonflikte viel weniger wahrscheinlich sind (vorausgesetzt, informierte Benutzer). Die Schulung von Entwicklern in der Verwendung ihrer Editoren / IDEs kann das Problem so gut wie lösen. Alle Editoren, die ich für Programmierer gesehen habe, sind in der Lage, damit umzugehen, wenn sie richtig konfiguriert sind.

Beachten Sie, dass dies autocrlfkeine Auswirkungen auf Inhalte hat, die sich bereits im Repository befinden. Wenn Sie zuvor etwas mit CRLF-Endungen festgelegt haben, bleiben diese so. Dies ist ein sehr guter Grund, um abhängig von autocrlf zu vermeiden; Wenn ein Benutzer es nicht eingestellt hat, kann er Inhalte mit CRLF-Endungen in das Repo aufnehmen, und es bleibt bestehen. Eine stärkere Möglichkeit, die Normalisierung zu erzwingen, ist das Textattribut . Wenn Sie es autofür einen bestimmten Pfad auf setzen, wird es für die Normalisierung am Zeilenende markiert, vorausgesetzt, git entscheidet, dass der Inhalt Text ist (nicht binär).

Eine verwandte Option ist safecrlf, die im Grunde nur eine Möglichkeit ist, um sicherzustellen, dass Sie keine CRLF-Konvertierung für eine Binärdatei irreversibel durchführen.

Ich habe nicht viel Erfahrung im Umgang mit Windows-Problemen und Git, daher ist Feedback zu Implikationen / Fallstricken auf jeden Fall willkommen.

Cascabel
quelle
Vielen Dank für eine klare und detaillierte Antwort! Ein paar Fragen: 1) Ist Text attr Teil des Repos? Wenn ein neuer Programmierer es klonen würde, würde er das attr damit erhalten? 2) Was wäre eine Motivation, sich der Newline-Stile bewusst zu werden? 3) Unter der Annahme, dass es keine gibt, sollte ich nach Ihren Erklärungen a) autocrlf = true setzen b) Text attr = auto auf den Stammpfad des Repos setzen und c) safecrlf = ?? 4) Wenn ich autocrlf = input setze und die Datei mit einer IDE "berühre", die nicht gut konfiguriert ist (wahrscheinlich LFs in CRLFs ändern), wird git diese Datei als modifid sehen?
Jonathan
1
@ Jonathan: (1) Schauen Sie sich die Manpage zu den verknüpften Gitattributen an. Attribute werden in Gitattributes-Dateien konfiguriert, die wie jede andere Datei verfolgt werden können. (2) Die Konfiguration Ihrer IDE zur Erzeugung der richtigen Ausgabe ist eine einmalige Sache und absolut notwendig - was ist mit konsistenter Einrückung, Abstand und Formatierung? Bewusst sein bedeutet keine Überraschungen. (3a, b) Wenn Sie das Textattribut für alles auf auto setzen, sollte die Einstellung autocrlf ohnehin unnötig werden, es sei denn, jemand hat es geschafft, einen Editor (Editor?) Auszuwählen, der LFs einfach nicht verarbeiten kann. Es ist ein sicherer Weg, dies zu tun.
Cascabel
@Jonathan: (3c) Das Aktivieren von safecrlf ist wahrscheinlich eine gute Idee in jedem Repo mit verfolgten Binärdateien und einer Art Konvertierung am Zeilenende. (4) Ich denke , in diesem Fall sollten Sie keine Änderungen sehen - aber ich habe viele Leute gesehen, die falsche Angaben zu geänderten Dateien erwähnt haben.
Cascabel
Wenn ich Ihren Links zu SA folge, lese ich immer wieder Leute, die vorschlagen, autocrlf = false zu behalten. Nach Ihrer ursprünglichen Antwort neigen Sie auch dazu, autocrlf = false zu verwenden. Ich schätze, ich muss meine IDE konfigurieren + verstehen, wie WTF läuft + alle meine aktuellen Dateien mit einem Tool, das ich online finde, in LF konvertieren ...
Jonathan
@ Jonathan: Online? Das dos2unix(wie fromdosin einigen Systemen verpackt , denke ich) ist der Standardweg, um dies zu tun. Und ja, ich würde wirklich empfehlen, autocrlf nicht zu verwenden. Wenn Sie versuchen möchten, Zeilenenden zu normalisieren, ist das Text-Gitattribut ein viel saubererer Weg, und ich glaube, es wurde in den letzten Versionen von Git verbessert.
Cascabel
11

Ich habe 3 mögliche Werte für Commit- und Checkout-Fälle untersucht und dies ist die resultierende Tabelle:

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║     false    ║     input    ║     true     ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║   git commit  ║ LF => LF     ║ LF => LF     ║ LF => LF     ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => LF   ║ CRLF => LF   ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║  git checkout ║ LF => LF     ║ LF => LF     ║ LF => CRLF   ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝

Ich würde empfehlen, core.autocrlf = inputplattformübergreifend zu verwenden. In diesem Fall wird Git CRLFimplizit konvertiert LF, und vorhandene Dateien LFbleiben unverändert.

pratt
quelle
1
Haben Sie diese Experimente auf einer Windows- oder einer Unix-Box durchgeführt?
Edward Falk
1
@EdwardFalk, das core.autocrlfVerhalten hängt nicht vom Betriebssystemtyp ab. Aber wenn ich mich nicht irre, ist der Standardwert unter Windows trueund unter Linux - input. Eine weitere Sache, die Probleme verursachen kann, ist, dass die meisten IDEs unter Windows so konfiguriert sind, dass sie standardmäßig CRLF für neue Dateien und unter Linux - LF verwenden.
Pratt
Ich denke, Sie haben die Dinge für inputund umgestellt true. Die Tabelle von Srikanth Popuri unten sieht für mich richtig aus.
Gandalf Saxe
@GandalfSaxe sieht so aus, als hättest du recht. Lassen Sie mich es reparieren
Pratt
4

Zu Ihrer Information: Standardmäßig akzeptiert die in Windows endende Zeile CRLF und Linux LF. Die folgende Tabelle dient zum besseren Verständnis.

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║    false     ║    input     ║    true      ║
║               ║ Win => Unix  ║ Win => Unix  ║ Win => Unix  ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║   git commit  ║ LF => LF     ║ LF => LF     ║ LF => LF     ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ *CRLF => LF  ║ *CRLF => LF  ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║  git checkout ║ LF => LF     ║ LF => LF     ║ *LF => CRLF  ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝

In den obigen tabellarischen Informationen hebt das Symbol * die Unterschiede zwischen Windows und Unix hervor. Im Folgenden finden Sie auf einen Blick die CLRF-Informationen, die auf den Betriebssystemplattformen basieren:


Für Windows-Benutzer

  • Wenn Windows-Benutzer mit plattformübergreifenden Projekten arbeiten, MUSS dies core.autocrlf=truefür Windows-Computer und core.autocrlf=inputfür Unix-Computer gelten.
  • Wenn Windows-Benutzer nur mit Windows-Projekten arbeiten, kann dies beides core.autocrlf=trueoder sein core.autocrlf=false. Dies core.autocrlf=inputführt jedoch in diesem Fall zu Problemen.

Für Unix-Benutzer (Linux / Mac OS)

  • Wenn Unix-Benutzer mit plattformübergreifenden Projekten arbeiten, MUSS dies core.autocrlf=truefür Windows-Computer und core.autocrlf=inputfür Unix-Computer gelten.
  • Wenn Unix-Benutzer nur mit Unix-Projekten arbeiten, kann dies beides core.autocrlf=inputoder sein core.autocrlf=false. Dies core.autocrlf=trueführt jedoch in diesem Fall zu Problemen.

Für dieselben Betriebssystembenutzer

  • Für ein reines Windows-Projekt oder ein reines Unix-Projekt kann dies der Fall sein core.autocrlf=false.
Srikanth Popuri
quelle