Редагувати:
Див @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 виконувати перезавантаження або злиття замість оформлення замовлення
- ви скажете 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>
У звичайних випадках ви вже виправили свою РОЗШИРЕНУ ГОЛОВУ, оскільки вона була пов'язана з однією з проблем з конфігурацією, наведеною вище.
фіксація ДЕТЕЧОВАНОГО ГОЛОВА коли .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, я сподіваюся, що зараз ви зрозумієте трохи більше, як відладкувати ваш конкретний випадок.