Saltar al contenido

La rama de Git no muestra todas las ramas

Nuestro grupo de redactores ha estado horas investigando para darle solución a tu interrogante, te compartimos la soluciones por esto nuestro objetivo es servirte de gran ayuda.

Solución:

Cuando clona un repositorio existente, su Git crea un repositorio nuevo y diferente, y lo copia en este nuevo repositorio. todos1 de las confirmaciones y ninguna de las ramas del repositorio original. los último paso de git clone es crear uno rama. Este nombre de rama es tuyo, no de ellos; es solo deletreado lo mismo como uno de sus nombres.

A medida que trabaja con su clon, un repositorio diferente, puede agregarle más y más ramas. Si le agregas todo el mismo ramas que están en el repositorio original, ahora tiene todas sus confirmaciones y todos sus nombres de sucursales (como sus propias sucursales, claro). Pero hasta entonces, solo tienes todos sus comete. Eso está bien, porque Git no se trata de ramas. Git se trata de comete.


1La descripción precisa es mucho más complicada que esto, pero pensar en ella como “copiar todas sus confirmaciones y ninguna de sus ramas” lo ayudará a comenzar.


Traté de resolver el problema clonando la rama dentro de una nueva carpeta (escrita git clone -b) y ahora solo aparece la rama que cloné ..

Cuando crea un nuevo clon, que, de nuevo, es un nuevo repositorio, donde obtienes todas las confirmaciones del repositorio anterior pero ninguna de sus ramas todavía, el último paso del git clone comando es ejecutar un git checkout o git switch mando2 eso hace una rama. los -b la bandera existe para que puedas decirle a tu Git cuales de sus nombres de sucursales para copiar, como último paso. Si omite el -b bandera, su Git pregunta a su repositorio de Git, el que está clonando, qué rama ellos recomendar. Pero de cualquier manera, solo obtienes una rama.

En realidad no necesitas alguna nombres de sucursales para trabajar en Git. Tu necesitas algunos Sin embargo, el tipo de nombre y los nombres de sucursales son el mejor tipo de nombre aquí. Es por eso que su Git hace un nombre al final del git clone proceso. Cada nombre que hagas te da una cosa más con la que trabajar.

Para entender lo que está pasando, sigue leyendo. Si está satisfecho con la respuesta a su pregunta inmediata, puede detenerse aquí.


2los git switch El comando se agregó por primera vez en la versión 2.23 de Git, para dividir el demasiado complicado git checkout comando en dos comandos separados, git switch y git restore. La existencia git checkout permanece; puede usarlo en lugar de los dos comandos nuevos y más simples. Sin embargo, los nuevos comandos simplificados son, en cierto sentido, más seguros: git switch El comando trata de ser muy seguro, al igual que la mitad de git checkout que copió. los git restore el mando, sin embargo, es deliberadamente inseguro en el sentido de que destruirá irrevocablemente el trabajo; copia la otra mitad de git checkout. Entonces, si usas git checkout, puedes invocar accidentalmente la mitad “destruir mi trabajo” cuando pensar estás invocando la mitad de “hacer las cosas con seguridad”.


Git se trata de confirmaciones

Para comprender qué está haciendo Git aquí y por qué lo hace así, comience con el hecho de que Git en sí se trata realmente de confirmaciones. No se trata de ramas, aunque los nombres de las ramas te ayudan (y a Git) encontrar se compromete. No se trata de archivos, aunque confirma Contiene archivos. Realmente se trata de las confirmaciones: todo lo demás que hace Git está al servicio de retener y agregar confirmaciones. Las confirmaciones son donde comienzan las cosas y son el propósito de todo lo demás.

Esto significa que es crucial entender qué es un compromiso. es, Como tu nombrar una confirmación en particulary como haces un nuevo cometer. Empecemos por el nombre.

El verdadero nombre de una confirmación es su ID de hash

Podría pensar que el nombre de una rama nombraría una confirmación, y de alguna manera lo hace, pero indirectamente. De hecho, cada confirmación se nombra por su número. Cada confirmación tiene un número único. Ningún otro compromiso puede tener ese número: una vez que se realiza ese compromiso, ese número se asigna a ese cometer. Debido a que esa confirmación ocupa ese número para siempre, el número tiene que ser realmente grande, y lo es. Actualmente, cada confirmación de Git obtiene una de 2160 números posibles.3 Este número se expresa en hexadecimal como una cadena grande y fea como e31aba42fb12bdeb0f850829e008e1e3f43af500 (esta es una confirmación real en un repositorio de Git para Git).

Este número siempre funciona: si tiene este compromiso, ese es su número, y git show e31aba42fb12bdeb0f850829e008e1e3f43af500 lo mostrará, por ejemplo. Por lo general, puede abreviar el número, a tan solo los primeros cuatro caracteres si no es ambiguo, por lo que si tiene un clon del repositorio de Git para Git, git show e31aba42fb12bdeb0f850829e008 está casi garantizado que funcionará. Pero git show e31a no lo hace porque podría ser la abreviatura de esta confirmación o de confirmación e31a17f741..., por ejemplo. Tiempo e31ab funciona hoy, a medida que se agregan más confirmaciones, es posible que deje de funcionar.

Estos números Mira aleatorio, pero no lo son. De hecho, cada uno es una suma de comprobación criptográfica del contenido completo de la confirmación.4 Git hace una doble verificación cuando extrae cualquiera de sus objetos internos, incluidas las confirmaciones, que la suma de verificación aún coincide, para detectar fallas de almacenamiento: le dice a Git que busque una confirmación (u otro objeto) por ID de hash y verifica que el hash ID todavía coincide. Por tanto, esto a su vez significa que ninguna parte de ninguna confirmación, ni ninguno de los otros objetos internos de Git, puede cambio, cualquiera. Puedes hacer nuevo unos, cada uno de los cuales obtiene un ID nuevo y diferente, pero esto no afecta a los existentes, que permanecen en el repositorio.


3Hay planes para rehacer el sistema de numeración para usar 2256 números, con una especie de transición fea.

4De hecho, todos los objetos internos de Git usan este esquema. Esto significa todos los objetos guardados se congelan para siempre. Así es como Git congela y elimina los duplicados del contenido del archivo, por ejemplo.


¿Qué hay en un compromiso?

Ahora que conocemos una, y la más profunda, por así decirlo, forma de buscar una confirmación, por su ID de hash, es hora de ver qué hay dentro de cada confirmación. Cada confirmación tiene dos partes:

  • Un compromiso tiene un instantánea completa de todos sus archivos. Estos son los datos principales de la mayoría de las confirmaciones (y normalmente también la mayor parte del repositorio). Cada archivo se almacena como un interno objeto blob, usando este mismo truco de codificación de nombres hash. Esto automáticamente elimina los duplicados de los archivos, de modo que si realiza un centenar de confirmaciones seguidas que en su mayoría reutilizan la mayoría de sus archivos, en realidad no ocupan espacio adicional.

  • Cada compromiso también contiene algunos metadatos, o información sobre el compromiso en sí: quién lo hizo, cuándo y por qué, por ejemplo. La parte del “por qué” es su mensaje de registro: su propia explicación para usted mismo y / o para otros más adelante. Por que es esta comprometerse mejor que el anterior? O al menos, por qué es diferente, si no es necesariamente mejor. El objetivo de esta confirmación en particular podría ser corregir algún error, agregar alguna característica nueva o preparar algo para agregar una nueva característica, o lo que sea. La confirmación en sí tiene el código fuente actualizado, pero no necesariamente nada sobre el insecto que se supone que debe solucionar la actualización. Esta es tu oportunidad de explicar eso.

Hay una parte de los metadatos que Git genera para usted y luego usa más tarde, que rara vez ve directamente, y es esta: cada confirmación contiene el ID de hash sin procesar de su confirmación predecesora inmediata. Estas cuerdas se comprometen juntas, hacia atrás, en una cadena de confirmaciones que termina con la última confirmación.

Podemos dibujar esto. Imagina que tenemos un repositorio con solo tres confirmaciones. En lugar de ID de hash reales, usaremos letras mayúsculas individuales para reemplazar las confirmaciones. El primer compromiso será A, el próximo será B, y el tercer compromiso es el compromiso C:

A <-B <-C

Desde cometer C es el último, tiene un compromiso anterior BID de hash en sus metadatos. Nosotros decimos eso Cpuntos aB. De la misma manera, comete B puntos a A. Ya que A es la primera confirmación realizada, carece de esta flecha que apunta hacia atrás: no apunta a ninguna parte. Git llama a esto un (o el) compromiso de root. Es donde llegamos a dejar de trabajar al revés.

Hace un momento mencioné que cada confirmación tiene una instantánea completa de cada archivo. Pero si tienes Git show un compromiso, Git te muestra lo que cambió. ¿Cómo y por qué hace esto Git?

los por qué es quizás el más fácil de explicar. Si desea ver todos los archivos que están en el compromiso, puedes simplemente verificar el compromiso. Git copiará todos esos archivos fuera de la confirmación, donde, recuerde, se almacenan en un formato Git congelado especial, deduplicados (y comprimidos también) en archivos de computadora ordinarios. Probablemente tenga un montón de visores de archivos que son más competentes de lo que Git podría ser: pueden mostrarle imágenes como imágenes, abrir documentos de texto en editores de texto, abrir archivos PDF con visores de PDF, etc. Pero su visor de archivos probablemente hipocresía compare la instantánea completa con la instantánea completa anterior. Git pueden.

Git puede comparar instantáneas C contra instantánea B con bastante facilidad, porque comete C mantiene el compromiso BID de hash. Entonces Git solo puede extraer ambos se compromete. Además, debido a la forma en que Git elimina los archivos duplicados, Git puede saberlo de inmediato, y ni siquiera molestar extrayendo — los archivos duplicados. Git solo necesita extraer y comparar el diferente archivos. Git hará eso y construirá un conjunto de cambios que convertirán los archivos antiguos en los nuevos. Eso es lo que te mostrará Git: este conjunto de instrucciones.

(Tenga en cuenta que Git crea el conjunto de instrucciones a pedido. Hasta que le pida a Git que compare dos confirmaciones, todo lo que Git tiene son las dos instantáneas. Puede obtener diferentes conjuntos de instrucciones según las opciones que pase al comando de comparación. Por ejemplo, Git puede realizar la verificación de diferencias basándose en palabras o, de lo contrario, ignorar ciertos tipos de cambios en los espacios en blanco. Las habilidades de Git aquí no siempre son tan buenas como nos gustaría, pero hay algunos trucos que podemos usar. Sin embargo, están fuera del alcance de esta respuesta en particular).

Encontrar confirmaciones por nombres de rama

Ya sabemos que si memorizamos los ID de hash grandes y feos (o los escribimos), podemos usarlos para encontrar confirmaciones. Pero esto es ridículo. Tenemos una computadora. ¿Por qué no tenemos el computadora anote los ID de hash para nosotros?

Esto es lo que hace un nombre de rama. Pero es un poco astuto. Lo que realmente hace un nombre de sucursal es almacenar solo el último Confirmar el ID de hash. Dibujemos ese repositorio de tres confirmaciones nuevamente y agreguemos un nombre, main, que identifica el último cometer:

A--B--C   <-- main

Aquí, en lugar de intentar recordarCID de hash, solo sabemos que el nombre main hace eso por nosotros. Entonces git checkout main (Git anterior a 2.23) o git switch main (2.23 y posterior) nos da la última confirmación, actualmente C—Sin importar qué ID de hash tenga.

Ahora podemos agregar un nuevo nombre que también apunta a comprometerse C:

A--B--C   <-- main, dev

Ahora necesitamos una cosa más: ¿cuál de estos nombres estamos usando? En este momento, no importa mucho, porque ambos nombres seleccionan confirmar C. Pero adjuntemos el nombre especial HEAD a uno de los dos nombres de rama, así:

A--B--C   <-- main (HEAD), dev

Si nosotros git switch dev, volvemos a adjuntar el nombre especial HEAD al nombre dev, como esto:

A--B--C   <-- main, dev (HEAD)

Ahora hagamos un nuevo cometer. Sin preocuparse por cómo hacemos un nuevo compromiso, supongamos que todo está hecho. Este nuevo compromiso D necesariamente, apuntará a un compromiso existente C, porque hicimos DdeC. Así que se ve así:

A--B--C
       
        D

Pero D es ahora el más reciente commit, por lo que Git tiene que actualizar un nombre. ¿Qué nombre debería actualizar? La respuesta es clara: conviene actualizar la que HEAD está adjunto a:

A--B--C   <-- main
       
        D   <-- dev (HEAD)

Ahora tenemos dos nombres de rama, y ​​los dos nombres especifican dos diferente confirmaciones "más recientes". El último compromiso en main es Cy la última confirmación de dev es D. Cometer D apunta hacia atrás para comprometerse C, que apunta a B, que apunta a A; entonces las cuatro confirmaciones son sobre rama dev, mientras que tres de ellos están en main.

Si volvemos al nombre main y hacer un nuevo compromiso allí, obtenemos:

        E   <-- main (HEAD)
       /
A--B--C
       
        D   <-- dev

lo que significa que ahora tenemos tres confirmaciones que se comparten en ambas ramas, y una confirmación que está solo en main y un compromiso que solo está en dev. Ahora nosotros necesitarambos nombres para encontrar las cinco confirmaciones; un nombre encontrará una confirmación, que encontrará las tres compartido confirma, pero necesitamos el otro nombre para encontrar la última confirmación restante.

Tenga en cuenta que los nombres de las ramas moverse. De hecho, se mueven automáticamente, a medida que realizamos nuevas confirmaciones: el nombre de la rama que tenga HEAD adjunto a él se mueve automáticamente para abarcar la nueva confirmación. Todos los otros nombres de sucursales permanecen en su lugar en ese momento, pero debido a que son nuestro nombres de sucursales, nosotros tenemos el control. Podemos hacer que nuestro Git mueva esos nombres en cualquier momento que queramos. La única restricción es que tenemos que tener un cometer para mover el nombre.

La clonación crea nombres de seguimiento remoto

Cuando clonamos el repositorio de otra persona, obtenemos todas sus confirmaciones y ninguna de sus ramas. ¿Como funciona esto? Bueno, supongamos que tenemos lo anterior, con dos nombres de sucursales reales main y dev seleccionando confirmaciones E y D respectivamente. Ahora hacemos un nuevo repositorio donde copiamos las cinco confirmaciones, dándonos:

        E
       /
A--B--C
       
        D

De hecho, necesitamos dos nombres para encontrar todas las confirmaciones. Pero no necesitamos rama nombres. El otro Git, que trabaja con el otro repositorio, tiene nombres de rama, porque son su ramas que moverá a medida que realice nuevas confirmaciones. Entonces, lo que hace nuestro Git es copia sus nombres pero cámbialos. Tenemos a nuestro Git tomando su rama nombres y crea nuestro nombres de seguimiento remoto, agregando algo, generalmente origin/—A los nombres.5 Entonces obtenemos:

        E   <-- origin/main
       /
A--B--C
       
        D   <-- origin/dev

Git se negará a adjuntar el nombre especial HEAD a uno de estos nombres de seguimiento remoto. HEAD solo se permite adjuntar a un rama nombre. Así que el último paso de nuestro git clone es usar el -b opción, o su recomendación, para elegir uno de estos dos nombres y crear un nombre de rama a partir de él, como este:

        E   <-- main (HEAD), origin/main
       /
A--B--C
       
        D   <-- origin/dev

Tenga en cuenta que el nombre de nuestra sucursal selecciona el mismo compromiso como el nombre de seguimiento remoto que nuestro git clone Hecho de su nombre de la sucursal. Pero ahora solo tenemos un nombre de rama, no dos. Si corremos:

git switch dev

esto usa una característica especial que proporciona Git, que encuentra su origin/dev y crea nuestro propio nombre nuevo dev:

        E   <-- main, origin/main
       /
A--B--C
       
        D   <-- dev (HEAD), origin/dev

y ahora tenemos dos nombres de sucursales. Pero inicialmente no lo hicimos. Tenga en cuenta que ahora también tenemos commit D comprobado, en lugar de comprometerse E, porque git switch (o git checkout, si usamos eso) no solo cambia las ramas, sino que también selecciona la confirmación que el nombre de la rama identifica, como la confirmación que se va a verificar y, por lo tanto, está disponible para que trabajemos.


5Técnicamente, un nombre de seguimiento remoto se encuentra en un espacio de nombres. Nuestro Git no se limita a virar origin/ al frente, reemplaza refs/heads/ con refs/remotes/origin/. El nombre origin es en realidad un remoto y podemos tener tantos controles remotos como queramos en nuestro repositorio de Git. Pero este es un tema para otra pregunta.

Notas:

  • puedes clonar una rama específica con git clone --branch --single-branch
  • puede tener varios árboles de trabajo (sin tener que copiar toda la carpeta) con git worktree

Para ramas, use git branch -avv para obtener una lista de todas las sucursales locales y remotas.
Luego intente nuevamente su copia y compare git branch -avv cuando se hace en la nueva carpeta copiada: si falta una rama remota, un simple git fetch será suficiente.

Para asegurarse de tener toda la información actualizada sobre las sucursales de Github (su control remoto), puede hacer un git fetch:

git fetch --all

Donde el --all bandera obtiene ramas de todos los controles remotos. Si tan solo quisieras ver todas las ramas (en su máquina y en su GitHub), puede hacer un git branch:

git branch -av

Dónde -a muestra sucursales de locales y remotos, y -v da una salida más detallada.

Recuerda algo, que tienes autorización de decir si te fue útil.

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



Utiliza Nuestro Buscador

Deja una respuesta

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