Skip to content

Commits et Fichiers

Commit

Un commit, ou validation, décrit une version comme un ensemble de changements sur au moins un fichier. Un commit peut contenir beaucoup de changements sur beaucoup de fichiers, des changements de texte, de nom, de nom de répertoire...

Un commit possède le nom et l'email de l'auteur, de manière à pouvoir identifier qui est à l'origine d'une modification.

Chaque commit est horodaté, et dans la plupart des cas l'historique des commits suit le temps indiqué.

Enfin, chaque commit possède un message de description, qui doit obligatoirement ne pas être vide. Il est important de mettre un message le plus clair et simple et cohérent possible.

Dans Git, à chaque commit est attribué un identifiant unique (appelons-le commit_id).

Info

Cet identifiant est un code de hachage (SHA-1) sur les informations citées ci-dessus ainsi que l'identifiant du commit précédent, appelé parent. Il est donc impossible pour un utilisateur de changer l'identifiant d'un commit.

L'historique des commits Git est consultable via l'option git log.

git log
commit 5c7855194611cb1c96f8531b736aa59a7d646df1 (HEAD, test2)
Author: moi <moi@home.io>
Date:   Fri Jul 19 16:28:08 2024 +0200

    Ajout de la documentation

La chaîne de caractères qui suit le nom commit est l'identifiant de ce commit, à utiliser lors des opérations de navigations dans l'historique.

Info

En général, utiliser les 6 premiers caractères de cette chaîne est suffisant pour les opérations de Git.

Pour créer un commit, vous devez d'abord ajouter les fichiers que vous voulez sauvegarder avec git add, puis faire git commit.

  • Sans l'option -m, un éditeur de texte s'ouvrira pour vous faire saisir le message.
  • en passant -m "mon message", le commit se créera avec ce message.
git add file1 file2
git add file3
git commit -m "Amélioration de truc"

Le message du dernier commit peut être modifié en tapant git commit --amend, ce qui ouvrira l'éditeur de texte en ligne.

Si vous avez oublié un fichier ou fait une faute lors de votre dernier commit et qu'il n'est pas encore poussé vers le serveur distant, vous pouvez:

  • ajouter de nouveau le fichier: git add mon_oubli.py
  • amender le dernier commit: git commit --amend

Copie de travail

Définition

La copie de travail, c'est la version courante sur laquelle vous faites vos modifications.

Par défaut, elle correspond au dernier commit sur la branche courante.

Lorsque vous créez un commit, votre version de travail se place automatiquement sur ce dernier commit:

Info

Le mot-clé HEAD de Git désigne le point courant d'écriture du prochain commit sur la branche courante. Nous en reparlerons lors des branches

La copie de travail possède un index, ou stage, qui correspond à la liste de fichiers prêts à être validés.

Vous pouvez voir l'état de votre copie de travail avec git status, utilisable depuis n'importe quel répertoire du dépôt.

La commande affichera:

  • Le nom de la branche courante
  • Le nombre de commits locaux non publiés, c'est-à-dire non poussés sur le dépôt distant associé
  • Les fichiers ajoutés à l'index (prêts pour un commit)
  • Les fichiers non ajoutés à l'index mais suivi par Git
  • Fichiers non suivis par Git

Sauvegarde

Le cas d'usage le plus courant avec une copie de travail modifiée est d'inclure les changements dans un nouveau commit:

git add file1 ... file2
git commit -m "mon message"

Si tous les fichiers modifiés sont à inclure, on peut faire le raccourci suivant:

git commit -am "mon message"

Effacer l'index

Si vous avez ajouté un fichier à l'index par erreur (via git add), vous pouvez l'enlever:

git restore --staged FILE

Si vous voulez enlever tous les fichiers de votre index mais garder les modifications:

git reset --soft HEAD

Effacer la copie de travail

Le deuxième cas d'usage courant avec une copie de travail modifiée est d'effacer tous vos changements. Attention, vous perdrez toutes vos modifications

git restore file1 ... file2

Une autre approche plus drastique consiste à effacer tous les changements sur l'ensemble de la copie de travail

git reset --hard HEAD
#puis pour revenir à la dernière eversion publiée sur la branche, ici main
git switch main

Attention

Dans les deux cas, vous perdez vos modifications locales. Faites un usage parcimonieux de ces commandes.

Brouillons

Votre copie de travail dispose d'un brouillon, ou stash, qui peut être très utile lors de changement de branche, récupération de modifications distantes ou autres manipulations. Le brouillon vous permet d'effacer temporairement votre copie de travail, et de restaurer ultérieurement vos modifications.

Ce brouillon est une pile pour laquelle:

  • git stash créé une nouvelle entrée contenant toutes vos modifications (indexées ou non-indexées)
  • git stash pop enlève la dernière entrée de la pile et l'applique sur la copie de travail
  • git stash drop enlève la dernière entrée de la pile sans l'appliquer
  • git stash show montre la liste des brouillons enregistrés

Un exemple très classique est d'avoir travaillé un moment sans faire de commit et de vouloir récupérer une modification faite par un collègue.

Il est fort probable que ces modifications impactent vos fichiers, et Git refusera de faire la fusion des données.

Vous pouvez alors éviter un commit inutile si vous ne voulez pas ajouter vos modifications dans l'état, en passant par le brouillon;

git stash
git pull
git stash pop

La restauration d'un brouillon peut introduire des conflits sur les fichiers qu'il vous faudra résoudre (voir chapitre suivant).

Vous pouvez associer un message à vos brouillons via git stash -m "mon message" et consulter la liste des brouillons via git stash list.

.gitignore

Par défaut, tous les fichiers de la copie de travail seront suivis par Git. Pour des fichiers générés automatiquement, comme des binaires suite à une compilation de code ou des résultats de vos programmes, cela n'a pas de sens.

Par ailleurs, vos outils d'éditions ont tendance à ajouter dans le répertoire de votre dépôt des fichiers cachés de configuration qui sont propres à votre machine et vos préférences et n'ont pas toujours vocation à être versionnés.

Si vous ne faites rien, Git regardera ces fichiers et les indiquera comme "non suivis" lors de git status.

Si vous ajoutez un répertoire contenant de tels fichiers via par exemple git add src/, tous ces fichiers seront ajoutés à votre dépôt.

Pour éviter cela, vous pouvez créer en racine de votre dépôt un fichier .gitignore qui contient les noms de fichiers ou extensions de fichier ou noms de répertoires qui ne doivent pas être suivis. Chaque nom doit être sur une seule ligne. Vous pouvez mettre des lignes de commentaires, elles devront commencer par #.

Exemple classique: sous MacOS X, des fichiers .DS_Store sont créés dans chaque répertoire ayant été ouvert par l'application Finder.

#ne pas suivre les fichiers java
*.class
#ne pas suivre le répertoire bin
bin/
#ignorer ce fichier file.txt
file.txt = ne pas suivre le fichier file.txt, même si c'est du texte
#ignorer la configuration de VisualStudioCode
./vscode
#ignorer fichiers du finder osx
.DS_Store

Vous devrez ensuite ajouter votre fichier .gitignore dans votre dépôt:

git add .gitignore
git commit -m "ajout de gitignore"

Les tags

Au fil de vos développements, vous aurez beaucoup de commit, et il deviendra compliqué de savoir quel commit correspond à une version stable à utiliser pour une démonstration par exemple. Vous pouvez bien sûr indiquer cela dans un message de logs, mais cela implique de parcourir l'historique des logs pour retrouver l'information, ce qui n'est pas très rapide pour les gros projets.

Heureusement, Git propose un système d'étiquettes (ou tags) que vous pouvez associer à un point particulier de l'historique du dépôt, typiquement sur le commit que vous voulez identifier comme une version stable.

Pour ajouter un tag, il est recommandé de faire des tags dit annotés.

Info

Il existe beaucoup de façons de mettre des étiquettes en Git, la version proposée ici est suffisante pour assigner des numéros de versions à vos développements.

  • Ajouter un tag:

    git tag -a "v1.0" -m "Démonstration du 10/11"
    

  • Voir les tags:

    git tag
    

  • Pousser le tag et les commits sur le dépôt distant:

    git push --follow-tags
    

Il est recommandé de toujours pousser vos étiquettes par défaut, donc éditez votre configuration Git comme suit:

git config --global push.followTags true

Vous pouvez revenir à la version correspondant à une étiquette via git switch

git switch v1.0

Historique des commits

Git permet de remonter dans le passé de vos modifications, le plus souvent des cas pour rechercher un bug ayant été introduit par une modification passée.

Pour cela, Git va trouver le commit par son identifiant et déplacer la tête de liste des commits (HEAD) vers ce commit:

 git checkout 4e7b6f7a

Vous verrez le message HEAD Detached(de même que lorsque vous ferez git status). Ceci signifie que tout nouveau commit fait à partir de ce point résultera dans une version alternative, ou branche, qu'il faudra créer sous peine de voir vos commits supprimés.

Par conséquent si vous voulez tester des modifications à partir d'un point dans le passé, il est recommandé de créer une branche dans la foulée:

git checkout 4e7b6f7a
git switch -c "test_debug"

Si vous voulez revenir au dernier commit local après avoir inspecté un commit passé, faites simplement

git switch master

Différence entre commits

Lorsque vous avez identifié un commit fautif, vous pouvez voir les différences entre commits via leurs identifiants.

Pour voir la différence entre votre version courante et la version correspondant au commit identifié sur l'ensemble des fichiers suivis:

git diff commit_id
Pour voir les modifications sur un seul fichier:
git diff commit_id FICHIER

Pour voir la différence entre deux commits identifiés:

git diff commit_pass..commit_fail

Vous pouvez aussi voir l'ensemble des commits et les auteurs sur un fichier :

git blame FICHIER

Envoyer ses commits

Si vous travaillez avec un dépôt distant, vous pourrez envoyer vos commits via git push (on parlera souvent de pousser ses commits):

git push

Lorsque vous travaillez à plusieurs, si vous envoyez vos modifications sur une branche et qu'un collègue a aussi envoyé des modifications sur cette branche, cette opération échouera si vous n'avez pas déjà récupéré les modifications distantes.

Il vous faudra donc récupérer les modifications (git pull), puis résoudre les conflits potentiels (voir chapitre suivant) avant de pouvoir envoyer vos modifications.

Annuler un commit

Il arrive parfois que votre dernier commit n'était pas forcément correct et que vous vouliez annuler.

Commit local

Si vous n'avez pas encore poussé vos modifications sur le dépôt suivant, vous pouvez revenir en arrière via git reset:

git reset HEAD~2
git status
Dans cet exemple, nous sommes revenus de 2 commits en arrière depuis notre position courante, et avons annulé ces deux commits. Vous verrez les fichiers modifiés via git status.

Attention

Si vous revenez à un commit qui a déjà été poussé sur le dépôt distant, vous ne pourrez pas pousser vos modifications depuis cette branche. Vous pouvez cependant à tout moment créer une nouvelle branche

Commit distant

Si vous avez poussé ce commit sur le dépôt distant, vous ne pourrez plus revenir dans le passé comme précédemment. Par contre vous pouvez inverser le commit via la commande revert:

  • trouvez le commit fautif
  • inversez-le: git revert commit_id