-
1. DĂ©marrage rapide
-
2. Les bases de Git
-
3. Les branches avec Git
-
4. Git sur le serveur
- 4.1 Protocoles
- 4.2 Installation de Git sur un serveur
- 4.3 Génération des clés publiques SSH
- 4.4 Mise en place du serveur
- 4.5 DĂ©mon (Daemon) Git
- 4.6 HTTP intelligent
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git hébergé
- 4.10 Résumé
-
5. Git distribué
-
6. GitHub
-
7. Utilitaires Git
- 7.1 SĂ©lection des versions
- 7.2 Indexation interactive
- 7.3 Remisage et nettoyage
- 7.4 Signer votre travail
- 7.5 Recherche
- 7.6 RĂ©Ă©crire lâhistorique
- 7.7 Reset démystifié
- 7.8 Fusion avancée
- 7.9 Rerere
- 7.10 DĂ©boguer avec Git
- 7.11 Sous-modules
- 7.12 Empaquetage (bundling)
- 7.13 Replace
- 7.14 Stockage des identifiants
- 7.15 Résumé
-
8. Personnalisation de Git
- 8.1 Configuration de Git
- 8.2 Attributs Git
- 8.3 Crochets Git
- 8.4 Exemple de politique gérée par Git
- 8.5 Résumé
-
9. Git et les autres systĂšmes
- 9.1 Git comme client
- 9.2 Migration vers Git
- 9.3 Résumé
-
10. Les tripes de Git
- 10.1 Plomberie et porcelaine
- 10.2 Les objets de Git
- 10.3 Références Git
- 10.4 Fichiers groupés
- 10.5 La refspec
- 10.6 Les protocoles de transfert
- 10.7 Maintenance et récupération de données
- 10.8 Les variables dâenvironnement
- 10.9 Résumé
-
A1. Annexe A: Git dans dâautres environnements
- A1.1 Interfaces graphiques
- A1.2 Git dans Visual Studio
- A1.3 Git dans Visual Studio Code
- A1.4 Git dans IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git dans Sublime Text
- A1.6 Git dans Bash
- A1.7 Git dans Zsh
- A1.8 Git dans PowerShell
- A1.9 Résumé
-
A2. Annexe B: Embarquer Git dans vos applications
- A2.1 Git en ligne de commande
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Commandes Git
- A3.1 Installation et configuration
- A3.2 Obtention et création des projets
- A3.3 Capture dâinstantanĂ© basique
- A3.4 Création de branches et fusion
- A3.5 Partage et mise Ă jour de projets
- A3.6 Inspection et comparaison
- A3.7 DĂ©bogage
- A3.8 Patchs
- A3.9 Courriel
- A3.10 SystĂšmes externes
- A3.11 Administration
- A3.12 Commandes de plomberie
10.6 Les tripes de Git - Les protocoles de transfert
Les protocoles de transfert
Git peut transfĂ©rer des donnĂ©es entre deux dĂ©pĂŽts de deux façons principales : le protocole « stupide » et le protocole « intelligent ». Cette section fait un tour dâhorizon du fonctionnement de ces deux protocoles.
Le protocole stupide
Si vous mettez en place un dĂ©pĂŽt Ă accĂ©der en lecture seule sur HTTP, câest vraisemblablement le protocole stupide qui sera utilisĂ©. Ce protocole est dit « stupide », car il ne nĂ©cessite aucun code spĂ©cifique Ă Git cĂŽtĂ© serveur durant le transfert ; le processus de rĂ©cupĂ©ration est une sĂ©rie de requĂȘtes GET, oĂč le client devine la structure du dĂ©pĂŽt Git prĂ©sent sur le serveur.
Note
|
Le protocole stupide est rarement utilisĂ© ces derniers temps. Il est difficile de le rendre sĂ©curisĂ© ou privĂ©, et donc la plupart des hĂ©bergeurs Git (sur le cloud ou sur serveur dĂ©diĂ©) refusent de lâutiliser. On conseille gĂ©nĂ©ralement dâutiliser le protocole intelligent, qui est dĂ©crit plus loin. |
Suivons le processus http-fetch
pour la bibliothÚque simplegit :
$ git clone https://server/simplegit-progit.git
La premiÚre chose que fait cette commande est de récupérer le fichier info/refs
.
Ce fichier est Ă©crit par la commande update-server-info
et câest pour cela quâil faut activer le crochet post-receive
, sinon le transfert HTTP ne fonctionnera pas correctement :
> GET info/refs
ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
On possÚde maintenant une liste des références distantes et empreintes SHA-1. Ensuite, on regarde vers quoi pointe HEAD, pour savoir sur quelle branche se placer quand on aura fini :
> GET HEAD
ref: refs/heads/master
On aura besoin de se placer sur la branche master
, quand le processus sera terminé.
On est maintenant prĂȘt Ă dĂ©marrer le processus de parcours.
Puisque votre point de dĂ©part est lâobjet commit ca82a6
que vous avez vu dans le fichier info/refs
, vous commencez par le récupérer :
> GET objects/ca/82a6dff817ec66f44342007202690a93763949
(179 bytes of binary data)
Vous obtenez un objet, cet objet est dans le format brut sur le serveur et vous lâavez rĂ©cupĂ©rĂ© Ă travers une requĂȘte HTTP GET statique. Vous pouvez le dĂ©compresser avec zlib, ignorer lâen-tĂȘte et regarder le contenu du commit :
$ git cat-file -p ca82a6dff817ec66f44342007202690a93763949
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
author Scott Chacon <schacon@gmail.com> 1205815931 -0700
committer Scott Chacon <schacon@gmail.com> 1240030591 -0700
changed the version number
Puis, vous avez deux autres objets supplémentaires à récupérer : cfda3b
qui est lâarbre du contenu sur lequel pointe le commit que nous venons de rĂ©cupĂ©rer et 085bb3
qui est le commit parent :
> GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
(179 bytes of data)
Cela vous donne le prochain objet commit. RĂ©cupĂ©rez lâobjet arbre :
> GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
(404 - Not Found)
Oups, on dirait que lâobjet arbre nâest pas au format brut sur le serveur, vous obtenez donc une rĂ©ponse 404. On peut en dĂ©duire certaines raisons : lâobjet peut ĂȘtre dans un dĂ©pĂŽt supplĂ©ant ou il peut ĂȘtre dans un fichier groupĂ© de ce dĂ©pĂŽt. Git vĂ©rifie la liste des dĂ©pĂŽts supplĂ©ants dâabord :
> GET objects/info/http-alternates
(empty file)
Si la rĂ©ponse contenait une liste dâURL supplĂ©antes, Git aurait cherchĂ© les fichiers bruts et les fichiers groupĂ©s Ă ces emplacements, câest un mĂ©canisme sympathique pour les projets qui ont dĂ©rivĂ© dâun autre pour partager les objets sur le disque.
Cependant, puisquâil nây a pas de supplĂ©ants listĂ©s dans ce cas, votre objet doit se trouver dans un fichier groupĂ©.
Pour voir quels fichiers groupés sont disponibles sur le serveur, vous avez besoin de récupérer le fichier objects/info/packs
, qui en contient la liste (générée également par update-server-info
)Â :
> GET objects/info/packs
P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
Il nâexiste quâun seul fichier groupĂ© sur le serveur, votre objet se trouve Ă©videmment dedans, mais vous allez tout de mĂȘme vĂ©rifier lâindex pour ĂȘtre sĂ»r. Câest Ă©galement utile lorsque vous avez plusieurs fichiers groupĂ©s sur le serveur, vous pouvez donc voir quel fichier groupĂ© contient lâobjet dont vous avez besoin :
> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
(4k of binary data)
Maintenant que vous avez lâindex du fichier groupĂ©, vous pouvez vĂ©rifier si votre objet est bien dedans car lâindex liste les empreintes SHA-1 des objets contenus dans ce fichier groupĂ© et des emplacements de ces objets. Votre objet est lĂ , allez donc rĂ©cupĂ©rer le fichier groupĂ© complet :
> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
(13k of binary data)
Vous avez votre objet arbre, vous continuez donc le chemin des commits.
Ils sont Ă©galement tous contenus dans votre fichier groupĂ© que vous venez de tĂ©lĂ©charger, vous nâavez donc pas dâautres requĂȘtes Ă faire au serveur.
Git récupÚre une copie de travail de votre branche master
qui été référencée par HEAD que vous avez téléchargé au début.
Le protocole intelligent
Le protocole stupide est simple mais un peu inefficace, et il ne permet pas lâĂ©criture de donnĂ©es du client au serveur. Le protocole intelligent est une mĂ©thode plus habituelle pour transfĂ©rer des donnĂ©es, mais elle nĂ©cessite lâexĂ©cution sur le serveur dâun processus qui connaĂźt Git : il peut lire les donnĂ©es locales et dĂ©terminer ce que le client a ou ce dont il a besoin pour gĂ©nĂ©rer un fichier groupĂ© personnalisĂ© pour lui. Il y a deux ensembles dâexĂ©cutables pour transfĂ©rer les donnĂ©es : une paire pour tĂ©lĂ©verser des donnĂ©es et une paire pour en tĂ©lĂ©charger.
Téléverser des données
Pour téléverser des données vers un exécutable distant, Git utilise les exécutables send-pack
et receive-pack
.
LâexĂ©cutable send-pack
tourne sur le client et se connecte Ă lâexĂ©cutable receive-pack
du cÎté serveur.
======= SSH
Par exemple, disons que vous exécutez git push origin master
dans votre projet et origin
est défini comme une URL qui utilise le protocole SSH.
Git appelle lâexĂ©cutable send-pack
, qui initialise une connexion Ă travers SSH vers votre serveur.
Il essaye dâexĂ©cuter une commande sur le serveur distant via un appel SSH qui ressemble Ă Â :
$ ssh -x git@server "git-receive-pack 'simplegit-progit.git'"
00a5ca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status \
delete-refs side-band-64k quiet ofs-delta \
agent=git/2:2.1.1+github-607-gfba4028 delete-refs
0000
La commande git-receive-pack
rĂ©pond immĂ©diatement avec une ligne pour chaque rĂ©fĂ©rence quâelle connaĂźt actuellement, dans ce cas, uniquement la branche master
et son empreinte SHA-1.
La premiÚre ligne contient également une liste des compétences du serveur (ici : report-status
, delete-refs
et quelques autres, dont lâidentifiant du client).
Chaque ligne commence avec une valeur hexadécimale sur 4 caractÚres, spécifiant le reste de la longueur de la ligne.
La premiĂšre ligne, ici, commence avec 00a5
, soit 165 en hexadĂ©cimal, ce qui signifie quâil y a 165 octets restants sur cette ligne.
La ligne dâaprĂšs est 0000
, signifiant que le serveur a fini de lister ses références.
Maintenant quâil connait lâĂ©tat du serveur, votre exĂ©cutable send-pack
détermine quels commits il a de plus que le serveur.
LâexĂ©cutable send-pack
envoie alors Ă lâexĂ©cutable receive-pack
les informations concernant chaque référence que cette commande push
va mettre Ă jour.
Par exemple, si vous mettez Ă jour la branche master
et ajoutez la branche experiment
, la réponse de send-pack
ressemblera à quelque chose comme :
0076ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 \
refs/heads/master report-status
006c0000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d \
refs/heads/experiment
0000
Git envoie une ligne pour chaque rĂ©fĂ©rence que lâon met Ă jour avec lâancien SHA-1, le nouveau SHA-1 et la rĂ©fĂ©rence en train dâĂȘtre mise Ă jour.
La premiÚre ligne contient également les compétences du client.
La valeur SHA-1 remplie de '0' signifie quâil nây avait rien Ă cet endroit avant, car vous ĂȘtes en train dâajouter la rĂ©fĂ©rence experiment
.
Si vous Ă©tiez en train de supprimer une rĂ©fĂ©rence, vous verriez lâopposĂ©Â : que des '0' du cĂŽtĂ© droit.
Puis, le client tĂ©lĂ©verse un fichier groupĂ© de tous les objets que le serveur nâa pas encore. Finalement, le serveur rĂ©pond avec une indication de succĂšs (ou dâĂ©chec) :
000eunpack ok
HTTP(S)
Le processus est quasiment le mĂȘme avec HTTP, Ă une diffĂ©rence prĂšs lors de lâĂ©tablissement de la liaison (handshaking). La connection est amorcĂ©e avec cette requĂȘte :
> GET https://server/simplegit-progit.git/info/refs?service=git-receive-pack
001f# service=git-receive-pack
00ab6c5f0e45abd7832bf23074a333f739977c9e8188 refs/heads/master \
report-status delete-refs side-band-64k quiet ofs-delta \
agent=git/2:2.1.1~vmg-bitmaps-bugaloo-608-g116744e
0000
Ceci est la fin du premier Ă©change client-serveur.
Le client fait alors une nouvelle requĂȘte, qui est cette fois un POST
, avec les données fournies par git-upload-pack
.
> POST https://server/simplegit-progit.git/git-receive/pack
La requĂȘte POST
contient la sortie de send-pack
et le fichier groupé.
Enfin, le serveur indique le succĂšs ou lâĂ©chec dans sa rĂ©ponse HTTP.
Gardez en tĂȘte que le protocole HTTP peut ensuite envelopper ces donnĂ©es dans un encodage de transfert par paquets.
Téléchargement des données
Lorsque vous téléchargez des données, les exécutables fetch-pack
et upload-pack
entrent en jeu.
Le client démarre un processus fetch-pack
qui se connecte Ă un processus upload-pack
du cÎté serveur pour négocier les données qui seront téléchargées.
SSH
Si vous téléchargez par SSH, fetch-pack
fait quelque chose comme ceci :
$ ssh -x git@server "git-upload-pack 'simplegit-progit.git'"
Une fois fetch-pack
connecté, upload-pack
lui répond quelque chose du style :
00dfca82a6dff817ec66f44342007202690a93763949 HEAD multi_ack thin-pack \
side-band side-band-64k ofs-delta shallow no-progress include-tag \
multi_ack_detailed symref=HEAD:refs/heads/master \
agent=git/2:2.1.1+github-607-gfba4028
003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master
0000
Ceci est trÚs proche de la réponse de receive-pack
mais les compétences sont différentes.
En plus, il envoie ce qui est pointé par HEAD (symref=HEAD:refs/heads/master
), afin que le client sache ce quâil doit rĂ©cupĂ©rer dans le cas dâun clone.
Ă ce moment, fetch-pack
regarde les objets quâil a et rĂ©pond avec la liste des objets dont il a besoin en envoyant « want » (vouloir) suivi du SHA-1 quâil veut.
Il envoie tous les objets quâil a dĂ©jĂ avec « have » suivi du SHA-1.
Ă la fin de la liste, il Ă©crit « done » (fait) pour inciter lâexĂ©cutable upload-pack
à commencer à envoyer le fichier groupé des données demandées :
003cwant ca82a6dff817ec66f44342007202690a93763949 ofs-delta
0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
0009done
0000
HTTP(S)
LâĂ©tablissement de la liaison pour une opĂ©ration de tĂ©lĂ©chargement nĂ©cessite deux requĂȘtes HTTP.
La premiĂšre est un GET
vers le mĂȘme point que dans le protocole stupide :
> GET $GIT_URL/info/refs?service=git-upload-pack
001e# service=git-upload-pack
00e7ca82a6dff817ec66f44342007202690a93763949 HEAD multi_ack thin-pack \
side-band side-band-64k ofs-delta shallow no-progress include-tag \
multi_ack_detailed no-done symref=HEAD:refs/heads/master \
agent=git/2:2.1.1+github-607-gfba4028
003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master
0000
Ceci ressemble beaucoup Ă un appel Ă git-upload-pack
par une connection SSH, mais le deuxiĂšme Ă©change est fait dans une requĂȘte sĂ©parĂ©e :
> POST $GIT_URL/git-upload-pack HTTP/1.0
0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7
0032have 441b40d833fdfa93eb2908e52742248faf0ee993
0000
Une fois de plus, ce format est le mĂȘme que plus haut. La rĂ©ponse Ă cette requĂȘte indique le succĂšs ou lâĂ©chec, et contient le fichier groupĂ©.
Résumé sur les protocoles
Cette section contient un survol basique des protocoles de transfert.
Les protocoles contiennent de nombreuses autres fonctionalités,
comme les compétences multi_ack
ou side-band
,
mais leur Ă©tude est hors du sujet de ce livre.
Nous avons essayé de vous donner une idée générale des échanges entre client et serveur.
Si vous souhaitez en connaĂźtre davantage, vous devrez probablement jeter un Ćil sur le code source de Git.