J'ai été piqué par le problème de fin de ligne de Windows/Linux avec git. Il semble, via GitHub, MSysGit et d’autres sources, que la meilleure solution consiste à configurer votre dépôt local pour qu’il utilise des fins de ligne de style linux, mais définissez core.autocrlf
à true
. Malheureusement, je ne l'ai pas fait assez tôt, alors chaque fois que je modifie, les fins de ligne sont bouchées.
Je pensais avoir trouvé une réponse ici mais je ne peux pas la faire fonctionner pour moi. Ma connaissance de la ligne de commande Linux est limitée au mieux, donc je ne suis même pas sûr de ce que la ligne "xargs fromdos" fait dans son script. Je continue à recevoir des messages indiquant qu'il n'existe aucun fichier ou répertoire de ce type, et lorsque je parviens à le diriger vers un répertoire existant, il me dit que je ne dispose pas d'autorisations.
J'ai essayé cela avec MSysGit sous Windows et via le terminal Mac OS X.
La documentation git pour gitattributes documente maintenant une autre approche pour "corriger" ou normaliser toutes les fins de ligne de votre projet. En voici l'essentiel:
$ echo "* text=auto" >.gitattributes
$ git add --renormalize .
$ git status # Show files that will be normalized
$ git commit -m "Introduce end-of-line normalization"
Si des fichiers qui ne doivent pas être normalisés apparaissent dans l'état git, désactivez leur attribut text avant d'exécuter git add -u.
manual.pdf -text
Inversement, la normalisation peut être activée manuellement dans les fichiers texte que git ne détecte pas.
weirdchars.txt text
Ceci tire parti d'un nouveau --renormalize
flag ajouté dans git v2.16.0, publié en janvier 2018. Pour les anciennes versions de git, quelques étapes supplémentaires sont nécessaires:
$ echo "* text=auto" >>.gitattributes
$ rm .git/index # Remove the index to force git to
$ git reset # re-scan the working directory
$ git status # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"
Le moyen le plus simple de résoudre ce problème consiste à créer un commit qui corrige toutes les fins de ligne. En supposant que vous n’ayez aucun fichier modifié, procédez comme suit.
# From the root of your repository remove everything from the index
git rm --cached -r .
# Change the autocrlf setting of the repository (you may want
# to use true on windows):
git config core.autocrlf input
# Re-add all the deleted files to the index
# (You should get lots of messages like:
# warning: CRLF will be replaced by LF in <file>.)
git diff --cached --name-only -z | xargs -0 git add
# Commit
git commit -m "Fixed crlf issue"
# If you're doing this on a Unix/Mac OSX clone then optionally remove
# the working tree and re-check everything out with the correct line endings.
git ls-files -z | xargs -0 rm
git checkout .
Ma procédure pour traiter les fins de ligne est la suivante (test de combat sur de nombreux dépôts):
Lors de la création d'un nouveau dépôt:
.gitattributes
dans le tout premier commit avec d’autres fichiers typiques comme .gitignore
et README.md
Lorsqu'il s'agit d'un dépôt existant:
.gitattributes
en conséquencegit commit -a -m "Modified gitattributes"
git rm --cached -r . && git reset --hard && git commit -a -m 'Normalize CRLF' -n"
-n
(--no-verify
est de sauter les hooks de pré-commit)alias fixCRLF="..."
Dans .gitattributes
Je déclare explicitement que tous les fichiers texte ont LF EOL ), car les outils Windows sont généralement compatibles avec LF tant que les Les outils Windows ne sont pas compatibles avec CRLF (même de nombreux outils de ligne de commande nodejs supposent LF et peuvent donc modifier l’EOL dans vos fichiers).
.gitattributes
Ma .gitattributes
ressemble habituellement à:
*.html eol=lf
*.js eol=lf
*.json eol=lf
*.less eol=lf
*.md eol=lf
*.svg eol=lf
*.xml eol=lf
Pour savoir quelles extensions distinctes sont suivies par git dans le référentiel actuel, regardez ici
Une fois que cela est fait, il y a une autre mise en garde commune.
Supposons que votre master
soit déjà à jour et normalisé, puis que vous passiez à la caisse outdated-branch
. Bien souvent, juste après avoir vérifié cette branche, git marque de nombreux fichiers comme modifiés.
La solution consiste à faire un faux commit (git add -A . && git commit -m 'fake commit'
) puis git rebase master
. Après le rebase, le faux commit devrait disparaître.
Voici comment j'ai corrigé toutes les fins de ligne de l'historique en utilisant git filter-branch
. Le ^M
le caractère doit être entré avec CTRL-V
+ CTRL-M
. J'ai utilisé dos2unix
pour convertir les fichiers car cela ignore automatiquement les fichiers binaires.
$ git filter-branch --tree-filter 'grep -IUrl "^M" | xargs -I {} dos2unix "{}"'
git status --short|grep "^ *M"|awk '{print $2}'|xargs fromdos
Explication:
git status --short
Ceci affiche chaque ligne dont git est et n’est pas au courant. Les fichiers qui ne sont pas sous le contrôle de git sont marqués au début de la ligne avec un '?'. Les fichiers modifiés sont marqués d'un M.
grep "^ *M"
Ceci filtre uniquement les fichiers qui ont été modifiés.
awk '{print $2}'
Cela montre seulement le nom de fichier sans aucun marqueur.
xargs fromdos
Cela prend les noms de fichiers de la commande précédente et les exécute via l'utilitaire 'fromdos' pour convertir les fins de ligne.
Le "| xargs fromdos" lit à partir de l'entrée standard (les fichiers find
trouve) et l'utilise comme argument de la commande fromdos
, qui convertit les fins de ligne. (Est-ce que fromdos est standard dans ces environnements? Je suis habitué à dos2unix). Notez que vous pouvez éviter d'utiliser xargs (particulièrement utile si vous avez suffisamment de fichiers pour que la liste d'arguments soit trop longue pour xargs):
find <path, tests...> -exec fromdos '{}' \;
ou
find <path, tests...> | while read file; do fromdos $file; done
Je ne suis pas totalement sûr de vos messages d'erreur. J'ai testé cette méthode avec succès. Quel programme produit chaque? Pour quels fichiers/répertoires n'avez-vous pas les autorisations? Cependant, voici un essai pour deviner ce que cela pourrait être:
Un moyen simple d'obtenir une erreur "fichier non trouvé" pour le script est d'utiliser un chemin relatif - utilisez un chemin absolu. De même, vous pouvez obtenir une erreur d'autorisation si vous n'avez pas rendu votre script exécutable (chmod + x).
Ajoutez des commentaires et je vais essayer de vous aider!
ok ... sous cygwin, fromdos n'est pas facilement disponible, et awk substeb vous explose au visage si vous avez des espaces dans les chemins d'accès aux fichiers modifiés (ce que nous avions), j'ai donc dû le faire un peu différemment:
git status --short | grep "^ *M" | sed 's/^ *M//' | xargs -n 1 dos2unix
bravo à @lloyd pour le gros de cette solution