Pourquoi ma tête de Submodule GIT est-elle détachée du maître?

j'utilise des sous-modules GIT. Après avoir tiré les modifications du serveur, plusieurs fois ma tête de sous-module se détache de la branche principale.

pourquoi ça arrive?

je dois toujours faire:

git branch
git checkout master

Comment puis-je m'assurer que mon sous-module pointe toujours vers master branch?

Muchas Gracias

86
demandé sur Skip Jack 2013-09-12 21:18:42

4 réponses

personnellement, je déteste les réponses ici qui dirigent vers des liens externes qui peuvent arrêter de travailler au fil du temps et de vérifier ma réponse ici (sauf si la question Est en double) - direction à la question qui couvre le sujet entre les lignes de l'autre sujet, mais dans l'ensemble égale: "Je ne réponds pas, lire la documentation."

revenons à la question: Pourquoi cela arrive-t-il?

Situation que vous avez décrite

après avoir tiré les modifications du serveur, plusieurs fois ma tête de sous-module se détache de la branche principale.

C'est un cas courant quand on n'utilise pas submodules trop souvent ou vient de commencer avec submodules . Je crois que je suis correct en disant ,que nous tous ont été là à un certain point où la tête de notre submodule se détache.

  • Cause: votre sous-module ne suit aucune branche ou ne corrige aucune branche. Solution: assurez-vous que votre sous-module est la bonne branche
$ 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>
  • Cause: votre parent repo n'est pas configuré pour suivre la branche submodules. Solution: faites suivre à votre sous-module sa branche distante en ajoutant de nouveaux submodules avec les deux commandes suivantes.
    • vous dites D'abord à git de tracer votre télécommande <branch> .
    • ensuite, vous dites à git de mettre à jour votre sous-module à distance.
    $ git submodule add -b <branch> <repository> [<submodule-path>]
    $ git submodule update --remote
  • si vous n'avez pas ajouté votre sous-module existant comme ceci, vous pouvez facilement corriger cela:
    • vous voulez D'abord vous assurer que votre sous-module a vérifié la branche que vous voulez suivre.
    $ 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>

cependant, même si vous avez configuré votre sous-module pour suivre la branche correcte, vous pouvez toujours vous trouver dans des situations où votre sous-module obtient HEAD detached at <commit-hash>

dans les cas courants, vous avez déjà fixé maintenant votre tête détachée puisqu'elle était liée à l'un des problèmes de configuration ci-dessus. Mais n'oubliez pas, votre dépôt parent ne gère plus l'état de votre sous-module (en utilisant un hachage de propagation engagé dans le dépôt parent), puisque votre sous-module suit sa propre branche distante, ce qui ouvre de nouvelles possibilités d'échec.

exécuter $ git status dans votre parent et aussi dans le chemin du sous-module pour vérifier que tout est suivi correctement et tout est à jour, puis exécuter $ cd <parent-repo> et git submodule update --remote . Comme vous le voyez, si vous voulez lancer à nouveau git status tout est bien pour le moment.

pour démontrer que juste au moment où tout semble être configuré correctement et que vous ne vous attendez pas à vous détacher de la tête, les choses peuvent mal tourner, jetons un coup d'oeil à ce qui suit:

$ 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.

mais si vous avez réussi à faire quelques changements localement déjà pour submodule et commited, poussé ceux-ci à distance puis lorsque vous avez exécuté 'git checkout ', Git vous avertit:

$ 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:

le l'option recommandée pour créer une branche temporaire peut être bonne, et alors vous pouvez simplement fusionner ces branches, etc. Cependant, je n'utiliserais personnellement que git cherry-pick <hash> dans ce cas.

$ 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>

bien qu'il y ait plus de cas où vous pouvez obtenir vos sous-modules dans un État de tête détaché, j'espère que vous comprenez maintenant un peu plus comment déboguer votre cas particulier.

117
répondu M.Kungla 2017-05-23 11:54:59

j'en avais assez de toujours me détacher donc j'utilise juste un script shell pour le construire pour tous mes modules. je suppose que tous les sous-modules sont sur master: voici le script:

#!/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 

l'exécuter à partir de votre module parent

9
répondu j2emanue 2018-04-24 08:42:42

regardez ma réponse ici: submodules: Spécifier une branche/étiquette

si vous voulez, vous pouvez ajouter la ligne" branch = master " dans votre .gitmodules fichier manuellement. Lisez le lien pour voir ce que je veux dire.

EDIT: Pour suivre un projet de sous-module existant dans une branche, suivez les instructions de VonC ici à la place:

submodules: Spécifier une branche/étiquette

8
répondu Johnny Z 2018-01-25 18:21:10

l'autre façon de faire votre sous-module pour vérifier la branche est d'aller dans le fichier .gitmodules dans le dossier racine et d'ajouter le champ branch dans la configuration du module comme suit:

branch = <branch-name-you-want-module-to-checkout>

6
répondu frontendgirl 2017-05-09 14:30:57