MODIFICARE:
Vedi la risposta di @Simba per una soluzione valida
submodule.<name>.update
è ciò che si desidera modificare, vedere i documenti - impostazione predefinitacheckout
submodule.<name>.branch
specificare il ramo remoto da tracciare - impostazione predefinitamaster
VECCHIA RISPOSTA:
Personalmente odio le risposte che si rivolgono a collegamenti esterni che potrebbero smettere di funzionare nel tempo e controllare la mia risposta qui (a meno che la domanda non sia duplicata) - indirizzare alla domanda che copre l'argomento tra le righe dell'altro argomento, ma nel complesso è uguale: "Sono non rispondendo, leggi la documentazione. "
Quindi torniamo alla domanda: perché succede?
Situazione che hai descritto
Dopo aver estratto le modifiche dal server, molte volte la mia testa del sottomodulo viene staccata dal ramo principale.
Questo è un caso comune quando uno non usa i sottomoduli troppo spesso o ha appena iniziato con sottomoduli . Credo di aver ragione nell'affermare, che siamo stati tutti lì ad un certo punto in cui la TESTA del nostro sottomodulo si stacca.
- Causa: il sottomodulo non sta monitorando il ramo corretto (master predefinito).
Soluzione: assicurarsi che il sottomodulo stia monitorando il ramo corretto
$ 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: il repository principale non è configurato per tenere traccia del ramo dei sottomoduli.
Soluzione: fai in modo che il tuo sottomodulo segua il suo ramo remoto aggiungendo nuovi sottomoduli con i seguenti due comandi.
- Per prima cosa dici a git di localizzare il tuo telecomando
<branch>
.
- dici a git di eseguire rebase o merge invece di checkout
- dici a git di aggiornare il tuo sottomodulo da remoto.
$ git submodule add -b <branch> <repository> [<submodule-path>]
$ git config -f .gitmodules submodule.<submodule-path>.update rebase
$ git submodule update --remote
- Se non hai aggiunto il tuo sottomodulo esistente in questo modo, puoi facilmente risolvere il problema:
- Prima di tutto, assicurati che il tuo sottomodulo abbia il ramo estratto che desideri monitorare.
$ 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>
Nei casi comuni, hai già risolto il tuo DETACHED HEAD dal momento che era correlato a uno dei problemi di configurazione sopra.
fissaggio TESTA STACCATA quando .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.
Ma se sei riuscito a apportare alcune modifiche localmente già per il sottomodulo e hai eseguito il commit, le hai spinte sul telecomando poi quando hai eseguito 'git checkout', Git ti avvisa:
$ 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:
L'opzione raccomandata per creare un ramo temporaneo può essere buona, quindi puoi unire questi rami ecc. Tuttavia, personalmente utilizzerei solo git cherry-pick <hash>
in questo 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>
Anche se ci sono altri casi in cui puoi portare i tuoi sottomoduli nello stato DETACHED HEAD, spero che tu capisca ora un po 'di più come eseguire il debug del tuo caso particolare.