Was ist die beste CRLF-Strategie (Wagenrücklauf, Zeilenvorschub) mit Git?


598

Ich habe versucht, Dateien mit CRLF-Endzeilen festzuschreiben, aber es ist fehlgeschlagen.

Ich verbrachte einen ganzen Arbeitstag auf meinem Windows-Computer und probierte verschiedene Strategien aus. Fast wollte ich aufhören, Git zu verwenden, und stattdessen Mercurial ausprobieren .

Bitte teilen Sie nur eine Best Practice pro Antwort.

Antworten:


753

Fast vier Jahre nachdem ich diese Frage gestellt habe, habe ich endlich eine Antwort gefunden, die mich vollkommen zufriedenstellt !

Weitere Informationen finden Sie in github: Hilfe zum Umgang mit Zeilenenden .

Mit Git können Sie die Zeilenende-Eigenschaften für ein Repo direkt mithilfe des Textattributs in der .gitattributesDatei festlegen . Diese Datei wird in das Repo übernommen und überschreibt die core.autocrlfEinstellung, sodass Sie ein konsistentes Verhalten für alle Benutzer unabhängig von ihren Git-Einstellungen sicherstellen können.

Und somit

Dies hat den Vorteil, dass Ihre Konfiguration am Ende der Leitung jetzt mit Ihrem Repository übertragen wird und Sie sich keine Gedanken mehr darüber machen müssen, ob Mitarbeiter über die richtigen globalen Einstellungen verfügen oder nicht.

Hier ist ein Beispiel für eine .gitattributesDatei

# Auto detect text files and perform LF normalization
*        text=auto

*.cs     text diff=csharp
*.java   text diff=java
*.html   text diff=html
*.css    text
*.js     text
*.sql    text

*.csproj text merge=union
*.sln    text merge=union eol=crlf

*.docx   diff=astextplain
*.DOCX   diff=astextplain

# absolute paths are ok, as are globs
/**/postinst* text eol=lf

# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf

Es gibt eine praktische Sammlung gebrauchsfertiger .gitattributes-Dateien für die beliebtesten Programmiersprachen. Es ist nützlich, um Ihnen den Einstieg zu erleichtern.

Sobald Sie Ihre erstellt oder angepasst haben .gitattributes, sollten Sie eine endgültige Normalisierung der Zeilenenden durchführen .

Beachten Sie, dass die GitHub Desktop- App eine .gitattributesDatei vorschlagen und erstellen kann, nachdem Sie das Git-Repo Ihres Projekts in der App geöffnet haben. Klicken Sie dazu auf das Zahnradsymbol (in der oberen rechten Ecke)> Repository-Einstellungen ...> Zeilenenden und Attribute. Sie werden aufgefordert, die empfohlenen .gitattributesDateien hinzuzufügen. Wenn Sie damit einverstanden sind, führt die App auch eine Normalisierung aller Dateien in Ihrem Repository durch.

Schließlich bietet der Artikel Mind the End of Your Line mehr Hintergrundinformationen und erklärt, wie sich Git in diesen Fragen entwickelt hat. Ich halte dies für erforderlich .

Sie haben wahrscheinlich Benutzer in Ihrem Team, die EGit oder JGit verwenden (Tools wie Eclipse und TeamCity verwenden sie), um ihre Änderungen festzuschreiben. Dann haben Sie kein Glück, wie @gatinueta in den Kommentaren dieser Antwort erklärt hat:

Diese Einstellung wird Sie nicht vollständig zufriedenstellen, wenn in Ihrem Team Mitarbeiter mit Egit oder JGit arbeiten, da diese Tools .gitattributes einfach ignorieren und die CRLF-Dateien https://bugs.eclipse.org/bugs/show_bug.cgi einchecken . id = 342372

Ein Trick könnte darin bestehen, dass sie ihre Änderungen auf einem anderen Client festschreiben, z . B. SourceTree . Unser damaliges Team hat dieses Tool für viele Anwendungsfälle Eclipse's EGit vorgezogen.

Wer hat gesagt, dass Software einfach ist? : - /


7
Möchten Sie Windows freigeben .gitattributes?
Colonel Panic

Wie können Sie sehen, was .gitattributesGitHub für Windows für Ihr Projekt vorschlägt? Ich habe GitHub für Windows installiert, die GUI-Version gestartet und konnte keine Option für .gitattributesVorschläge finden.
JLDiaz

4
Diese Einstellung wird Sie nicht vollständig zufriedenstellen, wenn in Ihrem Team Mitarbeiter mit Egit arbeiten, da egit .gitattributes einfach ignoriert und die CRLF-Dateien bugs.eclipse.org/bugs/show_bug.cgi?id=342372
gatinueta

19
Für Windows neige ich normalerweise dazu, die globale Einstellung festzulegen core.autocrlf = false- ich bevorzuge LF überall, aber einige Windows-Tools wie Visual Studio bestehen auf CRLF-Endungen in bestimmten Dateien (und mischen sie sogar in einigen ..). Das Nicht-Munging von Leitungsenden ist die sicherste Option. Wenn Sie wissen, was Sie tun, würde ich wahrscheinlich core.autocrlf = inputAusnahmen für Projekte unter Windows verwenden und machen, von denen Sie wissen, dass sie empfindlich auf Zeilenenden reagieren. Wie andere betonen, unterstützt jetzt jeder anständige Texteditor LF-Endungen. Ich denke tatsächlich, dass core.autocrlf = truees wahrscheinlich mehr Probleme verursachen kann, als es verhindert.
Adrian

1
@gatinueta Genauer gesagt handelt es sich um ein JGit-Problem. Das heißt, TeamCity, das auch JGit verwendet, ignoriert .gitattributes direkt.
sdds

122

Konvertieren Sie keine Zeilenenden. Es ist nicht die Aufgabe des VCS, Daten zu interpretieren - sie nur zu speichern und zu versionieren. Jeder moderne Texteditor kann sowieso beide Arten von Zeilenenden lesen.


25
Abgeordnet. Wenn Sie Probleme mit inkonsistenten Zeilenenden haben, ist es die beste Lösung, jemanden anzuschreien, der die falschen Editoreinstellungen verwendet, bis er sie behebt.

136
Nicht zustimmen. Native Linefeeds auf allen Plattformen sind praktisch.
Jonas Byström

25
Visual Studio ist eine PITA, wenn es um etwas anderes als CRLF geht.
Brett Ryan

32
Git hat die Option, Zeilenenden nicht zu konvertieren. Es ist autocrlf = false. Wenn Sie keine plattformübergreifende Entwicklung durchführen, wie z. B. Mono, sollten Sie es unter Windows auf false setzen und auf true setzen, wenn Sie Open Source entwickeln für Mono.
Chris Nicola

24
Das Problem mit dem Zeilenende ist die Berechnung der korrekten Differenzen. Die Antwort ist also falsch und irreführend.
Cos

84

Sie wollen fast immer, es autocrlf=inputsei denn, Sie wissen wirklich, was Sie tun.

Einige zusätzliche Zusammenhänge unten:

Es sollte entweder sein, core.autocrlf=truewenn Sie DOS-Endung mögen oder core.autocrlf=inputwenn Sie Unix-Newlines bevorzugen. In beiden Fällen verfügt Ihr Git-Repository nur über LF, was das Richtige ist. Das einzige Argument dafür core.autocrlf=falsewar, dass die automatische Heuristik möglicherweise eine Binärdatei als Text falsch erkennt und Ihre Kachel dann beschädigt wird. Daher wurde die core.safecrlfOption eingeführt, einen Benutzer zu warnen, wenn eine irreversible Änderung auftritt. Tatsächlich gibt es zwei Möglichkeiten für irreversible Änderungen: gemischte Zeilenenden in Textdateien. Diese Normalisierung ist wünschenswert, sodass diese Warnung ignoriert werden kann oder (sehr unwahrscheinlich), dass Git Ihre Binärdatei fälschlicherweise als Text erkannt hat. Dann müssen Sie Attribute verwenden, um Git mitzuteilen, dass diese Datei binär ist.

Der obige Absatz wurde ursprünglich aus einem Thread auf gmane.org gezogen, ist aber seitdem gesunken.


31
Warum ist es eine "richtige Sache"?
Artem Tikhomirov

35
core.autocrlf = true ist eine schreckliche Idee. Ich hatte keine Probleme mit dieser Option, und Sie müssen daran denken, sie festzulegen, wenn Sie das Repository klonen.
Luís Oliveira

28
Verwenden Sie NICHT autocrlf = true, es sei denn, Sie wissen, was Sie tun. Wenn Sie unter DOS / Win entwickeln, behält autocrlf = false die Endungen zwischen Remote- und lokalen Repos bei und ist in fast jeder Situation die beste Option.
Chris Nicola

13
@Chris - Was ist, wenn Ihre Entwickler Windows- und Multi-Plattform-Projekte haben, in denen einige der Multi-Plattform-Entwickler unter OSX oder Linux arbeiten? Sollte dann nicht die beste Option autocrlf = true sein?
Brett Ryan

20
Upvoted, mit Vorbehalt. Der einleitende Absatz ist nicht hilfreich. core.autocrlf=inputist die kanonische Antwort. Für die meisten Anwendungsfälle, core.autocrlf=trueund core.autocrlf=falsesind übereifrig (... gegens aber ebenso schreckliche Art und Weise, natürlich) und damit eigen destruktiv. "Git für Windows" sollte eigentlich mit "Checkout as-is, Commit-Zeilenenden im Unix-Stil" (dh core.autocrlf=input) als Standard-Newline-Strategie ausgeliefert werden. Es war nicht so. Also hier, wir hier - im verdammten Jahr 2015 - debattieren immer noch endlos darüber.
Cecil Curry

58

Zwei alternative Strategien, um in gemischten Umgebungen (Microsoft + Linux + Mac) konsistent über Zeilenenden zu werden:

A. Global für alle Repositorys einrichten

1) Konvertieren Sie alle in ein Format

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) Set core.autocrlfan inputauf Linux / UNIX oder trueauf MS Windows (Repository oder global)

git config --global core.autocrlf input

3) [Optional] core.safecrlfauf true(zum Stoppen) oder warn(zum Singen :) setzen, um einen zusätzlichen Schutz hinzuzufügen, der vergleicht, ob die umgekehrte Newline-Transformation zu derselben Datei führen würde

git config --global core.safecrlf true


B. Oder per Repository-Setup

1) Konvertieren Sie alle in ein Format

find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'

2) Fügen Sie .gitattributesIhrem Repository eine Datei hinzu

echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'

Mach dir keine Sorgen um deine Binärdateien - Git sollte klug genug sein.


Weitere Informationen zu safecrlf / autocrlf-Variablen


5
globaler Ansatz == Festlegen und Vergessen für alle Repos vs. pro Repo == erfordert nicht, dass andere ihre globale Konfiguration ändern.
Lukmdo

4
dos2unixist ein Kommandozeilen-Tool, das Sie je nach System möglicherweise zusätzlich installieren müssen
lukmdo

2
Sie sind nicht exklusiv, Sie können beide Ansätze gleichzeitig verwenden. Seien Sie auch bei der Verwendung sehr vorsichtig dos2unix- es besteht die Gefahr einer Beschädigung.git/index und wir müssen es nicht auf jede Datei anwenden. Es ist besser, so etwas wie zu verwenden find ./ -name "*.html"und anzugeben, auf welche Dateien Sie es anwenden möchten.
Cregox

6
ACHTUNG: Bevor die laufenden findLinien beachten Sie : die , dos2unixdie mit Git kommt versendeten für Windows hat einen eigentümlichen (IMO idiotisch und gefährlich) Verhalten, ohne Argumente: Statt auf UNIX zu ändern, es schaltet das Zeilenformat (DOS <-> UNIX )
Leonbloy

2
Und noch eine Warnung: DOS2UNIX nicht Ihren .git-Ordner. Ich sage nur.
hakre

10

Versuchen Sie, die core.autocrlfKonfigurationsoption auf einzustellen true. Schauen Sie sich auch die core.safecrlfOption an.

Eigentlich klingt es so, als ob core.safecrlfes bereits in Ihrem Repository festgelegt ist, weil (Hervorhebung von mir):

Wenn dies bei der aktuellen Einstellung von core.autocrlf nicht der Fall ist, lehnt git die Datei ab .

Wenn dies der Fall ist, möchten Sie möglicherweise überprüfen, ob Ihr Texteditor so konfiguriert ist, dass Zeilenenden konsistent verwendet werden. Sie werden wahrscheinlich auf Probleme stoßen, wenn eine Textdatei eine Mischung aus LF- und CRLF-Zeilenenden enthält.

Schließlich bin ich der Meinung, dass die Empfehlung, einfach "das zu verwenden, was Ihnen gegeben wurde" und LF-terminierte Leitungen unter Windows zu verwenden, mehr Probleme verursacht als löst. Git hat die oben genannten Optionen, um zu versuchen, Zeilenenden auf vernünftige Weise zu behandeln. Daher ist es sinnvoll, sie zu verwenden.


1
Wäre es nicht besser, repositoryweite Einstellungen über die .gitattributes-Datei zu verwenden? Ich habe mich nur gefragt: Es ist unpraktisch, jeden Benutzer zu zwingen, sich um seine Einstellungen für das Zeilenende auf seinem Computer zu kümmern ... Oder gibt es andere Nachteile?
Trainoasis

10

Die Verwendung von core.autocrlf=falsehat verhindert, dass alle Dateien als aktualisiert markiert werden, sobald ich sie in meinem Visual Studio 2010- Projekt ausgecheckt habe. Die beiden anderen Mitglieder des Entwicklungsteams verwenden ebenfalls Windows-Systeme, sodass keine gemischte Umgebung ins Spiel kam. In den Standardeinstellungen des Repositorys wurden jedoch alle Dateien unmittelbar nach dem Klonen als aktualisiert markiert.

Ich denke, das Endergebnis ist zu finden, welche CRLF-Einstellung für Ihre Umgebung funktioniert. Zumal in vielen anderen Repositorys unserer Linux-Boxen die Einstellung autocrlf = truebessere Ergebnisse liefert.

Über 20 Jahre später haben wir es immer noch mit Unterschieden zwischen den Betriebssystemen zu tun ... traurig.


31
@ orange80, die Ungleichheit ist unglücklich, aber es gibt keinen Grund, es als Windows-Schuld zu bezeichnen. LF-only macht vielleicht aus minimalistischer Sicht Sinn; CRLF ist jedoch sinnvoller, je nachdem, was CR und LF bedeuten. "Wagenrücklauf" bedeutet, zum Zeilenanfang zurückzukehren; "Zeilenvorschub" bedeutet, dass Sie direkt zur nächsten Zeile und nicht zum Anfang der nächsten Zeile wechseln. Aus semantischer Sicht ist Windows korrekter, wenn es um beides geht: Zurück zum Anfang (CR) und dann eine Zeile nach unten (LF).
Ryan Lundy

40
@Kyralessa "korrekter", wenn sie immer noch vorgibt, ein Computer sei eine Schreibmaschine, was es übrigens nicht ist. Die Beibehaltung der Schreibmaschinenanalogie macht keinen Sinn, da dies für Endbenutzer niemals der Fall ist und es sinnlos ist, zwei Zeichen anstelle von einem zu verwenden.
Jpswain

1
Einige Jahre zu spät zu dieser Party, aber Sie haben die Tatsache ignoriert, dass CR und LF Cursorpositionierungswerkzeuge sind. "CR" kann zu diesem Zeitpunkt in der Geschichte auch "Cursor Return" sein. Wenn ich wollte, dass der Cursor an den Anfang der Zeile zurückkehrt, würde ich die Anwendung anweisen, dies zu tun. Ansonsten muss es dort bleiben, wo ich es hingelegt habe.
EKW

2
Wenn CRLF "korrekter" ist, weil eine Textdatei-Zeilenumbruch wirklich sowohl ein "eine Zeile nach unten verschieben" als auch "zum Zeilenanfang verschieben" ist, würde nur ein CR den Texteditor veranlassen, eine Zeile mit dem zu überschreiben folgende Zeile. Ich kenne keine Redakteure, die dies tatsächlich unterstützen, was bedeutet, dass die Notwendigkeit, sowohl CRLF als auch CR als unterschiedliche Dinge auszudrücken, nicht wirklich besteht.
avl_sweden

@avl_sweden Es war ein sehr häufiges Verhalten vor DOS, und da Microsoft die Kompatibilität für wichtig hält, ist es seitdem so geblieben. Es war auch der Standardweg in den USA (als pere ASA) - ISO erlaubte sowohl CR + LF als auch LF (also war DOS wieder standardkonform); in beiden Fällen seit den sechziger Jahren. Multics (Unix-Vorläufer) unterstützten CR für Fettdruck / Strike. Heutzutage suchen viele Anwendungen (einschließlich der .NET-Funktionen "Nach Linien teilen") nach einer der drei Anwendungen (Lone CR, Lone LF, CRLF) und behandeln jede von ihnen als Endzeile. Viele Anwendungen sind jedoch immer noch durch gemischte Zeilenenden in einer Datei verwirrt.
Luaan

7

Dies sind die beiden Optionen für Windows- und Visual Studio- Benutzer, die Code für Mac- oder Linux- Benutzer freigeben. Eine ausführliche Erklärung finden Sie im Handbuch zu gitattributes .

* text = auto

Fügen Sie in der .gitattributesDatei Ihres Repos Folgendes hinzu:

*   text=auto

Dadurch werden alle Dateien mit LFZeilenenden im Repo normalisiert .

Abhängig von Ihrem Betriebssystem ( core.eolEinstellung) werden die Dateien im Arbeitsbaum LFfür Unix-basierte Systeme oder CRLFfür Windows-Systeme normalisiert .

Dies ist die Konfiguration, die Microsoft .NET- Repos verwenden.

Beispiel:

Hello\r\nWorld

Wird im Repo immer wie folgt normalisiert:

Hello\nWorld

Beim Auschecken wird der Arbeitsbaum in Windows konvertiert in:

Hello\r\nWorld

Beim Auschecken bleibt der Arbeitsbaum in Mac wie folgt:

Hello\nWorld

Hinweis: Wenn Ihr Repo bereits nicht normalisierte Dateien enthält, git statuswerden diese Dateien beim nächsten Ändern als vollständig geändert angezeigt, und es kann für andere Benutzer schwierig sein, ihre Änderungen später zusammenzuführen. Weitere Informationen finden Sie unter Aktualisieren eines Repositorys nach dem Ändern der Zeilenenden .

core.autocrlf = true

Wenn textin der .gitattributesDatei nichts angegeben ist, verwendet Git die core.autocrlfKonfigurationsvariable, um zu bestimmen, ob die Datei konvertiert werden soll.

Für Windows-Benutzer git config --global core.autocrlf trueist dies eine großartige Option, da:

  • Dateien werden nur dann auf LFZeilenenden normalisiert, wenn sie dem Repo hinzugefügt werden . Wenn das Repo Dateien enthält, die nicht normalisiert sind, werden sie durch diese Einstellung nicht berührt.
  • Alle Textdateien werden CRLFim Arbeitsverzeichnis in Zeilenenden konvertiert .

Das Problem bei diesem Ansatz ist, dass:

  • Wenn Sie Windows verwenden autocrlf = input, wird eine Reihe von Dateien mit LFZeilenenden angezeigt. Keine Gefahr für den Rest des Teams, da Ihre Commits weiterhin mit LFZeilenenden normalisiert werden.
  • Wenn Sie ein Windows-Benutzer mit sind core.autocrlf = false, werden eine Reihe von Dateien mit LFZeilenenden angezeigt, und Sie können Dateien mit CRLFZeilenenden in das Repo einfügen.
  • Die meisten Mac-Benutzer verwenden autocrlf = inputund erhalten möglicherweise Dateien mit CRLFDateiendungen, wahrscheinlich von Windows-Benutzern mit core.autocrlf = false.

1
Ihr Befehl für Windows-Benutzer sagt git config --global core.autocrl true. Du meinst git config --global core.autocrlf true.
JellicleCat

6

--- UPDATE 3 --- (widerspricht nicht UPDATE 2)

In Anbetracht des Falls, dass Windows-Benutzer lieber arbeiten CRLFund Linux / Mac-Benutzer lieber LFan Textdateien arbeiten. Bereitstellung der Antwort aus der Sicht eines Repository-Betreuers :

Für mich ist die beste Strategie (weniger Probleme zu lösen): Behalten Sie alle Textdateien mit LFInside Git Repo bei, auch wenn Sie an einem Windows-Projekt arbeiten. Geben Sie den Kunden dann die Freiheit, an dem von ihnen bevorzugten Zeilenendstil zu arbeiten , vorausgesetzt, sie wählen einen core.autocrlfEigenschaftswert aus, der Ihre Strategie (LF on Repo) berücksichtigt, während sie Dateien für das Festschreiben bereitstellen.

Staging ist das, was viele Leute verwirren, wenn sie versuchen zu verstehen, wie Newline-Strategien funktionieren. Es ist wichtig, die folgenden Punkte zu verstehen, bevor Sie den richtigen Wert für die core.autocrlfImmobilie auswählen :

  • Das Hinzufügen einer Textdatei zum Festschreiben ( Staging ) entspricht dem Kopieren der Datei an eine andere Stelle im .git/Unterverzeichnis mit konvertierten Zeilenenden (abhängig vom core.autocrlfWert in Ihrer Client-Konfiguration). All dies erfolgt vor Ort.
  • Die Einstellung core.autocrlfist wie eine Antwort auf die Frage (genau dieselbe Frage auf allen Betriebssystemen):
    • "Sollte git-client a. LF-zu-CRLF konvertieren, wenn die Repo-Änderungen von der Fernbedienung ausgecheckt (gezogen) werden, oder b. CRLF-zu-LF konvertieren, wenn eine Datei zum Festschreiben hinzugefügt wird? " Und die möglichen Antworten (Werte) sind:
    • false:" mach keines der oben genannten ",
    • input:" mach nur b "
    • true: " mach a und und b "
    • Beachten Sie, dass es KEIN " do only a " gibt.

Glücklicherweise

  • Die Standardeinstellungen des Git-Clients (Windows : core.autocrlf: true, Linux / Mac core.autocrlf: false:) sind mit der LF-Only-Repo- Strategie kompatibel .
    Bedeutung : Windows-Clients werden beim Auschecken des Repositorys standardmäßig in CRLF konvertiert und beim Hinzufügen zum Festschreiben in LF konvertiert. Und Linux-Clients führen standardmäßig keine Konvertierungen durch. Dies hält theoretisch Ihr Repo nur für.

Unglücklicherweise:

  • Möglicherweise gibt es GUI-Clients, die den Git- core.autocrlfWert nicht berücksichtigen
  • Es kann Leute geben, die keinen Wert verwenden, um Ihre lf-repo-Strategie zu respektieren. core.autocrlf=falseZum Beispiel verwenden sie eine Datei mit CRLF und fügen sie zum Festschreiben hinzu.

Um ASAP-Nicht-lf-Textdateien zu erkennen, die von den oben genannten Clients festgeschrieben wurden , können Sie den Anweisungen in --- Update 2 ---: ( git grep -I --files-with-matches --perl-regexp '\r' HEADauf einem Client folgen , der mit: --with-libpcreflag kompiliert wurde ).

Und hier ist der Haken : . Ich als Repo-Betreuer behalte eine, git.autocrlf=inputdamit ich falsch festgeschriebene Dateien reparieren kann, indem ich sie erneut für die Festschreibung hinzufüge. Und ich stelle einen Festschreibungstext bereit: "Korrigieren falsch festgeschriebener Dateien".

Soweit .gitattributesbekannt. Ich zähle nicht darauf, weil es mehr UI-Clients gibt, die es nicht verstehen. Ich verwende es nur, um Hinweise für Text- und Binärdateien bereitzustellen und möglicherweise einige außergewöhnliche Dateien zu kennzeichnen, die überall die gleichen Zeilenenden behalten sollten:

*.java          text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg           -text     # Don't do auto-detection. Treat as binary
*.sh            text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat           text eol=crlf # Treat as text. Checkout and add with eol=crlf

Frage: Aber warum interessieren wir uns überhaupt für die Newline-Handling-Strategie?

Antwort: Um ein Festschreiben eines einzelnen Buchstabens zu vermeiden, wird es als Änderung mit 5000 Zeilen angezeigt, nur weil der Client, der die Änderung durchgeführt hat, die vollständige Datei automatisch von crlf in lf (oder umgekehrt) konvertiert hat, bevor er sie zum Festschreiben hinzufügt. Dies kann sehr schmerzhaft sein, wenn es sich um eine Konfliktlösung handelt . Oder es könnte in einigen Fällen die Ursache für unangemessene Konflikte sein.


--- UPDATE 2 ---

Die Fehler des Git-Clients funktionieren in den meisten Fällen. Selbst wenn Sie nur Windows-Clients, Linux-Clients oder beides haben. Diese sind:

  • windows: core.autocrlf=true bedeutet, dass beim Auschecken Zeilen in CRLF und beim Hinzufügen von Dateien in LF konvertiert werden.
  • Linux: core.autocrlf=input bedeutet, dass beim Auschecken keine Zeilen konvertiert werden müssen (dies ist nicht erforderlich, da erwartet wird, dass Dateien mit LF festgeschrieben werden) und beim Hinzufügen von Dateien keine Zeilen in LF konvertiert werden (falls erforderlich). ( - update3 - : Scheint, dass dies falsestandardmäßig ist, aber es ist wieder in Ordnung)

Die Eigenschaft kann in verschiedenen Bereichen festgelegt werden. Ich würde vorschlagen, den Bereich explizit --globalfestzulegen, um einige am Ende beschriebene IDE-Probleme zu vermeiden.

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

Außerdem würde ich dringend davon abraten , Windows zu verwenden git config --global core.autocrlf false (falls Sie nur Windows-Clients haben), im Gegensatz zu dem, was für die Git-Dokumentation vorgeschlagen wird . Wenn Sie auf false setzen, werden Dateien mit CRLF im Repo festgeschrieben. Aber es gibt wirklich keinen Grund. Sie wissen nie, ob Sie das Projekt für Linux-Benutzer freigeben müssen. Außerdem ist dies ein zusätzlicher Schritt für jeden Client, der dem Projekt beitritt, anstatt Standardeinstellungen zu verwenden.

Nun können Sie für einige Sonderfälle von Dateien (z. B. *.bat *.sh), die mit LF oder CRLF ausgecheckt werden sollen, diese verwenden.gitattributes

Zusammenfassend ist für mich die beste Vorgehensweise :

  • Stellen Sie sicher, dass jede nicht-binäre Datei mit LF auf Git Repo festgeschrieben wird (Standardverhalten).
  • Verwenden Sie diesen Befehl, um sicherzustellen, dass keine Dateien mit CRLF festgeschrieben werden: git grep -I --files-with-matches --perl-regexp '\r' HEAD( Hinweis: Auf Windows-Clients funktioniert dies nur über git-bashund auf Linux-Clients, wenn es mit --with-libpcrein kompiliert wurde. ./configure)
  • Wenn Sie solche Dateien finden, indem Sie den obigen Befehl ausführen, korrigieren Sie sie. Dies beinhaltet (zumindest unter Linux):
    • set core.autocrlf=input( --- Update 3 - )
    • Ändern Sie die Datei
    • Änderung rückgängig machen (Datei wird weiterhin als geändert angezeigt)
    • begehen Sie es
  • Verwenden Sie nur das Nötigste .gitattributes
  • Weisen Sie die Benutzer an, die core.autocrlfoben beschriebenen Werte auf die Standardwerte zu setzen.
  • Zählen Sie nicht 100% auf das Vorhandensein von .gitattributes. Git-Clients von IDEs können sie ignorieren oder unterschiedlich behandeln.

Wie gesagt, einige Dinge können in Git-Attributen hinzugefügt werden:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

Ich denke, einige andere sichere Optionen für .gitattributesanstelle der automatischen Erkennung für Binärdateien:

  • -text(zB für *.zipoder *.jpgDateien: Wird nicht als Text behandelt. Daher werden keine Konvertierungen am Zeilenende versucht. Diff ist möglicherweise durch Konvertierungsprogramme möglich.)
  • text !eol(zB für *.java, *.html: Wird als Text behandelt, aber die Präferenz für den EOL-Stil ist nicht festgelegt. Daher wird die Client-Einstellung verwendet.)
  • -text -diff -merge(zB für *.hugefile: Nicht als Text behandelt. Kein Diff / Merge möglich)

--- VORHERIGES UPDATE ---

Ein schmerzhaftes Beispiel für einen Client, der Dateien falsch festschreibt:

Netbeans 8.2 (Windows), wird fälschlicherweise alle Textdateien mit Commit CRLFs, es sei denn , Sie haben ausdrücklich festgelegt , core.autocrlfwie global . Dies widerspricht dem Standardverhalten des Git-Clients und verursacht später beim Aktualisieren / Zusammenführen viele Probleme. Dies führt dazu, dass einige Dateien auch beim Zurücksetzen anders aussehen (obwohl dies nicht der Fall ist) .
Das gleiche Verhalten in Netbeans tritt auch dann auf, wenn Sie .gitattributesIhrem Projekt korrekt hinzugefügt haben .

Wenn Sie nach einem Commit den folgenden Befehl verwenden, können Sie zumindest frühzeitig erkennen, ob in Ihrem Git-Repo Probleme mit dem Zeilenende auftreten: git grep -I --files-with-matches --perl-regexp '\r' HEAD

Ich habe Stunden damit verbracht, die bestmögliche Nutzung zu finden .gitattributes, um endlich zu erkennen, dass ich mich nicht darauf verlassen kann.
Leider besteht .gitattributesdie sichere Lösung darin, LF überall zu erzwingen, selbst auf Editorebene, solange es JGit-basierte Editoren gibt (die nicht richtig handhaben können).

Verwenden Sie die folgenden anti-CRLFDesinfektionsmittel.


Ich stimme Ihnen zu, dass dies der beste Ansatz ist. Niemand sollte Editoren ohne LF-Unterstützung verwenden. Aber seien Sie vorsichtig mit Ihrer .gitattributesLinie, sie hat unbeabsichtigte Konsequenzen in Git <2.10, siehe stackoverflow.com/a/29508751/2261442
phk

git config --global core.autocrlf falseVerdammt noch mal ... Ich habe unzählige Antworten, die ich befürworte und empfehle, mich nur in .gitattributesRichtlinien mit EOL zu befassen .
VonC

5

Dies ist nur eine Problemumgehungslösung :

Verwenden Sie im Normalfall die Lösungen, die mit git geliefert werden. Diese funktionieren in den meisten Fällen hervorragend. Auf LF erzwingen, wenn Sie die Entwicklung auf Windows- und Unix-basierten Systemen durch Festlegen von .gitattributes freigeben .

In meinem Fall haben> 10 Programmierer ein Projekt unter Windows entwickelt. Dieses Projekt wurde bei CRLF eingecheckt und es gab keine Option, LF zu erzwingen.

Einige Einstellungen wurden intern auf meinem Computer geschrieben, ohne das LF-Format zu beeinflussen. Daher wurden einige Dateien bei jeder kleinen Dateiänderung global in LF geändert.

Meine Lösung:

Windows-Maschinen: Lassen Sie alles so wie es ist. Kümmere dich um nichts, da du ein Standardentwickler von Windows 'Lone Wolf' bist und so vorgehen musst: "Es gibt kein anderes System auf der ganzen Welt, oder?"

Unix-Maschinen

  1. Fügen Sie dem [alias]Abschnitt einer Konfiguration die folgenden Zeilen hinzu . Dieser Befehl listet alle geänderten (dh geänderten / neuen) Dateien auf:

    lc = "!f() { git status --porcelain \
                 | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
                 | cut -c 4- ; }; f "
  2. Konvertieren Sie alle geänderten Dateien in das Dos-Format:

    unix2dos $(git lc)
  3. Optional ...

    1. Erstellen Sie einen Git- Hook für diese Aktion, um diesen Prozess zu automatisieren

    2. Verwenden Sie params und schließen Sie sie ein und ändern Sie die grepFunktion so, dass sie nur bestimmten Dateinamen entspricht, z.

      ... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
    3. Fühlen Sie sich frei, es noch bequemer zu machen, indem Sie eine zusätzliche Verknüpfung verwenden:

      c2dos = "!f() { unix2dos $(git lc) ; }; f "

      ... und feuere das konvertierte Zeug durch Tippen ab

      git c2dos
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.