Git – le logiciel de gestion de version décentralisé (VCS)

Git est un VCS qui s'appuie sur une arborescence de fichiers binaires et permet de stocker et de connaître l'intégralité de la chronologie des modifications.

  Publié le

Git qu'est ce que c'est ?

Git est un logiciel de gestion de versions (VCS) décentralisée créée par Linus Torvalds sous licence GNU 2. Un VCS s'appuie sur une arborescence de fichiers et permet de stocker et de connaître l'intégralité de la chronologie et des modifications (ajout,suppression, modification) qui lui on été apportées. Le concept de décentralisation sert principalement à permettre à des membres d'une même équipe à travailler de manière désynchronisée des autres et éviter d'écraser les modifications des autres lors d'un accès concurrentiel à un fichier. Avec Git, chacun clone le dépôt en local sur son poste, puis n'envoie au serveur que ses modifications après avoir récupéré et fusionné les modifications des autres. Git surveille l'arborescence des fichiers et stock en mémoire une copie binaire de chaque fichier à chaque étape chronologique.

Git comment ça marche ?

Dans la logique en simplifiant à l'extrème : on déploie un dépôt (aussi appelé repository) dans un dossier, cela créera la branche master qui sera la branche finale (qui sera utilisée en production). On spécifie des fichiers à ignorer si besoin (des fichiers de logs par exemple).

git branch merge

Puis on génère une nouvelle branche appelée development (qui sera la branche sur laquelle nous ferons évoluer l'application). Ainsi en cas de bug dans l'environnement de développement nous pouvons à loisir revenir en arrière et ainsi nous éviter une perte de temps énorme en recherche de bug.

Dans ce schéma organisationnel la branche development est donc toujours soit en avance, soit au même niveau par rapport à la branche master. À l'inverse en cas de modification justifiée liée à l'évolution de notre application, nous fusionnons les deux branches sur la branche master.

git merge dev

Il est parfaitement possible d'envisager un flux de travail à plusieurs branches (master, development, features, fixit, etc.) correspondant aux différentes étapes de votre méthodologie.

Comment installer Git suivant mon environnement ?

Sous les distributions basées sur RPM (fedora,rhel,centos) :

sudo dnf install git-all

Sous les distributions Linux basées sur Debian (Ubuntu,Kali) :

sudo apt install git-all

Sous Windows :

Il suffit de télécharger l'exécutable à l'adresse suivante et de l'exécuter : Source GIT-SCM 


 

Comment créer un dépôt Git local dans un projet existant et indexer notre projet ?

Il suffit d'ouvrir un prompt puis de se placer dans le dossier de notre projet (cd D:\wamp64\www\myapp).

Nous allons commencer par alimenter la configuration de notre instance git à l'aide de la commande config.

git config --global user.email "dev@votremail.fr"

git config --global user.name "votrenom"

puis de saisir la commande git init:

git init

Cette commande génère un dépôt git vide avec une branche "master" par défaut. Il nous faudra encore spécifier l'ensemble des dossiers et fichiers dont les modifications devrons êtres suivies par git.

git init branche master vide

Nous pouvons spécifier des fichiers ou des dossiers à ignorer par l'indexation et la surveillance à l'aide du fichier .git\infos\exclude que nous trouverons en racine de notre application une fois notre dépôt initialisé donc dans : D:\wamp64\www\myapp\.git\infos\exclude.

Ce fichier se décompose en une règle par ligne, le caractère # correspondant à une ligne de commentaire qui sera ignorée par git.

Supposons que nous souhaitons ignorer les logs de notre application (présent dans le dossier : D:\wamp64\www\myapp\logs) nous ajouterons simplement une ligne logs.

Le dépôt git étant initialisé en racine du dossier myapp, la règle ignorera le dossier myapp/logs ainsi que l'ensemble de ses descendants.

Il est possible de spécifier des règles plus complexes à l'aide des tokens si nous souhaitons juste ignorer les fichiers txt du dossier logs : logs/*.txt.

(Si vous réalisez cette étape plus tard, vous devrez utiliser la commande git rm -r –cached logs pour vider le cache de l'arborescence binaire contenu dans votre dépôt git).

Une fois cette étape de limitation du spectre d'indexation validée, nous utilisons trois commandes : git add avec le paramètre -A (pour spécifier l'ensemble du dossier et de ces descendants, alias de git add –all). Cette première commande permet de préparer l'ajout de l'ensemble des fichiers de l'application à notre dépôt (en dehors des fichiers et dossiers ignorés).

git add -A

Ainsi que git commit avec le paramètre -m suffixé d'un message entre guillemets qui sert à résumer la modification (ici l'initialisation du dépôt). Cette commande sert à enregistrer les modifications dans notre dépôt git.

git commit -m "init repository"

À partir de là le contenu du dossier (sous dossier et fichiers) est indexé par git de manière récursive et alimente ainsi notre branche "master" en ignorant les fichiers du dossier logs. git init repository

Comment créer un dépôt Git local depuis un projet existant distant github ?

 

Il suffit d'ouvrir un interpréteur de commande puis de se placer comme précédemment dans le dossier qui accueillera notre projet et de saisir la commande : git clone url-du-depot-distant

Pour le dépôt public d'entrainement proposé par github hébergé sur github.com :

git clone https://github.com/github/training-kit.git

Maintenant dans le cadre d'un dépôt privé nécessitant des droits d'accès (ici un jeton de sécurité généré depuis le backoffice de github) :

git clone https://username:token@github.com/username/name-repository.git

Il est également possible de procéder à l'identification à l'aide d'une clef SSH.

À noter qu'il existe de nombreux sites comme github qui permettent d'héberger vos dépôts pour ne citer que les plus communs :

  • github.com
  • bitbucket.org
  • gitlab.com
  • sourceforge.net
  • launchpad.net
  • AWS CodeCommit

Comment créer une nouvelle branche dans un dépôt local Git ?

Comme vue plus haut, la méthodologie minimaliste nécessite au moins d'avoir deux branches pour permettre une gestion de nos versions cohérente. Pour créer une seconde branche qui s'appuiera sur le contenu de la première et s'appellera development (mais qui pourrait parfaitement s'appeler autrement) nous allons appeler la commande git branch avec pour paramètre le nom de notre branche.

git branch development

Notre nouvelle branche development est maintenant une copie parfaite de la branche master. Mais attention, ces deux branches ne sont pas synchronisées et par défaut nous sommes toujours positionnés sur la branche master. C'est à l'utilisateur qu'incombe la tâche de basculer d'une branche à l'autre et d'impacter les modifications jugées pertinentes de la branche development vers la branche master.

git branch development

Comment connaître les branches d'un dépôt local Git ?

Pour liste les branches disponibles dans un dépôt local Git on utilise la commande git branch sans paramètre. Cette dernière nous retourne la liste des branches disponibles ainsi que la branche active sur la qu'elle nous sommes actuellement en vert prefixé d'un astérisque "*".

  • development
  • *master

 Comment basculer sur une autre branche d'un dépôt local Git ?

Comme expliqué plus haut, une branche est une copie binaire d'une arborescence de dossiers et de fichiers. Le fait de basculer d'une branche à une autre change l'ensemble des dossiers et des fichiers présent dans notre dossier de travail, ce concept est important à conserver à l'esprit pour la suite. Pour réaliser la bascule on utilise la commande git checkout avec pour paramètre le nom de la branche cible.

git checkout development

Nous sommes donc positionnés sur la branche de developement. Pour les besoins de ce tutoriel, imaginons maintenant avoir ajouté un fichier login.php en racine de notre application et avoir réalisé des modifications sur le fichier script.js. Ces modifications ne sont effectives que depuis la branche development. Si nous rebasculons sur la branche master, ces informations n'existeront tout simplement pas.

git commit -m

Comment connaître l'état des fichiers sur la branche development ?

Pour connaître exactement les fichiers modifiés, supprimés ou ajoutés, il suffit d'utiliser la commande git status qui remonte une liste de fichier "modified" "deleted" "untracked file".

git status

modified : myapp/script.js

untracked file : myapp/login.php

Comment inclure ses modifications sur la branche development ? 

Si nous voulons sauvegarder l'ensemble des modifications sur la branche active sans faire le trie git add -A puis git commit -m "New page login and script update" (attention à ce moment-là les modifications ne sont pas répercutées sur la branche master). Le commit étant à percevoir comme une "validation" des modifications sur la branche active.

Si nous voulons ajouter uniquement un fichier (ex : login.php) nous utilisons la commande git add suivie de l'emplacement relatif du fichier :

git add login.php

git commit -m "new page login"

Si nous voulons inclure uniquement les ajouts et les modifications sans tenir compte des suppressions :

git add --ignore-removal .

De même pour tenir compte des modifications et des suppressions sans tenir compte des ajouts :

git add -u

Dans tout les cas on peu consulter les fichiers avant leur commit à l'aide de la commande git status.

Comment annuler ses modifications sur la branche development ?

Pour annuler les modifications d'un fichier nous utilisons la commande git checkout suivie de l'emplacement relatif du fichier.

git checkout script.js

Si c'est un nouveau fichier à été ajouté par erreur nous pouvons le supprimer à l'aide de la commande git restore avec deux paramètres, --staged et l'emplacement relatif de notre fichier.

git restore --staged login.php

De même si nous supprimons un fichier par erreur nous pouvons le rétablir à l'aide de la commande restore suivie de l'emplacement relatif du fichier à rétablir.

git restore login.php

Comment fusionner la branche development sur la branche master ?

Pour les besoins du test, supposons que nous avons réalisé l'ajout de l'ensemble de nos modifications et que nous souhaitons les envoyer dans la branche master. Nous commençons par nous placer sur la branche master à l'aide de la commande git checkout avec pour paramètre le nom de la branche (ici master).

git checkout master

Puis nous réalisons une fusion des deux branches à l'aide de la commande git merge suivi du nom de la branche de référence pour réaliser la fusion. Au final cette commande réalisera une fusion entre la branche où nous nous trouvons, et la branche de référence.

git merge development

git merge dev

Notre branche master contient maintenant les modifications de la branche developement que nous lui avons commité.