277 votes

Comment les conversions de fin de ligne fonctionnent avec git core.autocrlf entre différents systèmes d'exploitation

J'ai lu beaucoup de questions et de réponses différentes sur Stack Overflow ainsi que sur git la documentation sur la façon dont le core.autocrlf les travaux d'aménagement.

C'est ce que je comprends d'après ce que j'ai lu :

Les clients Unix et Mac OSX (les clients pré-OSX utilisent CR) utilisent des fins de ligne LF.
Les clients Windows utilisent des fins de ligne CRLF.

Lorsque core.autocrlf est défini à true sur le client, le dépôt git stocke toujours les fichiers au format de terminaison de ligne LF et les terminaisons de ligne dans les fichiers sur le client sont converties dans les deux sens lors du check out / commit pour les clients (c'est-à-dire Windows) qui utilisent des terminaisons de ligne non-LF, quel que soit le format des fichiers de terminaisons de ligne sur le client (ceci est en désaccord avec la définition de Tim Clem - voir la mise à jour ci-dessous).

Voici une matrice qui tente de documenter la même chose pour les paramètres 'input' et 'false' de core.autocrlf avec des points d'interrogation lorsque je ne suis pas sûr du comportement de conversion des fins de lignes.

Mes questions sont les suivantes :

  1. Que doivent être les points d'interrogation ?
  2. Cette matrice est-elle correcte pour les "points de non-question" ?

Je mettrai à jour les points d'interrogation des réponses au fur et à mesure qu'un consensus semble se former.

                       core.autocrlf value
            true            input              false
----------------------------------------------------------
commit   |  convert           ?                  ?
new      |  to LF      (convert to LF?)   (no conversion?)

commit   |  convert to        ?                 no 
existing |  LF         (convert to LF?)     conversion

checkout |  convert to        ?                 no
existing |  CRLF       (no conversion?)     conversion

Je ne cherche pas vraiment à obtenir des avis sur les avantages et les inconvénients des différents réglages. Je cherche simplement des données qui permettent de comprendre comment git doit fonctionner avec chacun de ces trois paramètres.

--

Mise à jour du 17 avril 2012 : Après avoir lu l'article de Tim Clem lié par JJD dans les commentaires, j'ai modifié certaines des valeurs dans les valeurs "inconnues" dans le tableau ci-dessus, ainsi que le changement de "checkout existing | true" pour convertir en CRLF au lieu de convertir en client". Voici les définitions qu'il donne, qui sont plus claires que tout ce que j'ai vu ailleurs :

core.autocrlf = false

Il s'agit de la valeur par défaut, mais la plupart des gens sont encouragés à la modifier. immédiatement. Le résultat de l'utilisation de false est que Git ne s'embarrasse jamais avec les fins de ligne de votre fichier. Vous pouvez archiver des fichiers avec LF ou CRLF ou CR ou un mélange aléatoire de ces trois éléments et Git ne s'en soucie pas. Ce Cela peut rendre les diffs plus difficiles à lire et les merges plus difficiles. La plupart des personnes La plupart des personnes travaillant dans le monde Unix/Linux utilisent cette valeur parce qu'elles problèmes de CRLF et n'ont pas besoin que Git fasse du travail supplémentaire à chaque fois que des fichiers sont écrits dans la base de données des objets ou dans le répertoire de travail.

core.autocrlf = true

Cela signifie que Git traitera tous les fichiers textes et s'assurera que les CRLF est remplacé par LF lors de l'écriture de ce fichier dans la base de données objet et transformera tous les LF en CRLF lors de l'écriture dans le répertoire de travail de travail. C'est la configuration recommandée sous Windows car elle garantit que votre référentiel peut être utilisé sur d'autres plates-formes tout en tout en conservant CRLF dans votre répertoire de travail.

core.autocrlf = entrée

Cela signifie que Git traitera tous les fichiers texte et s'assurera que les fichiers CRLF soit remplacé par LF lors de l'écriture de ce fichier dans la base de données d'objets. En revanche, il ne fera pas l'inverse. Lorsque vous lisez des fichiers de la base de données des objets et que vous les écrivez dans le répertoire de travail ils auront toujours des LF pour indiquer la fin de la ligne. Ceci Ce paramètre est généralement utilisé sur Unix/Linux/OS X pour empêcher les CRLFs d'être d'être écrits dans le référentiel. L'idée étant que si vous collez code depuis un navigateur web et que vous avez accidentellement mis des CRLFs dans un de vos fichiers, Git s'assurerait qu'ils soient remplacés par des LF lorsque vous écrivez dans la base de données objet.

L'article de Tim est excellent, la seule chose qui me semble manquer est qu'il suppose que le référentiel est au format LF, ce qui n'est pas forcément vrai, surtout pour les projets uniquement Windows.

En comparant l'article de Tim à celui qui a été le plus voté réponse à ce jour par jmlane montre un accord parfait sur les paramètres vrai et entrée et un désaccord sur le paramètre faux.

10 votes

En gardant autocrlf à faux semble tellement plus facile ;) stackoverflow.com/questions/2333424/

0 votes

@VonC : J'ai lu ça et je pense le comprendre, mais je n'ai pas forcément le choix. Je travaille avec des dépôts git que je ne contrôle pas et qui exigent que je définisse la valeur d'une certaine manière.

0 votes

@Michael : et, selon la version du serveur Git, les règles concernant eol et autocrlf sont sur le point de changer dans la prochaine version 1.7.2 ! Voir article.gmane.org/gmane.linux.kernel/1007412

154voto

jmlane Points 639

La meilleure explication de la façon dont core.autocrlf se trouve sur le site gitattributs dans la page de manuel text section attributaire .

C'est ainsi que core.autocrlf semble fonctionner actuellement (ou du moins depuis la v1.7.2 pour autant que je sache) :

  • core.autocrlf = true
  1. Les fichiers texte extraits du référentiel qui ont seulement LF Les caractères sont normalisés en CRLF dans votre arbre de travail ; les fichiers qui contiennent CRLF dans le référentiel ne seront pas touchés
  2. Les fichiers texte qui ont seulement LF dans le référentiel, sont normalisés à partir de CRLF a LF lorsqu'il est remis dans le référentiel. Les fichiers qui contiennent CRLF dans le référentiel seront livrés intacts.
  • core.autocrlf = input
  1. Les fichiers texte extraits du dépôt conserveront les caractères EOL originaux dans votre arbre de travail.
  2. Fichiers texte dans votre arbre de travail avec CRLF Les caractères sont normalisés en LF lorsqu'il est remis dans le référentiel.
  • core.autocrlf = false
  1. core.eol impose les caractères EOL dans les fichiers texte de votre arbre de travail.
  2. core.eol = native par défaut, ce qui signifie que les EOL des arbres de travail dépendront de l'endroit où git est exécuté : CRLF sur une machine Windows, ou LF dans *nix.
  3. Référentiel gitattributes détermine la normalisation des caractères EOL pour les commits dans le référentiel (par défaut, la normalisation se fait en fonction des caractères EOL). LF caractères).

Je n'ai fait que récemment des recherches sur cette question et je trouve également que la situation est très compliquée. Le site core.eol a définitivement aidé à clarifier la façon dont les caractères EOL sont traités par git.

3 votes

Pour autocrlf=true ne devrait-il pas être le suivant ? Les fichiers texte qui ont seulement des caractères CRLF EOL dans le référentiel, sont normalisés de CRLF à LF quand ils sont livrés au référentiel. Les fichiers qui contiennent LF dans le référentiel seront livrés sans être modifiés.

4 votes

Pour moi, même si autocrlf=false, git convertissait l'EOL en CRLF. Après avoir lu cette réponse, j'ai réalisé que mon fichier .gitattribute contenait text=auto, ce qui causait le problème.

1 votes

For core.autocrlf = false si je n'ai pas de gitattributes file signifie-t-il qu'il n'y aura pas de normalisation ? Ou cela signifie-t-il qu'il utilisera la normalisation par défaut ?

80voto

Adi Shavit Points 4470

La question de la fin de vie dans les projets de plates-formes mixtes me rend la vie misérable depuis longtemps. Les problèmes surviennent généralement lorsqu'il existe déjà des fichiers avec des dates d'expiration différentes et mélangées. déjà dans le repo. Cela signifie que :

  1. Le dépôt peut contenir différents fichiers avec des dates d'expiration différentes.
  2. Certains fichiers dans le repo peuvent avoir des EOL mixtes, par exemple une combinaison de CRLF y LF dans le même fichier.

La question n'est pas de savoir comment cela se produit, mais cela se produit.

J'ai effectué quelques tests de conversion sous Windows pour les différents modes et leurs combinaisons.
Voici ce que j'ai obtenu, dans un tableau légèrement modifié :

                 | Resulting conversion when       | Resulting conversion when 
                 | committing files with various   | checking out FROM repo - 
                 | EOLs INTO repo and              | with mixed files in it and
                 |  core.autocrlf value:           | core.autocrlf value:           
--------------------------------------------------------------------------------
File             | true       | input      | false | true       | input | false
--------------------------------------------------------------------------------
Windows-CRLF     | CRLF -> LF | CRLF -> LF | as-is | as-is      | as-is | as-is
Unix -LF         | as-is      | as-is      | as-is | LF -> CRLF | as-is | as-is
Mac  -CR         | as-is      | as-is      | as-is | as-is      | as-is | as-is
Mixed-CRLF+LF    | as-is      | as-is      | as-is | as-is      | as-is | as-is
Mixed-CRLF+LF+CR | as-is      | as-is      | as-is | as-is      | as-is | as-is

Comme vous pouvez le voir, il y a 2 cas où la conversion se produit lors du commit (3 colonnes de gauche). Dans le reste des cas, les fichiers sont livrés tels quels.

Lors du passage à la caisse (3 colonnes de droite), il n'y a qu'un seul cas où la conversion se produit :

  1. core.autocrlf es true y
  2. le fichier dans le repo a le LF EOL.

Le plus surprenant pour moi, et je soupçonne que c'est la cause de nombreux problèmes d'EOL, c'est qu'il n'y a pas de configuration dans laquelle des EOL mixtes comme CRLF + LF sont normalisés.

Notez également que les "anciens" Mac EOL de CR ne sont jamais convertis non plus.
Cela signifie que si un script de conversion EOL mal écrit essaie de convertir un fichier à terminaison mixte avec CRLF s+ LF en convertissant simplement LF s à CRLF s, alors il laissera le fichier en mode mixte avec "solitaire". CR s partout où une CRLF a été converti en CRCRLF .
Git ne convertira alors rien, même en true et les ravages de l'EOL continuent. C'est ce qui m'est arrivé, et mes fichiers ont été sérieusement endommagés, car certains éditeurs et compilateurs (par exemple VS2010) n'aiment pas les EOL Mac.

Je suppose que la seule façon de vraiment gérer ces problèmes est de occasionnellement normaliser le repo entier en vérifiant tous les fichiers dans input o false en exécutant une normalisation correcte et en remettant les fichiers modifiés (le cas échéant). Sous Windows, on peut reprendre le travail avec core.autocrlf true .

6 votes

Excellente réponse, mais il y a une phrase avec laquelle je ne peux pas être d'accord. Sous Windows, reprendre vraisemblablement le travail avec core.autocrlf true . Je crois personnellement que input devrait toujours être utilisé.

72voto

pratt Points 181

core.autocrlf La valeur ne dépend pas du type de système d'exploitation, mais sous Windows, la valeur par défaut est la suivante true et pour Linux - input . J'ai exploré 3 valeurs possibles pour les cas de commit et checkout et voici le tableau résultant :

 core.autocrlf      false         input         true     

                LF   => LF    LF   => LF    LF   => LF   
 git commit     CR   => CR    CR   => CR    CR   => CR   
                CRLF => CRLF  CRLF => LF    CRLF => LF   

                LF   => LF    LF   => LF    LF   => CRLF 
 git checkout   CR   => CR    CR   => CR    CR   => CR   
                CRLF => CRLF  CRLF => CRLF  CRLF => CRLF

13 votes

Résumé en quelques mots : Fichiers avec CR seuls ne sont jamais touchés. false ne touche jamais les fins de ligne. true s'engage toujours en tant que LF et se vérifie comme CRLF . Et input s'engage toujours en tant que LF et est vérifié en l'état.

41voto

VonC Points 414372

Les choses sont sur le point de changer sur le front de la "conversion eol", avec l'entrée en vigueur de l'accord sur le commerce électronique. prochainement Git 1.7.2 :

Un nouveau paramètre de configuration core.eol est en cours d'ajout/évolution :

Il s'agit d'un remplacement de la fonction "Ajouter ". core.eol Le commit "variable de configuration" qui est actuellement en pu (le dernier de ma série).
Au lieu de laisser entendre que " core.autocrlf=true "est un remplacement de " * text=auto ", elle rend explicite le fait que autocrlf est uniquement destiné aux utilisateurs qui veulent travailler avec CRLFs dans leur répertoire de travail sur un référentiel qui n'a pas de normalisation des fichiers normalisation des fichiers texte .
Lorsqu'il est activé, "core.eol" est ignoré.

Introduire une nouvelle variable de configuration, " core.eol ", qui permet à l'utilisateur de définir les fins de ligne à utiliser pour les fichiers normalisés en fin de ligne dans le répertoire de travail.
La valeur par défaut est " native ", ce qui signifie CRLF sous Windows et LF partout ailleurs. Notez que " core.autocrlf " a priorité sur core.eol .
Cela signifie que :

[core]
  autocrlf = true

met des CRLFs dans le répertoire de travail même si core.eol est réglé sur " lf ".

core.eol:

Définit le type de fin de ligne à utiliser dans le répertoire de travail pour les fichiers qui ont l'attribut text la propriété fixée.
Les alternatives sont 'lf', 'crlf' et 'native', qui utilise la terminaison de ligne native de la plateforme.
La valeur par défaut est native .


Autres évolutions sont en cours d'examen :

Pour 1.8, j'envisagerais de faire core.autocrlf simplement activer la normalisation et laisser la décision de fin de ligne du répertoire de travail à core.eol, mais cela sera casser les installations des gens.


git 2.8 (mars 2016) améliore la manière dont core.autocrlf influence l'eol :

Ver commettre 817a0c7 (23 février 2016), commettre 6e336a5 , commettre df747b8 , commettre df747b8 (10 février 2016), commettre df747b8 , commettre df747b8 (10 février 2016), et commettre 4b4024f , commettre bb211b4 , commettre 92cce13 , commit 320d39c , commettre 4b4024f , commettre bb211b4 , commettre 92cce13 , commit 320d39c (05 Fév 2016) par Torsten Bögershausen ( tboegi ) .
(fusionné par Junio C Hamano -- gitster -- en commettre c6b94eb , 26 février 2016)

convert.c : refactor crlf_action

Refactoriser la détermination et l'utilisation de crlf_action .
Aujourd'hui, alors qu'aucun " crlf L'attribut " " est défini sur un fichier, crlf_action est réglé sur CRLF_GUESS . Utilisez CRLF_UNDEFINED à la place, et recherchez " text " ou " eol " comme auparavant.

Remplacer l'ancien CRLF_GUESS l'usage :

CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF
CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY
CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT

Rendre plus clair, ce qui est quoi, en définissant :

- CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf
                   and core.eol is evaluated and one of CRLF_BINARY,
                   CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected
- CRLF_BINARY    : No processing of line endings.
- CRLF_TEXT      : attribute "text" is set, line endings are processed.
- CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text.
- CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text.
- CRLF_AUTO      : attribute "auto" is set.
- CRLF_AUTO_INPUT: core.autocrlf=input (no attributes)
- CRLF_AUTO_CRLF : core.autocrlf=true  (no attributes)

Comme torek ajoute dans les commentaires :

toutes ces traductions (toute conversion EOL de eol= o autocrlf et " clean filtres ") sont exécutés lorsque les fichiers passent de l'arbre de travail à l'index. c'est-à-dire que pendant git add plutôt qu'à git commit temps.
(Notez que git commit -a o --only o --include ajouter des fichiers à l'index à ce moment-là, cependant).

Pour en savoir plus, voir " Quelle est la différence entre autocrlf et eol ? ".

24 votes

Malheureusement, cela n'apporte pas de clarté pour moi. Il semble qu'ils disent qu'il y a des problèmes avec l'implémentation actuelle (ces problèmes ne sont pas clairs) et qu'ils augmentent la complexité dans un effort pour résoudre ces problèmes non spécifiés. À mon avis, le paramètre core.autocrlf est déjà excessivement complexe et sous-documenté et cette situation semble empirer. Merci encore pour l'info.

2 votes

Cela ne semble pas être une solution satisfaisante, et semble avoir les mêmes problèmes que core.autocrlf. Ma préférence serait que git ne modifie jamais rien automatiquement, mais qu'il prévienne l'utilisateur qui veut ajouter ou commiter les mauvaises fins de ligne. Il faudrait donc une option en ligne de commande pour permettre à "git add" d'ajouter les "mauvaises" fins de ligne. (git add est probablement le meilleur endroit pour vérifier cela que git commit).

0 votes

Cela obligerait l'utilisateur concerné à modifier les paramètres de son éditeur et réglerait réellement le problème. En revanche, cela permettrait de laisser les "mauvaises" fins de ligne pour les fichiers provenant de tiers ou déjà enregistrés dans le référentiel.

10voto

C.. Points 10739

Voici ce que j'en ai compris jusqu'à présent, au cas où cela aiderait quelqu'un.

core.autocrlf=true y core.safecrlf = true

Vous avez un dépôt où toutes les terminaisons de ligne sont les mêmes mais vous travaillez sur des plateformes différentes. Git s'assurera que vos fins de lignes sont converties en fonction des valeurs par défaut de votre plateforme. Pourquoi cela est-il important ? Disons que vous créez un nouveau fichier. L'éditeur de texte de votre plateforme utilisera ses fins de lignes par défaut. Lorsque vous l'enregistrez, si core.autocrlf n'a pas la valeur true, vous avez introduit une incohérence dans la fin de ligne pour quelqu'un qui utilise une autre fin de ligne par défaut. Je mets toujours safecrlf aussi parce que j'aimerais savoir que l'opération crlf est réversible. Avec ces deux paramètres, git modifie vos fichiers, mais il vérifie que les modifications sont réversibles .

core.autocrlf=false

Vous avez un référentiel qui a déjà des terminaisons de ligne mélangées vérifié et corriger les fins de lignes incorrectes pourrait casser d'autres choses. Il est préférable de ne pas demander à git de convertir les fins de lignes dans ce cas, car cela exacerberait le problème qu'il a été conçu pour résoudre - rendre les diffs plus faciles à lire et les merges moins pénibles. Avec ce paramètre, git ne modifie pas vos fichiers .

core.autocrlf=input

Je ne l'utilise pas parce que sa raison d'être est de couvrir un cas d'utilisation où vous avez créé un fichier qui a des fins de ligne CRLF sur une plate-forme qui a par défaut des fins de ligne LF. Je préfère plutôt faire en sorte que mon éditeur de texte enregistre toujours les nouveaux fichiers avec les fins de ligne par défaut de la plate-forme.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X