¿Cuál es la cabeza en git?

232

Parece que hay una diferencia entre el último commit, HEAD y el estado del archivo que puedo ver en mi directorio.

¿Qué es HEAD, qué puedo hacer con él y qué error debo evitar?

e-satis
fuente
1
Comenzando con Git v1.8.4, todas las respuestas a continuación que usan HEADo headahora pueden usar @en lugar de HEAD. Vea esta respuesta (última sección) para saber por qué puede hacer eso.
3
Desde git-scm : HEAD en Git es el puntero a la referencia de rama actual, que a su vez es un puntero a la última confirmación que realizó o la última confirmación que se verificó en su directorio de trabajo. Eso también significa que será el padre de la próxima confirmación que hagas. En general, es más simple pensar que HEAD es la instantánea de su último commit.
Quazi Irfan
3
Posible duplicado de ¿Qué es HEAD en Git?
Buts

Respuestas:

185

HEAD es una referencia a la última confirmación en la rama actualmente desprotegida.


Hay una pequeña excepción a esto, que es la CABEZA separada. Un HEAD separado es la situación en la que terminas cada vez que revisas un commit (o etiqueta) en lugar de una rama. En este caso, tiene que imaginar esto como una rama temporal sin nombre; así que en lugar de tener una referencia de rama con nombre, solo tenemos HEAD. Todavía le permitirá realizar confirmaciones (lo que actualizará HEAD), por lo que la definición breve anterior sigue siendo cierta si piensa en un HEAD separado como una rama temporal sin nombre.

dar un toque
fuente
1
Entonces, ¿por qué puedes tener dos cabezas?
e-satis
1
@ e-satis: a veces verá ramas denominadas cabezas, se almacenan en ellas refs/heads. Sin HEADembargo, la cabeza en minúscula es diferente . Mi respuesta aclara esto un poco.
Cascabel
77
@ e-satis: Eso no es expresión regular. Esta ^es la notación de git para "el commit before", ese es el commit antes del actual. (Si la corriente es una fusión, usa el primer padre).
Cascabel
1
@ e-satis: Consulte la sección de revisiones de especificación de la página de manual de git-rev-list para obtener más información sobre todas las formas de especificar confirmaciones: esta es solo una pequeña pieza. kernel.org/pub/software/scm/git/docs/…
Cascabel
1
No, cuando rev y HEAD apuntan al mismo commit, no hay diferencia. E incluso podría escribir la identificación de confirmación (el valor SHA-1) en lugar de rev o HEAD. Y no te preocupes, no nos hostigas con las preguntas :) (al menos yo: P)
mete el
87

HEAD es una referencia (referencia) al commit actualmente desprotegido.

En estados normales, en realidad es una referencia simbólica a la rama que ha desprotegido; si mira el contenido de .git / HEAD, verá algo como "ref: refs / heads / master". La rama en sí es una referencia a la confirmación en la punta de la rama. Por lo tanto, en el estado normal, HEADefectivamente se refiere a la confirmación en la punta de la rama actual.

También es posible tener una "CABEZA separada". Esto sucede cuando verifica algo además de una rama (local), como una rama remota, una confirmación específica o una etiqueta. El lugar más común para ver esto es durante un rebase interactivo, cuando elige editar una confirmación. En el estado HEAD separado, su HEAD es una referencia directa a una confirmación: el contenido de .git / HEAD será un hash SHA1.

En términos generales, HEAD es solo un nombre conveniente que significa "lo que ha verificado" y realmente no tiene que preocuparse mucho por eso. Solo tenga en cuenta lo que ha extraído y recuerde que probablemente no quiera comprometerse si no está en una rama (estado HEAD separado) a menos que sepa lo que está haciendo (por ejemplo, en un rebase interactivo) .

Cascabel
fuente
66
Esto es algo que no entiendo. Si paga una rama remota, ¿por qué termina con una "CABEZA separada"? ¿Por qué no saltas automáticamente a la rama en tu repositorio local que corresponde a tu control remoto?
e-satis
3
@ e-satis: si desea la sucursal local, consulte la sucursal local. Recuerde que los dos no son necesariamente lo mismo: debe decirle al local que combine el remoto (o el pull). El seguimiento es solo para que sepa cuál extraer automáticamente cuando lo solicita. La razón por la que se desconecta es que la rama remota está destinada a ser un puntero a la última ubicación de la rama en el repositorio remoto. Si intenta comprometerse, el repositorio remoto no cambia, por lo que la rama remota tampoco debería hacerlo.
Cascabel
1
OK, eso es lo que no obtuve: tener una sucursal local nombrada de alguna manera no implica que sea la misma que la remota. Muy difícil de conseguir al principio porque vengo de un fondo SVN :-) Gracias hombre. Por cierto, ¿cómo mueves un HEAD sin cabeza a una sucursal local para comprometerlo aquí?
e-satis
3
@ e-satis: La respuesta general es git rebase <branch> HEAD. Esto encontrará el último antepasado común de <branch>y HEAD, y luego tomará todas las confirmaciones desde allí HEADy las aplicará (reorganizarlas) <branch>. Esencialmente hace esto aplicándolos como parches, por lo que si las dos ramas son realmente diferentes, podría haber conflictos. Pero si <branch>es un antepasado de HEAD(es decir, estaba en el lugar correcto, simplemente olvidó que se había separado HEAD), el rebase es solo una fusión de avance rápido.
Cascabel
3
Esta es una de las descripciones más claras y precisas de git HEAD que he visto, después de buscar por un tiempo.
LarsH
21

Siempre pensé que HEAD~5significa IR a 5 commits antes. Pero no lleva la parte GO del comando. Solo lleva la referencia / 'dónde' parte del comando.

En términos simples, se utiliza para responder la pregunta de: ¿A dónde debo ir? ¿A qué compromiso?

  • HEAD significa (la referencia a) la confirmación actual
  • HEAD~1 significa (la referencia a) 1 commit antes
  • HEAD~ TAMBIÉN significa (la referencia a) 1 commit antes
  • HEAD~87 significa (la referencia a) 87 confirma antes

Uso:

  • git checkout HEAD~1 irá / saldrá a 1 commit / referencia antes
  • git reset HEAD~3 cancelará sus últimas 3 confirmaciones, sin eliminar los cambios, es decir, puede ver todos los cambios realizados en las últimas 3 confirmaciones juntas, eliminar cualquier cosa que no le guste o agregar a ellas y luego volver a confirmarlas.
  • git reset --hard HEAD~3cancelará su última confirmación y eliminará sus cambios . Eliminará por completo esos cambios. Para más información ver aquí .
  • git diff HEAD~3 para verificar los cambios en los últimos 3 commits
Miel
fuente
3
volviendo a mi propia respuesta :)
Honey
15

HEAD puntero en Git

Git mantiene una variable de referencia llamada HEAD. Y llamamos a esta variable un puntero, porque su propósito es hacer referencia, o señalar, una confirmación específica en el repositorio. A medida que realicemos nuevos compromisos, el puntero cambiará o se moverá para señalar un nuevo compromiso. HEAD siempre apunta a la punta de la rama actual en nuestro repositorio. Ahora, esto tiene que ver con nuestro repositorio, no con nuestro índice de ensayo o nuestro directorio de trabajo.

Otra forma de pensar es el último estado de nuestro repositorio o lo que se verificó por última vez, y porque es donde se detuvo el repositorio o el último estado, también puede decir que HEAD señala al padre del próximo commit o es donde se llevará a cabo la escritura de compromiso.

Creo que una buena metáfora para pensar en esto es la reproducción y el cabezal de grabación en una grabadora de cassette. Cuando comenzamos a grabar audio, la cinta pasa la cabeza y graba en ella. cuando presionamos Parar, el lugar donde se detiene el cabezal de grabación es el lugar donde comenzará a grabar nuevamente cuando presionamos Grabar por segunda vez. Ahora podemos movernos, podemos mover la cabeza a diferentes lugares, pero donde sea que esté la cabeza cuando presionamos Grabar nuevamente, ahí es donde comenzará a grabar.

El puntero HEAD en Git es muy similar, señala el lugar donde vamos a comenzar a grabar a continuación. Es el lugar donde dejamos en nuestro repositorio las cosas que hemos comprometido.

Suhail Gupta
fuente
0

En términos simples, HEAD es una referencia a la última confirmación en la rama de pago actual.

Piense en la CABEZA como la "rama actual". Cuando cambia de sucursal con git checkout, la revisión HEAD cambia para apuntar a la punta de la nueva sucursal.

Puede ver lo que HEAD señala haciendo:

cat .git/HEAD

Es posible que HEAD haga referencia a una revisión específica que no está asociada con un nombre de sucursal. Esta situación se llama CABEZA separada.

Testilla
fuente