Si tu veux bien comprendre les opérations que tu réalises avec Git, tu dois comprendre les étapes par lesquelles transitent tes fichiers pour gérer tes versions, et par conséquent tu dois connaître une partie de l’architecture de Git, à commencer par les zones.

Je sais, c’est terrible, il faut que tu apprennes l’outil si tu veux travailler finement et intelligemment, et lire la doc’, bah c’est chiant ! Heureusement que je suis là pour t’expliquer tout ça !😄

Comme je te le disais, Git propose une gestion très fine du cycle de vie des fichiers. Tu trouveras peut être ça plus compliqué que dans des outils comme Subversion, avec plus d'opérations à réaliser tout ça, tout ça. Mais en vrai, tu peux faire aussi peu d’opérations en Git ce qui te produira un historique tout aussi moisi. 

Quoi qu’il en soit, l'objectif de Git, c’est d'élargir le potentiel que présentaient ces outils et de te permettre d'effectuer aussi bien des opérations chirurgicales que des opérations classiques, et tant qu’à faire, le plus rapidement possible.

Les zones de Git vont te servir à ça, c’est-à-dire à construire tes commits et préparer, puis partager ton historique. Selon les zones que tu utilises, l’état des fichiers change pour passer d'un état de création à un état validé, enregistré dans Git.

5 zones

Il existe 5 zones en tout qu’on découpe virtuellement en fonction de leur fréquence d’utilisation, ce qui va également me faciliter leur explication. 

Les 3 zones que je qualifie de « principales » sont :
 
  • la copie de travail ;
  • l’index, dont le nom a varié dans le temps et qu’on retrouve parfois sous les noms de stage, staging area ou encore cache ;
  • enfin, le dépôt local ou local repository en anglais.

On a déjà vu ce qu’est la copie de travail, c’est l’endroit où tu réalises ton travail.

L’index est une zone tampon qui va te servir à affiner ton prototype de commit jusqu’à sa validation. Il est hyper précieux, car c’est grâce à lui que tu peux choisir les fichiers ou parties de fichiers que tu souhaites intégrer dans ton prochain commit.

Le dépôt local est en quelque sorte ta base de données locale puisqu’il stocke les commits et les autres informations qui sont utiles à ta gestion de versions.

Tu l’as certainement compris : ces 3 zones « principales » sont celles que tu utilises tout le temps puisque c’est à travers elles que tu construis ton historique. 

On utilise plus occasionnellement les 2 autres zones. On y trouve 
  • le stash, qu'on apelle aussi « remise » en français, et qui te permet de mettre de côté un travail que tu aurais commencé pour en réaliser un autre, souvent plus urgent ;
  • enfin on a le dépôt distant, qui te sert à partager ton historique de commits ou à le synchroniser avec d’éventuels membres d’une équipe. La synchronisation s’effectue donc entre ton dépôt local et un dépôt distant.

On va commencer par voir dans le détail ces 3 zones principales avec les étapes de construction d'un historique.

Les étapes d'un commit à travers les zones

On commence avec les étapes de création d’un commit à travers notre copie de travail, notre index et jusqu’à notre dépôt local.

Un commit stocke des informations liées à des fichiers qui sont créés, modifiés ou supprimés. 

Pour préparer un commit tu commences donc dans ta copie de travail, par exemple ici tu créés et tu mets à jour les fichiers « A », « B » et « C ». Tu prévois de tous les intégrer dans ton commit. Tu les ajoutes donc à l’index, ce qui prépare ce qu'on appelle des instantanés, des sortes de photos des fichiers.  Tu te rends alors compte que les fichiers B et C traitent en fait d’autres sujets que « A », et comme tu veux créer des commits qui ont du sens, tu décides de les retirer de l'index.  Tu modifies « C », ce qui est représenté par par le « C’ » à l'écran. Et vu qu'il traite maintenant du même sujet que A, tu le rajoutes à l’index. Le travail à l'air satisfaisant, tu valides donc et crées le commit.

Si jamais le commit mérite d’autres mises à jour, il faudra que tu le défasses en gardant le travail qu'il contenait, donc en revenant soit à l’état des fichiers indexés, soit à l’état de la copie de travail. Dans les 2 cas, tu oublies le commit sans perdre ton travail avec l'optique de créer un autre commit à la place.
Enfin, tu peux aussi vouloir simplement oublier tout le travail représenté par le commit, ce qui veut dire défaire ton travail dans les 3 zones.

Note que j’ai bien parlé d’oublier le commit. J'insiste là-dessus car Git ne supprime pas immédiatement les objets dans sa base de données, il ne fait que les déréférencer, mais ça, on reparlera plus tard.

Étapes de création d'un historique de commits

On a vu comment est réalisé un commit à travers les 3 zones principales. Voyons à présent comment un ensemble de commits donne lieu à ce qu’on appelle l’historique du projet, ou l’historique des versions.

Les transitions successives à travers nos 3 zones principales nous donnent un premier commit, puis un second et enfin un troisième.

Tu vois les flèches dans le dépôt local qui lient les commits ? Elles sont là pour marquer l'enchaînement des commits, c’est-à-dire leur séquence temporelle. 

Un commit peut d'ailleurs être lié à un ou plusieurs parents, notamment lors des fusions de branches. On obtient en définitive un arbre qui représente les étapes successives jusqu'à l'état actuel du projet.

Pour l'instant notre arbre est complètement linéaire, mais quand il intégrera des branches ça viendra l'enrichir.

Transitions d'état des fichiers

En plus des zones, tu dois comprendre les états par lesquels transitent les fichiers pour savoir comment les faire évoluer.

Les états sont bien entendu dépendants des zones que les fichiers parcourent, mais Git ne t’affichera pas chacun d’eux, il se contentera de te donner ceux qui sont pertinents, c’est-à-dire les états « intermédiaires », ou en d'autres termes : tout ce qui n'est pas commité. En résumé ça concerne ce qui est lié à la copie de travail et à l'index.

Voyons le cycle de vie classique d'un fichier :

Le fichier est créé. Il est considéré "non suivi" ou untracked en anglais, ce qui veut dire que Git n'en a pas connaissance (ni dans sa version actuelle du dépôt local, ni dans l'index).

Quand on procède à l'ajout du fichier à l'index en préparation du commit. Il passe à l'état "indexé" ou staged en anglais.

Quand on valide l'index et qu'on créé le commit, le fichier passe cette fois à l'état "non modifié", ce qui veut dire que Git ne nous indique plus de mise à jour à enregistrer pour ce fichier, car il est identique à travers l'ensemble des 3 zones.

Si ensuite on modifie le fichier, son état sera…(roulement de tambour)… "modifié", puisque Git verra une différence avec l'index.

Puis, si on ajoute et qu'on valide les modifications, on reste sur les états connus, à savoir : « indexé » puis « non modifié ».

Comment ça se passe pour la suppression d'un fichier ? Eh bien le cycle reste le même que pour un ajout ou une modification. C'est-à-dire que Git considère la suppression d'un fichier dans la copie de travail comme un changement à enregistrer. On a simplement à faire transiter cet état "supprimé" à travers les zones pour créer un nouvel enregistrement dans le dépôt local, donc sans le fichier.