¿Por qué mi repositorio Git entró en un estado HEAD separado?

387

Terminé con una cabeza separada hoy, el mismo problema que se describe en: git push dice que todo está actualizado a pesar de que tengo cambios locales

Hasta donde sé, no hice nada fuera de lo común, solo me comprometí y presioné desde mi repositorio local.

Entonces, ¿cómo terminé con un detached HEAD?

Adam Bergmark
fuente
18
Verificar una rama remota parece ser la forma más común de hacer esto accidentalmente; Otra forma común es verificar branch-name@{n}, la enésima posición anterior de branch-name. Pero no importa qué, en algún momento debe haber habido un git checkout <rev>. Si eso no suena, entonces probablemente hiciste lo que Will mencionó: trató de hacer git checkout <file>y logró especificar una revisión por accidente.
Cascabel
3
Para deshacer un estado HEAD separado, consulte ¿ Arreglar una cabeza separada Git? .
Mi repositorio terminó en este estado cuando se encontraron conflictos durante el rebase. Afortunadamente, Git me dijo qué hacer cuando corrí git status:all conflicts fixed: run "git rebase --continue"
Paul
2
También sucede si accidentalmente escribe en git checkout remotes/origin/my-branchlugar de git checkout my-brancho git checkout origin/my-branch.
Adam Libuša el
@adam Libusa, gracias, funcionó para mí. ¿Cuál es la diferencia entre git checkout remotes / origin / my-branch y git checkout my-branch? ¿No es lo mismo? pero lo que dijiste funcionó para mí. Por curiosidad estoy preguntando.
Karunakar bhogyari

Respuestas:

281

Cualquier pago de un commit que no sea el nombre de una de sus sucursales le dará un HEAD separado. Un SHA1 que representa la punta de una rama todavía da una CABEZA separada. Solo el pago de un nombre de sucursal local evita ese modo.

Ver comprometerse con una CABEZA separada

Cuando HEAD está desconectado, los commits funcionan de manera normal, excepto que no se actualiza ninguna rama con nombre. (Puedes pensar en esto como una rama anónima).

texto alternativo

Por ejemplo, si desprotege una "rama remota" sin rastrearla primero, puede terminar con un HEAD separado.

Ver git: cambiar de rama sin separar la cabeza


Con Git 2.23 (agosto de 2019), ya no tiene que usar el comando confusogit checkout .

git switch también puede pagar una rama y obtener un HEAD de separación, excepto:

  • tiene una --detachopción explícita

Para verificar el compromiso HEAD~3de inspección temporal o experimento sin crear una nueva sucursal:

git switch --detach HEAD~3
HEAD is now at 9fc9555312 Merge branch 'cc/shared-index-permbits'
  • no puede separar por error una rama de seguimiento remota

Ver:

C:\Users\vonc\arepo>git checkout origin/master
Note: switching to 'origin/master'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

Vs. usando el nuevo git switchcomando:

C:\Users\vonc\arepo>git switch origin/master
fatal: a branch is expected, got remote branch 'origin/master'

Si desea crear una nueva sucursal local que rastrea una sucursal remota:

git switch <branch> 

Si <branch>no se encuentra, pero existe una rama de seguimiento en exactamente un control remoto (llámelo <remote>) con un nombre coincidente, trate como equivalente a

git switch -c <branch> --track <remote>/<branch>

¡No más errores!
¡No más CABEZA separada no deseada!

VonC
fuente
12
Otra forma de ingresar al estado de la cabeza separada es si está en medio de un rebase interactivo y desea editar una de las confirmaciones. Cuando Git te deje en el commit para editar, estarás en un estado de cabeza separada hasta que termines el rebase.
En esta guía visual, hay esta explicación: git commit files creates a new commit containing the contents of the latest commit, plus a snapshot of files taken from the working directory. Additionally, files are copied to the stage.¿Qué significa "los archivos se copian en el escenario"? Pensé que los archivos estaban confirmados, lo que significa que la etapa está despejada.
máximo
16
De hecho, obtendrá un HEAD separado cada vez que compruebe cualquier confirmación por parte de su SHA1, ya sea que esté o no en la punta de una rama; El único tipo de cosa que puede pagar sin obtener un HEAD separado es un nombre de sucursal. Por ejemplo, aunque masteresté en ed489el diagrama de arriba, git checkout ed489le dará un HEAD separado, mientras git checkout masterque no lo hará.
musiphil
8
"You can think of this as an anonymous branch":) Me gusta la analogía
Adrien Be
118

Reproduje esto hace un momento por accidente:

  1. enumera las ramas remotas

    git branch -r
          origin/Feature/f1234
          origin/master
    
  2. Quiero pagar uno localmente, así que corté pegar:

    git checkout origin/Feature/f1234
    
  3. ¡Presto! Estado HEAD separado

    You are in 'detached HEAD' state. [...])
    

Solución # 1:

No incluya origin/en la parte delantera de la especificación de mi rama cuando la revise:

git checkout Feature/f1234

Solución # 2:

Agregar -bparámetro que crea una rama local desde el remoto

git checkout -b origin/Feature/f1234 o

git checkout -b Feature/f1234 volverá a su origen automáticamente

Owen
fuente
14
Esta es casi una gran respuesta, pero no explica por qué entraste en un estado de cabeza desprendida.
Ganso
55
Estoy de acuerdo pero proporciona la solución que estaba buscando. ¡¡Gracias!!
Kilmazing
Vi en esta otra respuesta que git checkout -b Feature/f1234<=> git branch Feature/f1234y git checkout Feature/f1234.
Footfoot
1
de forma predeterminada, se ve en el origen, por lo que cuando se da origin/branchname, se busca origin/origin/branchnamedecir que el primero es el nombre remoto que usa -b, si no lo hace, crea una anonymousrama que se separa. Del mismo modo, para retirar desde un control remoto diferente, tendría que mencionar el -bparámetro; de lo contrario, git no tiene una manera de saber que es desde un nuevo control remoto, lo buscará origin/remote/branchname.
garg10may
Eres un santo!
Harvey Lin
12

tratar

git reflog 

esto le brinda un historial de cómo su HEAD y los punteros de rama se movieron en el pasado.

p.ej :

88ea06b HEAD @ {0}: pago: pasar de DESARROLLO a controles remotos / origen / SomeNiceFeature e47bf80 HEAD @ {1}: extraer origen DESARROLLO: Avance rápido

la parte superior de esta lista es una razón por la que uno podría encontrarse con un estado de CABEZA DESCONECTADA ... revisando una rama de seguimiento remoto.

André R.
fuente
7

Puede suceder fácilmente si intenta deshacer los cambios que ha realizado al volver a extraer los archivos y no obtener la sintaxis correcta.

Puede ver el resultado de git log: puede pegar la cola del registro aquí desde la última confirmación exitosa, y todos podríamos ver lo que hizo. O bien, puede pegarlo y preguntar #gitsobre IRC de freenode.

Será
fuente
5

Puede suceder si tiene una etiqueta con el mismo nombre que una rama.

Ejemplo: si "release / 0.1" es el nombre de la etiqueta, entonces

git checkout release/0.1

produce CABEZA separada en "release / 0.1". Si espera que release / 0.1 sea un nombre de sucursal, se confunde.

radzimir
fuente
1
Si. ¿Pero cómo arreglas eso? ¿Cómo hacer un pago de la sucursal?
Martin
5

Detached HEAD significa que lo que está actualmente desprotegido no es una sucursal local.

Algunos escenarios que resultarán en un Detached HEADestado:

  • Si paga una sucursal remota , diga origin/master. Esta es una rama de solo lectura. Por lo tanto, cuando se crea una confirmación a partir de origin/masterella, será flotante , es decir, no estará conectada a ninguna rama.

  • Si revisa una etiqueta o confirmación específica . Al realizar una nueva confirmación desde aquí, volverá a flotar libremente , es decir , no estará conectada a ninguna rama. Tenga en cuenta que cuando se desprotege una rama , las nuevas confirmaciones siempre se colocan automáticamente en la punta.

    Cuando desee regresar y pagar una confirmación o etiqueta específica para comenzar a trabajar desde allí, puede crear una nueva rama que se origine a partir de esa confirmación y cambiar a ella git checkout -b new_branch_name. Esto evitará el Detached HEADestado ya que ahora tiene una rama desprotegida y no una confirmación.

Tim Skov Jacobsen
fuente
3

Una forma accidental simple es hacer un git checkout headcomo un error tipográfico de HEAD.

Prueba esto:

git init
touch Readme.md
git add Readme.md
git commit
git checkout head

lo que da

Note: checking out 'head'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b <new-branch-name>

HEAD is now at 9354043... Readme
Thomas Weller
fuente
También mencionado en longair.net/blog/2012/05/07/the-most-confusing-git-terminology (busque "“ HEAD ”y“ head ”")
VonC
@VonC: gracias por ese enlace. Estoy preparando un entrenamiento de Git y también quiero señalar por qué a veces es tan confuso. Ya tengo muchos ejemplos (como el checkout -bque parece un pago pero en realidad se ramifica) pero otra lista es bienvenida.
Thomas Weller
2

La otra forma de entrar en un estado de cabeza separada de git es intentar comprometerse con una rama remota. Algo como:

git fetch
git checkout origin/foo
vi bar
git commit -a -m 'changed bar'

Tenga en cuenta que si hace esto, cualquier intento adicional de verificar origen / foo lo devolverá a un estado de cabeza separada.

La solución es crear su propia sucursal local de foo que rastree el origen / foo, luego opcionalmente presione.

Probablemente esto no tenga nada que ver con su problema original, pero esta página tiene muchos éxitos de Google para "git detached head" y este escenario está muy poco documentado.

dspeyer
fuente
Esta situación parece ser de lo que habla la respuesta anterior de Owen, donde cortar y pegar "origin / foo" hace que git piense en ella como "origin / origin / foo".
mvanle
1

Cuando finaliza la compra en un commit git checkout <commit-hash>o en una rama remota, su HEAD se separará e intentará crear un nuevo commit en él.

Las confirmaciones a las que ninguna rama o etiqueta puede acceder serán basura recolectada y eliminada del repositorio después de 30 días.

Otra forma de resolver esto es mediante la creación de una nueva rama para el commit y checkout recién creado. git checkout -b <branch-name> <commit-hash>

Este artículo ilustra cómo puede llegar al estado HEAD separado .

Nesha Zoric
fuente