Gestion de versions du code : Git
Objectifs du cours
-
Comprendre l’intérêt du versionnement dans un projet de développement
-
Avoir une vision d’ensemble des différents systèmes de versionnement
-
S’approprier un outil de gestion de versions
La vie sans gestion de version
Système CPOLD
Chouette, un gentil relecteur :)
super_projet/
├── rapport.md
├── rapport-v2-relecture_bob.md
└── rapport-v2.md
C’est fini, on livre
super_projet/
├── rapport.md
├── rapport-v2-relecture_bob.md
├── rapport-v2.md
└── rapport-final.md
Systèmes centralisés
-
Un serveur contient tout l’historique des fichiers du projet
-
Chaque utilisateur possède une vue des fichiers
-
Un commit consiste à envoyer les modifications au serveur
Systèmes distribués
-
Chaque utilisateur possède son historique du projet
-
Un commit consiste à enregistrer les modifications dans la base de données locale
-
Il est toujours possible d’avoir un serveur central pour référence
Git !
Démarrer avec Git
Installation : Linux
Git est dans les paquets de toutes les distributions, par exemple :
-
Debian et dérivés
$ sudo apt update $ sudo apt install git tig git-cola -
NixOS
$ nix-shell -p gitFull tig git-cola
Installation: Windows
| WSL |
Linux dans Windows 10, pour les gens sérieux mais coincés sur Windows |
| Git pour Windows |
Simple et minimaliste |
| Cygwin |
Complexe, mais puissant, une collection d’outils Linux compilés pour Windows |
Préparation de Git
$ git config --global user.name "Your Name"
$ git config --global user.email "foo@bar.org"
Ajouter un premier fichier
$ echo "salut" > rapport.md
$ git add rapport.md
$ git commit -m "commit initial"
Les entrailles de Git
Git est un graphe
-
commit : 0 à n parent(s) + auteur + committer + message + état des fichiers
-
"master", "relecture" : branche, référence à un commit
-
"HEAD" : référence à la branche ou au commit sur lequel est basé l’espace de travail
Exploration du graphe
Que contient la référence master de super_projet ?
$ cat .git/refs/heads/master
8b3e8234ccad7d9213bb28d1e70351ebeff965c8
Git peut afficher le contenu du blob correspondant au hash, ici le commit référencé par la branche master
$ git cat-file -p 8b3e8234ccad7d9213bb28d1e70351ebeff965c8
tree 1ee6881b1653531a8fc24057be0c61d82b8325de
parent b4c8004bffba2d54753f906f5aa146a6d1ff4bef
author Yves Dubromelle <yves+git@dubronetwork.fr> 1587331162 +0200
committer Yves Dubromelle <yves+git@dubronetwork.fr> 1587331162 +0200
greeetings
!
Hash du commit parent ?
$ git cat-file -p b4c8004bffba2d54753f906f5aa146a6d1ff4bef
tree 19babb3bd3373b4b98e6d0a3b03aef4606dac4b6
author Yves Dubromelle <yves+git@dubronetwork.fr> 1587311802 +0200
committer Yves Dubromelle <yves+git@dubronetwork.fr> 1587311802 +0200
commit initial
Qu’y a-t-il dans tree ?
$ git cat-file -p 1ee6881b1653531a8fc24057be0c61d82b8325de
100644 blob 28d0af969b32e69a389087d7a267a2ecc05f1350 rapport.md
Contenu de rapport.md ?
$ git cat-file -p 28d0af969b32e69a389087d7a267a2ecc05f1350
coucou
!
Tous ces blobs référencés par leur hash sha1 sont présents dans .git/objects !
$ tree .git/objects/
.git/objects/
├── 19
│ └── babb3bd3373b4b98e6d0a3b03aef4606dac4b6
├── 1e
│ └── e6881b1653531a8fc24057be0c61d82b8325de
├── 28
│ └── d0af969b32e69a389087d7a267a2ecc05f1350
├── 8b
│ └── 3e8234ccad7d9213bb28d1e70351ebeff965c8
├── b4
│ └── c8004bffba2d54753f906f5aa146a6d1ff4bef
├── e6
│ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
├── info
└── pack
8 directories, 6 files
Exercice
Prenons le dépôt https://github.com/Taeradan/hahp :
-
Clonez le dépôt :
git clone https://github.com/Taeradan/hahp -
Déplacez-vous dans la branche webapi :
git checkout webapi -
Quel est le contenu de l’objet correspondant au dernier commit de la branche webapi ?
-
Quels sont les parents du commit 94fe1e8bc88b76635a9e4a0d9346c1eebccd6b4f ?
Travailler avec les branches
!
On veut relire notre rapport, création d’une branche relecture :
$ git checkout -b relecture
On corrige notre rapport :
$ echo "Salut tout le monde !" > rapport.md
$ git add rapport.md
$ git commit -m "plus d'enthousiasme"
!
Entre temps, le travail continue sur master :
$ git checkout master
$ echo "Projet ayant pour but de tester Git" > readme.md
$ git add readme.md
$ git commit -m "ajout readme"
L’état du projet :
$ git log --graph --decorate --oneline --all
* 0428e9b (HEAD -> master) ajout readme
| * 188be3e (relecture) plus d'enthousiasme
|/
* 8b3e823 greeetings
* b4c8004 commit initial
Réintégrer le travail de relecture
Il y a deux façons principales de réintégrer le travail de notre branche relecture dans master :
-
Un merge d’une branche dans l’autre
-
Un rebase d’une branche par-dessus l’autre
Rebase
Toujours le même graphe de départ :
Faire un rebase de relecture par-dessus master, c’est deux étapes :
!
2 : Rejouer les commits entre le 5 et celui pointé par relecture, ici 6, par-dessus de master
À noter : les commits ayant changé de parents, ils n’ont plus les mêmes hash, ce sont des commits différents !
Corrections à postériori
Quelques commandes utiles
-
Récupérer un commit depuis une autre branche :
git cherry-pick <hash>-
Le commit désigné sera joué par-dessus la branche courante, tout en restant à son emplacement d’origine
-
En cas de rebase ultérieur de la branche d’origine, le commit en double sera ignoré
-
-
Remiser des modifications :
git stash […] -
Référencer un commit particulier :
git tag -
Ignorer des fichiers : .gitignore