Почему у меня в Git подмодуля голова отдельно от хозяина?
Я использую подмодули GIT. После вытягивания изменений с сервера, много раз моя голова подмодуля отделяется от главной ветви.
почему это происходит?
Я должен всегда делать:
git branch
git checkout master
Как я могу убедиться, что мой подмодуль всегда указывает на главную ветвь?
Muchas Gracias
4 ответов:
лично я ненавижу ответы, которые ведут внешние ссылки, которые могут перестать работать со временем и проверить мой ответ здесь(если вопрос повторяющийся) - направление на вопрос, который охватывает тему между строками другой темы, но в целом равно: "я не отвечаю, прочитайте документацию."
Итак, вернемся к вопросу: почему это происходит?
ситуация, которую вы описали
после вытягивания изменений с сервера, много раз моя голова подмодуля отсоединяется от главной ветви.
это распространенный случай, когда никто не использует подмодулей слишком часто или только начал с подмодулей. Я считаю, что я прав, утверждая, что мы все были там в какой-то момент, когда наши субмодульголова отделяется.
- причина: ваш подмодуль не отслеживая ни одну или правильную ветку. Решение: убедитесь, что ваш подмодуль отслеживает правильную ветвь
$ 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, чтобы обновить свой подмодуль дистанционный.
$ git submodule add -b <branch> <repository> [<submodule-path>] $ 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>однако, даже если вы настроили свой подмодуль для отслеживания правильной ветви, вы все равно можете оказаться в ситуациях, когда ваш подмодуль получает
HEAD detached at <commit-hash>в обычных случаях вы уже исправили свою отделенную голову, так как это было связано с одной из проблем конфигурации выше. Но помните, что ваш родительский репозиторий больше не управляет состоянием вашего подмодуля (используя хэш фиксации, зафиксированный в Родительском репозитории), так как ваш подмодуль отслеживает свою собственную удаленную ветвь, что открывает новые возможности для сбоя.
выполнить
$ git statusв вашем Родителе, а также в путь подмодуля, чтобы убедиться, что все отслеживается правильно и все в актуальном состоянии, а затем запустить$ cd <parent-repo>иgit submodule update --remote. Как вы видите, если бы вы снова запустили git status, все сейчас просто отлично.чтобы продемонстрировать, что только тогда, когда все, кажется, настроено правильно, и вы не ожидаете, что отделится голова, все может пойти не так, давайте посмотрим на следующее:
$ 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>хотя есть еще несколько случаев, когда вы можете получить свои подмодули в состояние отсоединенной головы, я надеюсь, что теперь вы понимаете немного больше, как отлаживать ваш конкретный случай.
Я устал от того, что он всегда отсоединяется, поэтому я просто использую сценарий оболочки, чтобы построить его для всех моих модулей. я предполагаю, что все подмодули находятся на master: вот скрипт:
#!/bin/bash echo "Good Day Friend, building all submodules while checking out from MASTER branch." git submodule update git submodule foreach git checkout master git submodule foreach git pull origin masterвыполнить его из родительского модуля
проверьте мой ответ здесь: подмодули Git: укажите ветвь / тег
Если вы хотите, вы можете добавить строку "branch = master" в свой .gitmodules файл вручную. Читай ссылку, чтобы увидеть, что я имею в виду.
изменить: Чтобы отслеживать существующий проект подмодуля в ветке, следуйте инструкциям VonC здесь вместо этого:
другой способ сделать свой подмодуль, чтобы проверить ветку, - это пойти
.gitmodulesфайл в корневой папке и добавить полеbranchв конфигурации модуля следующим образом:
branch = <branch-name-you-want-module-to-checkout>
Comments