Saltar al contenido

Ramas de GitHub: ¿Problema de sensibilidad a mayúsculas y minúsculas?

Solución:

Git es esquizofrénico sobre esto.1 Partes de Git están distingue entre mayúsculas y minúsculas, por lo que la rama HELLO y rama hello están diferente sucursales. Otras partes de Git son, en Windows y MacOS de todos modos, case-ensensible, entonces esa rama HELLO y rama hello están lo mismo rama.

El resultado es confusión. Es mejor evitar la situación por completo.

Para corregir el problema:

  1. Establecer algunos adicional, privado y temporal, nombre (s) de rama o etiqueta que no encontrará confusos, para recordar cualquier ID de hash de confirmación que realmente le interese, en su propio repositorio local. Entonces corre git pack-refs --all para que todas tus referencias estén empaquetadas. Esto elimina todos los nombres de archivo, poniendo todas sus referencias en el .git/packed-refs flat-file, donde sus nombres distinguen entre mayúsculas y minúsculas. Tu Git ahora puede decirle a tu Abc de tu abc, si tiene ambos.

    Ahora que su repositorio está desconfundido, Eliminar cualquier nombre de rama incorrecto. Sus nombres temporales contienen los valores que desea recordar. Puedes borrar ambos abcyAbc si uno o ambos pueden estar estropeados. Tu remember-abc tiene el correcto hash en él.

  2. Vaya a la máquina del servidor Linux que tiene las ramas que difieren solo en el caso de la suya. (Siempre es una máquina Linux; este problema nunca ocurre en servidores Windows o MacOS porque hacen el plegado de la caja lo suficientemente temprano como para que nunca crear el problema en primer lugar.) Allí, cambie el nombre o elimine los nombres incorrectos ofensivos.

    La máquina Linux no tiene problemas con las mayúsculas y minúsculas (ramas cuyo nombre difiere solo en el caso de que siempre sean diferentes), por lo que no hay rarezas aquí. Pueden ser necesarios algunos pasos y algunos git branch comandos para enumerar todos los nombres, pero eventualmente, no tendrá nada más que nombres claros y distintos: no habrá ramas nombradas Abc y abc ambos.

    Si no hay tales problemas en el servidor Linux, el paso 2 es “no hacer nada”.

  3. Usar git fetch --prune en su sistema local. Ahora ya no tiene nombres incorrectos como nombres de seguimiento remoto, porque en el paso 2, se aseguró de que el servidor, el sistema que llama su Git local origin—No tiene malos nombres, y tu Git local ha convertido tu Git local origin/* los nombres coinciden con los nombres de las ramas.

  4. Ahora vuelva a crear los nombres de sucursales que desee localmente y / o cambie el nombre de los nombres temporales que hizo en el paso 1. Por ejemplo, si hizo remember-abc recordar abc, puedes simplemente correr git branch -m remember-abc abc para moverseremember-abc para abc.

    Si abc debería tener origin/abc establecido como su flujo ascendente, hágalo ahora:

    git branch --set-upstream-to=origin/abc abc
    

    (Puede hacer esto en el paso 1 cuando cree remember-abc, pero creo que tiene más sentido aquí, así que lo puse en el paso 4.)

Hay varios atajos que puede usar, en lugar de los 4 pasos anteriores. Enumeré los cuatro de esta manera para aclarar el propósito: debería ser obvio para usted lo que es cada paso destinado a lograr y, si lees el resto de esto, por qué estás dando ese paso.

La razón por la que ocurre el problema se describe en la respuesta de nowox: Git a veces almacena el nombre de la rama en un nombre de archivo y, a veces, lo almacena como un string en un archivo de datos. Dado que Windows (y MacOS) tiende a usar la combinación de nombre de archivo, la variante de nombre de archivo conserva su caso original, pero ignora los intentos de crear un segundo archivo con el otro nombre de variante de caso, y luego Git piensa que Abc y abc son de otra manera lo mismo. La variante de datos en un archivo conserva la distinción de mayúsculas y minúsculas, así como la distinción de valor, y cree que Abc y abc son dos ramas diferentes que identifican dos confirmaciones diferentes.

Cuando git rev-parse refs/heads/abc o git rev-parse refs/remotes/origin/abc obtiene su información de .git/packed-refs—Un archivo de datos que contiene cadenas— obtiene la información “correcta”. Pero cuando obtiene su información del sistema de archivos, un intento de abrir .git/refs/heads/abc o .git/refs/remotes/origin/abc realmente abre .git/refs/heads/Abc (si ese archivo existe en este momento) o la variante de seguimiento remoto con un nombre similar (si ese archivo existe), y Git obtiene la información “incorrecta”.

Configuración core.ignorecase (a cualquier cosa) no ayuda en absoluto ya que esto afecta solamente la forma en que Git se ocupa del plegado de cajas en el árbol de trabajo. Los archivos dentro de las bases de datos internas de Git no se ven afectados de ninguna manera.

Todo este problema nunca surgiría si, por ejemplo, Git usara una base de datos real para almacenar su mesa. El uso de archivos individuales funciona bien en Linux. No funciona bien en Windows y MacOS, de todos modos no de esta manera. Usando archivos individuales podría Trabaja ahí si Git no los almacenó en archivos con nombres legibles, por ejemplo, en lugar de refs/heads/master, quizás Git podría usar un archivo llamado refs/heads/6d6173746572, aunque eso reduce a la mitad la longitud disponible del nombre del componente. (Ejercicio: cómo es 0x6d m, 0x61 a, ¿etcétera?)


1Técnicamente, esta es la palabra incorrecta. Sin embargo, es descriptivo seguro. Una palabra mejor podría ser esquizoide, como se usa en el título de un episodio de The Prisoner, pero también tiene un significado equivocado. La palabra raíz aquí es realmente cisma, lo que significa dividido y algo opuesto a sí mismo, y eso es a lo que nos dirigimos aquí.

En Git, las ramas son solo indicadores de una confirmación. Las sucursales se almacenan como archivos sin formato en su .git repositorio.

Por ejemplo, puede tener abc y def archivos en .git/refs/heads.

$ tree .git/refs/heads/
.git/refs/heads/
├── abc
├── def
└── master

El contenido de estos archivos es solo el número de confirmación al que apunta la rama.

No estoy seguro, pero creo que la opción ignorecase solo es relevante para su directorio de trabajo, no el .git carpeta. Entonces para quitar el extraño ramas en mayúscula, es posible que solo necesite eliminar / cambiar el nombre de los archivos en .git/refs/heads.

Además de esto, el enlace ascendente de una sucursal local a una sucursal remota se almacena en el .git/config expediente. En este archivo puede tener algo como:

[branch "Abc"]
        remote = origin
        merge = refs/heads/abc

Observe en este ejemplo que la rama remota se llama Abc pero la sucursal local es abc (minúsculas).

Para resolver su problema, intentaría:

  1. Modificar el .git/config expediente
  2. Cambie el nombre de las ramas dañadas en .git/refs/heads tal como abc se renombra abc-old
  3. Prueba tu git pull

Te mostramos reseñas y puntuaciones

Si posees algún titubeo o disposición de ascender nuestro tutorial eres capaz de escribir una observación y con gusto lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *