Est-il possible d’avoir des sous-modules peu profonds? J’ai un superprojet avec plusieurs sous-modules, chacun avec une longue histoire, donc il est inutile de faire glisser tout cet historique.
Tout ce que j’ai trouvé, c’est ce fil sans réponse .
Dois-je juste pirater git-submodule pour l’implémenter?
Nouveau dans le prochain git1.8.4 (juillet 2013) :
”
git submodule update
” peut éventuellement cloner les repositorys de sous-modules en profondeur.
(Et git 2.10 Q3 2016 permet d’enregistrer cela avec le git config -f .gitmodules submodule.
.
Voir la fin de cette réponse)
Voir commit 275cd184d52b5b81cb89e4ec33e540fb2ae61c1f :
Ajoutez l’option
--depth
aux commandes add et update de “git submodule”, qui est ensuite transmise à la commande clone. Ceci est utile lorsque les sous-modules sont énormes et que vous n’êtes pas vraiment intéressé par la dernière validation.Des tests sont ajoutés et certains ajustements d’indentation ont été faits pour se conformer au rest du fichier de test sur “la mise à jour du sous-module peut gérer les liens symboliques dans pwd”.
Signé par: Fredrik Gustafsson
Acquitté par: Jens Lehmann
Cela signifie que cela fonctionne:
git submodule add --depth 1 -- repository path git submodule update --depth -- [...]
Avec:
--depth::
Cette option est valide pour les commandes d’
add
et deupdate
.
Créez un clone «peu profond» avec un historique tronqué au nombre de révisions spécifié.
atwyman ajoute dans les commentaires :
Autant que je sache, cette option n’est pas utilisable pour les sous-modules qui ne suivent pas les
master
très près. Si vous définissez la profondeur 1, lasubmodule update
ne peut réussir que si le sous-module que vous souhaitez est le dernier maître. Sinon, vous obtenez ”fatal: reference is not a tree
“ .
C’est vrai.
C’est-à-dire jusqu’à git 2.8 (mars 2016). Avec la version 2.8, la submodule update --depth
du submodule update --depth
– submodule update --depth
a une chance supplémentaire de réussir, même si le SHA1 est directement accessible depuis l’un des repo HEADs distants.
Voir commit fb43e31 (24 février 2016) par Stefan Beller ( stefanbeller
) .
Aider: Junio C Hamano ( gitster
) .
(Fusionné par Junio C Hamano – gitster
– dans commit 9671a76 , 26 février 2016)
sous-module: essayez plus difficile de récupérer le sha1 nécessaire par extraction directe sha1
Lorsque vous examinez une modification qui met également à jour un sous-module dans Gerrit, une pratique courante consiste à télécharger et sélectionner le correctif localement pour le tester.
Cependant, en le testant localement, lagit submodule update
peut échouer, car la validation correspondante dans le sous-module ne fait pas encore partie de l’historique du projet, mais uniquement une modification proposée.Si
$sha1
ne faisait pas partie de la récupération par défaut, nous essayons de récupérer directement le$sha1
. Certains serveurs ne prennent toutefois pas en charge l’extraction directe par sha1, ce qui entraîne l’échec rapide degit-fetch
.
Nous pouvons nous échouer ici car le sha1 encore manquant conduirait de toute façon à un échec plus tard dans la phase de contrôle, alors échouer ici est aussi bon que possible.
MVG fait remarquer dans les commentaires de commettre fb43e31 (git 2.9, février 2016)
Il me semble que commit fb43e31 demande le commit manquant par identifiant SHA1, donc les parameters
uploadpack.allowReachableSHA1InWant
etuploadpack.allowTipSHA1InWant
sur le serveur affecteront probablement son fonctionnement.
J’ai écrit un article sur la liste git aujourd’hui , soulignant comment l’utilisation de sous-modules peu profonds pourrait être mieux adaptée à certains scénarios, à savoir si le commit est également une balise.
Attendons voir.J’imagine que c’est la raison pour laquelle fb43e31 a fait de l’extraction pour un SHA1 spécifique un repli après l’extraction de la twig par défaut.
Néanmoins, en cas de «–depth 1», je pense qu’il serait logique d’abandonner au plus tôt: si aucune des références listées ne correspond à celle demandée et que demander par SHA1 n’est pas supporté par le serveur, chercher n’importe quoi, puisque nous ne serons pas en mesure de satisfaire à l’exigence de sous-module de toute façon.
Mise à jour d’août 2016 (3 ans plus tard)
Avec Git 2.10 (Q3 2016), vous pourrez faire
git config -f .gitmodules submodule..shallow true
Voir ” Sous-module Git sans poids supplémentaire ” pour plus d’informations.
Git 2.13 (T2 2017) ajoute à comm 8d3047c (19 avril 2017) par Sebastian Schuberth ( sschuberth
) .
(Fusionné par Sebastian Schuberth – sschuberth
– dans commit 8d3047c , 20 avr. 2017)
un clone de ce sous-module sera exécuté comme un clone peu profond (avec une profondeur d’historique de 1)
Ciro Santilli ajoute cependant dans les commentaires (et les détails dans sa réponse )
shallow = true
sur.gitmodules
n’affecte que la référence suivie par HEAD de la télécommande lors de l’utilisation de--recurse-submodules
, même si la validation cible est pointée par une twig, et même si vous placezbranch = mybranch
sur les.gitmodules
comme bien.
Suite à la réponse de Ryan, j’ai été capable de créer ce script simple qui parcourt tous les sous-modules et les clone peu profonds:
#!/bin/bash git submodule init for i in $(git submodule | sed -e 's/.* //'); do spath=$(git config -f .gitmodules --get submodule.$i.path) surl=$(git config -f .gitmodules --get submodule.$i.url) git clone --depth 1 $surl $spath done git submodule update
Git 2.9.0 sous-modules de support clone peu profond directement, alors maintenant vous pouvez simplement appeler:
git clone url://to/source/repository --recursive --shallow-submodules
En parcourant le git-submodule “source”, il semble que git submodule add
puisse gérer les sous-modules qui ont déjà leurs repositorys. Dans ce cas…
$ git clone $remote1 $repo $ cd $repo $ git clone --depth 5 $remotesub1 $sub1 $ git submodule add $remotesub1 $sub1 #repeat as necessary...
Vous devez vous assurer que la validation requirejse se trouve dans le repo du sous-module, alors assurez-vous de définir un paramètre approprié –depth.
Edit: Vous pourrez peut-être vous en sortir avec plusieurs clones de sous-modules manuels suivis d’une seule mise à jour:
$ git clone $remote1 $repo $ cd $repo $ git clone --depth 5 $remotesub1 $sub1 #repeat as necessary... $ git submodule update
Récapitulatif du comportement bogue / inattendu / agaçant de Git 2.14.1
shallow = true
dans .gitmodules
n’affecte que git clone --recurse-submodules
si HEAD
des sous-modules distants pointe sur le commit requirejs, même si le commit cible est pointé par une twig, et même si vous placez branch = mybranch
sur le .gitmodules
aussi.
Script de test local . Même comportement sur GitHub 2017-11, où HEAD
est contrôlé par le paramétrage par défaut du repo de twig:
git clone --recurse-submodules https://github.com/cirosantilli/test-shallow-submodule-top-branch-shallow cd test-shallow-submodule-top-branch-shallow/mod git log # Multiple commits, not shallow.
git clone --recurse-submodules --shallow-submodules
échoue si le commit n’est pas référencé par une twig ou une balise avec un message: error: Server does not allow request for unadvertised object
.
Script de test local . Même comportement sur GitHub:
git clone --recurse-submodules --shallow-submodules https://github.com/cirosantilli/test-shallow-submodule-top-sha # error
J’ai également demandé sur la liste de diffusion: https://marc.info/?l=git&m=151863590026582&w=2 et la réponse était:
En théorie, cela devrait être facile. 🙂
En pratique pas tellement, malheureusement. Cela est dû au fait que le clonage n’obtiendra que la dernière pointe d’une twig (généralement maître). Il n’y a pas de mécanisme dans le clone pour spécifier le sha1 exact recherché.
Le protocole de fil prend en charge pour demander des sha1 exacts, de sorte que cela devrait être couvert. (Attention: cela ne fonctionne que si l’opérateur du serveur active uploadpack.allowReachableSHA1InWant, quel github n’a pas AFAICT)
git-fetch permet de récupérer des sha1 arbitraires. Pour contourner ce problème, vous pouvez exécuter une récupération après le clone récursif en utilisant “git submodule update”, car cela utilisera les récupérations après le clone initial.
Test TODO: allowReachableSHA1InWant
.
Les emplacements canoniques de vos sous-modules sont-ils distants? Si oui, êtes-vous d’accord pour les cloner une fois? En d’autres termes, voulez-vous les clones peu profonds juste parce que vous souffrez de la bande passante gaspillée de (re) clones de sous-module fréquents?
Si vous voulez que les clones superficiels sauvent l’espace disque local, la réponse de Ryan Graham semble être une bonne façon de faire. Clonez manuellement les référentiels afin qu’ils soient superficiels. Si vous pensez que ce serait utile, adaptez le git submodule
pour le supporter. Envoyez un courrier électronique à la liste pour en faire la demande (conseils pour la mise en œuvre, suggestions sur l’interface, etc.). À mon avis, les gens soutiennent les consortingbuteurs potentiels qui souhaitent sérieusement améliorer Git de manière constructive.
Si vous êtes d’accord pour faire un clone complet de chaque sous-module (plus des recherches ultérieures pour les garder à jour), vous pouvez utiliser l’option --reference
de la git submodule update
(dans Git 1.6.4 et versions ultérieures). aux magasins d’objects locaux (par exemple, créer des --mirror
clones de --mirror
des repositorys de sous-modules canoniques, puis utiliser --reference
dans vos sous-modules pour --reference
ces clones locaux). Veillez simplement à lire à propos de git clone --reference
/ git clone --shared
avant d’utiliser --reference
. Le seul problème probable lors du référencement des miroirs serait s’ils finissent par récupérer des mises à jour sans accélération (bien que vous puissiez activer les reflections et développer leurs fenêtres d’expiration pour aider à retenir les modifications abandonnées susceptibles de poser problème). Vous ne devriez avoir aucun problème tant que
Si vous optez pour quelque chose comme ça et que vous pouvez transporter des commits de sous-modules locaux dans vos arborescences de travail, il serait probablement judicieux de créer un système automatisé garantissant que les objects critiques référencés par les sous-modules extraits ne sont pas laissé en suspens dans les référentiels miroir (et s’il en trouve, les copie dans les référentiels qui en ont besoin).
Et, comme le dit la page de --reference
du git clone
, n’utilisez pas --reference
si vous ne comprenez pas ces implications.
# Full clone (mirror), done once. git clone --mirror $sub1_url $path_to_mirrors/$sub1_name.git git clone --mirror $sub2_url $path_to_mirrors/$sub2_name.git # Reference the full clones any time you initialize a submodule git clone $super_url super cd super git submodule update --init --reference $path_to_mirrors/$sub1_name.git $sub1_path_in_super git submodule update --init --reference $path_to_mirrors/$sub2_name.git $sub2_path_in_super # To avoid extra packs in each of the superprojects' submodules, # update the mirror clones before any pull/merge in super-projects. for p in $path_to_mirrors/*.git; do GIT_DIR="$p" git fetch; done cd super git pull # merges in new versions of submodules git submodule update # update sub refs, checkout new versions, # but no download since they reference the updated mirrors
Alternativement, au lieu de --reference
, vous pouvez utiliser les clones miroir en combinaison avec la fonctionnalité de liaison par défaut du git clone
en utilisant des miroirs locaux comme source pour vos sous-modules. Dans les nouveaux clones de super-projets, faites git submodule init
, éditez les URL de sous-modules dans .git/config
pour pointer vers les miroirs locaux, puis effectuez la git submodule update
. Vous devez reclonez tous les sous-modules vérifiés existants pour obtenir les liens en dur. Vous économiserez de la bande passante en ne téléchargeant qu’une seule fois dans les miroirs, puis en les récupérant localement dans vos sous-modules extraits. La liaison matérielle permettrait d’économiser de l’espace disque (même si les récupérations ont tendance à s’accumuler et à être dupliquées sur plusieurs instances des magasins d’objects des sous-modules extraits), vous pouvez régulièrement reclasser les sous-modules extraits pour obtenir un gain de place. reliure).
J’ai créé une version légèrement différente, quand elle ne fonctionne pas à la pointe de la technologie, ce que tous les projets ne font pas. Les ajouts de sous-modules standard ne fonctionnaient pas, pas plus que le script ci-dessus. J’ai donc ajouté une recherche de hachage pour la balise ref, et si elle n’en a pas, elle revient au clone complet.
#!/bin/bash git submodule init git submodule | while read hash name junk; do spath=$(git config -f .gitmodules --get submodule.$name.path) surl=$(git config -f .gitmodules --get submodule.$name.url) sbr=$(git ls-remote --tags $surl | sed -r "/${hash:1}/ s|^.*tags/([^^]+).*\$|\1|p;d") if [ -z $sbr ]; then git clone $surl $spath else git clone -b $sbr --depth 1 --single-branch $surl $spath fi done git submodule update
Référence à Comment cloner le repository git avec une révision / changeset spécifique?
J’ai écrit un script simple qui n’a aucun problème lorsque votre référence de sous-module est éloignée du maître
git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD'
Cette instruction va extraire la version référencée du sous-module.
Il est rapide mais vous ne pouvez pas valider votre modification sur le sous-module (vous devez le récupérer avant https://stackoverflow.com/a/17937889/3156509 )
en entier:
#!/bin/bash git submodule init git submodule foreach --recursive 'git rev-parse HEAD | xargs -I {} git fetch origin {} && git reset --hard FETCH_HEAD' git submodule update --recursive