РЕДАКТИРОВАТЬ:
См @Simba Ответ для правильного решения
submodule.<name>.update
это то, что вы хотите изменить, см. документы - по умолчаниюcheckout
submodule.<name>.branch
укажите удаленную ветвь для отслеживания - по умолчаниюmaster
СТАРЫЙ ОТВЕТ:
Лично я ненавижу здесь ответы, которые ссылаются на внешние ссылки, которые могут перестать работать со временем, и проверяю мой ответ здесь (если вопрос не повторяется) - я обращаюсь к вопросу, который охватывает тему между строк другой темы, но в целом равен: «Я не отвечая, прочитайте документацию. "
Итак, вернемся к вопросу: почему это происходит?
Ситуация, которую вы описали
После получения изменений с сервера моя голова субмодуля много раз отсоединялась от основной ветки.
Это распространенный случай, когда кто-то не использует подмодули слишком часто или только начинает работу с подмодулями . Я полагаю, что я правильно заявляю, что мы все были там в какой-то момент, когда отсоединяется ГОЛОВА нашего подмодуля .
- Причина: Ваш подмодуль не отслеживает правильную ветвь (мастер по умолчанию).
Решение: убедитесь, что ваш подмодуль отслеживает правильную ветку
$ 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>
- Причина. Ваш родительский репозиторий не настроен для отслеживания ветви подмодулей.
Решение: Сделайте так, чтобы ваш подмодуль отслеживал его удаленную ветвь, добавляя новые подмодули с помощью следующих двух команд.
- Сначала вы говорите Git, чтобы отслеживать ваш пульт
<branch>
.
- вы говорите git выполнить rebase или объединить вместо checkout
- вы говорите git обновить ваш подмодуль с пульта.
$ git submodule add -b <branch> <repository> [<submodule-path>]
$ git config -f .gitmodules submodule.<submodule-path>.update rebase
$ git submodule update --remote
- Если вы не добавили существующий субмодуль, как это, вы можете легко это исправить:
- Во-первых, вы хотите убедиться, что в вашем подмодуле отмечена ветка, которую вы хотите отслеживать.
$ 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>
В общих случаях вы уже исправили свою DETACHED HEAD, так как она была связана с одной из проблем конфигурации выше.
фиксация DETACHED HEAD, когда .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.
Но если вам удалось внести некоторые изменения локально уже для субмодуля и зафиксировать, перенести их в удаленный режим, а затем, когда вы выполнили «git checkout», Git уведомит вас:
$ 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:
Рекомендуемая опция для создания временной ветки может быть хорошей, и тогда вы можете просто объединить эти ветви и т. Д. Однако я лично использовал бы только git cherry-pick <hash>
в этом случае.
$ 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>
Хотя есть еще несколько случаев, когда вы можете перевести свои подмодули в состояние DETACHED HEAD, я надеюсь, что теперь вы немного больше понимаете, как отлаживать ваш конкретный случай.