22/10/2024

Comprendre la notion de commit

I. Qu'est-ce qu'un commit ?

Nous avons déjà vu qu’un commit est un snapshot ou un cliché instantané du contenu du répertoire de travail qui a été ajouté préalablement à l’espace de staging. Nous savons qu’un commit comprend un message pour décrire le contenu de ce qui est enregistré, mais d’autres éléments d’informations sont conservés durant cette opération.

Voici les informations (métadonnées) qui sont incluses dans chaque commit :

  • Les détails des changements effectués (et les noms et emplacements des fichiers modifiés).
  • Le nom et le mail de l'utilisateur qui a fait le commit.
  • Un horodatage (timestamp) du commit.
  • Un pointeur vers le commit précédent (ou commit parent) sur la branche en cours (nous verrons cette notion dans le prochain module).

L'image suivante a été générée à partir du site Visualizing Git, une excellente ressource pour pratiquer et visualiser les différentes opérations faites dans Git. Ici, nous pouvons voir une chaîne de commits avec les pointeurs qui, pour chacun d'eux, renvoient au commit parent :

Comme on peut le voir sur l'illustration précédente, chaque commit est représenté par une chaîne de (40) caractères en hexadécimal obtenue grâce à la fonction de hachage SHA-1 (Secure Hash Algorithm) qui est générée lors de l'exécution de la commande « git commit -m ». Ce hash est l’identifiant unique de chaque commit et il est stocké dans la base de données objet qui est située dans le répertoire « /objects » sous « /.git ». Voici un exemple de ce répertoire sous Windows en mode graphique :

Plus spécifiquement, chaque commit (hash) est conservé dans un répertoire qui est généré sous « /objects » :

Voici un exemple de commit, c'est-à-dire de son identifiant sous la forme d'un hash de 40 caractères :

II. Les commandes git log, git revert et git reset

La commande « git log » permet d’afficher les différents éléments d’information mentionnés plus haut pour les derniers commits effectués :

# Commande git log version longue
$ git log

# Commande git log version courte
$ git log --oneline

La capture suivante montre la sortie des deux versions de la commande « git log » :

Nous voyons que la version courte tronque le hash des commits parce que Git n'a pas besoin pas d'avoir la chaîne complète pour les retrouver.

Pour avoir un équivalent de « git log --oneline » qui affiche le hash complet, vous pouvez utiliser la commande « git log --pretty=online » comme ceci :

# Commande git log pour voir le hash complet d'un commit
$ git log --pretty=oneline
0073ca253a401b61ee99f24bf9f900f2163e4539 (HEAD -> main) Ajout de texte pour le git diff
3dfc85133852659b356a912df1704d6945c0125a Ajout fichier .gitignore
eede2d4c1eead302e24adfc7631151e35821d042 Ajout contenu fichier README
443dfe50f1372ea8c1380bfca702585725353c7e Commit initial

Pour consulter un commit spécifique, vous pouvez utiliser la commande « git show » avec les premiers caractères du hash. Voici un exemple qui affiche les détails du « Commit initial » commençant par 6f725ab6af :

Pour supprimer un commit, vous disposez de la commande « git revert » qui offre deux options principales : la première, utilisée avec le paramètre « -e », crée un nouveau commit permettant d'ajouter un message pour justifier la suppression, tandis que l'autre annule les changements effectués par un ou plusieurs commits en créant un nouveau commit automatiquement.

Avec la commande « git revert -e HEAD » ou « git revert -e <hash_du_commit> », vous pouvez supprimer le dernier commit de la branche en cours. Le pointeur HEAD, sur lequel nous reviendrons sous peu, indique qu'il s'agit de la branche où vous vous trouvez (ici « main »). Si vous ajoutez un tilde (~) après HEAD suivi d'un chiffre, vous pouvez spécifier le commit à supprimer à partir du dernier :

# Suppression du dernier commit
$ git revert -e HEAD

# Suppression de l'avant dernier commit
$ git revert -e HEAD~1

# Suppression d'un commit à partir de son hash
$ git revert -e 2a0291ab

Cette commande va ouvrir votre éditeur de texte (Vim, par défaut) pour vous permettre d'expliquer pourquoi vous faites cette suppression et créer un nouveau commit qui annule les changements précédents.

Sinon, vous pouvez choisir l'autre option et supprimer un (ou plusieurs) commits sans avoir à le justifier avec la commande « git revert -n HEAD » ou « git revert -n <hash_du_commit> ». Dans ce cas, les modifications seront retirées de la base de données objets de Git et un nouveau commit sera créé automatiquement pour identifier l'opération dans l'historique.

# Supprimer le dernier commit
$ git revert -n HEAD

# Supprimer l'avant dernier commit
$ git revert -n HEAD~1

# Supprimer un commit à partir de son hash
$ git revert -n 2a0291ab

Si vous faites une erreur dans le message de votre dernier commit, vous pouvez utiliser la commande « git commit --amend » qui ouvrira également votre éditeur de texte pour modifier le message.

Pour revenir à une version antérieure de votre dépôt, c'est-à-dire restaurer un commit à partir duquel vous pourrez recommencer à travailler, il suffit d'utiliser la commande « git reset » que nous avons vue plus haut avec le paramètre « --hard » suivi du hash du commit :

# Restaurer une version ou commit antérieur
$ git reset --hard 2a0291ab

Notez que nous ne présentons pas ici tous les paramètres de chaque commande, nous nous limitons à ceux que vous aurez à utiliser le plus souvent au quotidien. Git comprend des fichiers d'aide très complets et faciles à consulter avec la commande « git --help ».

Astuce : sous Windows, la commande git --help <commande> ouvre la page du manuel sur votre navigateur par défaut.

Voici un petit récapitulatif des nouvelles commandes que nous avons abordées dans ce chapitre :

# Récapitulatif des commandes abordées dans ce chapitre

git log      Faire afficher l'information sur les derniers commits
git revert   Annuler un ou plusieurs commits 
git reset    Restaurer une version ou commit antérieur

author avatar
Luc BRETON Administrateur système et cloud
Administrateur système et cloud avec une orientation DevOps pour une grande chaîne de pharmacies québécoise. Je suis plutôt généraliste avec une forte expérience côté virtualisation, stockage, cloud hybride et un intérêt particulier pour l'automatisation. J'aime le transfert de connaissances et il me fait plaisir d'être la première voix nord-américaine d'IT-Connect !
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

Laisser un commentaire

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

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