remove - Git submódulo cabeza ''referencia no es un árbol'' error
git tag commit id (12)
Causa posible
Esto puede suceder cuando:
- Submódulo (s) se han editado en su lugar
- Submódulo (s) confirmado (s), que actualiza el hash del submódulo al que se apunta
- Submódulo (s) no empujado .
por ejemplo, algo como esto sucedió:
$ cd submodule
$ emacs my_source_file # edit some file(s)
$ git commit -am "Making some changes but will forget to push!"
Debería haber empujado el submódulo en este punto.
$ cd .. # back to parent repository
$ git commit -am "updates to parent repository"
$ git push origin master
Como resultado, el usuario remoto posiblemente no pudo encontrar las confirmaciones faltantes porque todavía están en el disco local.
Solución
Informa a la persona que modificó el submódulo para empujar, es decir
$ cd submodule
$ git push
Tengo un proyecto con un submódulo que apunta a un compromiso no válido: el compromiso de submódulo se mantuvo local y cuando intento obtenerlo de otro repositorio obtengo:
$ git submodule update
fatal: reference is not a tree: 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
Unable to checkout ''2d7cfbd09fc96c04c4c41148d44ed7778add6b43'' in submodule path ''mysubmodule''
Sé lo que debería ser el submódulo HEAD, ¿hay alguna forma de cambiar esto localmente, sin presionar desde el repositorio que sí tiene 2d7cfbd09fc96c04c4c41148d44ed7778add6b43
?
No estoy seguro de si estoy siendo claro ... aquí hay una situación similar que encontré.
En mi caso, ninguna de las respuestas anteriores resuelve el problema, incluso si son buenas respuestas. Así que publico mi solución (en mi caso hay dos clientes git, el cliente A y B):
ir a la direccion del submodulo
cd sub
salida a dominar:
git checkout master
Rebase a un código de confirmación que ambos clientes pueden ver
volver al directorio de los padres:
comprometerse a dominar
Cambie al otro cliente, haga
rebase
nuevamente.¡Finalmente funciona bien ahora! Tal vez pierda un par de veces pero funciona.
Para su información, no intente eliminar su submódulo, permanecerá
.git/modules
allí y no podrá volver a leer este submódulo, a menos que sea uno local reactivo.
Esta respuesta es para usuarios de SourceTree con experiencia limitada en git de terminal.
Abra el submódulo problemático desde el proyecto Git (superproyecto).
Recupera y asegúrate de que "Buscar todas las etiquetas" esté marcado.
Rebase tira de tu proyecto Git.
Esto resolverá el problema de ''la referencia no es un árbol'' 9 de cada diez veces. Esa vez que no, es una solución de terminal como se describe en la respuesta superior.
Este error puede significar que falta una confirmación en el submódulo. Es decir, el repositorio (A) tiene un submódulo (B). A quiere cargar B para que apunte a una confirmación determinada (en B). Si ese compromiso falta de alguna manera, obtendrá ese error. Una vez posible causa: la referencia a la confirmación se insertó en A, pero la confirmación real no se eliminó de B. Por lo tanto, comenzaría allí.
Menos probable, hay un problema de permisos y no se puede extraer la confirmación (posible si está utilizando git + ssh).
Asegúrese de que las rutas de los submódulos se vean bien en .git / config y .gitmodules.
Una última cosa que probar, dentro del directorio de submódulos: git reset HEAD --hard
Esto también puede suceder cuando tienes un submódulo que apunta a un repositorio que se ha rebasado y el compromiso dado se ha "ido". Mientras que la confirmación aún puede estar en el repositorio remoto, no está en una rama. Si no puede crear una nueva rama (por ejemplo, no su repositorio), tiene que actualizar el súper proyecto para apuntar a un nuevo compromiso. Alternativamente, puede enviar una de sus copias de los submódulos a otra parte y luego actualizar el superproyecto para que apunte a ese repositorio.
Me topé con este problema y ninguna de estas soluciones funcionó para mí. Lo que resultó ser la solución para mi problema es en realidad mucho más simple: actualizar Git. El mío era 1.7.1, y después de actualizarlo a 2.16.1 (más reciente), ¡el problema desapareció sin dejar rastro! Supongo que lo dejo aquí, espero que ayude a alguien.
Para sincronizar el repositorio de git con la cabeza del submódulo, en caso de que realmente sea lo que quieres, encontré que eliminar el submódulo y luego leerlo evita los retoques con el historial. Desafortunadamente, eliminar un submódulo requiere piratería en lugar de ser un solo comando git, pero factible.
Pasos que seguí para eliminar el submódulo, inspirado en https://gist.github.com/kyleturner/1563153 :
- Ejecutar git rm --cached
- Elimine las líneas relevantes del archivo .gitmodules.
- Eliminar la sección correspondiente de .git / config.
- Eliminar los archivos de submódulos ahora sin seguimiento.
- Eliminar directorio .git / modules /
Nuevamente, esto puede ser útil si lo único que quiere es apuntar a la cabeza del submódulo nuevamente, y no ha complicado las cosas al tener que mantener intacta la copia local del submódulo. Se asume que tiene el submódulo "correcto" como su propio repositorio, donde sea que se origine, y solo quiere volver a incluirlo correctamente como un submódulo.
Nota: siempre haga una copia completa de su proyecto antes de involucrarse en este tipo de manipulación o cualquier comando git más allá de la simple confirmación o empuje. Yo recomendaría eso con todas las demás respuestas también, y como una guía general de git.
Recibí este error cuando lo hice:
$ git submodule update --init --depth 1
pero el compromiso en el proyecto padre apuntaba a un compromiso anterior.
Eliminando la carpeta de submódulos y ejecutando
$ git submodule update --init
NO resolvió el problema. Borré el repositorio y lo intenté de nuevo sin el indicador de profundidad y funcionó.
Solo para estar seguro, intenta actualizar tus binarios git
.
GitHub para Windows tiene la versión git version 1.8.4.msysgit.0
que en mi caso fue el problema. La actualización lo solucionó.
Su historial de submódulos se conserva de forma segura en el git submódulo de todos modos.
Entonces, ¿por qué no eliminar el submódulo y agregarlo nuevamente?
De lo contrario, ¿intentó editar manualmente HEAD
o refs/master/head
dentro del submódulo .git
Suponiendo que el repositorio del submódulo contenga un compromiso que desea usar (a diferencia del compromiso al que se hace referencia desde el estado actual del superproyecto), hay dos formas de hacerlo.
El primero requiere que ya conozca el compromiso del submódulo que desea usar. Funciona desde “adentro, afuera” ajustando directamente el submódulo y luego actualizando el superproyecto. El segundo funciona desde "afuera, adentro" al encontrar el compromiso del superproyecto que modificó el submódulo y luego restablecer el índice del superproyecto para referirse a un compromiso diferente del submódulo.
De adentro hacia afuera
Si ya sabe qué compromiso desea que use el submódulo, cd
al submódulo, verifique el compromiso que desea, luego git add
y git commit
it back en el superproyecto.
Ejemplo:
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout ''e47c0a16d5909d8cb3db47c81896b8b885ae1556'' in submodule path ''sub''
Vaya, alguien hizo un compromiso de superproyecto que se refiere a un compromiso no publicado en el sub
módulo de submódulos. De alguna manera, ya sabemos que queremos que el submódulo esté en commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
. Ve allí y échale un vistazo directamente.
Checkout en el submódulo
$ cd sub
$ git checkout 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
Note: moving to ''5d5a3ee314476701a20f2c6ec4a53f88d651df6c'' which isn''t a local branch
If you want to create a new branch from this checkout, 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 5d5a3ee... quux
$ cd ..
Como estamos verificando un compromiso, esto produce una CABEZA separada en el submódulo. Si desea asegurarse de que el submódulo está utilizando una rama, use git checkout -b newbranch <commit>
para crear y desproteger una rama en el commit o verifique la rama que desee (por ejemplo, uno con el commit deseado en la punta) ).
Actualizar el Super-proyecto
Una verificación en el submódulo se refleja en el superproyecto como un cambio en el árbol de trabajo. Así que necesitamos escalonar el cambio en el índice del superproyecto y verificar los resultados.
$ git add sub
Ver los resultados
$ git submodule update
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
La actualización del submódulo fue silenciosa porque el submódulo ya está en la confirmación especificada. El primer diff muestra que el índice y el worktree son los mismos. La tercera diferencia muestra que el único cambio por etapas es mover el submódulo sub
a un compromiso diferente.
Cometer
git commit
Esto confirma la entrada del submódulo fijo.
De fuera hacia dentro
Si no está seguro de qué compromiso debe usar en el submódulo, puede consultar el historial en el superproyecto para guiarlo. También puede gestionar el reinicio directamente desde el super-proyecto.
$ git submodule update
fatal: reference is not a tree: e47c0a16d5909d8cb3db47c81896b8b885ae1556
Unable to checkout ''e47c0a16d5909d8cb3db47c81896b8b885ae1556'' in submodule path ''sub''
Esta es la misma situación que la anterior. Pero esta vez nos centraremos en solucionarlo desde el superproyecto en lugar de sumergirnos en el submódulo.
Encuentra el Errant Commit del Super-proyecto
$ git log --oneline -p -- sub
ce5d37c local change in sub
diff --git a/sub b/sub
index 5d5a3ee..e47c0a1 160000
--- a/sub
+++ b/sub
@@ -1 +1 @@
-Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
+Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
bca4663 added sub
diff --git a/sub b/sub
new file mode 160000
index 0000000..5d5a3ee
--- /dev/null
+++ b/sub
@@ -0,0 +1 @@
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
OK, parece que se puso malo en ce5d37c
, así que restauraremos el submódulo de su padre ( ce5d37c~
).
Alternativamente, puede tomar la confirmación del submódulo del texto del parche ( 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
) y usar el proceso anterior "adentro, afuera" en su lugar.
Checkout en el superproyecto
$ git checkout ce5d37c~ -- sub
Esto restableció la entrada del submódulo para sub
a lo que era en el compromiso ce5d37c~
en el superproyecto.
Actualizar el submódulo
$ git submodule update
Submodule path ''sub'': checked out ''5d5a3ee314476701a20f2c6ec4a53f88d651df6c''
La actualización del submódulo fue correcta (indica una CABEZA separada).
Ver los resultados
$ git diff ce5d37c~ -- sub
$ git diff
$ git diff --cached
diff --git c/sub i/sub
index e47c0a1..5d5a3ee 160000
--- c/sub
+++ i/sub
@@ -1 +1 @@
-Subproject commit e47c0a16d5909d8cb3db47c81896b8b885ae1556
+Subproject commit 5d5a3ee314476701a20f2c6ec4a53f88d651df6c
El primer diff muestra que sub
es ahora el mismo en ce5d37c~
. El segundo diff muestra que el índice y el worktree son los mismos. La tercera diferencia muestra que el único cambio por etapas es mover el submódulo sub
a un compromiso diferente.
Cometer
git commit
Esto confirma la entrada del submódulo fijo.
prueba esto:
git submodule sync
git submodule update