2010-03-27 23 views
31

Tenemos el repositorio de git bare en Unix que tiene archivos con el mismo nombre que difiere solo en los casos.Los nombres de archivo sensibles a mayúsculas y minúsculas de Git-windows no se manejan correctamente

Ejemplo:

GRANT.sql 
grant.sql 

Cuando clonar el repositorio desnudo desde UNIX a una caja de ventanas, git status detecta el archivo modificado. El árbol de trabajo se carga solo con grant.sql, pero el estado de git compara grant.sql y GRANT.sql y muestra el archivo modificado en el árbol de trabajo.

He intentado utilizar el core.ignorecase falso pero el resultado es el mismo.

¿Hay alguna manera de solucionar este problema?

+0

pregunta impresionante y la respuesta de Greg es simplemente genial! – Hazok

+0

Esto también puede suceder cuando crea el archivo con diferentes envolturas en diferentes ramas en Windows. – Thomas

Respuesta

4

No estoy seguro de que esto sea posible. El caso omiso de Git maneja las discrepancias en el caso del único archivo. No funcionará con la incapacidad de Window de tener dos nombres de archivo en el único directorio que difieren solo por caso.

FWIW, tener dos nombres de archivo idénticos, pero para su caso es una muy mala idea, incluso en Unix.

+0

Si solo los desarrolladores del kernel de Linux estuvieron de acuerdo con usted ... –

36

Windows no distingue entre mayúsculas y minúsculas (más precisamente, preservación de mayúsculas y minúsculas). Simplemente no existe una forma posible de que existan dos archivos cuyos nombres solo difieren en el caso: dos nombres de archivo que difieren solo en caso de que tengan el mismo nombre de archivo. Período.

Entonces, Git recorre el repositorio, revisando un archivo después del otro, hasta que llega al primero de los dos archivos problemáticos. Git lo verifica, luego va más allá sobre su negocio hasta que llega al segundo archivo. Nuevamente, Git lo verifica. Dado que desde el punto de vista de Windows el nombre del archivo es el mismo que el primero, el primer archivo simplemente se sobrescribe con el segundo. Lo que ahora hace que Git piense que el primer archivo fue cambiado para tener el mismo contenido que el segundo.

Tenga en cuenta que esto no tiene nada que ver con Git: exactamente lo mismo ocurriría si tuviera un tarball, un archivo zip o un repositorio de Subversion.

Si desea hacer desarrollo en múltiples plataformas diferentes, debe respetar las restricciones de esas plataformas y debe limitarse al mínimo común denominador de todas las plataformas que admite. Windows admite ADS, Linux no. OSX admite resource bifurcaciones, Windows no. BSD admite mayúsculas y minúsculas, Windows no. Entonces, no puedes usar ninguno de esos. Esa es la forma como es.

core.ignorecase no lo ayudará aquí, porque maneja exactamente el problema opuesto a.

+2

+1 para una explicación detallada – cctan

+1

Reparar esto no significa hacerlo funcionar. Al solucionar esto, significa que convierte el comportamiento loco en un error evidente. – jrodman

+1

Definitivamente hay una forma de que existan dos archivos cuyos nombres solo difieren en el caso, pero se necesita un cambio en el registro. Cygwin lo hace, pero no sé si msys puede (hay una bandera especial que debe pasarse a la API de Win32): https://cygwin.com/cygwin-ug-net/using-specialnames.html – Matt

32

Acabo de encontrar un problema similar. En mi caso, los dos archivos con nombres similares que difieren solo en el caso estaban en un subdirectorio que no era relevante en el clon de Windows. Git 1.7 tiene una característica sparse checkout que le permite excluir ciertos archivos de una copia de trabajo. Para excluir este directorio:

git config core.sparsecheckout true 
echo '*' >.git/info/sparse-checkout 
echo '!unwanted_dir/' >>.git/info/sparse-checkout 
git read-tree --reset -u HEAD 

Después de esto, el subdirectorio unwanted_dir/ había desaparecido por completo de mi copia de trabajo y Git continúa trabajando con el resto de los archivos de forma normal.

Si su GRANT.sql y grant.sql no son relevantes en el clon de Windows, puede agregar sus nombres al .git/info/sparse-checkout para excluir esos archivos específicamente.

+1

Esto la respuesta fue simplemente increíble y también funciona para los nombres de los archivos demasiado largos. Gracias por aliviar los dolores de cabeza que he tenido !!! Dio un +1 hace un par de meses. – Hazok

+1

¡Gran solución! Necesitaba que la configuración fuera 'core.sparseCheckout' para que funcione –

+1

¡La sugerencia es realmente útil! ¡Increíble! – Fei

1

Cygwin maneja la distinción entre mayúsculas y minúsculas y los caracteres divertidos en los nombres de archivo mucho mejor que MSys.

Cambiar esta clave del registro para habilitar mayúsculas y minúsculas en Windows:

HKLM \ System \ CurrentControlSet \ Control \ Session Manager \ Kernel \ ObCaseInsensitive = 0

Ver here para algunas advertencias en cómo se soporta mayúsculas y minúsculas en Cygwin.

2

Si desea mantener su repositorio amigable con los sistemas de archivos que no distinguen entre mayúsculas y minúsculas, puede agregar un enlace de confirmación que le impide registrar los archivos en conflicto.

#!/bin/bash 

# Save current state 
git stash -u -q --keep-index || exit 1 

# Get the list of clashing files in the whole repository 
CLASHING=`find "$(git rev-parse --show-toplevel)" | sort | uniq -d -i` 

# Restore previous state 
git stash pop -q 

if [[ $CLASHING ]]; then 
    echo "Found clashing files on case-insensitive file systems" 
    echo "$CLASHING" 
    exit 1 
fi 

exit 0 

Este script requiere la versión git> = 1.7.7, ya que utiliza -u escondite, para evitar su defecto en archivos sin seguimiento.

+1

Puede fallar en los archivos sin seguimiento en '.gitignore'. – djjeck

+0

¿Alguien sabe cómo obtener el árbol actual, incluidos los cambios escalonados? Tenga en cuenta que simplemente anexar 'git diff -staged' a' HEAD' no es suficiente; por ejemplo, no funcionaría cuando cambie la caja en un nombre de archivo. – djjeck

+0

Gran solución. Decir "No hagas eso" es muy inútil. No creo que una tienda razonable permita dos archivos o carpetas que difieran solo en el caso, incluso si utilizan Linux. –

1

La forma más sencilla de solucionar realmente el problema es cambiar el nombre de uno de los archivos para que no entren en conflicto en un sistema de archivos entre mayúsculas y minúsculas como Windows o OS X.

Después de una confirmación de la Linux/El sistema Unix donde más fácilmente puede resolver el problema, todo estará bien en Windows después de un tirón. Para evitar que se produzca este problema, deberá agregar un enlace de confirmación similar al sugerido por djjeck.

Los síntomas en Windows para esto son muy confuso e incluyen:

  • Los archivos que siempre se muestran tan cambiado, incluso si se les revierte lo que hace que el cambio de ramas o rebase muy difícil.
  • , dos copias del archivo con los nombres que difieren sólo en caso de que ambos muestran los cambios en GUI git

Dado que ambos archivos no pueden coexistir en una plataforma insensibles caso de tener que cambiar uno de los nombres de archivo para evitar la problema.

Cuestiones relacionadas