web-dev-qa-db-fra.com

Pourquoi `git checkout` ne fait-il pas automatiquement` git submodule update --recursive`?

Quelqu'un s'il vous plaît aidez-moi à comprendre les sous-modules dans git. Je sais qu'ils obtiennent beaucoup de dénigrement sur Internet, mais comme je suppose que les développeurs Git sont des gens intelligents, il doit y avoir une raison au comportement actuel - et peut-être un moyen de contourner mon problème.

J'ai donc un projet et quelques sous-modules. Le projet a différentes branches, comme:

  • MyApp_version2
  • MyApp_version3
  • MyApp_version4
  • MyApp_liteversion
  • MyApp_development

Mes sous-modules ne sont pas mis à jour aussi souvent (peut-être une fois par semaine) donc je suis d'accord avec eux n'étant pas attaché automatiquement à la tête du référentiel de sous-modules .

Cependant, lorsque je vérifie une ancienne branche - parce que je dois corriger un bogue dans une ancienne version du logiciel - j'ai également besoin de mettre à jour les sous-modules.

Pourquoi dois-je faire ça?

Je m'attendrais à ce que git fonctionne comme svn. Lorsque j'engage mon travail dans mon référentiel principal, je m'attends à ce que git pense quelque chose dans ce sens: "OK, il veut engager son travail maintenant. Je peux voir que les sous-modules sont actuellement en révision abc donc quand il à un moment donné dans le futur revenir à cet engagement, il veut probablement les sous-modules à la même révision à nouveau. "

Je ne peux pas voir un seul cas où vous voudriez que les sous-modules restent à la révision actuelle pendant que vous remontez 3 ans dans votre référentiel principal. Cependant, il doit y avoir une raison à cette mise en œuvre, non?

J'aimerais vraiment savoir si l'un d'entre vous connaît les pensées derrière cela, mais en tout cas j'aimerais vraiment une solution. Y a-t-il un moyen de dire à git: "Je veux valider ce travail avec ces sous-modules. Si je reviens à un moment donné à cet état, je veux que les sous-modules soient également extraits dans la bonne version."

Exemple de clarification

Mon référentiel principal est une application qui doit utiliser SSL, et je trouve une bibliothèque SSL (libSSL) que j'ajoute comme sous-module.

Le 31 octobre 2010, je crée un commit dans mon référentiel principal (2fd4e1) tandis que le sous-module pointe vers libSSL version 3 (c67a2d).

Le temps passe, libSSl est mis à jour vers la version 34, j'adapte mon code, la vie est bonne.

Le 14 mai 2013, je crée un nouveau commit (28fced) et le sous-module pointe vers la version la plus récente de libSSL (849ee1).

Cependant, si je vérifie 2fd4e1, mon sous-module restera à 849ee1 même si le commit d'origine a été créé avec c67a2d. Git sait que j'ai fait le commit d'origine avec c67a2d et je ne vois pas comment vous pourriez vouloir un autre sous-module que celui avec lequel le commit d'origine a été créé.

35
Markus

Il semble que ce que vous voulez faire puisse être réalisé à partir de git v2.13 avec le nouveau --recurse-submodules option de git checkout. Du git-checkout page de manuel:

- [no-] recurse-submodules

L'utilisation de --recurse-submodules mettra à jour le contenu de tous les sous-modules initialisés en fonction de la validation enregistrée dans le superprojet. Si des modifications locales dans un sous-module étaient écrasées, la vérification échouera à moins que -f ne soit utilisé. Si rien (ou --no-recurse-submodules) n'est utilisé, les arbres de travail des sous-modules ne seront pas mis à jour.

Voir aussi ceci message de liste de diffusion git pertinent sur cette nouvelle option .

28
Cyril Cressent

Simplifiez vos raccourcis/alias en utilisant:

alias checkitout='git checkout $1; git submodule update --recursive'
1
thomas bogard

Vous voulez essentiellement que git effectue toutes les opérations de manière récursive et automatique pour tous les sous-modules. Ce qui est probablement trivial dans un modèle client-serveur centralisé comme svn.

Mais git est distribué. Votre sous-module peut provenir d'une URL totalement différente, avec un protocole totalement différent. Vous n'avez probablement pas accès à Push au référentiel Origin du sous-module, tandis que vous le faites pour le référentiel principal.

Il ne peut donc pas y avoir de poussée récursive.

Par conséquent, les concepteurs ont probablement décidé d'éviter partout la récursivité automatique des sous-modules. Ce qui est cohérent, mais une énorme douleur.

À tel point que, dans un certain projet, nous les avons complètement abandonnés et avons plutôt utilisé des fusions de sous-arbres.

0
SzG