¿Presionar un repositorio Git existente a Github solo envía aproximadamente la mitad de las confirmaciones?
-
04-07-2019 - |
Pregunta
Tengo un repositorio local de Git en el que he estado desarrollando durante unos días: tiene dieciocho confirmaciones hasta ahora. Esta noche, creé un repositorio privado de Github al que esperaba empujarlo; Sin embargo, cuando lo hice, solo terminó empujando ocho de los dieciocho compromisos con Github. Eliminé el repositorio de Github y lo volví a intentar, con el mismo resultado.
¿Alguna idea sobre por qué esto podría estar sucediendo? He hecho este procedimiento antes sin éxito varias veces, así que estoy un poco perplejo.
Actualizar : hay, y siempre ha habido, solo la rama maestra en este repositorio. Solo para abordar algunas de las respuestas publicadas ...
Solución
Eché un vistazo al repositorio en cuestión y esto es lo que estaba pasando:
- En algún momento, rpj realizó
git checkout [commit id]
. Esto apuntaba a HEAD a un commit suelto en lugar de una rama reconocida Creo que esta es la " cabeza colgante " problema al que se refiere CesarB. - Sin darse cuenta de este problema, siguió haciendo cambios y cometiéndolos, lo que incrementó a HEAD en todo momento. Sin embargo, HEAD solo apuntaba a una cadena de compromisos en suspensión, no a una rama reconocida.
- Cuando fue a impulsar sus cambios, git empujó todo hasta la parte superior del maestro, que estaba a la mitad del árbol actual en el que estaba.
- Se produjo confusión
Este diagrama debería dejarlo más claro:
-- D -- E -- F
/ ^
A -- B -- C - |
^ ^ HEAD
| |
remote master
Cuando intentó forzar sus cambios, solo se empujó A
a través de C
y remoto
se movió hasta C
. No pudo obtener las confirmaciones de D
a través de F
para empujar porque no están referenciadas por una rama conocida.
Esto es lo que ves cuando estás en este estado:
$ git branch
* (no branch)
master
La solución es mover master
hasta F
en la cadena de compromisos que cuelga. Así es como lo hice.
-
Cree una rama legítima para el estado actual:
git checkout -b tmp
- La rama
tmp
ahora apunta al commitF
en el diagrama de arriba
- La rama
-
Avance rápido
master
atmp
git checkout master
git merge tmp
-
master
ahora apunta al commitF
.
-
-
Tira tu rama temporal
git branch -d tmp
-
Con gusto puede enviar al repositorio remoto y debería enviar todos sus cambios.
Otros consejos
A partir de Git 1.7.3, puedes hacer esto con un simple comando:
git checkout -B master
El interruptor -b
significa & # 8220; crear rama aquí antes de verificarlo & # 8221; y -B
es la versión incondicional de eso, & # 8220; incluso si la rama ya existe & # 8211; en ese caso, muévalo aquí antes de comprobarlo & # 8221 ;.
Un enfoque muy simple para solucionar este tipo de problema es simplemente eliminar la rama master
y volver a crearla. Después de todo, las ramas en git son simplemente nombres para confirmaciones y la rama master
no es nada especial.
Asumiendo que el compromiso actual es el que quieres que sea master
, simplemente lo haces
git branch -D master
para eliminar la rama master
existente, luego haz
git checkout -b master
para a) crear una nueva rama llamada master
que apunte a la confirmación actual yb) actualizar HEAD
para que apunte a la master
. Después de eso, HEAD
se adjuntará a master
y, por lo tanto, master
avanzará cada vez que se comprometa.
Comprueba si estás empujando las ramas correctas y que las ramas realmente tienen lo que crees que tienen. En particular, verifique si no tiene una CABEZA separada, lo que puede ser bastante confuso si no se hace a propósito.
La forma más fácil de verificar es utilizar gitk --all
, que muestra gráficamente todas las ramas, la CABEZA y más.
Supongo que lo primero que haría sería ejecutar git fsck
en su repositorio local para asegurarse de que todo esté en buen estado.
Nunca he visto este problema antes, y no puedo pensar en lo que podría estar mal.
No tengo la reputación de comentar directamente sobre la respuesta anterior de CesarB, pero gitk --all
no funciona en este caso porque solo enumera las sucursales conocidas.
gitk HEAD
muestra este problema, pero no está del todo claro. El arma humeante es que master
aparece en el árbol de confirmación en lugar de en la confirmación más reciente.
Entonces, resulta que ambos: el hash de confirmación en .git / refs / heads / master estaba correcto y la información en .git / logs / refs / heads / master estaba incompleta; Quiero decir que solo subió e incluyó el hash de confirmación especificado en .git / refs / heads / master.
Una vez que arreglé estos archivos (a mano) y los devolví a Github, todo volvió a estar listo. Todavía no tengo ni idea de lo que sucedió para lograrlo en este estado, pero me alegro de al menos haber descubierto la solución.
En caso de que alguien se esté preguntando: para corregir .git / refs / heads / master, simplemente reemplacé el contenido de ese archivo con el último hash de confirmación (HEAD), y para corregir .git / logs / refs / heads / master Simplemente copié el contenido de .git / logs / HEAD en .git / logs / refs / heads / master. Fácil peasy ... NO.
He tenido este mismo problema dos veces, y finalmente descubrí qué estaba haciendo lo que lo estaba causando. En el proceso de editar una confirmación antigua con git rebase -i
, en lugar de llamar a git commit --amend
, estaba llamando a git commit -a
por fuerza de hábito, seguido inmediatamente por git rebase --continue
, por supuesto. Alguien más podría ser capaz de explicar lo que está sucediendo detrás de la escena, pero parece que el resultado es el problema de HEAD.