Question Sous-modules Git: Spécifiez une branche / étiquette


Comment ça git submodule add -b travail?

Après avoir ajouté un sous-module à une branche spécifique, un nouveau repo cloné (après git submodule update --init) sera à un engagement spécifique, pas la branche elle-même (git status sur le sous-module montre "Pas actuellement sur une branche").

Je ne trouve aucune information sur .gitmodules ou .git/config à propos de la branche du sous-module ou de tout commit spécifique, alors comment git-il le comprendre?

Aussi, est-il possible de spécifier une étiquette au lieu d'une branche?

PS: J'utilise 1.6.5.2.


540
2017-11-22 04:55


origine


Réponses:


Note: Git 1.8.2 a ajouté la possibilité de suivre les branches. Voir quelques-unes des réponses ci-dessous.


C'est un peu déroutant de s'y habituer, mais les sous-modules ne sont pas sur une branche. Ils sont, comme vous le dites, juste un pointeur vers une validation particulière du dépôt du sous-module.

Cela signifie que lorsque quelqu'un d'autre extrait votre référentiel, ou tire votre code, et met à jour le sous-module git, le sous-module est extrait pour ce commit particulier.

C'est génial pour un sous-module qui ne change pas souvent, car alors tout le monde sur le projet peut avoir le sous-module au même commit.

Si vous souhaitez déplacer le sous-module vers un tag particulier:

cd submodule_directory
git checkout v1.0
cd ..
git add submodule_directory
git commit -m "moved submodule to v1.0"
git push

Ensuite, un autre développeur qui souhaite que submodule_directory soit changé en tag

git pull
git submodule update

git pull changements qui commettent leurs points de répertoire sous-module. git submodule update fusionne réellement dans le nouveau code.


571
2017-11-22 09:19



Je voudrais ajouter une réponse ici qui n'est vraiment qu'un conglomérat d'autres réponses, mais je pense que c'est peut-être plus complet.

Vous savez que vous avez un sous-module git quand vous avez ces deux choses.

1) Votre .gitmodules a une entrée comme ça:

[submodule "SubmoduleTestRepo"]
    path = SubmoduleTestRepo
    url = https://github.com/jzaccone/SubmoduleTestRepo.git

2) Vous avez un objet sous-module (nommé SubmoduleTestRepo dans cet exemple) dans votre dépôt git. Github les montre comme des objets "submodules". Ou faire git submodule status à partir d'une ligne de commande. Les objets sous-module Git sont un type spécial d'objet git et ils contiennent l'information SHA pour un commit spécifique.

Chaque fois que vous faites un git submodule update, il peuplera votre sous-module avec le contenu de la validation. Il sait où trouver le commit en raison de l'information dans le .gitmodules.

Maintenant, tous les -b est d'ajouter une ligne dans votre .gitmodules fichier. Donc, en suivant le même exemple, cela ressemblerait à ceci:

[submodule "SubmoduleTestRepo"]
    path = SubmoduleTestRepo
    url = https://github.com/jzaccone/SubmoduleTestRepo.git
    branch = master

EDIT: seul le nom de la branche est supporté ci-dessus, pas SHA ou TAG.

L'objet submodule pointe toujours sur un commit spécifique. La seule chose que le -b option vous achète est la possibilité d'ajouter un --remote drapeau à votre mise à jour selon la réponse de Vogella:

git submodule update --remote

Au lieu de renseigner le contenu du sous-module sur le commit pointé par le sous-module, il remplace ce commit par le dernier commit sur la branche master, ALORS il remplit le sous-module avec ce commit. Cela peut être fait en deux étapes par djacobs7 réponse. Puisque vous avez maintenant mis à jour la validation vers laquelle pointe l'objet submodule, vous devez valider l'objet sous-module modifié dans votre dépôt git.

git submodule add -b n'est pas un moyen magique de tout garder à jour avec une succursale. Il ajoute simplement des informations sur une branche dans le .gitmodulesfichier et vous donne la possibilité de mettre à jour l'objet sous-module à la dernière validation d'une branche spécifiée avant de le remplir.


383
2017-09-14 02:33



Notez que si vous avez un existant sous-module qui n'est pas suivre une branche encore, puis (si vous avez git 1.8.2+):

  • Assurez-vous que le référentiel parent sait que son sous-module suit désormais une branche:

    cd /path/to/your/parent/repo
    git config -f .gitmodules submodule.<path>.branch <branch>
    
  • Assurez-vous que votre sous-module est réellement au plus tard de cette branche:

    cd path/to/your/submodule
    git checkout -b branch --track origin/branch
      # if the master branch already exist:
      git branch -u origin/master master
    

(avec 'origine' étant le nom du dépôt à distance en amont le sous-module a été cloné.
UNE git remote -v à l'intérieur de ce sous-module l'affichera. Habituellement, c'est "origine")

  • N'oubliez pas d'enregistrer le nouvel état de votre sous-module dans votre repo parent:

    cd /path/to/your/parent/repo
    git add path/to/your/submodule
    git commit -m "Make submodule tracking a branch"
    
  • La mise à jour subséquente de ce sous-module devra utiliser --remote option:

    # update your submodule
    # --remote will also fetch and ensure that
    # the latest commit from the branch is used
    git submodule update --remote
    
    # to avoid fetching use
    git submodule update --remote --no-fetch 
    

Notez qu'avec Git 2.10+ (Q3 2016), vous pouvez utiliser '.'en tant que nom de branche:

Le nom de la succursale est enregistré comme submodule.<name>.branch dans .gitmodules pour update --remote.
Une valeur spéciale de . est utilisé pour indiquer que le nom de la branche dans le sous-module doit être le même que celui de la branche actuelle dans le référentiel actuel.


Si vous voulez mettre à jour tous vos sous-modules en suivant une branche:

    git submodule update --recursive --remote

Notez que le résultat, pour chaque sous-module mis à jour, sera presque toujours être un TETE détachée, comme Dan Cameron noter dans sa réponse.

(Clintm Remarques dans les commentaires ça, si tu cours git submodule update --remote et le sha1 résultant est le même que la branche sur laquelle le sous-module est actuellement, il ne fera rien et laissera le sous-module toujours "sur cette branche" et pas dans l'état de tête détaché.)

Pour s'assurer que la branche est effectivement extraite (et cela ne modifiera pas le SHA1 du entrée spéciale représentant le sous-module pour le repo parent), il suggère:

git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; git checkout $branch'

Chaque sous-module référencera toujours le même SHA1, mais si vous faites de nouveaux validations, vous pourrez les pousser car elles seront référencées par la branche que vous voulez que le sous-module effectue.
Après cette poussée à l'intérieur d'un sous-module, n'oubliez pas de revenir au référentiel parent, d'ajouter, de valider et de pousser le nouveau SHA1 pour ces sous-modules modifiés.

Notez l'utilisation de $toplevel, conseillé dans les commentaires par Alexander Pogrebnyak.
$toplevel a été introduit dans git1.7.2 en mai 2010: commenter f030c96.

il contient le chemin absolu du répertoire de niveau supérieur (où .gitmodules est).

dtmland ajoute dans les commentaires:

Le script foreach ne parviendra pas à extraire les sous-modules qui ne suivent pas une branche.
  Cependant, cette commande vous donne les deux:

 git submodule foreach -q --recursive 'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; [ "$branch" = "" ] && git checkout master || git checkout $branch' –

La même commande mais plus facile à lire:

git submodule foreach -q --recursive \
    'branch="$(git config -f $toplevel/.gitmodules submodule.$name.branch)"; \
     [ "$branch" = "" ] && \
     git checkout master || git checkout $branch' –

umläute raffine dtmlandLa commande avec une version simplifiée dans les commentaires:

git submodule foreach -q --recursive 'git checkout $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

plusieurs lignes:

git submodule foreach -q --recursive \
  'git checkout \
  $(git config -f $toplevel/.gitmodules submodule.$name.branch || echo master)'

241
2017-09-14 06:59



Git 1.8.2 a ajouté la possibilité de suivre les branches.

# add submodule to track master branch
git submodule add -b master [URL to Git repo];

# update your submodule
git submodule update --remote 

Voir également Git sous-modules


146
2018-04-03 08:44



Un exemple de comment j'utilise les sous-modules git.

  1. Crée un nouveau repo
  2. Puis clone un autre repo comme sous-module
  3. Ensuite, nous avons ce sous-module utiliser une étiquette appelée V3.1.2
  4. Et puis nous nous engageons

Et cela ressemble un peu à ceci:

git init 
vi README
git add README
git commit 
git submodule add git://github.com/XXXXX/xxx.yyyy.git stm32_std_lib
git status

git submodule init
git submodule update

cd stm32_std_lib/
git reset --hard V3.1.2 
cd ..
git commit -a

git submodule status 

Peut-être que ça aide? (même toi j'utilise une étiquette et pas une branche)


48
2017-11-22 09:53



Dans mon expérience, le fait de changer de branche dans le superprojet ou les futures vérifications entraîneront toujours des HEADs détachées des sous-modules, que le sous-module soit correctement ajouté et suivi (c'est-à-dire @ djacobs7 et @Johnny Z répond).

Et au lieu de vérifier manuellement la branche correcte manuellement ou via un script git submodule foreach peut être utilisé.

Cela vérifie le fichier de configuration du sous-module pour la propriété de la branche et extrait la branche set.

git submodule foreach -q --recursive 'branch="$(git config -f <path>.gitmodules submodule.$name.branch)"; git checkout $branch'


31
2017-11-09 04:54



Les sous-modules git sont un peu étranges - ils sont toujours en mode «tête détachée» - ils ne se mettent pas à jour sur le dernier commit sur une branche comme vous pouvez vous y attendre.

Cela a du sens quand vous y réfléchissez. Disons que je crée un référentiel foo avec une barre de sous-module. J'appuie sur mes changements et vous demande de vérifier le commit a7402be du dépôt foo.

Alors imaginez que quelqu'un commet un changement à la barre repo avant de pouvoir faire votre clone.

Lorsque vous vérifiez a7402be commit de repo foo, vous vous attendez à obtenir le même code que j'ai poussé. C'est pourquoi les sous-modules ne se mettent pas à jour jusqu'à ce que vous leur disiez explicitement et que vous fassiez une nouvelle validation.

Personnellement, je pense que les sous-modules sont la partie la plus confuse de git. Il y a beaucoup d'endroits qui peuvent expliquer les sous-modules mieux que je peux. je recommande Pro Git par Scott Chacon.


25
2017-11-22 05:22



J'ai ceci dans mon fichier .gitconfig. C'est encore un brouillon, mais s'est avéré utile dès maintenant. Cela m'aide à toujours rattacher les sous-modules à leur branche.

[alias]

######################
#
#Submodules aliases
#
######################


#git sm-trackbranch : places all submodules on their respective branch specified in .gitmodules
#This works if submodules are configured to track a branch, i.e if .gitmodules looks like :
#[submodule "my-submodule"]
#   path = my-submodule
#   url = git@wherever.you.like/my-submodule.git
#   branch = my-branch
sm-trackbranch = "! git submodule foreach -q --recursive 'branch=\"$(git config -f $toplevel/.gitmodules submodule.$name.branch)\"; git checkout $branch'"

#sm-pullrebase :
# - pull --rebase on the master repo
# - sm-trackbranch on every submodule
# - pull --rebase on each submodule
#
# Important note :
#- have a clean master repo and subrepos before doing this !
#- this is *not* equivalent to getting the last committed 
#  master repo + its submodules: if some submodules are tracking branches 
#  that have evolved since the last commit in the master repo,
#  they will be using those more recent commits !
#
#  (Note : On the contrary, git submodule update will stick 
#to the last committed SHA1 in the master repo)
#
sm-pullrebase = "! git pull --rebase; git submodule update; git sm-trackbranch ; git submodule foreach 'git pull --rebase' "

# git sm-diff will diff the master repo *and* its submodules
sm-diff = "! git diff && git submodule foreach 'git diff' "

#git sm-push will ask to push also submodules
sm-push = push --recurse-submodules=on-demand

#git alias : list all aliases
#useful in order to learn git syntax
alias = "!git config -l | grep alias | cut -c 7-"

6
2018-04-01 16:27