Git

Git est le logiciel de gestion de versions décentralisé le plus utilisé pour le développement informatique. Il permet de synchroniser les contenus d’une (ou plusieurs) machine locale et d’un dépôt distant.

../_images/misc-02-git-fig-01.png

On peut en avoir une utilisation plus ou moins avancée :

  • un seul développeur : l’utilisation standard permet d’enregistrer les différentes versions d’un projet et de les synchroniser avec un dépôt distant (Git ESIEE, GitHub, BitBucket, …) ;

  • plusieurs développeurs : maintient une version centralisée du projet et permet à plusieurs personnes de contribuer au développement, chacun ayant une version à jour du code sur sa machine locale.

Installation

Windows 11

Git n’est pas installé par défaut. Il doit être installé depuis cette page.

../_images/misc-02-git-fig-02.png

Il est ensuite disponible dans un terminal Git Bash que l’on trouve dans le menu Démarrer:

$ git --version
git version 2.38.1.windows.1

La version peut varier.

Linux et MacOS

Git est installé par défaut et accessible directement dans le terminal standard

$ git --version
git version 2.38.0

La version peut varier.

Créer un répertoire local

On crée un répertoire local destiné à héberger les fichiers du projet

$ mkdir myproject

Pour créer un contenu minimal, éditer un fichier README.md avec uniquement le titre du projet.

Créer un repo distant

Pour synchroniser son travail entre la machine locale et le repo distant, il faut disposer d’un compte sur une plateforme. Pour les élèves de l’ESIEE, un compte est déjà créé sur https://git.esiee.fr.

../_images/misc-02-git-fig-03.png

Il faut ensuite créer le repo distant proprement dit :

  1. New project

  2. Create blank project

  3. Project name : myproject

  4. Visibility level : Public

  5. DON’T Initialize repository with a README

puis exécuter les instructions :

  • de la section « Git global setup » ;

  • et de la section « Push an existing folder » en utilisant le répertoire local créé à l’étape précédente.

Avertissement

Sur une autre plateforme, GitHub par exemple, la procédure est similaire même si les termes peuvent varier.

Maintenant on dispose d’un répertoire local synchronisé avec un repo distant.

Recharger la page du projet sur la plateforme distante. Le fichier README.md créé à l’étape précédente doit maintenant être présent.

Forker un projet

Chaque utilisateur dispose de son propre espace distant.

../_images/misc-02-git-fig-04.png

Un utilisateur peut héberger plusieurs repos dans son espace.

../_images/misc-02-git-fig-05.png

Si un repo est public, on peut le copier dans son espace distant avec un fork.

../_images/misc-02-git-fig-06.png

Ici, Lazare Garçin se rend sur la page public du repo myproject de Adam Labrosse, s’identifie, et fork le projet. Il dispose ensuite d’une copie exacte du projet dans son propre espace.

Cloner un projet

Le fork est une copie d’un repo distant vers un espace distant. L’opération permettant de copier un repo distant sur une machine locale est un clonage.

../_images/misc-02-git-fig-07.png

On peut cloner sur sa machine :

  • les repos dont on est propriétaire ;

  • les repos publics.

Dans chaque cas, une procédure d’authentification est déclenchée. Il y a 2 alternatives.

  • l’authentification https ne nécessite aucune opération supplémentaire mais le login/password est demandée à chaque transaction:

    $ git clone https://git.esiee.fr/labrossa/myproject.git
    
  • l’authentification ssh nécessite un paramétrage (génération de clés SSH et ajout au compte Gitlab), mais elle est ensuite réalisée automatiquement par comparaison des clés locales et distantes:

    $ git clone git@git.esiee.fr:labrossa/myproject.git
    

Synchroniser son travail avec le repo distant

Tout au long de la vie du projet, vous pouvez être amenés à utiliser plusieurs machines de développement (des machines différentes dans les salles de l’ESIEE, votre machine personnelle, etc…). Si vous maintenez la synchronisation entre repo distant et repo local, vous pourrez disposer à tout moment de la dernière version de votre travail. Vous pouvez utiliser git, depuis le terminal ou depuis Visual Studio Code, pour maintenir la synchronisation entre votre répertoire local et votre repo distant.

../_images/misc-02-git-fig-08.png

Avant une phase de développement, on récupére les modifications depuis le repo distant avec la commande:

$ git pull

Lorsqu’une nouvelle fonctionnalité est implémentée :

  • on ajoute les fichiers du répertoire à l’index

    $ git add .
    
  • on enregistre les modifications dans le repo local avec un message explicatif:

    $ git commit -m "ajout d'une interface graphique"
    
  • on pousse les modifications de la machine locale vers le repo distant

    $ git push origin master
    

Avertissement

Ne pas oublier de pusher votre travail à chaque étape significative du projet.

Travail collaboratif

Un projet informatique implique généralement plusieurs contributeurs et il est primordial de disposer d’une version à jour du travail effectué par chacun. Git est très efficace dans ce domaine.

../_images/misc-02-git-fig-09.png

Un prérequis est que le propriétaire du repo distant (Adam Labrosse dans ce cas) invite l’autre développer en lui donnant les droits nécessaires (Developer). Sur la plateforme https://git.esiee.fr:

Project Information > Members > Invite members
  1. une version v1 du projet est développée par Adam Labrosse et incluse dans le repo local ;

  2. le repo local est transféré vers le repo distant ;

  3. Lazare Garçin n’a pas encore contribué au projet. Il récupère le travail de Adam Labrosse en clonant le projet ;

  4. il produit une version v2 en apportant des modifications au projet ;

  5. puis ajoute ses fichiers à l’index ;

  6. les inclut dans le repo local ;

  7. et transfère son repo local modifié vers le repo distant ;

  8. Lazare Garçin récupère la dernière version du repo et dispose maintenant de la v2 sur sa machine.

Avertissement

Sur une autre plateforme, GitHub par exemple, la procédure est similaire même si les termes peuvent varier.

Utilisation plus avancée

Git a été utilisé jusqu’à présent de façon basique avec en particulier une seule branche de développement. Pour un projet complexe, on peut mettre en oeuvre un développement sur plusieurs branches.

../_images/misc-02-git-fig-10.png

Chaque disque représente un commit et chaque couleur, une branche différente, indépendante des autres, permettant de développer des fonctionnalités nouvelles sans impacter le projet qui reste toujours dans une version stable.

On peut se familiariser avec la gestion des branches avec Learn Git Branching.

Exercice

Ce travail est individuel. Il permet de simuler une collaboration entre deux utilisateurs, Alice et Bob, sur un projet Git. Chaque élève joue ici le rôle d’Alice.

Avertissement

L’ordonnancement des étapes est strict. Il est impératif de suivre rigoureusement les étapes dans l’ordre indiqué pour éviter les conflits et les erreurs de synchronisation. Les id des commits sont donnés à titre indicatif et peuvent varier d’une machine à l’autre.

Créer un répertoire dédié à cet exercice et se positionner dedans

$ mkdir git-playground
$ cd git-playground

Tout le travail sera réalisé dans ce répertoire. A terme, il contiendra :

  • un repo central (pour simuler un repo distant) et permettre l’échange d’informations entre Alice et Bob ;

  • un répertoire de travail pour Alice, dont le repo local sera associé et synchronisé au repo central ;

  • un répertoire de travail pour Bob, dont le repo local sera associé et synchronisé au même repo central.

Il est important de souligner que l’échange d’informations entre Alice et Bob se fait uniquement par le biais du repo central. Ils ne peuvent pas accéder directement aux répertoires de travail de l’autre.


Création du repo central

Pour simuler le repo distant, on crée un repo bare sur le disque local. Ce repo possédera toutes les propriétés d’un vrai repo distant. Son caractère local simplifiera les interactions

~/git-playground $ git init --bare exercice-git.git
Initialized empty Git repository in ~/git-playground/exercice-git.git/
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint:       git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:       git branch -m <name>

Ce repo est créé vide, comme le précise le message de confirmation. Il n’y a pas de branche, pas de commit, pas de fichier. Il est prêt à recevoir des contributions.

../_images/misc-02-git-fig-11.png

Il apparait comme un répertoire dans le système de fichiers, mais il ne contient pas de fichiers visibles. Il est organisé pour stocker les objets Git (commits, blobs, etc.) et les références (branches, tags, etc.)

~/git-playground $ cd exercice-git.git
~/git-playground/exercice-git.git $ ls -la
total 40
drwxrwxr-x 7 alice alice 4096 Jul  6 20:13 .
drwxrwxr-x 3 alice alice 4096 Jul  6 20:13 ..
drwxrwxr-x 2 alice alice 4096 Jul  6 20:13 branches
-rw-rw-r-- 1 alice alice   66 Jul  6 20:13 config
-rw-rw-r-- 1 alice alice   73 Jul  6 20:13 description
-rw-rw-r-- 1 alice alice   23 Jul  6 20:13 HEAD
drwxrwxr-x 2 alice alice 4096 Jul  6 20:13 hooks
drwxrwxr-x 2 alice alice 4096 Jul  6 20:13 info
drwxrwxr-x 4 alice alice 4096 Jul  6 20:13 objects
drwxrwxr-x 4 alice alice 4096 Jul  6 20:13 refs

Important

Le repo distant constitue le référentiel unique du projet, en ce sens qu’il est l’espace opérationnel du projet. Dit autrement, le projet n’existe que par les fichiers qu’il contient dans le repo distant.


Alice clone le repo (1)

Un clone est la copie conforme d’un repo. Ici Alice va cloner le repo central, ce qui lui permettra de travailler dans un répertoire dédié. Elle clone le repo central avec la commande git clone en spécifiant l’URL du repo distant (ici, le chemin local)

~/git-playground/exercice-git.git $ cd ..
~/git-playground $ git clone exercice-git.git alice-exercice-git
Cloning into 'alice-exercice-git'...
warning: You appear to have cloned an empty repository.
done.
../_images/misc-02-git-fig-12.png

Important

Cette opération ne doit être réalisée qu’une seule fois, au début du projet. Si elle est répétée, le contenu du repo local sera écrasé par le repo central qui n’est vraisemblablement pas dans le même état.

Maintenant le repo cloné est disponible sous la forme d’une copie parfaite du repo initial stocké dans un répertoire de travail dans lequel Alice va pouvoir ajouter des fichiers

~/git-playground $ ls -la
total 16
drwxrwxr-x 4 alice alice 4096 Jul  6 20:14 .
drwxrwxr-x 7 alice alice 4096 Jul  6 20:13 ..
drwxrwxr-x 3 alice alice 4096 Jul  6 20:14 alice-exercice-git
drwxrwxr-x 7 alice alice 4096 Jul  6 20:13 exercice-git.git

Le repo proprement dit est hébergé dans le répertoire de travail dans un sous-répertoire caché. Le dossier caché .git est le répertoire qui confère à ce répertoire de travail un statut particulier pour Git. Il contient les informations nécessaires pour suivre l’historique des modifications, les branches, les commits, etc. Il contient également la configuration. Immédiatement après le clone, le répertoire .git est identique à celui du repo distant, car le clone crée une copie exacte de l’état du repo

git-playground $ cd alice-exercice-git
git-playground/alice-exercice-git (master) $ ls -la
total 0
drwxr-xr-x 1 user 1049089 0 juil.  3 15:27 ./
drwxr-xr-x 1 user 1049089 0 juil.  3 15:27 ../
drwxr-xr-x 1 user 1049089 0 juil.  3 15:27 .git/

master est précisé avant le prompt. Il s’agit de la branche (par défaut) créée par Git. On verra ultérieurement comment travailler avec plusieurs branches.

Note

Par abus de langage, mais pour simplifier les choses, on appellera indifféremment repo :

  • le repo au sens strict, hébergé dans le dossier .git (définition stricte),

  • mais également tout répertoire de travail contenant un dossier .git.

Le repo au sens large est donc la co existence des 3 espaces de travail vus plus haut :

  • le répertoire de travail, qui contient les fichiers du projet. C’est le répertoire que l’on voit dans l’explorateur de fichiers ;

  • l’index, qui est une zone intermédiaire entre le répertoire de travail et l’historique. C’est une sorte de zone de préparation avant l’enregistrement des modifications dans l’historique ;

  • le repo au sens strict, qui est la liste des commits effectués sur le projet. Un commit est une photographie instantanée de l’état du projet à un moment donné. Il est identifié par un hash unique.


Alice configure son identité

Avant de commencer à travailler, Alice doit configurer son identité dans le repo local. Cela permet d’associer ses commits à son nom et son adresse e-mail. Par défaut, la configuration locale

~/git-playground/alice-exercice-git (master) $ git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=~/git-playground/exercice-git.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

Pour le moment aucun utilisateur n’est associé à ce repo. Alice doit définir son nom et son adresse e-mail

~/git-playground/alice-exercice-git (master) $ git config user.name "alice"
~/git-playground/alice-exercice-git (master) $ git config user.email "alice@esiee.fr"

On vérifie que la configuration a bien été prise en compte

~/git-playground/alice-exercice-git (master) $ git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=~/git-playground/exercice-git.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.name=alice
user.email=alice@esiee.fr

Note

Il est important de configurer son identité avant de commencer à travailler sur un repo Git. Cela permet d’associer les commits à l’utilisateur et de garder une trace des contributions. Il est même possible que Git refuse de créer un commit si l’identité n’est pas configurée.


Alice crée un fichier

Alice ajoute de l’information dans son répertoire de travail. Elle crée un fichier texte cr.txt et y écrit le début de la fable de La Fontaine « Le Corbeau et le Renard »

~/git-playground/alice-exercice-git (master) $ echo "Le corbeau et le renard" >> cr.txt

Note

Ici, pour la clarté du propos, la commande echo permet d’écrire simplement du texte dans un fichier. Le processus normal consiste à faire appel à un éditeur de texte ou un environnement de développement comme VS Code.

On peut vérifier que le fichier a bien été créé en listant les fichiers du répertoire de travail

~/git-playground/alice-exercice-git (master) $ ls -la
total 16
drwxrwxr-x 3 alice alice 4096 Jul  6 20:18 .
drwxrwxr-x 4 alice alice 4096 Jul  6 20:14 ..
-rw-rw-r-- 1 alice alice   24 Jul  6 20:18 cr.txt
drwxrwxr-x 7 alice alice 4096 Jul  6 20:17 .git

On peut également contrôler la validité du contenu du fichier

~/git-playground/alice-exercice-git (master) $ cat cr.txt
Le corbeau et le renard
../_images/misc-02-git-fig-13.png

On vérifie que le fichier est « détecté » par git mais pas encore ajouté au repo. C’est le sens du caractère ??

~/git-playground/alice-exercice-git (master) $ git status -s
?? cr.txt

Alice ajoute le fichier à son repo local (2)

Le repo local est une structure de données distinctes du répertoire de travail. Pour rappel elle est stockée dans le sous-répertoire caché .git. Le répertoire de travail contient les fichiers que l’on peut voir et modifier, tandis que le repo local contient l’historique des modifications, les branches, les commits, etc.

Pour le moment, rien n’a été ajouté à l’index (staging area) de Git. L’index est une zone intermédiaire où les modifications sont préparées avant d’être enregistrées dans l’historique du repo local. Il permet de sélectionner les modifications à inclure dans le prochain commit. On observe le contenu de l’index avec la commande

~/git-playground/alice-exercice-git (master) $ git ls-files --stage
~/git-playground/alice-exercice-git (master) $

Pour que le fichier cr.txt soit pris en dans le repo, Alice doit l’ajouter à l’index (staging area) avec la commande git add

~/git-playground/alice-exercice-git (master) $ git add .

Maintenant, si on vérifie l’état du repo, on constate que le fichier cr.txt fait partie des fichiers suivis par Git (mais pas encore commités)

~/git-playground/alice-exercice-git (master) $ git status -s
A  cr.txt

Et l’index reflète maintenant cette opération

~/git-playground/alice-exercice-git (master) $ git ls-files --stage
100644 d8b1220cc7f638af1d2de695d775f14c68a826be 0   cr.txt

Aucun commit n’a été effectué, et l’historique est vide

~/git-playground/alice-exercice-git (master) $ git log
Command failed with exit code 128
fatal: your current branch 'master' does not have any commits yet

Puisque le fichier a été ajouté à l’index, il est prêt à être commité, c’est à dire inscrit dans l’historique. L’opération de commit doit être accompagnée d’un message décrivant les modifications apportées

~/git-playground/alice-exercice-git (master) $ git commit -m "create le corbeau et le renard"
[master (root-commit) 033c477] create le corbeau et le renard
1 file changed, 1 insertion(+)
create mode 100644 cr.txt

Le commit est maintenant enregistré dans le repo local. On peut vérifier l’état du repo

~/git-playground/alice-exercice-git (master) $ git status -s
nothing to commit, working tree clean

et le contenu de l’historique

~/git-playground/alice-exercice-git (master) $ git log
commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard
../_images/misc-02-git-fig-14.png

Maintenant, les modifications apportées au fichier cr.txt sont bien dans l’historique du repo local et le message « nothing to commit, working tree clean » indique que le répertoire de travail est à jour par rapport à l’historique.

Note

Git construit les commit par différence entre l’état du répertoire de travail avant et après le commit. Il n’enregistre pas le contenu complet du fichier, mais seulement les modifications apportées.


Alice pousse ses modifications vers le repo distant (3)

Alice doit maintenant synchroniser ses modifications avec le repo central pour que Bob puisse les voir. Elle n’a pas besoin de spécifier l’adresse du repo distant, car elle a déjà été configurée lors du clonage

~/git-playground/alice-exercice-git (master) $ git config --get remote.origin.url
~/git-playground/exercice-git.git

La commande git push envoie les commits de la branche courante du repo local vers la branche correspondante du repo central

~/git-playground/alice-exercice-git (master) $ git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 8 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 434 bytes | 28.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To //files/user/git-playground/exercice-git.git
 * [new branch]      master -> master
../_images/misc-02-git-fig-15.png

On peut vérifier l’état du repo central en utilisant la commande git log avec l’option --git-dir pour spécifier le chemin du repo distant

~/git-playground/alice-exercice-git (master) $ git --git-dir=../exercice-git.git log
commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

On peut voir ainsi la liste des commits dans le repo central (qui contient pour le moment le seul commit d’Alice). Chacun est décrit par

  • son identifiant (hash) ;

  • la branche sur laquelle il se trouve ;

  • son auteur ;

  • son adresse e-mail ;

  • et le message associé.


Alice modifie le fichier (4) et (5)

Alice décide de continuer à travailler sur le fichier cr.txt

~/git-playground/alice-exercice-git (master) $ echo "" >> cr.txt
~/git-playground/alice-exercice-git (master) $ echo "Maitre Corbeau sur son arbre perché" >> cr.txt

Le fichier reflète bien les modifications apportées

~/git-playground/alice-exercice-git (master) $ cat cr.txt
Le corbeau et le renard

Maitre Corbeau sur son arbre perché

On peut vérifier que la modification n’a pas échappé à Git, c’est le sens du caractère M

~/git-playground/alice-exercice-git (master) $ git status -s
M  cr.txt

Pour visualiser la différence entre l’état du fichier avant et après la modification

~/git-playground/alice-exercice-git (master) $ git diff
diff --git a/cr.txt b/cr.txt
index d8b1220..7608325 100644
--- a/cr.txt
+++ b/cr.txt
@@ -1 +1,3 @@
Le corbeau et le renard
+
+Maitre Corbeau sur son arbre perché

L’information fournie ici est dense.

  • diff --git a/cr.txt b/cr.txt indique qu’il y a une différence entre deux versions du fichier cr.txt :

    • a/cr.txt : version du dernier commit (HEAD)

    • b/cr.txt : version du répertoire de travail (modifiée)

  • index d8b1220..7608325 100644 indique les informations sur le fichier :

    • d8b1220 est le hash SHA-1 du commit précédent (HEAD)

    • 7608325 est le hash SHA-1 du fichier modifié

    • 100644 est le mode d’accès du fichier, indiquant qu’il s’agit d’un fichier normal avec des permissions standard.

  • --- a/cr.txt et +++ b/cr.txt indiquent les versions du fichier :

    • --- a/cr.txt : la version « ancienne » du fichier (celle du repo, HEAD)

    • +++ b/cr.txt : la version « nouvelle » (celle modifiée dans le répertoire de travail)

  • @@ -1 +1,3 @@ indique le contexte de la modification et identifie le « hunk » (bloc de changement):

    • -1 = à partir de la ligne 1 dans l’ancienne version

    • +1,3 = ligne 1, et maintenant il y a 3 lignes au lieu d’une seule

  • Les lignes suivantes montrent les différences :

    • Le corbeau et le renard : ligne inchangée

    • + : ligne vide ajoutée

    • +Maître Corbeau, sur un arbre perché : ligne ajoutée

Une fois la modification effectuée, Alice ajoute le fichier à l’index (staging area) et effectue un commit

~/git-playground/alice-exercice-git (master) $ git add .
~/git-playground/alice-exercice-git (master) $ git commit -m "add cr verse 1"
[master c752930] add cr verse 1
1 file changed, 2 insertions(+)

Puis push vers le repo central

~/git-playground/alice-exercice-git (master) $ git push
To ~/git-playground/exercice-git.git
033c477..c752930  master -> master
../_images/misc-02-git-fig-16.png

On peut vérifier l’état du repo local

~/git-playground/alice-exercice-git (master) $ git log
commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

et celui du repo central (en précisant le chemin du repo distant)

~/git-playground/alice-exercice-git (master) $ git --git-dir=../exercice-git.git log
commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

Ils sont bien tous les deux synchronisés.

Note

Dans le travail collaboratif entre Alice et Bob, il est essentiel de garder l’ensemble des repos synchronisés. Chaque utilisateur doit régulièrement pousser ses modifications vers le repo central et récupérer les modifications des autres utilisateurs pour éviter les conflits.


Alice modifie une nouvelle fois le fichier (6)

Le travail sur un projet nécessite de nombreuses modifications. Alice décide de continuer à travailler sur le fichier cr.txt et ajoute un autre vers

~/git-playground/alice-exercice-git (master) $ echo "tenait en son bec un fromage." >> cr.txt

C’est une bonne pratique de contrôler le bon déroulement de chacune des opérations

~/git-playground/alice-exercice-git (master) $ cat cr.txt
Le corbeau et le renard

Maitre Corbeau sur son arbre perché
tenait en son bec un fromage.

On fait apparaitre la différence entre le fichier modifié et le fichier du dernier commit

~/git-playground/alice-exercice-git (master) $ git diff
diff --git a/cr.txt b/cr.txt
index 7608325..8bd1c83 100644
--- a/cr.txt
+++ b/cr.txt
@@ -1,3 +1,4 @@
Le corbeau et le renard

Maitre Corbeau sur son arbre perché
+tenait en son bec un fromage.

La bonne pratique est de réaliser l’opération add/commit/push pour chaque modification significative. Ici l’opération n’est pas spécialement significative, pour les besoins de la démonstration:

~/git-playground/alice-exercice-git (master) $ git add .
~/git-playground/alice-exercice-git (master) $ git commit -m "add cr verse 2"
[master afa888b] add cr verse 2
1 file changed, 1 insertion(+)
~/git-playground/alice-exercice-git (master) $ git push
To ~/git-playground/exercice-git.git
c752930..afa888b  master -> master

On vérifie l’état du repo local

~/git-playground/alice-exercice-git (master) $ git log
commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

et par acquis de conscience, on vérifie également le repo central (en précisant le chemin du repo distant)

~/git-playground/alice-exercice-git (master) $ git --git-dir=../exercice-git.git log
commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

pour constater qu’ils sont parfaitement synchronisés avec un empilement de 3 opérations.

../_images/misc-02-git-fig-17.png

Voyager dans l’historique

L’historique (obtenu avec git log) est un empilement de photographies instantanées du projet à plusieurs moments dans le temps. Chaque commit représente un état du projet à un instant donné. On peut naviguer dans cet historique pour voir les modifications apportées au fil du temps

~/git-playground/alice-exercice-git (master) $ git switch --detach 033c477
HEAD is now at 033c477 create le corbeau et le renard
~/git-playground/alice-exercice-git (HEAD detached at 033c477) $ cat cr.txt
Le corbeau et le renard

Le fichier cr.txt est dans un état du passé, l’état dans lequel il était au moment du commit 033c477.

On revient au présent du projet

~/git-playground/alice-exercice-git (HEAD detached at 033c477) $ git switch master
Previous HEAD position was 033c477 create le corbeau et le renard
Switched to branch 'master'
Your branch is up to date with 'origin/master'.

Et le fichier cr.txt est de nouveau dans son état actuel

~/git-playground/alice-exercice-git (master) $ cat cr.txt
Le corbeau et le renard

Maitre Corbeau sur son arbre perché
tenait en son bec un fromage.

Bob clone le repo central (7)

C’est au tour de Bob d’apporter des modifications au projet qu’il a en commun avec Alice. Il clone lui aussi le repo central dans un répertoire dédié en spécifiant l’URL du repo distant (ici, le chemin local)

~/git-playground/alice-exercice-git (master) $ cd ..
~/git-playground $ git clone exercice-git.git bob-exercice-git
Cloning into 'bob-exercice-git'...
done.

Note

Ici le rôle de Bob est joué également par l’élève :

  • l’élève endosse le rôle d’Alice lorsqu’il est dans le répertoire alice-exercice-git ;

  • et le rôle de Bob lorsqu’il est dans le répertoire bob-exercice-git.

Contrairement à Alice, lorsque Bob clone le repo central, il n’y a pas de message d’avertissement indiquant que le repo est vide, car il contient déjà les commit d’Alice.

Maintenant le repo cloné de Bob est également disponible sous la forme d’un répertoire de travail

~/git-playground $ ls -la
total 20
drwxrwxr-x 5 alice alice 4096 Jul  6 20:36 .
drwxrwxr-x 7 alice alice 4096 Jul  6 20:13 ..
drwxrwxr-x 3 alice alice 4096 Jul  6 20:18 alice-exercice-git
drwxrwxr-x 3 alice alice 4096 Jul  6 20:36 bob-exercice-git
drwxrwxr-x 7 alice alice 4096 Jul  6 20:34 exercice-git.git

Pour la suite, Bob va travailler dans son propre répertoire de travail. On peut vérifier qu’il contient bien le fichier cr.txt créé puis modifié par Alice

~/git-playground $ cd bob-exercice-git
~/git-playground/bob-exercice-git (master) $ ls -la
total 16
drwxrwxr-x 3 alice alice 4096 Jul  6 20:36 .
drwxrwxr-x 5 alice alice 4096 Jul  6 20:36 ..
-rw-rw-r-- 1 alice alice   92 Jul  6 20:36 cr.txt
drwxrwxr-x 8 alice alice 4096 Jul  6 20:36 .git
../_images/misc-02-git-fig-18.png

On peut également contrôler la validité du contenu du fichier. Il contient bien toutes les modifications apportées par Alice

~/git-playground/bob-exercice-git (master) $ cat cr.txt
Le corbeau et le renard

Maitre Corbeau sur son arbre perché
tenait en son bec un fromage.

On vérifie également que le repo local de Bob est synchronisé avec le repo central. Il contient les deux commits d’Alice, et l’historique est identique à celui du repo central

~/git-playground/bob-exercice-git (master) $ git log
commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

Bob a donc récupéré le repo central (augmenté du travail d’Alice) et va pouvoir contribuer à son tour.


Bob configure son identité

Avant de commencer à ajouter du contenu, comme Alice, Bob doit configurer son identité dans le repo local. Cela permet d’associer ses commits à son nom et son adresse e-mail. On obtient les paramètres de configuration locale avec la commande

~/git-playground/bob-exercice-git (master) $ git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=~/git-playground/exercice-git.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

Pour le moment aucun utilisateur n’est associé à ce repo. Comme Alice, Bob doit définir son nom et son adresse e-mail

~/git-playground/bob-exercice-git (master) $ git config user.name "bob"
~/git-playground/bob-exercice-git (master) $ git config user.email "bob@esiee.fr"

On vérifie également que la configuration a bien été prise en compte

~/git-playground/bob-exercice-git (master) $ git config --local --list
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=~/git-playground/exercice-git.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.name=bob
user.email=bob@esiee.fr

Bob modifie le contenu (8)

Bob va maintenant ajouter du contenu dans son répertoire de travail, d’abord en modifiant le fichier cr.txt qu’il a récupéré du repo central.

Pour le moment cr.txt est dans l’état suivant

~/git-playground/bob-exercice-git (master) $ cat cr.txt
Le corbeau et le renard

Maitre Corbeau sur son arbre perché
tenait en son bec un fromage.

Bob ajoute un autre vers

~/git-playground/bob-exercice-git (master) $ echo "Maitre Renard par l'odeur alléché" >> cr.txt
~/git-playground/bob-exercice-git (master) $ cat cr.txt
Le corbeau et le renard

Maitre Corbeau sur son arbre perché
tenait en son bec un fromage.
Maitre Renard par l'odeur alléché

Le fichier a été modifié dans le répertoire de Bob, mais la modification n’a pas été inscrite dans le repo local. On peut vérifier l’état du repo

~/git-playground/bob-exercice-git (master) $ git status -s
M  cr.txt

et plus précisément, les différences entre la version locale et celle inscrite dans le repo:

~/git-playground/bob-exercice-git (master) $ git diff
diff --git a/cr.txt b/cr.txt
index 8bd1c83..ff6cf27 100644
--- a/cr.txt
+++ b/cr.txt
@@ -2,3 +2,4 @@ Le corbeau et le renard

Maitre Corbeau sur son arbre perché
tenait en son bec un fromage.
+Maitre Renard par l'odeur alléché

Note

Ces opérations partagent une même logique, c’est à dire des modifications d’un même fichier. Plus généralement une logique regroupe des caractéristiques communes à des ajouts, des modifications ou des suppressions de fichiers, ou d’un ensemble de fichiers. On peut par exemple regrouper en un seul commit, les modifications de fichiers correspondant à une fonctionnalité. La granularité des commit est un choix de l’utilisateur qui doit être fait dans le sens de la construction d’un historique facile à exploiter.

Bob fait le choix d’effectuer un commit après sa modification

~/git-playground/bob-exercice-git (master) $ git add .
~/git-playground/bob-exercice-git (master) $ git commit -m "add cr verse 3"
[master 9391bb0] add cr verse 3
1 file changed, 1 insertion(+)

On vérifie que l’historique contient maintenant la contribution de Bob

~/git-playground/bob-exercice-git (master) $ git log
commit 9391bb01aa60740e10a2abc63a9b5279d9d90f0f
Author: bob <bob@esiee.fr>
Date:   Sun Jul 6 20:43:53 2025 +0200

    add cr verse 3

commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard
../_images/misc-02-git-fig-19.png

Bob crée un autre contenu (9) et (10)

Bob décide également d’ajouter une fable au répertoire. Il crée un fichier texte lt.txt et y écrit le contenu de la fable correspondante

~/git-playground/bob-exercice-git (master) $ echo "Le lièvre et la tortue" >> lt.txt
~/git-playground/bob-exercice-git (master) $ echo "" >> lt.txt
~/git-playground/bob-exercice-git (master) $ echo "Rien ne sert de courir ; il faut partir à point." >> lt.txt
~/git-playground/bob-exercice-git (master) $ echo "Le Lièvre et la Tortue en sont un témoignage." >> lt.txt

On vérifie que le fichier a bien été créé dans le répertoire de travail de Bob

~/git-playground/bob-exercice-git (master) $ cat lt.txt
Le lièvre et la tortue

Rien ne sert de courir ; il faut partir à point.
Le Lièvre et la Tortue en sont un témoignage.

Le repo reflète l’état du répertoire de travail

~/git-playground/bob-exercice-git (master) $ git status -s
?? lt.txt

Il est temps pour Bob d’ajouter ces fichiers au repo local

~/git-playground/bob-exercice-git (master) $ git add .
~/git-playground/bob-exercice-git (master) $ git commit -m "nouvelle fable : le lievre et la tortue"
[master 86fd9c0] nouvelle fable : le lievre et la tortue
1 file changed, 4 insertions(+)
create mode 100644 lt.txt

On vérifie que l’historique local contient maintenant la nouvelle contribution de Bob

~/git-playground/bob-exercice-git (master) $ git log
commit 86fd9c0da518f7461512bc5b4b543e4e04e6c4bb (HEAD -> master, origin/master, origin/HEAD)
Author: bob <bob@esiee.fr>
Date:   Sun Jul 6 20:48:23 2025 +0200

    nouvelle fable : le lievre et la tortue

commit 9391bb01aa60740e10a2abc63a9b5279d9d90f0f
Author: bob <bob@esiee.fr>
Date:   Sun Jul 6 20:43:53 2025 +0200

    add cr verse 3

commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

L’indication HEAD -> master indique que la branche master de son repo local pointe sur le commit 86fd9c0.

Ici le repo local de Bob est en avance sur le repo central qui ne contient que les contributions d’Alice

~/git-playground/bob-exercice-git (master) $ git --git-dir=../exercice-git.git log
commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard

Bob pousse ses modifications vers le repo central:

~/git-playground/bob-exercice-git (master) $ git push
To ~/git-playground/exercice-git.git
afa888b..86fd9c0  master -> master

et maintenant le repo central est à jour avec les contributions de Bob

~/git-playground/bob-exercice-git (master) $ git --git-dir=../exercice-git.git log
commit 86fd9c0da518f7461512bc5b4b543e4e04e6c4bb
Author: bob <bob@esiee.fr>
Date:   Sun Jul 6 20:48:23 2025 +0200

    nouvelle fable : le lievre et la tortue

commit 9391bb01aa60740e10a2abc63a9b5279d9d90f0f
Author: bob <bob@esiee.fr>
Date:   Sun Jul 6 20:43:53 2025 +0200

    add cr verse 3

commit afa888bba48d30a74d18116fd7a7e34f7091f5a4
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:34:23 2025 +0200

    add cr verse 2

commit c75293083f19c74a2cf1511e7ec0a3e89e43e45c
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:29:23 2025 +0200

    add cr verse 1

commit 033c4775de53968803942fa96acd495839a3c811
Author: alice <alice@esiee.fr>
Date:   Sun Jul 6 20:22:53 2025 +0200

    create le corbeau et le renard
../_images/misc-02-git-fig-20.png

Création d’un conflit

Jusqu’à présent, Alice et Bob ont travaillé de manière séquentielle, c’est à dire ne se sont jamais trouvé en situation de posséder dans son répertoire local, un même fichier, mais dans un état différent. Cette situation est bien sûr à privilégier, par une organisation rigoureuse du travail collaboratif et une bonne communication entre les membres de l’équipe.

Cependant, il peut arriver que deux personnes modifient le même fichier en même temps, ce qui peut entraîner des conflits lors de la synchronisation des repos.

Note

Ici la base de temps est fixée par la mise à jour du repo central. C’est uniquement lors de cet évènement périodique qu’un conflit peut être détecté.

De manière symétrique, Alice doit maintenant récupérer les modifications apportées par Bob dans le repo central.

Pour le moment son repo est dans l’état suivant

git-playground/alice-exercice-git (master) $ git log --pretty=full
commit 0c41c60cb5052a9e026e96950f727307a2d07909 (HEAD -> master, origin/master)
Author: alice <alice@esiee.fr>
Commit: alice <alice@esiee.fr>

    le corbeau et le renard (1)

Puisqu’elle a déjà cloné le repo central (à ne faire qu’une seule fois), elle utilise maintenant la commande git pull pour synchroniser son repo local avec le repo central. Cette commande récupère les commits du repo distant et les fusionne avec la branche courante de son repo local

git-playground/alice-exercice-git (master) $ git pull
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 6 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (6/6), 1.34 KiB | 3.00 KiB/s, done.
From //files/user/git-playground/exercice-git
0c41c60..08732e7  master     -> origin/master
Updating 0c41c60..08732e7
Fast-forward
cr.txt              |  9 ---------
corbeau-renard.txt |  3 +++
lievre-tortue.txt  | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 40 insertions(+), 9 deletions(-)
delete mode 100644 cr.txt
create mode 100644 corbeau-renard.txt
create mode 100644 lievre-tortue.txt

Toutes les opérations de fusion sont effectuées automatiquement par Git. Il n’y a pas de conflit, car Alice n’a pas modifié les fichiers que Bob a ajoutés.

Avertissement

Une organisation courante pour le travail collaboratif est de structurer le projet en 4 branches distinctes :

  • main : la branche principale qui contient la version stable du projet ;

  • alice : la branche de développement d’Alice ;

  • bob : la branche de développement de Bob ;

  • dev : la branche de développement contient les fonctionnalités en cours de développement.

On crée une branche avec la commande git branch et on bascule dessus avec git switch. Par exemple

$ git branch alice
$ git switch alice

Ressources Git

Git est un système de développement logiciel et de versioning puissant, mais sa maitrise avancée nécessite du temps d’apprentissage et de l’expérience. Ci dessous quelques ressources supplémentaires pour approfondir les choses :