EDITAR:
Ver @Simba Answer para una solución válida
submodule.<name>.update
es lo que desea cambiar, consulte los documentos : predeterminado,checkout
submodule.<name>.branch
especifique la rama remota a rastrear: predeterminadomaster
ANTIGUA RESPUESTA:
Personalmente, odio las respuestas aquí que dirigen a enlaces externos que pueden dejar de funcionar con el tiempo y compruebo mi respuesta aquí (a menos que la pregunta sea duplicada) : dirigir a la pregunta que cubre el tema entre las líneas de otro tema, pero en general es igual a: "Estoy sin contestar, lea la documentación ".
Volviendo a la pregunta: ¿por qué sucede?
Situación que describiste
Después de extraer los cambios del servidor, muchas veces la cabeza de mi submódulo se separa de la rama maestra.
Este es un caso común cuando uno no usa submódulos con demasiada frecuencia o acaba de comenzar con submódulos . Creo que estoy en lo correcto al afirmar que todos hemos estado allí en algún momento donde la CABEZA de nuestro submódulo se separa.
- Causa: su submódulo no está rastreando la rama correcta (maestro predeterminado).
Solución: asegúrese de que su submódulo rastrea la rama correcta
$ cd <submodule-path>
# if the master branch already exists locally:
# (From git docs - branch)
# -u <upstream>
# --set-upstream-to=<upstream>
# Set up <branchname>'s tracking information so <upstream>
# is considered <branchname>'s upstream branch.
# If no <branchname> is specified, then it defaults to the current branch.
$ git branch -u <origin>/<branch> <branch>
# else:
$ git checkout -b <branch> --track <origin>/<branch>
- Causa: su repositorio principal no está configurado para rastrear la rama de submódulos.
Solución: Haga que su submódulo rastree su rama remota agregando nuevos submódulos con los siguientes dos comandos.
- Primero le dices a git que rastree tu control remoto
<branch>
.
- le dices a git que realice un rebase o una fusión en lugar de pagar
- le dices a git que actualice tu submódulo desde el control remoto.
$ git submodule add -b <branch> <repository> [<submodule-path>]
$ git config -f .gitmodules submodule.<submodule-path>.update rebase
$ git submodule update --remote
- Si no ha agregado su submódulo existente de esta manera, puede solucionarlo fácilmente:
- Primero, debe asegurarse de que su submódulo tenga la rama verificada de la que desea realizar un seguimiento.
$ cd <submodule-path>
$ git checkout <branch>
$ cd <parent-repo-path>
# <submodule-path> is here path releative to parent repo root
# without starting path separator
$ git config -f .gitmodules submodule.<submodule-path>.branch <branch>
$ git config -f .gitmodules submodule.<submodule-path>.update <rebase|merge>
En los casos comunes, ya ha reparado su CABEZA DESCONECTADA ya que estaba relacionada con uno de los problemas de configuración anteriores.
Fijación de la cabeza separada cuando .update = checkout
$ cd <submodule-path> # and make modification to your submodule
$ git add .
$ git commit -m"Your modification" # Let's say you forgot to push it to remote.
$ cd <parent-repo-path>
$ git status # you will get
Your branch is up-to-date with '<origin>/<branch>'.
Changes not staged for commit:
modified: path/to/submodule (new commits)
# As normally you would commit new commit hash to your parent repo
$ git add -A
$ git commit -m"Updated submodule"
$ git push <origin> <branch>.
$ git status
Your branch is up-to-date with '<origin>/<branch>'.
nothing to commit, working directory clean
# If you now update your submodule
$ git submodule update --remote
Submodule path 'path/to/submodule': checked out 'commit-hash'
$ git status # will show again that (submodule has new commits)
$ cd <submodule-path>
$ git status
HEAD detached at <hash>
# as you see you are DETACHED and you are lucky if you found out now
# since at this point you just asked git to update your submodule
# from remote master which is 1 commit behind your local branch
# since you did not push you submodule chage commit to remote.
# Here you can fix it simply by. (in submodules path)
$ git checkout <branch>
$ git push <origin>/<branch>
# which will fix the states for both submodule and parent since
# you told already parent repo which is the submodules commit hash
# to track so you don't see it anymore as untracked.
Pero si logró realizar algunos cambios localmente para el submódulo y se comprometió, los empujó al control remoto y luego cuando ejecutó 'git checkout', Git le notifica:
$ git checkout <branch>
Warning: you are leaving 1 commit behind, not connected to any of your branches:
If you want to keep it by creating a new branch, this may be a good time to do so with:
La opción recomendada para crear una rama temporal puede ser buena, y luego puede fusionar estas ramas, etc. Sin embargo, personalmente lo usaría solo git cherry-pick <hash>
en este caso.
$ git cherry-pick <hash> # hash which git showed you related to DETACHED HEAD
# if you get 'error: could not apply...' run mergetool and fix conflicts
$ git mergetool
$ git status # since your modifications are staged just remove untracked junk files
$ rm -rf <untracked junk file(s)>
$ git commit # without arguments
# which should open for you commit message from DETACHED HEAD
# just save it or modify the message.
$ git push <origin> <branch>
$ cd <parent-repo-path>
$ git add -A # or just the unstaged submodule
$ git commit -m"Updated <submodule>"
$ git push <origin> <branch>
Aunque hay algunos casos más en los que puede poner sus submódulos en el estado HEAD DETACHED, espero que ahora entienda un poco más cómo depurar su caso particular.