GIT restaura el último HEAD separado

85

Por favor, tengo un gran problema en mi proyecto: este es el escenario. Tengo un proyecto de xcode en GIT. Hoy me di cuenta de que la última confirmación rompió algunas pruebas, así que revisé la confirmación anterior. Usé SourceTree y esta es la advertencia

Si lo hace, su copia de trabajo se convertirá en una 'HEAD separada', lo que significa que ya no estará en una rama. Si desea comprometerse después de esto, probablemente desee volver a verificar una rama o crear una nueva rama. ¿Esta bien?

Trabajé todo un día y al final lo comprometí todo. Así que necesitaba fusionar mi trabajo en la rama de desarrollo, así que revisé la rama de desarrollo y ... mi trabajo desapareció instantáneamente :(

Sé que estuvo mal separar mi CABEZA y Sourcetree me advirtió ... pero ¿hay una manera de restaurar mi trabajo?

IgnazioC
fuente
Un hilo relacionado para el mismo problema aquí y los detalles técnicos sobre cómo sucede aquí .
RBT

Respuestas:

254

Si escribe git reflog, le mostrará el historial de las revisiones HEADseñaladas. Tu cabeza separada debería estar ahí. Una vez que lo encuentre, haga git checkout -b my-new-branch abc123o git branch my-new-branch abc123(dónde abc123está el SHA-1 de la CABEZA separada) para crear una nueva rama que apunte a su cabeza separada. Ahora puede fusionar esa rama a su gusto.

En general, si revisa una rama después de trabajar en una cabeza separada, Git debería informarle la confirmación de la cabeza separada en la que había estado, para que pueda recuperarla si lo necesita. Nunca he usado SourceTree, así que no sé si transmite ese mensaje. Pero si mostró ese mensaje, entonces debería poder usarlo para encontrar la confirmación, y nuevamente usar git checkout -bo git branchpara crear una rama a partir de esa confirmación.

Brian Campbell
fuente
4
Gracias Brian. Salvaste mi día.
Muzammil
Brian, ¡me salvaste la vida! ¡¡Gracias!!
cldrr
Soy nuevo en git ... obtengo fatal: A branch named 'mybranch' already exists.¿Cómo agregar una rama existente?
Ramesh Murugesan
1
Como anuncio de servicio público para todos los que agradecen a Brian: si estás haciendo un trabajo que no quieres perder, colócalo en un control remoto (por ejemplo, github) cada pocas horas. Cuando un meteoro cae sobre su computadora, se alegrará de haberlo hecho. Si aún no está listo para compartirlo con colaboradores, simplemente colóquelo en una rama que nadie conozca por ahora y luego vuelva a basarlo en master más tarde.
MatrixManAtYrService
1
Además, si es una única confirmación perdida que acaba de desaparecer y la encontraste allí, puedes traerla de vuelta con git cherry-pick e5b2f7b, ¿dónde e5b2f7bestá el SHA-1 de la confirmación?
Aidin
10

En Sourcetree, puede hacer esto usando la GUI.

Primero busque la confirmación "perdida" buscando un mensaje en el Historial de comandos (ver: Mostrar salida de comando). Probablemente estará en el comando "Cambio de rama" después de la confirmación que perdió. En ese mensaje, con suerte verá el comentario de confirmación con un ID de confirmación 1234567.

Lleve ese ID de confirmación al siguiente paso.

Presione el botón "Rama" en la barra de herramientas superior y debería obtener un cuadro de diálogo "Nueva rama" donde puede especificar una determinada confirmación. Coloque ese ID de confirmación allí, especifique un nuevo nombre de rama, presione Crear rama y debería obtener una nueva rama con su confirmación perdida.

ingrese la descripción de la imagen aquí

blalond
fuente
realmente funciona. Asegúrese de ver el comentario correcto con el ID de confirmación.
Hammad Khan
@blalond Hola, Después de leer su respuesta, tengo una pequeña pregunta: cuando en SourceTree hago doble clic en un compromiso anterior (para verificarlo), recibo el mismo mensaje de que esto causaría un desprendimiento de la cabeza, así que me pregunto ¿Qué significa cuando la gente dice que simplemente puede volver a cualquier revisión anterior con git? Entonces, ¿cómo retrocedo a una confirmación en particular? Gracias
5

Si no desea mantener los cambios de HEAD separado y desea ir a la última confirmación de rama, use el siguiente comando directamente.

git checkout - 

Nota: Eliminaré todos sus cambios en el HEAD separado.

Rosa del desierto
fuente
El OP solicitó mantener su trabajo. Esto no responde a la pregunta original. Simplemente agregar la opción para mantener eso en una rama haría que esta respuesta fuera útil.
manuelvigarcia
1

Un colega mío acaba de tener esta situación. En su caso, hubo commits en cabecera desprendida - trabajan en R-Studio-- y la herramienta sí les advirtió que podían crear la rama con esta y aquella referencia SHA ... pero como la única opción era "Cerrar" --¡¡duh !! era un cuadro de información: cerraron el diálogo y perdieron la información para siempre ...

Gracias al reflogcomando pudimos ver que los cambios no se perdieron. Pero en nuestro caso, el git branchno funcionó como se esperaba ... o un entrante git pulllo estropeó de alguna manera. Tuvimos que pescar los cambios del reflog a la rama recién creada:

 git cherry-pick 0b823d42..3cce27fc

que colocó todas las confirmaciones que queríamos en la rama. Entonces podríamos fusionar la rama developsin problemas.

En caso de que esto sea informativo para alguien, identificamos las confirmaciones en la cabeza separada en el reflogal mirar las que están entre las marcadas con "checkout" (que identifican el cambio de rama):

e09f183b HEAD@{3}: pull: Fast-forward
b5bf3e1d HEAD@{4}: checkout: moving from lost_changes to develop
b5bf3e1d HEAD@{5}: checkout: moving from 3cce27fca50177a288df0252f02edd5da5ee64fd to lost_changes
3cce27fc HEAD@{6}: commit: add statistics
417a99a4 HEAD@{7}: commit: add test
0b823d42 HEAD@{8}: commit: new utility class
d9ea8a63 HEAD@{9}: checkout: moving from develop to d9ea8a635d4c2349fcb05b3339a6d7fad5ae2a09
b5bf3e1d HEAD@{10}: pull: Fast-forward

Aquellos que queríamos eran HEAD@{8}a HEAD@{6}(ambos inclusive). Entonces los obtuvimos por:

git cherry-pick 0b823d42..3cce27fc

Luego, la resolución de fusión habitual y la confirmación final nos dejaron con la rama lost_changes que aloja el trabajo de cabezal separado que creíamos perdido. Fusionar eso en desarrollo fue un avance rápido esta vez.

manuelvigarcia
fuente
0

Probé este escenario y encontré que git me dice SHA-1 de la última confirmación:

vors@localhost:~/git-test$ git checkout master 
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  ec600e6 333

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name ec600e6eb2473dd4f3732539c5c1fa5829f631b7

Switched to branch 'master'

¿Viste este mensaje?

xvorsx
fuente
No. O tal vez no presto atención. Estoy buscando una copia de seguridad en timemachine; (
IgnazioC
1
@IgnazioC No necesitas mirar una copia de seguridad. ¿Echaste un vistazo a mi respuesta? git reflogdebería mostrarte lo que necesitas.
Brian Campbell
0

La cabeza separada está bien siempre que no desee realizar ningún cambio.

Si desea revertir una confirmación, puede usar git revert en una rama específica

Si desea trabajar con la cabeza separada y hacer compromisos; crear una nueva rama (y luego fusionarla);

forvaidya
fuente
¡Si! conocemos las reglas. Pero cuando los colegas trabajan con despreocupación y luego abandonan esos compromisos, piden respuestas, no reglas.
manuelvigarcia
0
  1. Primero, corre git reflogpara ver el historial.
  2. La revisión más antigua será la última de la lista.
  3. Cambie a su compromiso deseado usando git checkout -b temp e35d2b3aquí e35dd23 es el valor hash de su compromiso.
  4. Eso es. Ahora solo haz git add. etc ....

Acéptelo como una respuesta si resuelve su problema. De lo contrario, comparta su comentario.

sohaib
fuente