super_projet/
└── rapport.mdComprendre 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
Système CPOLD
super_projet/
└── rapport.mdsuper_projet/
├── rapport.md
└── rapport-v2.md
super_projet/
├── rapport.md
├── rapport-v2-relecture_bob.md
└── rapport-v2.mdsuper_projet/
├── rapport.md
├── rapport-v2-relecture_bob.md
├── rapport-v2.md
└── rapport-final.md
super_projet/
├── rapport.md
├── rapport-v2-relecture_bob.md
├── rapport-v2.md
├── rapport-final-correction.md
└── rapport-final.mdConvention de nommage
Au bon vouloir de chacun
Ordre réel des versions pas évident à deviner
5 fichiers pour un rapport
Synchronisation compliquée
Échanges par mail, stockage externe
Même fichier → contenu différent pour chacun
Déléguer à un système fiable l’historique de nos fichiers
Revenir à une version antérieure
Traçabilité : qui a fait quoi et quand
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
1986, peut encore être rencontré en entreprise, utilisé par NetBSD et OpenBSD
2000, successeur de CVS, encore massivement utilisé
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
2003, écrit en Haskell et pensé pour les projets Haskell
2005, supporté par Canonical (Ubuntu)
2005, écrit par Linus Torvalds pour le développement du noyau Linux
Gestionnaire de versions distribué
Créé par Linus Torvalds en 2005 pour la gestion des sources du noyau Linux
Le nom "git" est une référence directe à l’auteur…
I’m an egotistical bastard, and I name all my projects after myself. First Linux, now git.
Git ne retient pas une suite de différences, mais des snapshots des fichiers
La majorité des opérations sont locales
Git ne fait pratiquement qu’ajouter des données à sa base
Chaque utilisateur peut disposer de tous les commits
⇒ Serveur pas indispensable
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-colaNixOS
$ nix-console -p gitFull tig git-cola| 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 |
$ git config --global user.name "Your Name"
$ git config --global user.email "foo@bar.org"$ mkdir super_projet
$ cd super_projet
$ git init .$ echo "salut" > rapport.md
$ git add rapport.md
$ git commit -m "commit initial"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
Que contient la référence master de super_projet ?
$ cat .git/refs/heads/master
8b3e8234ccad7d9213bb28d1e70351ebeff965c8Git 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
greeetingsHash 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 initialQu’y a-t-il dans tree ?
$ git cat-file -p 1ee6881b1653531a8fc24057be0c61d82b8325de
100644 blob 28d0af969b32e69a389087d7a267a2ecc05f1350 rapport.mdContenu de rapport.md ?
$ git cat-file -p 28d0af969b32e69a389087d7a267a2ecc05f1350
coucouTous ces objets 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 filesPrenons 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 le dossier nouvellement créé
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 ?
On veut relire notre rapport, création d’une branche relecture :
$ git checkout -b relectureOn 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 initialLa commande précédente est longue à taper, mais néanmoins très utile. On va utiliser un alias git pour se simplifier la vie :
$ git config --global alias.lola "log --graph --decorate --oneline --all"On a plus besoin que de taper git lola pour obtenir le même résultat !
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
On repart du graphe précédent :
Faire un merge de relecture dans master, c’est deux étapes :
1 : Créer un commit ayant pour parents les derniers commits de chaque branche, donc 6 et 7
2 : Déplacer la référence de la branche dans laquelle on merge, ici master, sur le nouveau commit
Toujours le même graphe de départ :
Faire un rebase de relecture par-dessus master, c’est deux étapes :
1 : Trouver le commit à partir duquel les branches ont divergé, ici 5
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 distincts !
Dans super_projet, on a modifié readme.md dans master et rapport.md dans relecture.
On merge relecture dans master
Dans relecture, sur rapport.md, modifiez "Salut" en "Hello" puis commitez
Dans master, sur rapport.md, modifiez "Salut" en "Coucou" puis commitez
Lancer un merge de relecture vers master
Qu’est-ce qui se passe ?
Quel est le contenu de rapport.md avant de régler le problème ?
Effectuer les corrections nécessaires dans l’espace de travail
git commit --amend
Modifier le message si nécessaire
Relever le hash du commit précédent ou une branche
git rebase --interactive <hash/branch>
Se laisser guider par les commentaires
git reflog
Relever le hash de l’opération précédente
git reset --hard <hash>
Projet privé, limité à un groupe restreint
Possibilité de travailler directement entre les personnes (SSH)
Souvent, utilisation d’un serveur commun par commodité
Projet public, ou ne nous appartenant pas
Faire un "Fork"
Modifier le projet
Demander un "merge"
N’importe quelle machine Linux + SSH
Gitea (auto-hébergement, logiciel libre)
Gitlab (instance centrale + auto-hébergement, logiciel libre + fonctionnalités payantes, Gitlab Inc.)
Github (instance unique, logiciel propriétaire, Microsoft)
Créer un compte sur le serveur Git d’exemple
Configurer une clé SSH par votre profil
Créer un projet dans votre espace Gitlab
Transformer un projet existant en dépôt git local
Exécuter les instructions données à la création pour pousser le code existant dans le projet Gitlab
Fork = Embranchement
Action de copier le dépôt d’un projet pour le lire ou le modifier sans perturber le travail du propriétaire.
Merge = Fusionner
Demande polie au propriétaire d’un projet d’y inclure nos modifications.
Faire un fork "circulaire" du projet cours-cesi https://gitlab.dubronetwork.fr/Taeradan/cours-git
Enora → Yves
Safiatou → Enora
Clarence → Safiatou
Omar → Clarence
Anaïs → Omar
Nathan → Anaïs
Corentin → Nathan
Samuel → Corentin
Ruben → Samuel
Frédéric → Ruben
Yves → Frédéric
Être certain de la provenance d’un commit
Clé cryptographique forte avec GPG
Créer une clé GPG
Configurer Git pour utiliser la signature (ou demander la signature pour un commit précis)
Envoyer sa clé GPG sur le serveur Git
Exécuter un certain nombre d’opérations après un git push
Exécuter des tests
Vérifier que le projet compile
Vérifier des mauvaises pratiques
Livrer le résultat
Intégré à Gitlab
serveur Git SSH basique
Scripts avec inotify sur un
Hooks Git
Systèmes de CI/CD indépendants
Drone
Jenkins
Placez-vous dans le projet du TP de C importé précédemment
Activer le CI/CD dans le projet par le menu "Settings" → "General" → "…project features…"
Passer par l’éditeur de pipeline dans l’IHM pour créer un squelette de fichier .gitlab-ci.yml
Écrivez un job de CI permettant de compiler le projet
Définissez un artefact contenant le résultat de compilation pour pouvoir le télécharger par l’IHM
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