web-dev-qa-db-fra.com

Quel est le moyen le plus rapide de cloner un référentiel git sur une connexion réseau rapide?

J'ai une situation avec un référentiel git relativement grand situé sur un hôte âgé et lent sur mon réseau local où il faut un certain temps pour faire le clone initial.

ravn@bamboo:~/git$ git clone gitosis@gitbox:git00
Initialized empty Git repository in /home/ravn/git/git00/.git/
remote: Counting objects: 89973, done.
remote: Compressing objects: 100% (26745/26745), done.
remote: Total 89973 (delta 50970), reused 85013 (delta 47798)
Receiving objects: 100% (89973/89973), 349.86 MiB | 2.25 MiB/s, done.
Resolving deltas: 100% (50970/50970), done.
Checking out files: 100% (11722/11722), done.
ravn@bamboo:~/git$

Il n'y a aucun changement de configuration spécifique à git dans la gitose.

Existe-t-il un moyen d'accélérer le bit de réception jusqu'à ce que le réseau soit capable?


EDIT: J'ai besoin que les nouveaux référentiels soient correctement connectés avec le référentiel en amont. À ma connaissance, cela nécessite que git fasse le clonage, et donc la copie de bits bruts en dehors de git ne fonctionnera pas.

24

Après avoir réalisé que la limite supérieure de la vitesse de transfert des données, est la connexion ssh qui est établie "en dehors" de git, j'ai fait quelques expériences et constaté que la limite supérieure d'utilisation de pcsp (PuTTY scp) était de 3,0 Mo/s car le schéma de chiffrement Blowfish a été correctement choisi. Une expérience de contrôle avec ftp brut a montré que la vitesse de transfert était de 3,1 Mo/s, elle a donc indiqué qu'il s'agissait de la limite supérieure du réseau.

Cela s'exécute à l'intérieur d'un hyperviseur vmware, et comme le processus effectuant les E/S réseau utilise presque 100% de CPU, il indique que le goulot d'étranglement est le pilote de la carte réseau Ubuntu. J'ai ensuite constaté que même si les outils vmware étaient installés, pour une raison quelconque, le noyau utilisait toujours le pilote vlance (émulant une carte réseau 10 Mbps avec IRQ et tout) au lieu du pilote vmxnet (qui parle directement à l'hyperviseur). Cela attend maintenant une fenêtre de service à changer.

En d'autres termes, le problème n'était pas lié à git mais au "matériel" sous-jacent.

Utilisez la profondeur pour créer un clone peu profond.

git clone --depth 1 <repository>
28
northtree

[~ # ~] ps [~ # ~] . Avertissement juste:

git est généralement considéré comme extrêmement rapide. Vous devriez essayer de cloner un dépôt complet de darcs, Bazaar, hg (Dieu ne plaise: TFS ou Subversion ...). De plus, si vous clonez régulièrement des référentiels complets à partir de zéro, vous feriez de toute façon quelque chose de mal. Vous pouvez toujours simplement git remote update et obtenez des modifications incrémentielles.

Pour diverses autres façons de garder complet repos synchronisé, voir, par ex.

(Les contiennent des liens vers d'autres SO posts) pertinents)

Copie muette

Comme mentionné, vous pouvez simplement copier un référentiel avec un transfert de fichiers "stupide".

Cela ne perdra certainement pas de temps à compresser, reconditionner, deltifier et/ou filtrer.

De plus, vous obtiendrez

Cela peut ou peut pas être ce dont vous avez besoin, mais il est agréable d'être conscient du fait


Paquet

Git clone optimise par défaut la bande passante. Puisque git clone, par défaut, ne fait pas miroir toutes les branches (voir --mirror) il ne serait pas logique de simplement vider les fichiers pack tels quels (car cela enverra peut-être bien plus que nécessaire).

Lors de la distribution à un vraiment grand nombre de clients, pensez à utiliser bundles.

Si vous voulez un clone rapide sans le coût côté serveur, la méthode git est bundle create. Vous pouvez désormais distribuer le bundle, sans même que le serveur soit impliqué. Si vous voulez dire que bundle... --all comprend plus que de simples git clone, par exemple bundle ... master pour réduire le volume.

git bundle create snapshot.bundle --all # (or mention specific ref names instead of --all)

et distribuez le lot d'instantanés à la place. C'est le meilleur des deux mondes, bien sûr, vous n'obtiendrez pas les éléments de la liste à puces ci-dessus. Côté réception, juste

git clone snapshot.bundle myclonedir/

Configurations de compression

Vous pouvez envisager de réduire la charge du serveur en réduisant/supprimant la compression. Jetez un œil à ces paramètres de configuration (je suppose que pack.compression peut vous aider à réduire la charge du serveur)

core.compression

Un entier -1..9, indiquant un niveau de compression par défaut. -1 est la valeur par défaut de zlib. 0 signifie pas de compression et 1..9 sont différents compromis vitesse/taille, 9 étant le plus lent. S'il est défini, cela fournit une valeur par défaut à d'autres variables de compression, telles que core.loosecompression et pack.compression.

core.loosecompression

Un entier -1..9, indiquant le niveau de compression pour les objets qui ne sont pas dans un fichier pack. -1 est la valeur par défaut de zlib. 0 signifie pas de compression et 1..9 sont différents compromis vitesse/taille, 9 étant le plus lent. S'il n'est pas défini, la valeur par défaut est core.compression. Si ce n'est pas le cas, la valeur par défaut est 1 (meilleure vitesse).

pack.compression

Un entier -1..9, indiquant le niveau de compression des objets dans un fichier pack. -1 est la valeur par défaut de zlib. 0 signifie pas de compression et 1..9 sont différents compromis vitesse/taille, 9 étant le plus lent. S'il n'est pas défini, la valeur par défaut est core.compression. Si ce n'est pas défini, la valeur par défaut est -1, la valeur par défaut de zlib, qui est "un compromis par défaut entre la vitesse et la compression (actuellement équivalent au niveau 6)".

Notez que la modification du niveau de compression ne recompressera pas automatiquement tous les objets existants. Vous pouvez forcer la recompression en passant l'option -F à git-repack (1).

Étant donné la large bande passante du réseau, ceci le sera se traduira en fait par des clones plus rapides. N'oubliez pas git-repack -F lorsque vous décidez de comparer cela!

28
sehe

Le git clone --depth=1 ...suggéré en 2014 deviendra plus rapide au T2 2019 avec Git 2.22.
En effet, pendant un clone partiel initial "git clone --depth=...", Il est inutile de passer des cycles pour une grande partie du contrôle de connectivité qui énumère et ignore les objets prometteurs (qui par définition sont tous des objets récupéré de l'autre côté).
Ceci a été optimisé.

clone: vérifie plus rapidement les objets pour les clones partiels

Pour les clones partiels, effectuer une vérification complète de la connectivité est un gaspillage; nous ignorons les objets prometteurs (qui, pour un clone partiel, sont tous des objets connus), et les énumérer tous pour les exclure de la vérification de la connectivité peut prendre beaucoup de temps sur les grands référentiels.

Tout au plus, nous voulons nous assurer que nous obtenons les objets référencés par les références voulues.
Pour les clones partiels, vérifiez simplement que ces objets ont été transférés.

Résultat:

  Test                          dfa33a2^         dfa33a2
  -------------------------------------------------------------------------
  5600.2: clone without blobs   18.41(22.72+1.09)   6.83(11.65+0.50) -62.9%
  5600.3: checkout of result    1.82(3.24+0.26)     1.84(3.24+0.26) +1.1%

62% plus rapide!


Avec Git 2.26 (T1 2020), une vérification de connectivité inutile est désormais désactivée dans un clone partiel lors de la récupération.

Voir commit 2df1aa2 , commit 5003377 (12 janvier 2020) par Jonathan Tan (jhowtan) .
(Fusionné par Junio ​​C Hamano - gitster - in commit 8fb3945 , 14 février 2020)

connected : vérifie la promesse du clone partiel

Signé par: Jonathan Tan
Révisé par: Jonathan Nieder

Valider dfa33a298d ("clone: effectuer une vérification d'objet plus rapide pour les clones partiels", 2019-04-21, Git v2.22.0-rc0 - merge ) optimisé le contrôle de connectivité effectué lors du clonage avec --filter pour ne vérifier que l'existence d'objets directement pointés par refs.
Mais cela ne suffit pas: ils doivent également être des objets prometteurs.
Rendez cette vérification plus robuste en vérifiant plutôt que ces objets sont des objets promisor, c'est-à-dire qu'ils apparaissent dans un pack promisor.

Et:

fetch : renoncez à la vérification complète de la connectivité si --filter

Signé par: Jonathan Tan
Révisé par: Jonathan Nieder

Si un filtre est spécifié, nous n'avons pas besoin d'une vérification de connectivité complète sur le contenu du packfile que nous venons de récupérer; il suffit de vérifier que les objets référencés sont des objets prometteurs.

Cela accélère considérablement les récupérations dans les référentiels qui contiennent de nombreux objets prometteurs, car lors de la vérification de la connectivité, tous les objets prometteurs sont énumérés (pour les marquer comme NON INTÉRESSANTS), ce qui prend beaucoup de temps.


Et, toujours avec Git 2.26 (Q1 2020), les machines bitmap d'accessibilité aux objets et les machines de clonage partiel n'étaient pas préparées à fonctionner correctement ensemble, parce que certains critères de filtrage d'objets que les clones partiels utilisent intrinsèquement reposent sur la traversée d'objet, mais la machinerie bitmap est une optimisation pour contourner cette traversée d'objet .

Il y a cependant des cas où ils peuvent travailler ensemble, et on leur a appris à leur sujet.

Voir commit 20a5fd8 (18 février 2020) par Junio ​​C Hamano (gitster) .
Voir commit 3ab3185 , commit 84243da , commit 4f3bd56 , commit cc4aa28 , commit 2aaeb9a , commit 6663ae , commit 4eb707e , commit ea047a8 , commit 608d9c9 , commit 55cb10f , commit 792f811 , commit d90fe06 (14 février 2020), et commit e03f928 , commit acac50d =, commit 551cf8b (13 février 2020) par Jeff King (peff) .
(Fusionné par Junio ​​C Hamano - gitster - in commit 0df82d9 , 02 mars 2020)

pack-bitmap : implémentez le filtrage BLOB_LIMIT

Signé par: Jeff King

Tout comme le le commit précédent a implémenté BLOB_NONE , nous pouvons prendre en charge les filtres BLOB_LIMIT En examinant la taille des blobs dans le résultat et en désinstallant leurs bits comme il convient.
C'est un peu plus cher que BLOB_NONE, Mais produit toujours une accélération notable (ces résultats sont sur git.git ):

Test                                         HEAD~2            HEAD
------------------------------------------------------------------------------------
5310.9:  rev-list count with blob:none       1.80(1.77+0.02)   0.22(0.20+0.02) -87.8%
5310.10: rev-list count with blob:limit=1k   1.99(1.96+0.03)   0.29(0.25+0.03) -85.4%

L'implémentation est similaire à celle de BLOB_NONE, À l'exception que nous devons aller objet par objet tout en parcourant le bitmap de type blob (car nous ne pouvons pas masquer les correspondances, mais devons rechercher le taille individuellement pour chaque blob).
L'astuce avec l'utilisation de ctz64() est tirée de show_objects_for_type(), qui doit également trouver des bits individuels (mais veut sauter rapidement les gros morceaux sans taches).

2
VonC

Je suis un clone de git de benchmark.

Cela peut être plus rapide avec les options --jobs si le projet inclut des sous-modules ex:

git clone --recursive --shallow-submodules --depth 1 --branch "your tag or branch" --jobs 5 --  "your remote repo"
1
dwa.kang

À partir du journal, il semble que vous ayez déjà terminé le clone, si votre problème est que vous devez effectuer ce processus plusieurs fois sur différentes machines, vous pouvez simplement copier le répertoire du référentiel d'une machine à l'autre. De cette façon, vous préserverez la relation (télécommandes) entre chaque copie et le référentiel à partir duquel vous avez cloné.

1
idanzalz