Comment forcer git à utiliser LF au lieu de CR + LF sous Windows?

335

Je veux forcer git à extraire des fichiers sous Windows en utilisant simplement LFpas CR+LF. J'ai vérifié les deux options de configuration mais je n'ai pas pu trouver la bonne combinaison de paramètres.

Je veux qu'il convertisse tous les fichiers LFet les conserve LF.

Remarque: j'ai utilisé autocrlf = inputmais cela ne fait que réparer les fichiers lorsque vous les validez. Je veux le forcer à les utiliser LF.

Je n'étais probablement pas aussi clair: le référentiel utilise déjà LFmais les fichiers extraits à l'aide de msysgit utilisent CR+LFet je veux forcer msysgit à les obtenir avec LF: forçage des fins de ligne Unix .

>git config --list | grep crlf
core.autocrlf=input
Sorin
la source
2
autocrlf=inputest la bonne option. Bien sûr, il ne vous protège pas des fichiers qui ont réellement cr+lfdans le référentiel ou de la création de fichiers avec cr+lfdans un autre outil avant de les ajouter à git. Quels problèmes rencontrez-vous pour lesquels cela ne fonctionne pas?
CB Bailey
2
Les fichiers du référentiel utilisent déjà uniquement, LFmais lorsque je les obtiens sous Windows, msysgit les convertit CR+LF.
sorin
Il doit y avoir quelque chose avec votre configuration; Je viens de tester cela sur mon installation msysgit. Avec autocrlfdéfini sur input, git laisse les lfsauts de ligne seuls. Pouvez-vous publier la sortie de git config?
CB Bailey
1
Dans ce cas, je vous suggère de consigner un bogue; de préférence en pointant vers un référentiel de test qui présente votre problème et en incluant des étapes pour se reproduire car le comportement que vous voyez est définitivement faux (mais je ne peux pas le reproduire).
CB Bailey
1
Une petite astuce consiste également à vous assurer que vous exécutez les commandes git sur le 'git' que vous pensez être. Par exemple, vous pouvez avoir git installé sur Windows et git installé sur cygwin, alors assurez-vous d'avoir défini la bonne configuration git.
lfred

Réponses:

106

Le PO a ajouté dans sa question:

les fichiers extraits en utilisant msysgit utilisent CR+LFet je veux forcer msysgit pour les obtenir avecLF

Une première étape simple serait toujours dans un .gitattributesfichier:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(comme indiqué dans les commentaires de petit - enfant , se référant à la .gitattributesconversion de fin de ligne ), pour éviter toute CRLFconversion de fichiers avec correct eol.

Et j'ai toujours recommandé git config --global core.autocrlf false de désactiver toute conversion (qui s'appliquerait à tous les fichiers versionnés)

Voir Meilleures pratiques pour la configuration git multiplateforme?

Depuis Git 2.16 (Q1 2018), vous pouvez utiliser git add --renormalize .pour appliquer ces .gitattributesparamètres immédiatement.


Mais une deuxième étape plus puissante implique un pilote de filtre gitattribute et ajoute une étape de maculage

pilote de filtre

Chaque fois que vous mettriez à jour votre arborescence de travail, un script pourrait, uniquement pour les fichiers que vous avez spécifiés dans .gitattributes, forcer la LF eolet toute autre option de formatage que vous souhaitez appliquer.
Si le clearscript " " ne fait rien, vous aurez (après validation) transformé vos fichiers, en appliquant exactement le format que vous souhaitez qu'ils suivent.

VonC
la source
Une question: * .txt se réfère à tous les fichiers avec l'extension .txt ou à tous les fichiers texte (non binaires)? Je ne peux pas faire une liste avec toutes sortes d'extensions de fichiers que j'aurai dans le projet.
sorin
1
@Sorin: tous les fichiers avec .txtextension. Il est préférable d'établir d'abord cela et de le tester sur un groupe spécifique, avant de généraliser à *, et d'ajouter une règle négative !*.xyz ...pour exclure quelques fichiers de cette règle.
VonC
1
À ce stade, les .gitattributeslignes doivent se lire: *.txt text eol=lfselon git-scm.com/docs/gitattributes
petit
@grandchild Merci. J'ai inclus votre commentaire dans la réponse pour plus de visibilité.
VonC
Je suppose qu'après avoir ajouté, .gitattributesnous devons fairegit add --renormalize .
shuva
461

La bonne façon d'obtenir les terminaisons LF dans Windows est d'abord de définir core.autocrlfsur false:

git config --global core.autocrlf false

Vous devez le faire si vous utilisez msysgit, car il le définit truedans ses paramètres système.

Maintenant, git ne fera aucune normalisation de fin de ligne. Si vous souhaitez que les fichiers que vous archivez soient normalisés, procédez comme suit: Définissez text=autovotre .gitattributespour tous les fichiers:

* text=auto

Et réglé core.eolsur lf:

git config --global core.eol lf

Maintenant, vous pouvez également basculer un seul référentiel vers crlf (dans le répertoire de travail!) En exécutant

git config core.eol crlf

Une fois la configuration terminée, vous souhaiterez peut-être que git normalise tous les fichiers du référentiel . Pour ce faire, accédez à la racine de votre référentiel et exécutez ces commandes:

git rm --cached -rf .
git diff --cached --name-only -z | xargs -n 50 -0 git add -f

Si vous voulez maintenant que git normalise également les fichiers dans votre répertoire de travail , exécutez ces commandes:

git ls-files -z | xargs -0 rm
git checkout .
Chronial
la source
3
Je reçois une pathspec fatale '' ne correspond à aucun fichier, juste aprèsgit diff --cached --name-only -z | xargs -0 git add
CMCDragonkai
3
quelle est la sortie de git diff --cached --name-only?
Chronial
1
Il peut être utile de mentionner que vous pouvez définir cette configuration lors du clonage du dépôt en question, par exemple git clone --config core.autocrlf=false <repo path>.
Chris Long
240

Je reviens à cette réponse assez souvent, mais aucune de ces réponses ne me convient parfaitement. Cela dit, la bonne réponse pour moi est un mélange des autres.

Ce que je trouve fonctionne comme suit:

 git config --global core.eol lf
 git config --global core.autocrlf input

Pour les dépôts qui ont été extraits après que ces paramètres globaux ont été définis, tout sera extrait comme quoi que ce soit dans le dépôt - avec un peu de chance LF( \n). Tout CRLFsera converti en juste LFlors de l'enregistrement.

Avec un référentiel existant que vous avez déjà extrait - qui a les terminaisons de ligne correctes dans le référentiel mais pas votre copie de travail - vous pouvez exécuter les commandes suivantes pour le corriger:

git rm -rf --cached .
git reset --hard HEAD

Cela supprimera ( rm) récursivement ( r) sans prompt ( -f), tous les fichiers sauf ceux que vous avez édités ( --cached), du répertoire actuel ( .). Le resetretourne ensuite tous ces fichiers dans un état où ils ont leurs vraies fins de ligne (correspondant à ce qui est dans le référentiel).

Si vous devez corriger les fins de ligne des fichiers dans un référentiel, je vous recommande de saisir un éditeur qui vous permettra de le faire en bloc comme IntelliJ ou Sublime Text, mais je suis sûr que tout bon supportera probablement cela.

Ben Liyanage
la source
1
Nous avons un seul dépôt avec des sous-répertoires qui nécessitent une gestion de fin de ligne différente. La définition d'une option globale ne fonctionne donc pas pour cela. Pas même dans le repo unique. Comment appliquez-vous ces mêmes paramètres dans .gitattributes?
RobG
Notepad++montre également la fin de la ligne du fichier ouvert dans le coin inférieur droit. Un clic droit sur ce champ vous permettra de modifier les fins de ligne.
winklerrr
1
L' core.autocrlf inputoption remplace le core.eolparamètre, donc le réglage des deux est redondant. (Voir git-scm.com/docs/git-config )
Andrew Marshall
1
Merci, avec votre aide, j'ai conquis les peluches et Linux. Et peut désormais archiver des fichiers.
GC_
57

Le contexte

Si vous

  1. veulent forcer tous les utilisateurs à avoir des fins de ligne LF pour les fichiers texte et
  2. vous ne pouvez pas vous assurer que tous les utilisateurs modifient leur configuration git,

vous pouvez le faire à partir de git 2.10. La version 2.10 ou ultérieure est requise, car la version 2.10 a corrigé le comportement de text = auto avec eol = lf . Source .

Solution

Mettez un .gitattributesfichier à la racine de votre dépôt git ayant le contenu suivant:

* text=auto eol=lf

Engagez-le.

Ajustements facultatifs

Vous pouvez également ajouter un .editorconfigà la racine de votre référentiel pour vous assurer que les outils modernes créent de nouveaux fichiers avec les fins de ligne souhaitées.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
koppor
la source
3
C'était la meilleure solution pour moi. J'ai également combiné cela avec editorconfig.org afin que lors de l'écriture dans Intellij j'écrive des LF EOL.
Jazzepi
C'est de loin la meilleure solution. Pas besoin d'exécuter manuellement les commandes de configuration!
Cameron Tacklind
26

core.autocrlf=inputest le bon réglage pour ce que vous voulez, mais vous devrez peut-être faire un git update-index --refreshet / ou un git reset --hardpour que le changement prenne effet.

Avec core.autocrlfdéfini sur input, git n'appliquera pas de conversion de nouvelle ligne au moment du départ (donc si vous avez LF dans le repo, vous obtiendrez LF), mais il s'assurera que si vous vous trompez et introduisez des CRLF dans le travail copier en quelque sorte, ils ne feront pas leur entrée dans le repo.

kusma
la source
19
Les commandes doivent être git rm --cached -r. && git reset --hard
koppor
0

Vous pouvez trouver la solution à ce problème sur: https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings

Description simplifiée de la façon dont vous pouvez résoudre ce problème sur Windows:

Paramètres globaux pour les fins de ligne La commande git config core.autocrlf est utilisée pour modifier la façon dont Git gère les fins de ligne. Cela prend un seul argument.

Sous Windows, vous passez simplement fidèle à la configuration. Par exemple: C:> git config --global core.autocrlf true

Bonne chance, j'espère avoir aidé.

c-santana
la source