J'ai essayé de valider des fichiers avec des lignes de fin CRLF, mais cela a échoué.
J'ai passé toute une journée de travail sur mon ordinateur Windows à essayer différentes stratégies et j'étais presque tenté de cesser d'utiliser Git et d'essayer plutôt Mercurial .
Veuillez ne partager qu’une seule bonne pratique par réponse.
Presque quatre ans après avoir posé cette question, j'ai enfin trouvé une réponse qui me satisfait complètement !
Voir les détails dans github: help Guide de Traitement des fins de ligne .
Git vous permet de définir directement les propriétés de fin de ligne pour un repo en utilisant le attribut de texte dans le fichier
.gitattributes
. Ce fichier est validé dans le référentiel et remplace le paramètre _core.autocrlf
_, vous permettant ainsi de garantir un comportement cohérent pour tous les utilisateurs, quels que soient leurs paramètres git.
Et ainsi
L'avantage de cela est que votre configuration de fin de ligne est désormais acheminée avec votre référentiel et vous n'avez pas à vous soucier de savoir si les collaborateurs disposent des paramètres globaux appropriés.
Voici un exemple de fichier .gitattributes
_# 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
_
Il existe une pratique collection de fichiers .gitattributes prêts à l'emploi pour les langages de programmation les plus populaires. C'est utile pour commencer.
Une fois que vous avez créé ou ajusté votre .gitattributes
, vous devez effectuer une opération unique une fois pour toutes fin de ligne -normalisation .
Notez que l'application GitHub Desktop peut suggérer et créer un fichier .gitattributes
après avoir ouvert le dépôt Git de votre projet dans l'application. Pour essayer, cliquez sur l'icône représentant un engrenage (dans le coin supérieur droit)> Paramètres du référentiel ...> Terminaisons et attributs. Vous serez invité à ajouter le recommandé .gitattributes
et si vous acceptez, l'application procédera également à une normalisation de tous les fichiers de votre référentiel. .
Enfin, l'article Attention à la fin de votre ligne fournit davantage d'informations de base et explique comment Git a évolué sur les sujets traités. Je considère que cela nécessite une lecture .
Certains membres de votre équipe utilisent probablement EGit ou JGit (des outils tels que Eclipse et TeamCity les utilisent) pour valider leurs modifications. Alors vous n'avez pas de chance, comme l'explique @gatinueta dans les commentaires de cette réponse:
Ce paramètre ne vous satisfera pas complètement si vous avez des personnes travaillant avec Egit ou JGit dans votre équipe, car ces outils ignoreront simplement .gitattributes et archiveront les fichiers CRLF sans problème https://bugs.Eclipse.org/bugs/ show_bug.cgi? id = 342372
Une astuce pourrait consister à les faire appliquer leurs modifications à un autre client, par exemple SourceTree . Notre équipe à l'époque préférait cet outil à l'Egit d'Eclipse pour de nombreux cas d'utilisation.
Qui a dit que le logiciel est facile? : - /
Ne convertissez pas les fins de ligne. Ce n’est pas à VCS d’interpréter les données, mais de les stocker et de les mettre en version. Tout éditeur de texte moderne peut lire les deux types de fin de ligne.
Vous voulez presque toujours autocrlf=input
sauf si vous savez vraiment ce que vous faites.
Un contexte supplémentaire ci-dessous:
Cela devrait être soit
core.autocrlf=true
si vous aimez les fins de DOS, soitcore.autocrlf=input
si vous préférez unix-newlines. Dans les deux cas, votre référentiel Git n'aura que LF, ce qui est la bonne chose. Le seul argument decore.autocrlf=false
était que l'heuristique automatique peut détecter de manière incorrecte un binaire en tant que texte et votre tuile sera alors corrompue. Ainsi, l'optioncore.safecrlf
a été introduite pour avertir un utilisateur en cas de modification irréversible. En fait, il existe deux possibilités de modifications irréversibles: une fin de ligne mixte dans un fichier texte, cette normalisation est souhaitable. Cet avertissement peut donc être ignoré ou bien (très peu probable) que Git ait incorrectement détecté votre fichier binaire en tant que texte. Ensuite, vous devez utiliser des attributs pour indiquer à Git que ce fichier est binaire.
Le paragraphe ci-dessus a été extrait d'un fil de discussion sur gmane.org, mais il a depuis diminué.
Deux stratégies alternatives deviennent cohérentes concernant les fins de ligne dans des environnements mixtes (Microsoft + Linux + Mac):
1) Convertissez tous en un seul format
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
2) Définissez core.autocrlf
sur input
sous Linux/UNIX ou true
sur MS Windows (référentiel ou global)
git config --global core.autocrlf input
3) [Facultatif] définissez core.safecrlf
sur true
(pour arrêter) ou warn
(pour chanter :) pour ajouter une protection supplémentaire en comparant si la transformation de nouvelle ligne inversée aboutit au même fichier
git config --global core.safecrlf true
1) Convertissez tous en un seul format
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
2) ajoutez le fichier .gitattributes
à votre référentiel
echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'
Ne vous inquiétez pas pour vos fichiers binaires - Git devrait être assez intelligent à leur sujet.
Essayez de régler l’option de configuration core.autocrlf
sur true
. Regardez également l'option core.safecrlf
.
En fait, il semble que core.safecrlf
soit peut-être déjà défini dans votre référentiel, car (c'est moi qui souligne):
Si ce n'est pas le cas pour le paramètre actuel de core.autocrlf, git rejettera le fichier.
Si tel est le cas, vous pouvez vérifier que votre éditeur de texte est configuré pour utiliser les fins de ligne de manière cohérente. Vous rencontrerez probablement des problèmes si un fichier texte contient une combinaison de fins de ligne LF et CRLF.
Enfin, j'estime que la recommandation consistant simplement à "utiliser ce que l'on vous donne" et à utiliser LF lignes terminées sous Windows causera plus de problèmes qu'elle n'en résoudra. Git a les options ci-dessus pour essayer de gérer les fins de ligne de manière judicieuse, il est donc logique de les utiliser.
L'utilisation de core.autocrlf=false
a arrêté la mise à jour de tous les fichiers dès que je les ai extraits dans mon projet Visual Studio 201 . Les deux autres membres de l'équipe de développement utilisent également des systèmes Windows; un environnement mixte n'a donc pas été mis en place. Cependant, les paramètres par défaut fournis avec le référentiel indiquaient toujours que tous les fichiers étaient mis à jour immédiatement après le clonage.
Je suppose que l’essentiel est de trouver le réglage CRLF qui convient à votre environnement. D'autant plus que dans de nombreux autres référentiels de nos boîtes Linux, le paramètre autocrlf = true
donne de meilleurs résultats.
Plus de 20 ans plus tard, nous avons toujours affaire à des disparités de fin de ligne entre systèmes d’exploitation… triste.
Ce sont les deux options pour les utilisateurs de Windows et Visual Studio qui partagent le code avec les utilisateurs de Mac ou Linux. Pour une explication détaillée, lisez le manuel de gitattributes .
Dans le fichier .gitattributes
de votre référentiel, ajoutez:
* text=auto
Cela normalisera tous les fichiers avec LF
fins de lignes dans le référentiel.
Et selon votre système d'exploitation (paramètre core.eol
), les fichiers de l'arborescence de travail seront normalisés à LF
pour les systèmes Unix ou à CRLF
pour les systèmes Windows.
C'est la configuration que Microsoft .NET repos utilise.
Exemple:
Hello\r\nWorld
Sera normalisé dans le repo toujours comme:
Hello\nWorld
À la caisse, l’arbre de travail dans Windows sera converti en:
Hello\r\nWorld
À la caisse, l’arbre de travail sur Mac sera laissé comme suit:
Hello\nWorld
Remarque: Si votre référentiel contient déjà des fichiers non normalisés,
git status
affichera ces fichiers comme étant complètement modifiés la prochaine fois que vous leur apporterez des modifications. Les autres utilisateurs auraient du mal à fusionner leurs modifications ultérieurement. Voir actualiser un référentiel après avoir changé les fins de ligne pour plus d'informations.
Si text
n'est pas spécifié dans le fichier .gitattributes
, Git utilise la variable de configuration core.autocrlf
pour déterminer si le fichier doit être converti.
Pour les utilisateurs de Windows, git config --global core.autocrlf true
est une excellente option pour les raisons suivantes:
LF
fins de lignes uniquement lorsqu'ils sont ajoutés au référentiel. S'il existe des fichiers non normalisés dans le référentiel, ce paramètre ne les touchera pas.CRLF
dans le répertoire de travail.Le problème avec cette approche est que:
autocrlf = input
, vous verrez un tas de fichiers avec des fins de ligne LF
. Ce n'est pas un danger pour le reste de l'équipe, car vos commits seront toujours normalisés avec des fins de ligne LF
.core.autocrlf = false
, vous verrez un groupe de fichiers avec des fins de ligne LF
et vous pouvez introduire des fichiers avec des fins de ligne CRLF
dans le référentiel.autocrlf = input
et peuvent obtenir des fichiers avec les fins de fichier CRLF
, probablement des utilisateurs Windows dotés de core.autocrlf = false
.J'ai passé des heures à trouver le meilleur usage possible de .gitattributes
, pour enfin réaliser que je ne peux pas compter dessus.
Malheureusement, tant qu'il existe des éditeurs basés sur JGit (qui ne peuvent pas gérer correctement .gitattributes
), la solution sûre consiste à forcer LF partout, même au niveau de l'éditeur.
Utilisez les désinfectants anti-CRLF
suivants.
clients Windows/Linux: core.autocrlf=input
commis .gitattributes
: * text=auto eol=lf
commit .editorconfig
( http://editorconfig.org/ ), qui est un type de format normalisé, combiné à des plugins d'éditeur:
Les dafaults de git client fonctionneront dans la plupart des cas. Même si vous ne possédez que des clients Windows, que des clients Linux ou les deux. Ceux-ci sont:
core.autocrlf=true
signifie convertir les lignes en CRLF à la caisse et les convertir en LF lors de l'ajout de fichiers.core.autocrlf=input
signifie ne pas convertir les lignes à la caisse (inutile de le faire, car les fichiers doivent être validés avec LF) et convertir les lignes to LF (si nécessaire) lors de l'ajout de fichiers.La propriété peut être définie dans différentes portées. Je suggérerais de définir explicitement la portée de --global
pour éviter certains problèmes de IDE décrits à la fin.
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
Aussi, je déconseillerais fortement d’utiliser git config --global core.autocrlf false
(si vous n’avez que des clients Windows) contrairement à ce qui est proposé à git documentation . La définition de false validera les fichiers avec CRLF dans le référentiel. Mais il n'y a vraiment aucune raison. Vous ne savez jamais si vous devrez partager le projet avec les utilisateurs de Linux. De plus, il s'agit d'une étape supplémentaire pour chaque client qui rejoint le projet au lieu d'utiliser les valeurs par défaut.
Maintenant, pour certains cas spéciaux de fichiers (par exemple *.bat
*.sh
) que vous voulez qu'ils soient extraits avec LF ou avec CRLF, vous pouvez utiliser .gitattributes
Pour résumer pour moi la meilleure pratique est la suivante:
git grep -I --files-with-matches --Perl-regexp '\r' HEAD
( Remarque: sur les clients Windows ne fonctionne que via git-bash
et sur les clients Linux uniquement s'ils ont été compilés avec --with-libpcre
dans ./configure
)..gitattributes
core.autocrlf
décrit ci-dessus sur ses valeurs par défaut..gitattributes
. Les clients git des IDE peuvent les ignorer ou les traiter différemment.Comme dit, certaines choses peuvent être ajoutées dans les attributs de git:
# Always checkout with LF
*.sh text eol=lf
# Always checkout with CRLF
*.bat text eol=crlf
Je pense que d'autres options sûres pour .gitattributes
au lieu d'utiliser la détection automatique pour les fichiers binaires:
-text
(par exemple, pour les fichiers *.Zip
ou *.jpg
: ne seront pas traités comme du texte. Ainsi, aucune conversion de fin de ligne ne sera tentée. Des différences pourraient être possibles via les programmes de conversion)text !eol
(par exemple pour *.Java
, *.html
: traité comme du texte, mais la préférence de style eol n'est pas définie. Le paramètre client est donc utilisé.)-text -diff -merge
(p.ex. pour *.hugefile
: non traité comme du texte. Aucune diff/fusion possible)Exemple douloureux d'un client qui commettra des fichiers à tort:
netbeans 8.2 (sur Windows), validera à tort tous les fichiers texte avec des CRLF , sauf si vous avez explicitement défini core.autocrlf
comme global . Cela contredit le comportement standard du client git et pose beaucoup de problèmes plus tard, lors de la mise à jour/fusion. C’est ce qui fait que certains fichiers paraissent différents (bien qu’ils ne le soient pas) même lorsque vous les revenez .
Le même comportement se produit dans netbeans même si vous avez ajouté le correct .gitattributes
à votre projet.
L'utilisation de la commande suivante après une validation vous aidera au moins à détecter rapidement si votre référentiel git présente des problèmes de fin de ligne: git grep -I --files-with-matches --Perl-regexp '\r' HEAD
Ceci est juste une solution de contournement :
Dans des cas normaux, utilisez les solutions fournies avec git. Ceux-ci fonctionnent bien dans la plupart des cas. Forcer à LF si vous partagez le développement sur des systèmes Windows et Unix en définissant . Gitattributes .
Dans mon cas, il y avait> 10 programmeurs développant un projet sous Windows. Ce projet a été archivé avec CRLF et il n’existait pas d’option permettant de forcer à LF.
Certains paramètres ont été écrits en interne sur ma machine sans aucune influence sur le format LF; ainsi, certains fichiers ont été globalement modifiés en LF à chaque modification de fichier de petite taille.
Ma solution:
Windows-Machines: Laissez tout tel quel. Ne vous souciez de rien, puisque vous êtes un développeur Windows par défaut et que vous devez gérer comme suit: "Il n'y a pas d'autre système dans le monde entier, n'est-ce pas?"
Unix-Machines
Ajoutez les lignes suivantes à la section [alias]
d'une config. Cette commande répertorie tous les fichiers modifiés (c'est-à-dire modifiés/nouveaux):
lc = "!f() { git status --porcelain \
| egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
| cut -c 4- ; }; f "
Convertissez tous les fichiers modifiés au format dos:
unix2dos $(git lc)
Optionnellement ...
Créez un git hook pour cette action afin d'automatiser ce processus
Utilisez les paramètres, incluez-les et modifiez la fonction grep
pour qu'elle ne corresponde qu'à des noms de fichiers particuliers, par exemple:
... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
N'hésitez pas à le rendre encore plus pratique en utilisant un raccourci supplémentaire:
c2dos = "!f() { unix2dos $(git lc) ; }; f "
... et déclenchez la conversion en tapant
git c2dos