Sous-modules Git: spécifiez une twig / une étiquette

Comment git submodule add -b ?

Après avoir ajouté un sous-module avec une twig spécifique, un nouveau git submodule update --init cloné (après la git submodule update --init ) se trouvera dans un commit spécifique et non dans la twig elle-même.

Je ne trouve aucune information sur .gitmodules ou .git/config sur la twig du sous-module ou sur un commit spécifique, alors comment git le .gitmodules.git/config il?

En outre, est-il possible de spécifier une balise au lieu d’une twig?

PS: J’utilise 1.6.5.2 .

Remarque: Git 1.8.2 a ajouté la possibilité de suivre les twigs. Voir certaines des réponses ci-dessous.


Il est un peu déroutant de s’y habituer, mais les sous-modules ne sont pas sur une twig. Ils sont, comme vous le dites, juste un pointeur sur une validation particulière du référentiel du sous-module.

Cela signifie que lorsque quelqu’un d’autre extrait votre référentiel ou extrait votre code et effectue la mise à jour du 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 même sous-module en même temps.

Si vous souhaitez déplacer le sous-module vers une balise particulière:

 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 veut avoir submodule_directory changé pour cette balise, fait-il

 git pull git submodule update 

git pull modifications qui valident leur répertoire sous-module pointe vers. git submodule update fusionne en fait dans le nouveau code.

J’aimerais append ici une réponse qui n’est en réalité qu’un conglomérat d’autres réponses, mais je pense que cela pourrait être plus complet.

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

1) Votre .gitmodules a une entrée comme celle-ci:

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

2) Vous avez un object submodule (nommé SubmoduleTestRepo dans cet exemple) dans votre repository git. Github les présente comme des objects “sous-modules”. Ou faites le git submodule status de git submodule status partir d’une ligne de commande. Les objects de sous-module Git sont un type spécial d’object git et contiennent les informations SHA pour un commit spécifique.

Chaque fois que vous effectuez une git submodule update , le contenu du commit est renseigné dans votre sous-module. Il sait où trouver le commit à cause des informations contenues dans les .gitmodules .

Maintenant, tout ce que fait -b consiste à append une ligne dans votre fichier .gitmodules . Donc, 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 twig est pris en charge ci-dessus, pas SHA ou TAG.

L’object submodule pointe toujours vers un commit spécifique. La seule chose que l’option -b achète est la possibilité d’append un indicateur --remote à votre mise à jour selon la réponse de Vogella:

 git submodule update --remote 

Au lieu de renseigner le contenu du sous-module sur la validation pointée par le sous-module, il remplace cette validation par la dernière validation de la twig principale, puis remplit le sous-module avec cette validation. Cela peut être fait en deux étapes par djacobs7 répondre. Comme vous avez maintenant mis à jour le commit sur lequel l’object du sous-module pointe, vous devez valider l’object de sous-module modifié dans votre référentiel git.

git submodule add -b n’est pas une façon magique de garder tout à jour avec une twig. Il ajoute simplement des informations sur une twig dans le fichier .gitmodules et vous donne la possibilité de mettre à jour l’object de sous-module avec la dernière validation d’une twig spécifiée avant de le .gitmodules .

Notez que si vous avez un sous-module existant qui ne suit pas encore une twig , alors ( si vous avez la version 1.8.2+ ):

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

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

     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 repo distant en amont duquel le sous-module a été cloné.
Un git remote -v 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 repository parent:

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

     # 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 ‘ . ‘comme nom de twig:

Le nom de la twig est enregistré en tant que submodule..branch dans les .gitmodules pour la update --remote à update --remote .
Une valeur spéciale de . est utilisé pour indiquer que le nom de la twig dans le sous-module doit avoir le même nom que la twig en cours dans le référentiel actuel .


Si vous souhaitez mettre à jour tous vos sous-modules en suivant une twig:

  git submodule update --recursive --remote 

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

( Clintm note dans les commentaires que, si vous exécutez git submodule update --remote et que le sha1 résultant est identique à la twig sur laquelle se trouve le sous-module, il ne fera rien et laissera le sous-module “sur cette twig” pas dans l’état de tête détaché.)

Pour s’assurer que la twig est effectivement extraite (et que cela ne modifiera pas le SHA1 de l’ entrée spéciale représentant le sous-module parent pour le référentiel 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 commits, vous pourrez les pousser car ils seront référencés par la twig que vous voulez que le sous-module suive.
Après cette poussée dans un sous-module, n’oubliez pas de revenir au repository parent, d’append, de valider et de pousser le nouveau SHA1 pour ces sous-modules modifiés.

Notez l’utilisation de $toplevel , recommandée dans les commentaires d’ Alexander Pogrebnyak .
$toplevel été introduit dans git1.7.2 en mai 2010: commit f030c96 .

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

dtmland ajoute dans les commentaires :

Le script foreach ne parvient pas à extraire les sous-modules qui ne suivent pas une twig.
Cependant, cette commande vous donne à la fois:

  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 affine la commande de dtmland 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)' 

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

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

Voir aussi les sous-modules Git

Un exemple de la façon dont j’utilise les sous-modules git.

  1. Crée un nouveau repo
  2. Clone ensuite un autre repo en tant que sous-module
  3. Ensuite, nous avons ce sous-module qui utilise une balise 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 si j’utilise un tag et non une twig)

D’après mon expérience, la commutation de twigs dans le superprojet ou les extractions futures entraînera toujours des HEAD détachées des sous-modules, que le sous-module soit correctement ajouté ou suivi (réponses à @ djacobs7 et @Johnny Z).

Et au lieu de vérifier manuellement la twig correcte manuellement ou via un script, le sous-module git peut être utilisé.

Cela vérifie le fichier de configuration du sous-module pour la propriété de twig et extrait la twig définie.

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

Les sous-modules git sont un peu étranges – ils sont toujours en mode “détaché” – ils ne sont pas mis à jour avec la dernière validation sur une twig, comme vous vous en doutez.

Cela a du sens quand on y pense, cependant. Disons que je crée foo de référentiel avec la barre de sous-module. Je pousse mes modifications et je vous demande de vérifier le commit a7402be du foo du référentiel.

Imaginez ensuite que quelqu’un commette un changement sur la barre de repo avant de pouvoir créer votre clone.

Lorsque vous extrayez commit a7402be de repo foo, vous vous attendez à obtenir le même code que celui que j’ai poussé. C’est pour cette raison que les sous-modules ne sont pas mis à jour tant que vous ne leur avez pas dit explicitement, puis effectué un nouveau commit.

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

Je l’ai dans mon fichier .gitconfig. C’est toujours un brouillon, mais il s’est avéré utile dès maintenant. Cela m’aide à toujours rattacher les sous-modules à leur twig.

 [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, ie 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 twigs # 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-" 

Pour changer de twig pour un sous-module (en supposant que le sous-module fait déjà partie du référentiel):

  • cd à la racine de votre repo contenant les sous-modules
  • Ouvrez les .gitmodules pour l’édition
  • Ajouter une ligne sous path = ... et url = ... qui dit branch = your-branch , pour chaque sous-module; enregistrer le fichier .gitmodules .
  • puis sans changer de répertoire do $ git submodule update --remote

… cela devrait entraîner les derniers commits sur la twig spécifiée, pour chaque sous-module ainsi modifié.

Nous utilisons Quack pour extraire un module spécifique d’un autre référentiel git. Nous devons extraire du code sans base de code complète du référentiel fourni – nous avons besoin d’un module / fichier très spécifique de cet immense référentiel et nous devons le mettre à jour chaque fois que nous exécutons une mise à jour.

Nous avons donc réalisé de cette manière,

Créer une configuration

 name: Project Name modules: local/path: repository: https://github.com//.git path: repo/path branch: dev other/local/path/filename.txt: repository: https://github.com//.git hexsha: 9e3e9642cfea36f4ae216d27df100134920143b9 path: repo/path/filename.txt profiles: init: tasks: ['modules'] 

Avec la configuration ci-dessus, il crée 1 répertoire à partir du référentiel github fourni comme spécifié dans la première configuration du module, et l’autre consiste à extraire et créer un fichier à partir d’un référentiel donné.

Les autres développeurs ont juste besoin de courir

 $ quack 

Et il tire le code des configurations ci-dessus.

Le choix d’une twig pour un sous-module a pour seul effet de permettre à git de --checkout état HEAD détaché (si le comportement de --checkout par défaut est sélectionné) la dernière validation de la twig sélectionnée lorsque vous transmettez l’option --remote dans la ligne de commande .

Notez que la twig que vous choisissez à cette fin dans les parameters de sous-module N’EST PAS celle qui sera clonée lors de la submodule update --remote . Conséquence subtile si vous passez également le paramètre --depth et que vous ne --depth pas git de la twig que vous souhaitez cloner – !! et en fait vous ne pouvez pas dans la ligne de commande de mise à jour du sous-module git !! -, il se comportera implicitement comme expliqué dans le docu de git-clone(1) pour le paramètre explicite --branch de git clone --single-branch WITH MISSING et par conséquent il ne --branch la twig primaire . Sans surprise, au stade de clone et quand il essaiera finalement de trouver le dernier commit pour la twig que vous avez choisie pour le sous-module, si ce n’est pas le premier, il échouera avec

fatal: besoin d’une seule révision

Impossible de trouver la révision d’origine / nonPrimaryBranch actuelle dans le chemin de sous-module ‘mySubmodule’