gui - El submódulo de Git está en estado de "cabeza separada" después de la clonación y la actualización del submódulo
git repository (3)
El contenido de los directorios de git se almacena en simples manifiestos de archivos de texto (es decir, listados de directorios) llamados "árboles" que se parecen a los siguientes, donde las manchas son el contenido de los archivos, y los árboles son aún más árboles como este:
100644 blob 0c31be662540ce902cee106f86bfdeef519fc662 .gitignore
100644 blob 1d364edf530c2238e79162bf2d9f30c2af610347 .gitmodules
040000 tree fc6bc39202ec20228e9135cd426110c558b625cd foo
040000 tree 2f9fc460f3a2370ed45b39b2bcaaf9b6e746b823 bar
Sin embargo, si la barra era un submódulo, en lugar de un simple directorio, el árbol que lo contiene se mostrará así:
100644 blob 0c31be662540ce902cee106f86bfdeef519fc662 .gitignore
100644 blob 1d364edf530c2238e79162bf2d9f30c2af610347 .gitmodules
040000 tree fc6bc39202ec20228e9135cd426110c558b625cd foo
040000 commit 2f9fc460f3a2370ed45b39b2bcaaf9b6e746b823 bar
Tenga en cuenta que en lugar de que la barra sea un árbol, ahora es un compromiso (en un submódulo). Esto es todo lo que git almacena sobre un submódulo en el nivel de árbol / compromiso, por lo que no puede saber en qué rama estaba el compromiso. De hecho, almacenar nombres de sucursales no puede funcionar. Ellos pueden cambiar. Además, si revisa una confirmación antigua en su repositorio que también necesita deshacer el submódulo, ¿debería la rama retroceder en el submódulo? Eso convertiría los compromisos después de la nueva ubicación de la sucursal en un territorio sin referencia.
Las ramas son para uso de los humanos, para dar sentido al DAG, y donde están las líneas particulares de pensamiento. Git no le importa cómo nos referimos a los compromisos. Necesita una ubicación concreta para que pueda mover de manera segura el repositorio que lo contiene y saber que el submódulo siempre se revisará hasta donde estaba en ese momento. La única verdad es el hash.
Cuando cloné mi repositorio git, uno de los submódulos está en una rama con un nombre extraño, lo que creo que significa que tiene una " cabeza separada " (ni siquiera estoy seguro de lo que eso significa).
Si compruebo mi rama principal para el submódulo, a continuación, ejecute " git submodule update --init --recursive
" vuelve a suceder.
¿Alguien sabe lo que está pasando?
Para los usuarios de Sourcetree , observará el mismo comportamiento, un clon le dará submódulos en un estado separado. Como menciona en su respuesta, si desea contribuir al submódulo, debe realizar algunos pasos adicionales.
Además de crear una nueva rama desde el punto del submódulo SHA-1, en la mayoría de los casos simplemente querrá revisar el encabezado de la rama existente. Esto será maestro a menos que el submódulo esté configurado para seguir una rama específica.
Puede abrir cada submódulo y verificar manualmente sus sucursales correspondientes, o puede crear una acción personalizada para que lo haga por usted ( recursivamente ):
Script para ejecutar
cmd
Parámetros
/c %LOCALAPPDATA%/Atlassian/SourceTree/git_local/bin/sh.exe --login -i -c "git pull; git submodule foreach -q --recursive ''toplevel=/"$(git rev-parse --show-toplevel)/"; branch=/"$(git config -f $toplevel/.gitmodules submodule.$name.branch)/"; [ /"$branch/" = /"/" ] && branch=master; git checkout $branch; git fetch; git merge FETCH_HEAD;''"""
Esto comprobará si hay submódulos en su proyecto y verificará la rama a la que apuntan (o el maestro si no especifican una rama). Es recursivo, por lo que también se manejarán los submódulos que contengan submódulos.
Como descubrí en una publicación anterior , se requieren el par adicional de citas al final.
Un submódulo siempre se verifica como HEAD extraído (vea " ¿Por qué git separó mi cabeza? "), Ya que el índice del repositorio principal contiene solo el SHA1 como una entrada especial en su índice , como lo explica la answer . .
Incluso si configura su submódulo para seguir una rama (o convierte un submódulo existente para seguir una rama ), una git submodule update --remote
el último SHA1 de esa rama remota, pero el resultado aún sería una HEAD separada.
Debe ingresar a ese submódulo y hacer una rama allí mismo, si desea contribuir a dicho submódulo (hacer nuevos compromisos en él).
cd mySubmodule
git checkout -b aNewBranch
# work
git add .
git commit -m "new commits"
git push -u origin aNewBranch
# record the new submodule state in the parent repo:
cd ..
git add mySubmodule
git commit -m "new state of mySubmodule"
git push
Nota para Git 2.16 (Q1 2018): " git checkout --recursive
" puede sobrescribir y rebobinar el historial de la rama que se comprueba en los repositorios de submódulos, lo que podría no ser deseable.
Desconecte la HEAD
pero aún así permita que la verificación recursiva tenga éxito en tal caso.
Ver commit 57f22bf (28 de julio de 2017), y commit 3ef2538 (24 de julio de 2017) por Stefan Beller ( stefanbeller
) .
(Fusionada por Junio C Hamano - gitster
- in commit 0b75572 , 06 de diciembre de 2017)
submódulos recursivos: separar HEAD del nuevo estado
Cuando un submódulo está en una rama y en su superproyecto ejecuta una verificación recursiva, la rama del submódulo se actualiza a lo que el superproyecto verifica.
Esto es muy inesperado en el modelo actual de Git, ya que, por ejemplo, la "submodule update
" siempre separa el submódulo HEAD.A pesar de tener planes de no separar los HEADS en el futuro, el comportamiento actual es realmente malo, ya que no coincide con las expectativas del usuario y no está comprobando la pérdida de confirmaciones (solo se puede recuperar a través del reflog).
Desconecte la CABEZA incondicionalmente en el submódulo cuando la actualice.