INF103: Travaux Pratiques sur GIT seul (sans Eclipse, sans SSH et sans GITLAB)

Laurent Pautet (pautet@telecom-paris.fr)

Index


1 TP de GIT

Objectifs

L’objectif de ce TP consiste à découvrir GIT sans rajouter les complexités liées à l’utilisation de SSH et de GITLAB et sans exiger la participation d’un autre étudiant pour provoquer des conflits de modification.

Pour ce faire, nous allons créer un dépôt “distant” sur votre compte personnel et deux dépôts locaux également sur votre compte personnel. L’objectif des deux dépôts locaux consiste à représenter deux utilisateurs distincts qui vont effectuer des opérations conflictuelles.


1.1 Création de l’environnement

On crée un dépôt distant archive.git sans espace de travail (–bare).

git init --bare remote/archive.git

Pour voir la différence avec la commande (git init), exécutez les commandes ci-dessous:

git init remote-bis
ls -a remote-bis

Vous pouvez constater que le répertoire git se trouve être un répertoire caché remote-bis/.git. Les fichiers ou répertoires commençant par un point sont cachés en Unix, car ils ne sont pas affichés lorsque l’on utilise ls (sans -a).

Effacez le répertoire remote-bis grâce à

rm -fr remote-bis

Pour un utilisateur u1, nous créons un espace de travail u1 et un dépôt local u1/.git à partir du dépôt distant remote/archive.git. Notez que pour accèder au dépôt distant, nous n’utilisons pas ssh:// mais file:// pour un accès local au fichier remote/archive.git. Vous créez de même un espace de travail pour un utilisateur u2.

git clone file://$PWD/remote/archive.git u1

1.2 Premier commit de l’utilisateur u1

Nous allons nous rendre dans le répertoire u1 du premier utilisateur.

Créez un fichier f.txt que vous remplissez avec du texte. Pour ce faire, vous pouvez utiliser Atom. Dans les commandes suivantes, edit représente un appel à cet éditeur.

cd u1
edit f.txt

Puis grâce à git add, ajoutez ce fichier à l’index (liste) des fichiers que gèrent git : le fichier est ajouté puis marqué comme modifié.

git add f.txt

Puis enregistrez les modifications dans le dépôt local (u1/.git).

git commit -m "first commit de u1"

Constatez que vos modifications sont bien enregistrées.

git log

Vous pouvez vous rendre dans l’espace de travail de u2 pour constater que son dépôt reste désespérement vide. Puis revenez dans le répertoire de u1.

cd ../u2
git log
fatal: bad default revision
cd ../u1

Vous pouvez désormais propager la modification faite dans le dépôt local de u1 dans le dépôt distant (remote/archive.git. Pour cela, vous allez faire un git push qui va faire un équivalent de commit vers le dépôt distant. On “pousse” les modifications faites dans le dépôt local u1/.git dans le dépôt distant remote/archive.git.

git push

1.3 Premier commit de l’utilisateur u2

Vous pouvez vous rendre dans l’espace de travail de u2 pour constater que son dépôt reste toujours désespérement vide.

cd ../u2
git log
fatal: bad default revision

Par contre, nous pouvons le mettre à jour car il peut désormais intégrer les modifications apportées par u1 qui se trouvent dans le dépôt partagé distant. Nous allons “tirer” ces modifications dans l’espace de travail de u2. Vérifiez que vous êtes dans le répertoire de u2.

git pull
git log

Nous restons dans l’espace de u2 et modifions f.txt avec notre éditeur. Vous modifierez des lignes existantes du fichier (celles introduites par u1. Puis en une seule commande nous allons marquer et archiver notre modification sur ce fichier.

edit f.txt
git commit -a -m 'first commit de u2'

Ici, l’option -a permet de prendre en compte les fichiers connus de git (ajoutés à son index) et qui ont été modifiés. Notez que la modification de u2 n’a pas été reversée dans le dépôt distant.


1.4 Conflit et reconciliation entre u1 et u2

Nous retournons maintenant chez u1 pour faire une modification. Vous modifierez des lignes existantes du fichier. Ici, u1 et u2 travaillent en parallèle. Vous enregistrerez votre nouvelle modification dans le dépôt local puis vous la pousserez sur le dépôt distant. Ceci est possible puisque le dépôt distant n’a reçu qu’une modification de u1.

cd ../u1
edit f.txt
git commit -a -m 'second commit de u1'
git push
git log

Vous pouvez vous rendre dans l’espace de travail de u2 pour pousser les modifications faites par u2.

cd ../u2
git push
error: failed to push some refs to 'file://.../remote/archive.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.

Cette erreur est attendue. En effet, la modification de u2 n’est pas un ajout à ce qui se trouve dans le dépôt distant puisqu’il a été modifié entre temps. Il faut donc remettre à jour le dépôt local de u2 et incorporer la seconde modification faite par u1.

git pull
....
CONFLICT (content): Merge conflict in f.txt
Automatic merge failed; fix conflicts and then commit the result.

Si vous avez fait des modifications uniquement sur des espaces disjoints, git pourra fusionner les modifications (fast forward). Si les modifications portent sur des espaces communs (comme nous vous l’avons suggéré), il va falloir fusionner vous-même.

Que la fusion soit automatique ou manuelle, il faudra ensuite archiver le résultat dans le dépôt local de u2 puis le reverser dans le dépôt distant.

git commit -a -m 'fusion de premier commit de u2 et de second commit de u1'
git push
git log

Voila


1.5 Résumé

Ce petit exemple vise à clarifier l’emploi de git sur un exemple très simple en éliminant les problèmes liés à gitlab et à ssh.

Et pourquoi utiliser gitlab ? Dans cet exemple, nous avons utilisé un dépôt distant qui se trouve être sur le même disque que les dépôts locaux des utilisateurs. Ce qui ne sera pas utile dans la pratique. Si nous utilisons un dépôt réellement distant, nous allons typiquement utiliser ceux fournis par le serveur gitlab.enst.fr. Le server gitlab va par exemple permettre de déclarer les utilisateurs pouvant accèder au dépôt.

Et pourquoi utiliser ssh ? Pour accèder aux dépôts et plus généralement au serveur gitlab.enst.fr, il faudra s’authentifier en donnant au serveur une clé publique et en ayant en local son équivalent en clé secret. Cela permet d’une part de vérifier que l’utilisateur peut accèder au dépôt demandé et d’autre part qu’il est bien celui qu’il prétend être.

Un dernier point : GIT ne s’utilise pas uniquement pour développer en Java, cela sert pour tout travail dans lequel on partage et fait évoluer des fichiers (des fichiers texte de préférence).