Utiliser git

Git Logo with transparency

Git est indispensable parce qu’il permet aux développeurs de versionner le code.

L’outil favorise également la collaboration et le travail d’équipe.

Sommaire

Prérequis

Git, c'est quoi ?

C’est un logiciel de gestion de version décentralisé. C’est un outil capable de conserver des versions de vos fichiers (plusieurs versions du même fichier mais dans des états différents) et de les comparer.

Quel est l'intérêt ?

Imaginons que vous êtes un (ou une) jeune développeur/se fraichement arrivé(e) sur le marché du travail qui va créer son premier programme :

nano coucou.sh
 

Voici le contenu du script (version du 16 Février 2022) :

coucou.sh

#!/bin/bash

echo "COUCOU"
 

Pendant une semaine, le code évolue (version du 23 Février 2022) :

coucou.sh

#!/bin/bash 

echo "VERSION ÉVOLUÉE DE NOTRE PROGRAMME, SOUHAITEZ-VOUS AFFICHER COUCOU ?" 

read ouinon 

case $ouinon in 

oui) 

    echo "COUCOU" ;; 

non) 

    echo "VOUS AVEZ CHOISI DE NE PAS AFFICHER COUCOU MAIS JE L'AFFICHE QUAND MEME, CHEH, COUCOU" ;; 

*) 

    echo "PAS COMPRIS L'INPUT" ;; 

esac
 

Initialiser un dépôt

Pour initialiser un dépôt git, il faut se placer dans un répertoire de travail :

# Initialisation du dépôt Git

cd myworkingfolder && git init 

Regardons l’état de l’historique des versions :

git-init

Ajoutons le script coucou.sh (version du 16 Février 2022) dans notre répertoire de travail :

cp coucou.sh myworkingfolder 

Voici l’état de l’arborescence :

 tree  # Commande pour afficher une arborescence
 .
 └── coucou.sh 

On affiche le statut de git, pour voir ce qui est suivi comme fichier actuellement :

git status 

Résultat

On branch master
No commits yet
Untracked files:
  (use "git add ..." to include in what will be committed)
        coucou.sh
nothing added to commit but untracked files present (use "git add" to track) 

Comme on observe que la commande git status parle de branche, on va mettre à jour notre schéma pour coller  à la réalité :

git-no-tracking

Contrôler les versions d'un fichier

Pour que git comprenne qu’il doit suivre les évolutions du fichier coucou.sh (version du 16 Février 2022), il faut l’ajouter au contrôle de version :

git add coucou.sh 

On affiche à nouveau le statut de git :

git status 

Résultat

On branch master
No commits yet
Changes to be committed:
  (use "git rm --cached ..." to unstage)
        new file:   coucou.sh # Cette ligne nous indique que le fichier coucou.sh est pris en compte par git désormais 

On mets à jour le schéma :

tracking-by-git

Les commits

C’est quoi un commit ? Il faut le voir comme une photo instantanée de vos fichiers trackés par Git à un instant donné. Tous les fichiers qui sont trackés dans le dépôt git seront “photographiés” au moment du commit. Pour imager le mécanisme, on va ajouter le fichier coucou.sh dans un premier commit :

git commit -m "Première version de mon code" 

Résultat

[master (root-commit) 14c78af] Première version de mon code
 Committer: root 
Your name and email address were configured automatically based
on your username and hostname. Please check that they are accurate.
You can suppress this message by setting them explicitly. Run the
following command and follow the instructions in your editor to edit
your configuration file:
    git config --global --edit
After doing this, you may fix the identity used for this commit with:
    git commit --amend --reset-author
 1 file changed, 3 insertions(+)
 create mode 100644 coucou.sh
 

On va analyser les logs de git pour voir ce qui s’est passé concrètement :

git log 

Résultat

commit 540585a17c087859a9b9df6c9bf349cd8f9991e9 (HEAD -> master)
Author: committer 
Date:   Wed Feb 16 19:25:44 2022 +0100
    Première version de mon code 

On mets à jour le schéma :

git-commit-1

Éditer le code

On édite le script coucou.sh pour le remettre dans sa version du 23 Février 2022 :

coucou.sh

#!/bin/bash 

echo "VERSION ÉVOLUÉE DE NOTRE PROGRAMME, SOUHAITEZ-VOUS AFFICHER COUCOU ?" 

read ouinon 

case $ouinon in 

oui) 

    echo "COUCOU" ;; 

non) 

    echo "VOUS AVEZ CHOISI DE NE PAS AFFICHER COUCOU MAIS JE L'AFFICHE QUAND MEME, CHEH, COUCOU" ;; 

*) 

    echo "PAS COMPRIS L'INPUT" ;; 

esac 

On vérifie à nouveau le statut de git :

git status 

Résultat

On branch master
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git restore ..." to discard changes in working directory)
        modified:   coucou.sh
no changes added to commit (use "git add" and/or "git commit -a") 

On mets à jour l’état du fichier dans git :

git add coucou.sh 

On contrôle à nouveau l’état du dépôt git :

git status 

Résultat

On branch master
Changes to be committed:
  (use "git restore --staged ..." to unstage)
        modified:   coucou.sh 

Nouveau commit

On va créer un nouveau commit :

git commit -m "Seconde version évoluée du programme coucou.sh" 

Résultat

[master 460afc5] Seconde version évoluée du programme coucou.sh
 1 file changed, 17 insertions(+), 2 deletions(-) 

Regardons les logs de git :

git log 

Résultat

commit 460afc5d150ad96f9fcb853093cde5184e18a3f5 (HEAD -> master)
Author: committer
Date:   Wed Feb 16 20:00:39 2022 +0100
    Seconde version évoluée du programme coucou.sh
commit 540585a17c087859a9b9df6c9bf349cd8f9991e9
Author: committer
Date:   Wed Feb 16 19:25:44 2022 +0100
    Premiere version de mon code 

On mets à jour le schéma :

Avant le commit

git-commit-2

Après le commit

git-commit-3

Solution au problème initial

Quelqu’un du métier vient et nous demande de reprendre la version de notre script coucou.sh du 16 Février 2022. Grâce à git, il suffit de récupérer le contenu du premier commit pour y trouver le code qui y résidait à cette date :

git checkout 540585a17c087859a9b9df6c9bf349cd8f9991e9 

Résultat

Note: switching to '540585a17c087859a9b9df6c9bf349cd8f9991e9'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:
  git switch -c 
Or undo this operation with:
  git switch -
Turn off this advice by setting config variable advice.detachedHead to false
HEAD is now at 540585a Première version de mon code
 

On mets à jour le schéma :

git-commit-detached-head

Affichons le code du script pour être sur de bien avoir reculé dans l‘historique des commits :

cat coucou.sh 

coucou.sh

#!bin/bash 

echo "COUCOU" 

Maintenant on repart sur la version actualisée du code :

# Permets d'annuler notre HEAD qui est détaché et de faire un rollback !

git switch - 

On mets à jour le schéma :

git-commit-3

En guise de dernière vérification on va ré afficher le contenu du script :

cat coucou.sh 

coucou.sh

#!/bin/bash 

echo "VERSION ÉVOLUÉE DE NOTRE PROGRAMME, SOUHAITEZ-VOUS AFFICHER COUCOU ?" 

read ouinon 

case $ouinon in 

oui) 

    echo "COUCOU" ;; 

non) 

    echo "VOUS AVEZ CHOISI DE NE PAS AFFICHER COUCOU MAIS JE L'AFFICHE QUAND MEME, CHEH, COUCOU" ;; 

*) 

    echo "PAS COMPRIS L'INPUT" ;; 

esac - 

Les branches

Les branches sont sur quoi reposent les commits, sans branche(s), il est impossible d’effectuer des commits. Par soucis de clarté, j’ai préféré d’abord expliqué les commits  mais c’est bien les branches qui permettent de stocker les commits. Reprenons l’état initial du dépôt pour expliquer :

git-init-2

Après avoir clarifié ce point, reprenons le dernier état connu de notre dépôt git :

git-commit-3

Nouveau besoin

On va imaginer qu’on a besoin de continuer à faire évoluer notre programme. En parallèle, il doit rester possible d’accéder au code déployé en production à n’importe quel moment. C’est pour répondre à ce besoin que les branches existent, elles vont permettre de séparer les usages du code lors des phases de développement. On va donc créer une deuxième branche pour séparer l’usage de notre code :

# Créée une nouvelle branch "develop" 

git branch develop 

On liste les branches existantes :

# Liste les branches existantes

git branch 

Résultat

develop
* master 

Actualisons le schéma :

git-branch-1

Utiliser les branches

On souhaite maintenant changer de branche afin de passer de la branche master (sélectionnée actuellement) à la branche develop :

git checkout develop 

Résultat

Switched to branch 'develop' 

Maintenant on veut faire évoluer le code de notre script :

coucou.sh

#!/bin/bash

echo "VERSION ÉVOLUÉE DE NOTRE PROGRAMME, SOUHAITEZ-VOUS AFFICHER COUCOU ?"

read ouinon

case $ouinon in

oui)
    echo "COUCOU"
;;

non)
    echo "VOUS AVEZ CHOISI DE NE PAS AFFICHER COUCOU MAIS JE L'AFFICHE QUAND MEME, CHEH, COUCOU"
;;

# On rajoute une réponse peutetre
peutetre)
    echo "VOUS ETES HESITANT, ET C'EST COMPREHENSIBLE, LA PERIODE NOUS POUSSE A L'ETRE. QUOIQU'IL EN SOIT, IL FAUT CHOISIR...!"
;;

*)
    echo "PAS COMPRIS L'INPUT"
;;

esac 

On demande à git de nous afficher le statut du dépôt :

git status 

Résultat

On branch develop
Changes not staged for commit:
  (use "git add ..." to update what will be committed)
  (use "git restore ..." to discard changes in working directory)
        modified:   coucou.sh
no changes added to commit (use "git add" and/or "git commit -a") 

On commit les modifications :

git add coucou.sh

git commit -m "Ajout d'une nouveau cas (peut-etre) dans le switch pour écrire coucou" 

Résultat

[develop a524648] Ajout d'un nouveau cas(peut-etre) dans le switch pour écrire coucou
 1 file changed, 4 insertions(+) 

On va observer les logs de git pour bien comprendre :

git log 

Résultat

commit a524648431de87c4e65758c1ec7f4240c9eabc1f (HEAD -> develop)
Author: committer
Date:   Mon Feb 21 19:27:02 2022 +0100
    Ajout d'un nouveau cas dans le switch pour ecrire coucou
commit 460afc5d150ad96f9fcb853093cde5184e18a3f5 (master)
Author: committer
Date:   Wed Feb 16 20:00:39 2022 +0100
    Seconde version évoluée du programme coucou.sh
commit 540585a17c087859a9b9df6c9bf349cd8f9991e9
Author: committer
Date:   Wed Feb 16 19:25:44 2022 +0100
    Premiere version de mon code 

On actualise à nouveau le schéma :

git-branch-2

Les merges

On expliquait en fin de partie sur les branches qu’il est habituel dans l’informatique d’utiliser la branche master pour stocker le code stable. Pour notre besoin de séparation des usages, on a créée une nouvelle branche develop. Imaginons maintenant que les tests soit passés sur le script que l’on a codé sur la branche “develop“, notre métier souhaite qu’on rapatrie le code sur la version stable, c’est grâce à un merge qu’on va réaliser cela :

# On commence par se mettre sur la branche sur laquelle on veux fusionner. 

git checkout master 

Résultat

Switched to branch 'master' 

On demande à Git de fusionner (merge) la branche “master” avec la branche “develop” :

# On est sur la branche master, on demande un merge de la branche "develop" sur la branche "master"

git merge develop 

Résultat

Updating 460afc5..a524648
Fast-forward
 coucou.sh | 4 ++++
 1 file changed, 4 insertions(+) 

On affiche les logs sur la branche “master” :

git log 

Résultat

commit a524648431de87c4e65758c1ec7f4240c9eabc1f (HEAD -> master, develop)
Author: cgerard 
Date:   Mon Feb 21 19:27:02 2022 +0100
    Ajout d'un nouveau cas dans le switch pour ecrire coucou
commit 460afc5d150ad96f9fcb853093cde5184e18a3f5 (re-attach)
Author: cgerard 
Date:   Wed Feb 16 20:00:39 2022 +0100
    Seconde version évoluée du programme coucou.sh
commit 540585a17c087859a9b9df6c9bf349cd8f9991e9
Author: cgerard 
Date:   Wed Feb 16 19:25:44 2022 +0100
    Premiere version de mon code
 

Actualisons à nouveau le schéma :

git-merge-1

On va faire une dernière vérification :

# Depuis la branche master

cat coucou.sh 

Résultat

#!/bin/bash

echo "VERSION ÉVOLUÉE DE NOTRE PROGRAMME, SOUHAITEZ-VOUS AFFICHER COUCOU ?"

read ouinon

case $ouinon in

oui)
    echo "COUCOU"
;;

non)
    echo "VOUS AVEZ CHOISI DE NE PAS AFFICHER COUCOU MAIS JE L'AFFICHE QUAND MEME, CHEH, COUCOU"
;;

# On rajoute une réponse peutetre
peutetre)
    echo "VOUS ETES HESITANT, ET C'EST COMPREHENSIBLE, LA PERIODE NOUS POUSSE A L'ETRE. QUOIQU'IL EN SOIT, IL FAUT CHOISIR...!"
;;

*)
    echo "PAS COMPRIS L'INPUT"
;;

esac 

Bonnes pratiques

Une des bonnes pratiques lorsque l’on travaille avec git (et en équipe) est de créer un dépôt Git avec une hiérarchie à 3 étages :

  • Un étage qui représente la branche “master” (version stable).
  • Un étage qui représente la branche “develop” et qui hérite de la branche “master” (version tests ou pré-production).
  • Un étage qui représente la branche “feature” et qui hérite de la branche “develop” (version utilisé par les devs).
On va imager le principe :
git-teamwork-1

Une autre bonne pratique est de toujours renseigner un message clair lors d’un commit dans le dépôt git, car si la raison de la modification est claire le jour J, elle ne l’est plus forcément 2 semaines plus tard. Une dernière bonne pratique est d’utiliser un gestionnaire de version qui permet d’utiliser un dépôt distant, Github, Gitea ou encore Gitlab !

Aller plus loin...

Laisser un commentaire

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