GIT - Gestion de version

Je vous en ai déjà parlé bon nombre de fois dans divers articles… Cette fois, je me lance sur le sujet pour quelque chose de plus étoffé !

J’ai découvert cet outil voilà maintenant plusieurs années, mais je n’avais jamais eu le courage de me pencher dessus plus en détail, pas vraiment faute de temps, mais faute de motivation je l’avoue.
Je suis arrivé à un stade ou mes implications dans diverses associations et projets OpenSource m’ont « obligé » à rentrer et à appréhender plus en détail cet outil.

Nous allons donc détailler ici de quoi il retourne.

GIT, c’est quoi ?

Tout d’abord, un petit brief sur l’outil, qu’est-ce que c’est et à quoi ça sert.

GIT a été créé et développé par Linus TORVALDS qui est également le papa du kernel Linux. Donc de fait, on est en droit de croire que l’outil est quelque chose de propre, et pleinement fonctionnel.
Je vous le dit directement, pour moi, l’outil en lui même est bien plus que satisfaisant ! Je m’en sers quotidiennement depuis maintenant plus d’une année. D’ailleurs, tous les articles de ce site sont géré via GIT.

Dans les faits, c’est un outil de gestion de version. Il permet très facilement l’analyse de chaque modifications faites sur ce qu’il gère, que cela soit du code, des configurations ou bien d’autres choses.
Pourquoi ? Et bien tout simplement pour pouvoir revenir instantanément à une version antérieure de notre travail.
Mais en définitive, pas que ! Il introduit une grande facilité de travail collaboratif par le biais, notamment, des dépôts distant, au travers de forges logicielles ou non.

Mais nous détaillerons ça plus loin.

Fonctionnement

Attelons nous plus en détail sur le fonctionnement de GIT.
C’est, je dirais, le plus complexe à comprendre. Mais c’est ce qui fait toute la force et la flexibilité de l’outil.
J’avais déjà fait un petit bout de travail sur mon Wiki, il n’est clairement pas complet, et n’est pas non plus dédié à l’explication de ce qu’est l’outil mais plus à l’utilisation.

GIT permet donc comme je le disais de versionner des fichiers. Mais au final, c’est quoi le versionnement ?

Et bien c’est de suivre les modifications faites sur un fichier, pouvoir naviguer entre ces différentes modifications (plus exactement entre les différentes versions), pouvoir annuler une modifications, ou même faire des modifications sur une version antérieure et de rejouer les modifications suivantes jusqu’au dernier état connu.
Ne vous inquiétez pas, c’est totalement normal si ce n’est pas clair pour le moment. Ça viendra au fur et à mesure, je vais essayer de vous donner des exemples plus parlant (ou peut être dans un autre billet).

Architecture

Pour vous expliquer comment GIT fait pour gérer les différentes versions d’un ou plusieurs fichiers, il faut que je vous expose les différentes strates par lesquelles passent un fichier quand il est géré par GIT.

Pour se faire, je vous laisse le petit schéma suivant qui est assez parlant une fois lié aux explications qui vont bien.
Il est associé aux commandes permettant le passage d’une strate à une autre, mais pour le moment, je ne les détaillerais pas, ce sera le but d’un autre billet compte tenu de la longueur de celui-ci.

Donc allons un peu dans le détails des différents niveaux qu’utilise GIT.

Rapidement, on identifier :

  • Workspace
  • Index
  • Local repository
  • Remote repository

On va laisser un peu de côté la partie remote repository pour le moment, on y reviendra plus tard dans l’article.

Workspace

Le tout premier niveau, c’est le workspace, l’« espace de travail courant ». En fait, sans le savoir, vous êtes toujours dans un workspace.
C’est en effet le niveau « avant » la prise en charge d’un fichier par GIT si on peut dire. Mais pas exactement non plus.

Admettons le cas suivant, vous êtes en train (comme moi) de rédiger un article (ou un quelconque fichier) mais vous n’avez pas fait quoi que se soit en rapport avec GIT pour le moment. Vous êtes de fait dans un Workspace (attention, on ne parle pas du cadre de GIT pour le moment), tout simplement parce que vous êtes dans un espace de travail.

Passons au cadre de GIT maintenant. Avant de commencer à travailler avec GIT donc, vous êtes déjà dans un workspace. Quand vous travaillez avec GIT, votre fichier passe une première fois par le stade « index » que l’on va détailler juste après, puis, quand vous le modifiez, reviens un niveau workspace.
Si on simplifie la chose à l’extrême, vous ne pouvez uniquement travailler sur un fichier que dans le workspace.

Sur ce niveau là, rien de plus. Il ne sert ni plus ni moins qu’à laisser un accès au fichier pour pouvoir les faire évoluer.

Index

Tracking

La stade index est le premier « vrai » stade de GIT. C’est à ce moment que l’on va dire à GIT qu’il faut qu’il gère un fichier. Ce stade s’appelle le « tracking ». C’est une ajout à l’indexation si l’on peut dire.

Au moment où un fichier est traqué (en fait on va dire suivi, c’est plus joli) par GIT, il « sort » en quelque sorte du workspace dans l’état actuel. GIT prends en compte le fichier tel quel pour le traiter. Ni plus ni moins pour le moment. C’est une simple étape transitoire vers l’état suivant qui est vraiment le cœur de GIT.

C’est cette phase d’index qui génère tout ce qui gravite autour du fichier qui est géré par GIT. On va voir le détail de tout ça dans la partie local repository.

Stagging

Un niveau du stade « index », on va retrouver un autre stade ou état possible pour le fichier. Ce stade s’appelle le « stagging » le principe de fonctionnement est identique au tracking si on veut, mais là nous n’ajoutons pas une nouvelle entrée dans l’index GIT, mais on met à jour l’index avec la nouvelle version du fichier.
Celà implique donc que le fichier ai déjà été suivi par GIT et soit donc présent dans l’index.

Au final, ce niveau est une simple gestion d’index, par des mécanisme d’ajout/suppression/mise à jour.

Local Repository

Aller, on passe à l’étape vraiment intéressante de l’outil. La partie Local Repository (dépot local pour les francophones).

C’est ici que tout se joue pour GIT ! C’est le cœur du bestiau.

Bon aller, j’arrête mes digressions ! De quoi il en retourne ?
Et bien… Beaucoup de choses ! En vrac on va détailler :

  • Les dépôts
  • Les branches
  • Les commit et commit ID
  • La fonction blame

Oulà, maiskeskidit ! Oui c’est barbare balancé comme ça !

Dépôt

Introduisons rapidement les dépôts. C’est, en somme, une base de données de l’ensemble des modifications que vous avez réalisé sur vos fichiers indexé.

Le comportement des dépôts et un poil complexe à vous expliquer dans le détail, mais je vais quand même essayer de vous expliquer grossièrement…
En fait, ce que fait GIT au niveau des dépôts, c’est une découpe de chaque fichiers en x blocs. Chaque blocs étant un contenu d’information particulière pour d’une partie du fichier.
Chaque bloc étant référencé par un hash et journalisé. Ce hashing permettant une indexation et une navigation plus simple dans l’historique du fichier. La partie journal permet donc de savoir quand, qui et quelle modification ont été faites sur le fichier en question. (On y revient juste en dessous lorsque l’on va parler des commits).

Un dépôt est donc, comme je le spécifiais plus haut, une sorte de base de donnée référençant chaque fichiers et chaque modifications de fichiers. Chaque modifications étant en rapport avec une date/heure de modification, mais également la personne ayant fait la modification.

En somme, ce que GIT stocke à chaque fois que l’on modifie un fichier et que nous le « déposons » dans le dépôt local, ce n’est pas un fichier entier, mais juste une différence avec le fichier n-1. Ce ne sont que des incréments.
Si je vous refais le process complet, lors de la première indexation et envoi dans le dépôt local, GIT pousse le fichier entier dans le dépôt. Dès lors, il ne poussera plus que des différences (des deltas) sur le même fichier.

Branches

Rapidement, GIT permet de gérer des branches. On peut créer des arbres assez complexes en utilisant ce mécanisme.
Dans les faits, les branches sont faites afin de faire évoluer en parallèle des fichiers, pour plusieurs raisons, par exemple lorsque plusieurs personnes travaillent sur le même fichier (pour des développeurs c’est très pratiques), ou alors pour une personne seule qui travaille sur plusieurs choses en même temps, comme différentes fonctionnalités.

Ça peut aussi servir pour conserver en accès rapide une certaine version du dépôt, soit pour venir y retravailler plus tard, soit pour pouvoir s’en servir.

Les détails approfondis viendrons plus tard ne vous inquiétez pas, ça fait déjà pas mal d’infos à digérer d’un coup.

Commits

Rappelez vous une dizaine de ligne plus haut, je vous parlais d’indexation de fichier et d’« étape transitoire », l’étape suivante à cette indexation de fichier, c’est le « commit ».
C’est simplement une action de versement des modifications au « dépôt local », enfin simplement du point de vue de l’utilisateur !

Dans les faits, l’action de génération d’un commit fait plein de chose au niveau du dépôt. je ne vais pas revenir sur l’histoire de mes blocs, ça vous avez déjà appréhendé (ou pas). Par contre, ce qui est intéressant à savoir, c’est que c’est lorsque l’action de commit est demandé que le hashing des fichiers se fait, et que GIT génère un Commit ID (qui au final est un Hash SHA256) qui va être un identifiant discriminant unique du commit.
L’action de commit va donc lier le hash de référencement, l’auteur du commit, la date et l’heure, mais également un commentaire que l’auteur du commit va laisser au moment où il va générer le commit.

Pourquoi identifier l’auteur du commit vous allez me dire ? Et bien simplement parce que plusieurs utilisateurs peuvent travailler sur le même dépôt. Pour les développeur, ça peut être super pratique de savoir qui a écrit la ligne 1843 du fichier toto.pl vous ne croyez pas ?
Et bien c’est exactement à ça que sert de connaître l’auteur d’un commit, pour utiliser une fonction de GIT qui s’appelle « blame » et qui va être en mesure d’identifier ligne à ligne l’auteur.

Remote Repository

Ah enfin les remotes repositories ! (Enfin)

Pourquoi j’ai attendu pour vous en parler à ce moment là ? Et bien la raison en est on ne peut plus simple.
Tout simplement parce que c’est une grosse partie de l’usage, enfin, tout dépends du point de vue et de l’utilisation que vous voulez faire de GIT.

Je m’explique sans plus attendre ! Nous avons déjà détaillé assez finement ce que peut faire GIT précédemment. En fait, si on s’en tient stricto sensus à la partie « versionning » nous avons déjà fait le tour de l’outil.
Mais ! Parce qu’il y a un mais, lors du développement de GIT il y a un facteur « collaboratif » qui est entré en compte. Pouvoir faire participer des personnes au processus de développement est toujours bien.
Mais pour ce faire, on ne pouvait pas travailler simplement sur un dépôt local. Comprenez bien que en faisant ça, il fallait copier le dépôt pour le passer à son collègue, et pour faire la récupération des nouveautés et l’inclusion dans le travail que vous aviez fait entre temps ce n’est pas pratique pour deux Francs (Bouhh il est vieux il parle en Francs).
Pour pallier à ça, Linus TORVALDS a prévu à GIT un « mode serveur » que l’on retrouvera sous la petite dénommination « bare ».

En quoi ça consiste ce fameux mode « bare » ? Et bien… Comment vous expliquer, c’est une pure « copie » de votre dépôt local. Attention ! Je ne parle pas du workspace, mais bien de ce qu’à fait GIT avec vos fichiers (indexation, hashing, etc, etc…).
Dans l’idée, vous travaillez sur votre machine A. Vous créez un dépôt distant (oui oui le fameux remote repository) sur une machine S. Vous pourrez très facilement avec GIT envoyer tout votre travail vers la machine S sans perdre d’information entre votre dépot local et le dépôt distant.

Magique non ?

Ça c’était la « première façon » de faire pour avoir un dépôt distant.

L’autre façon de faire, et c’est celle que je préfère utiliser, même si je n’en tire que peu d’avantages vu que beaucoup de mes dépots sont à utilisateur unique, c’est de passer par une forge logicielle.
Pour bien des choses, c’est plus facile d’utiliser une forge logicielle, elles permettent d’intervenir directement sur les dépôts qui sont stocké dessus, par exemple pour fusionner les codes de chacuns, mais surtout parce qu’elle permet d’avoir une vrai vision avec une interface web de votre dépôt.
Outre ça, elles intègrent assez souvent des outils de suivi de demandes ou de suivi de bug (Issues) simple et directement connecté à vos dépôts.

Personnellement, comme je le disais, j’ai fait le choix de travailler par le biais d’une forge qui gère très bien mes dépôts distant, elle les crées, les supprimes, les indexes, etc…
Elle me permet également de laisser l’accès à d’autres personnes qui vont contribuer à certains de mes projets (mon wiki c’est déjà le cas, même s’il ne bouge que très peu, et bientôt ce site sera également contributif).

Bref, tout ça pour dire…

GIT est prévu pour travaille avec des dépôts distant pour que l’ensemble des contributeurs puissent facilement récupérer, ajouter, modifier du contenu dans les dépots. Elles sont dans le cas de beaucoup de projets OpenSource sur des forges directement sur Internet, mais dans d’autres cas, on peut les positionner uniquement en réseau interne à une entreprise, pour des développements qui ne doivent surtout pas sortir du cadre de l’entreprise.

C’est cette fonctionnalité qui apporte tout le côté collaboratif de GIT, même si sans ça il le serait quand même, ce côté facilite énormément l’accès aux informations par x personnes.


Je vais maintenant m’arrêter là pour ce billet, je vais en faire un adjacent pour rentrer purement dans l’utilisation de GIT.
J’avais dans l’idée de tout faire sur un seul billet, mais, à la réflexion, ça va faire beaucoup trop long…

Bibliographie

  1. (en) GIT
  2. (en) Linus TORVALDS
  3. (en) Kernel Linux
  4. (fr) Outil de gestion de version
  5. (fr) Forges logicielle