Gestion des versions avec Git

Présentation

Git est un utilitaire de gestion de versions décentralisé (comme Mercurial). Git sauvegarde l'intégralité de l'historique dans un dépôt en local (dossier .git/ caché à la racine du projet). Toutes les manipulations standard sont faites en local (commit, checkout, reset, ...), ce qui permet de travailler hors connexion sur le projet.

Pour permettre le travail collaboratif et donc bénéficier des modifications des collaborateurs, on peut récupérer ou envoyer les fichiers simplement en connaissant l'adresse distante. Les transferts se font à l'aide des protocoles GIT (9418) ou http, https ou ssh.

On peut par exemple récupérer un projet complet sur GitHub.

Installation de Git

On peut télécharger Git (sous licence GNU GPL) à l'adresse suivante : http://git-scm.com/downloads. La version utilisée dans ce tutoriel est 1.8.0.

Pour prendre un exemple d'utilisation, sous Windows, après l'installation, on dispose de plusieurs manières d'utiliser Git :

  • par l'interface utilisateur (Git GUI)
  • par le menu contextuel dans l'explorateur de fichiers (clic droit)
  • ou en lignes de commandes (Git Bash).

Afin de bien appréhender le fonctionnement de Git, il sera abordé ici uniquement le fonctionnement en lignes de commandes.

Configuration de Git

Lancer l'utilitaire en lignes de commandes par le menu Démarrer et y taper :

git config --global user.name "Nom d'utilisateur"
git config --global user.email "utilisateur@ideotechnologies.com"

pour configurer les informations utilisateur afin de reconnaître ses contributions au projet.

Les commandes de cet utilitaire sont les mêmes que sous Unix  (ls, cp, mkdir, ...)

Usage de Git

Au préalable, il faut avoir un projet existant, afin d'avoir des fichiers à ajouter au dépôt. Une bonne pratique consiste à faire le premier commit avec uniquement les dossiers racines vides du projet et un fichier README.md, mais on va ici traiter un unique fichier afin de comprendre comment Git fonctionne.
Pour ce faire, on peut par exemple créer un nouveau projet avec Eclipse : projetGit avec pour dossier de sources /src/main/java/ et d'output : /target/classes.
De cette façon, les fichiers .class seront disponibles dans le dossier /target/classes et n'auront pas à être commités.

Création d'un dépôt Git initial et premier commit

Par l'invite de commandes, se rendre dans le dossier racine de Git et lancer git-bash.bat ou lancer le terminal par le raccourci du menu Démarrer. A partir de ce point, il reste ouvert pour l'exécution de commandes Git.
On crée un dépôt Git très simplement une fois arrivé à la racine du projet :

git init

L'utilitaire a créé un dossier caché .git/ et comme l'on n'a encore ajouté aucun fichier à ce dépôt, il est vide. Créer un fichier vide README.md à la racine du projet.
Pour ajouter ce fichier au dépôt, il faut taper :

git add README.md
git commit -m "Creation du depot"

Dans ce cas, Git informe qu'il a ajouté un fichier au dépôt (README.md).
Il faut toujours spécifier un message après -m qui permet d'indiquer brièvement ce que contient la version qui est commitée.
Dans le projet, ajouter une classe Tutoriel qui contient la fonction main() et l'affichage d'un texte.
Extrait de src/main/java/Tutoriel.java :

...
public static void main(String[] args) {
System.out.println("Version initiale");
}
...

Publier les modifications :

git add src/main/java
git commit -m "Version initiale"

Dans ce cas, Git informe qu'il a ajouté le fichier Tutoriel.java au dépôt.

Sauvegarde des modifications

Modifier la classe Tutoriel comme suit :

...
System.out.println("Deuxieme version");
...


Puis afficher les différences avec la dernière version commitée :

git diff


Fichier, par fichier (un seul dans notre cas), les lignes inchangées sont affichées en blanc. Les lignes modifiées sont considérées comme une ligne supprimée (en rouge) suivie d'une ajoutée (en vert).

Puis procéder au commit :

git commit -m "Deuxieme version"


A noter que si vous souhaitez faire ces deux opérations en une seule étape, vous pouvez utiliser l'option -a qui ajoute automatiquement les modifications apportées :

git commit -a -m "Deuxieme version"


Vérifier que git diff ne retourne rien.

Parcours des différentes versions

Pour afficher l'intégralité des commits effectués jusqu'alors, taper :

git log


Pour revenir à une version commitée, taper :

git checkout 25fb5de5cb5d9cc6f8d7c13e5418e1d16b2ca964

(copier le SHA-1 correspondant au commit voulu).
Si vous modifiez le fichier Tutoriel avec :

...
System.out.println("Troisieme version");
...


Pour revenir à la dernière version commitée (et écraser toute modification non commitée) :

git reset --hard HEAD


De retour à Eclipse, confirmer le remplacement du contenu du fichier Tutoriel.java. On obtient donc :

...
System.out.println("Deuxieme version");
...


Git est revenu à la version en tête (HEAD) et la troisième version non commitée est écrasée.

Gérer des branches

Avec Git, on peut créer et modifier des branches, puis les rassembler avec la branche principale (master).
Pour créer une nouvelle branche (sans rien faire d'autre) :

git branch nouvellebranche master

(ou remplacer "master" par le nom de la branche en cours)

et la sélectionner :

git checkout nouvellebranche

Modifier la classe Tutoriel avec :

...
System.out.println("Nouvelle branche");
...

Vérifier le git diff, et le git log puis lancer le commit :

git commit -a -m "Nouvelle branche"

Comparer le contenu des branches nouvellebranche et master :

git diff nouvellebranche master

Etant donné que le commit de cette version a été effectué uniquement dans la branche nouvellebranche, on observe un résultat identique à celui que l'on aurait en étant dans la branche master.
Pour récupérer le contenu de la branche nouvellebranche sur master, on exécute :

git checkout master
git merge nouvellebranche

Revenir dans la branche nouvellebranche et modifier la classe Tutoriel :

...
System.out.println("Nouvelle branche avec une modification");
...

Commiter ces modifications dans la branche (nouvellebranche) puis revenir dans la branche master.
La classe Tutoriel contient :

...
System.out.println("Nouvelle branche");
...

sans la modification !
On peut créer un nombre quelconque de branches. Cette pratique est fortement encouragée si l'on veut effectuer des modifications importantes qui risquent de prendre du temps ou ne sont pas aisées ou d'une manière générale lorsque l'on souhaite proposer une évolution de code dans un mode collaboratif.

Travail collaboratif

On peut récupérer un clone d'un projet distant par la commande :

git clone adresse/du/depot/distant.git

Ainsi, tous les fichiers du projet à l'adresse du dépôt distant sont accessibles dans le dossier courant.
Pour travailler à plusieurs sur un projet avec Git, il n'est pas nécessaire que chaque utilisateur ait une version de Git installée, mais qu'il connaisse son adresse IP (commande ipconfig /all dans Windows, ifconfig | grep inet dans Linux).
Pour récupérer les modifications d'un collaborateur sans affecter ses propres fichiers, effectuer dans un premier temps :

git fetch https://github.com/sprodhomme/tutorielgit.git

Par la suite, pour affecter ses fichiers avec les modifications des autres collaborateurs, effectuer un :

git pull https://github.com/sprodhomme/tutorielgit.git

Dans ce cas, il est demandé de fournir son adresse mail et son mot de passe puis la confirmation du transfert est affichée.

Intégration de Git avec l'IDE

Git s'intègre facilement avec tous les IDE couramment utilisés (Eclipse, NetBeans, IntelliJ, ...).

Il est possible d'ajouter le plugin "EGit" dans Eclipse, fourni dans le dépôt officiel de la release d'Eclipse utilsée. Par exemple, pour Eclipse 3.7 (Indigo), le chemin est :
Indigo - http://download.eclipse.org/releases/indigo
Collaboration > Eclipse EGit

Dans ce cas, on retrouve les termes habituels de Subversion (commit, ...). Pour ce faire, on ajoute le projet à un dépôt local dont on choisit l'emplacement et il sera migré vers ce dossier. On sélectionne les fichiers à ajouter et l'on fait le premier commit.
Par la suite, pour sauvegarder les modifications, on clique-droit sur le projet et l'on commite les fichiers que l'on souhaite. Il est toujours possible de cocher ou décocher les fichiers présents dans le dépôt local ou encore non ajoutés.

Conclusion

Git permet de travailler en local, ce qui permet de n'avoir presqu'aucun temps d'attente pour synchroniser ses modifications et réaliser les commits. Lorsque l'on est à nouveau connecté, on peut envoyer ses commits et merger les fichiers du projet avec les modifications présentes sur le dépôt distant. De plus, comme Git permet de travailler sans serveur centralisé, il est possible d'échanger facilement ses commits entre collaborateurs sans perturber un dépôt central.

Git permet d'avoir une grande flexibilité avec la gestion des branches, qu'il est fortement conseillé d'utiliser. Par recherche dichotomique, il est plus facile de retrouver la source d'une régression.

Pour conclure, Git est un outil de gestion de version très efficace permettant de sauvegarder l'historique des modifications des fichiers textes de son projet et de les partager à la demande avec les autres collaborateurs. Sa souplesse, sa simplicité d'utilisation, notamment avec les IDE et sa fiabilité en font certainement un moyen très pratique de sauvegarder ses modifications avec un contrôle complet.

Git s'adapte aux contraintes de son projet et non l'inverse.

Pour aller plus loin :

5 commentaires

  1. Bonsoir,

    Git est un outil formidable. Nous sommes ravis de voir que vous participez à la communauté. Vous véhiculez une bonne image de l’outil et c’est une bonne chose pour son avenir.

    L’idéal quand on développe un outil, une application, c’est tout de même de l’utiliser directement intégré à l’EDI dont vous spécifiez la possibilité.

    Merci pour ce beau récapitulatif qui aideront sûrement un bon nombre d’internautes.

    Bonne soirée,


    L’équipe GitStack

  2. Bonjour,

    Je vous remercie pour votre commentaire. Je suis content que vous ayez trouvé mon article pédagogique, c’était l’un de mes objectifs.
    Depuis que j’ai découvert Git, je l’utilise aussi bien dans le milieu professionnel, qu’à titre privé, et, effectivement, toujours intégré à l’EDI (EGit pour Eclipse ou en natif sous XCode).

    Bien à vous,


    Serge Prod’homme

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.