Cause possible n ° 1 - Normalisation de fin de ligne
Une situation dans laquelle cela peut se produire est lorsque le fichier en question a été archivé dans le référentiel sans la configuration correcte pour les fins de ligne (1) résultant en un fichier dans le référentiel avec soit des fins de ligne incorrectes, soit des fins de ligne mixtes. Pour confirmer, vérifiez que git diff
ne montre que les changements dans les fins de ligne (ceux-ci peuvent ne pas être visibles par défaut, essayez git diff | cat -v
de voir les retours chariot comme littéraux^M
caractères ).
Par la suite, quelqu'un a probablement ajouté .gitattributes
ou modifié lecore.autocrlf
paramètre pour normaliser les fins de ligne (2). Sur la base de la .gitattributes
configuration globale ou, Git a appliqué des modifications locales à votre copie de travail qui appliquent la normalisation de fin de ligne demandée. Malheureusement, pour une raison quelconquegit reset --hard
ces modifications de normalisation de ligne ne sont pas annulées.
Solution
Les solutions de contournement dans lesquelles les terminaisons de ligne locales sont réinitialisées ne résoudront pas le problème. Chaque fois que le fichier est "vu" par git, il essaiera de réappliquer la normalisation, entraînant le même problème.
La meilleure option est de laisser git appliquer la normalisation qu'il souhaite en normalisant toutes les fins de ligne dans le repo pour correspondre à .gitattributes
, et en validant ces changements - voir Essayer de réparer les fins de ligne avec git filter-branch, mais sans chance .
Si vous voulez vraiment essayer d'annuler les modifications du fichier manuellement, la solution la plus simple semble être d'effacer les fichiers modifiés, puis de dire à git de les restaurer, bien que je note que cette solution ne semble pas fonctionner de manière cohérente à 100%. l'heure ( AVERTISSEMENT: NE l' exécutez PAS si vos fichiers modifiés ont des changements autres que des fins de ligne !!):
git status --porcelain | grep "^ M" | cut -c4- | xargs rm
git checkout -- .
Notez que, à moins que vous ne normalisiez les fins de ligne dans le référentiel à un moment donné, vous continuerez à rencontrer ce problème.
Cause possible n ° 2 - Insensibilité à la casse
La deuxième cause possible est l'insensibilité à la casse sous Windows ou Mac OS / X. Par exemple, supposons qu'un chemin comme celui-ci existe dans le référentiel:
/foo/bar
Maintenant, quelqu'un sur Linux valide les fichiers /foo/Bar
(probablement à cause d'un outil de construction ou de quelque chose qui a créé ce répertoire) et pousse. Sous Linux, il s'agit en fait maintenant de deux répertoires distincts:
/foo/bar/fileA
/foo/Bar/fileA
La vérification de ce dépôt sur Windows ou Mac peut entraîner une modification fileA
qui ne peut pas être réinitialisée, car à chaque réinitialisation, git sur Windows extrait /foo/bar/fileA
, puis parce que Windows ne respecte pas la casse, écrase le contenu de fileA
avec /foo/Bar/fileA
, ce qui entraîne leur "modification".
Un autre cas peut être un ou des fichiers individuels qui existent dans le référentiel et qui, lorsqu'ils sont extraits sur un système de fichiers insensible à la casse, se chevauchent. Par exemple:
/foo/bar/fileA
/foo/bar/filea
Il peut y avoir d'autres situations similaires qui pourraient causer de tels problèmes.
git sur les systèmes de fichiers insensibles à la casse devrait vraiment détecter cette situation et afficher un message d'avertissement utile, mais ce n'est pas le cas actuellement (cela pourrait changer à l'avenir - voir cette discussion et les correctifs proposés sur la liste de diffusion git.git).
Solution
La solution consiste à aligner la casse des fichiers dans l'index git et la casse sur le système de fichiers Windows. Cela peut être fait sous Linux qui montrera le vrai état des choses, OU sous Windows avec l'utilitaire open source très utile Git-Unite . Git-Unite appliquera les modifications de cas nécessaires à l'index git, qui pourra ensuite être validé dans le dépôt.
(1) Cela était probablement dû à une personne utilisant Windows, sans aucune .gitattributes
définition du fichier en question, et utilisant le paramètre global par défaut core.autocrlf
qui est false
(voir (2)).
(2) http://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line/
.
représente le répertoire actuel et non le répertoire racine