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:
-
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 tuAbc
de tuabc
, 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
abc
yAbc
si uno o ambos pueden estar estropeados. Turemember-abc
tiene el correcto hash en él. -
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 nombradasAbc
yabc
ambos.Si no hay tales problemas en el servidor Linux, el paso 2 es “no hacer nada”.
-
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 localorigin
—No tiene malos nombres, y tu Git local ha convertido tu Git localorigin/*
los nombres coinciden con los nombres de las ramas. -
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
recordarabc
, puedes simplemente corrergit branch -m remember-abc abc
para moverseremember-abc
paraabc
.Si
abc
debería tenerorigin/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 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:
- Modificar el
.git/config
expediente - Cambie el nombre de las ramas dañadas en
.git/refs/heads
tal comoabc
se renombraabc-old
- 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.