2010-03-18 7 views
15

J'ai un référentiel Git qui a des fichiers au format DOS (\r\n terminaisons de ligne). Je voudrais simplement exécuter les fichiers à travers dos2unix (ce qui changerait tous les fichiers au format UNIX, avec \n fins de ligne), mais à quel point cela affecterait l'histoire, et est-ce recommandé?Git: Suppression des retours de chariot des fichiers contrôlés par la source

Je suppose que la norme est de toujours utiliser les fins de ligne UNIX pour les fichiers contrôlés par la source, et optionnellement passer aux fins de ligne spécifiques au système d'exploitation en local?

+1

question connexe pour les personnes intéressées par ce: http://stackoverflow.com/questions/446244/are-crlf-lines-ok-in-a-rails-project-deployed-on-linux – Blixt

Répondre

10

L'approche que vous devrez utiliser dépend de la façon dont votre référentiel est public. Si cela ne vous dérange pas ou ne vous souciez pas de changer tous les SHA parce que vous êtes plus ou moins le seul à l'utiliser, mais que vous voulez régler ce problème pour toujours, vous pouvez lancer un git filter-branch et appliquer dos2unix à tous fichiers dans chaque commit. (Si vous partagez le référentiel, tout le monde a besoin de plus ou moins pour le renouveler complètement, donc c'est potentiellement dangereux.)

Donc la meilleure option et aussi un moyen plus simple serait de le changer seulement dans les têtes actuelles . Cela signifie que vos commits passés ont encore \r\n terminaisons mais à moins que vous ne fassiez beaucoup de sélection du passé, cela ne devrait pas poser de problème. Les outils diff peuvent se plaindre un peu plus souvent, bien sûr, mais normalement, vous ne faites que des différences avec les commits à proximité, donc ce problème se résout au fur et à mesure que les commits s'accumulent.

Et les fins de ligne UNIX sont standard, vous avez raison à ce sujet. La meilleure approche consiste à configurer votre éditeur pour qu'il n'écrit ces fins que sur Windows. Sinon, il existe également un paramètre autocrlf que vous pouvez utiliser.


Ajout à la partie réécriture historique:

La dernière fois que je l'ai fait la même chose, j'ai utilisé la commande suivante pour modifier tous les fichiers de fins unix.

#!/bin/bash 
all2dos() { find * -exec dos2unix {} \; } 
export -f all2dos 
git filter-branch -f --tree-filter 'all2dos' --tag-name-filter cat --prune-empty -- --all 
+0

Merci. À l'heure actuelle, je suis la seule personne qui travaille sur le dépôt, car c'est plutôt «jeune», donc réécrire l'histoire ne devrait pas poser de problème. Mais dans quelle mesure 'git filter-branch' jouerait-il avec github (j'ai mis le dépôt là-bas)? – Blixt

+0

Je pense que vous devez supprimer toutes les branches et toutes les balises sur github pour vous assurer qu'elles peuvent être créées à nouveau. (Cela * pourrait * fonctionner sans cela, mais peut-être vaut-il mieux recommencer à zéro.) Sinon, vous supprimez tout le repo, puis vous le réessayez. Cela devrait être trouvé avec github à moins que certaines personnes en aient cloné. Ensuite, ils devront faire la même chose, en fonction de leur aisance avec git. – Debilski

+0

Très bien. J'ai juste enlevé le dépôt et l'ai repoussé avec l'historique retravaillé. J'avais besoin de résoudre certains problèmes avec certains vieux messages de validation étant multi-ligne aussi, de toute façon. – Blixt

4

Pour la solution continue, un coup d'oeil à la core.autocrlf (et core.safecrlf) config parameters. Faire ceci une fois à tout votre dépôt créera juste un commit avec lequel il sera impossible de fusionner (puisque chaque ligne de ces fichiers sera modifiée), mais une fois que vous l'aurez dépassé, cela ne devrait pas être grave. (Oui, vous pouvez utiliser git filter-branch pour faire la modification tout au long de l'histoire, mais c'est un peu effrayant.)

22

Cette chose crlf nous a rendu fou lorsque nous avons converti de svn à git (dans un central (nu) comme) environnement scm. La chose qui nous a finalement été de copier le fichier .gitconfig global à la racine de l'utilisateur (yep à la fois windows et linux) avec l'initiale provenant d'un système Windows et ayant core.autocrlf = true et core.safecrlf = false qui a fait des ravages sur les utilisateurs de Linux (comme les scripts bash ne fonctionnaient pas et tous ces horribles^M). Donc, nous avons d'abord fait un script checkout et clone qui a fait un dos2unix après ces commandes. Puis je suis tombé sur les core.autocrlf et articles configuration core.safecrlf et les Définie en fonction de l'O/S:

de Windows: core.autocrlf = true et core.safecrlf = false Linux: core.autocrlf = entrée et coeur.safecrlf = false

Ces ont été mis à: --- --- sous Windows

git config --global core.autocrlf true 
git config --global core.safecrlf false 

--- Linux ---

git config --global core.autocrlf input 
git config --global core.safecrlf false 

Alors pour nos développeurs Linux nous configurons un petit script bash/usr/local/bin/gitfixcrlf:

#!/bin/sh 
# remove local tree 
git ls-files -z | xargs -0 rm 
# checkout with proper crlf 
git checkout . 

qui ils ne devaient courir sur leur sa locale ndbox clones une fois. Tout futur clonage a été fait correctement. Toutes les futures poussées tirées maintenant ont été traitées correctement. Donc, cela a résolu nos problèmes d'O/S multiples avec les sauts de ligne. Notez également que Mac tombe dans la même configuration que Linux.