L’issue s’ouvre déjà remplie avec le titre et l’adresse de cette page.
Ce guide vous explique comment Git pense. Avant d'enchaîner les
commandes, comprendre son modèle interne rend la plupart de ses
messages lisibles et ses erreurs prévisibles. Vous verrez comment Git
stocke vos données (des snapshots), comment il identifie
chaque version (le SHA), et par quelles trois zones passent vos
fichiers avant d'entrer dans l'historique.
Prérequis : aucun pour lire. Pour rejouer les commandes, il vous faut
Git installé et un terminal. Ce guide est le point de départ
recommandé pour tout débutant.
Git enregistre à chaque commit l'état complet de votre projet, là où
les anciens systèmes de version centralisés, comme CVS ou
Subversion (SVN), raisonnent en deltas : la liste des différences
d'une version d'un fichier à la suivante.
À chaque commit, Git prend donc une photo complète (un snapshot)
de tous les fichiers suivis. Une photo complète ne veut pas dire une
copie complète : un fichier inchangé n'est pas dupliqué, Git réutilise
la version déjà enregistrée et se contente d'y faire référence.
Le modèle et le stockage sur disque sont deux choses distinctes.
Pour gagner de la place, Git range régulièrement ses objets dans des
packfiles, où il compresse les versions proches les unes par rapport
aux autres, avec des deltas. C'est une optimisation invisible à
l'usage : vous manipulez toujours des snapshots.
Le modèle par snapshots rend la plupart des opérations locales et
directes. Chaque commit désigne une arborescence complète : pour
afficher une version, Git la lit telle quelle, sans rejouer une chaîne de
différences. Le tableau compare les deux familles sur ce que vous ferez
au quotidien.
Ce que vous faites
Deltas centralisés (SVN, CVS)
Snapshots distribués (Git)
Ouvrir une version passée
Requête au serveur, qui reconstruit la version
Lecture locale du snapshot
Consulter l'historique
Requête au serveur
Lecture locale de .git/
Committer sans réseau
Impossible : le commit part au serveur
Possible, le commit est local
Vérifier l'intégrité
Sommes de contrôle par fichier
Chaque objet est nommé par son empreinte
Glissez pour voir
Pour comparer deux versions, git diff calcule bien des différences,
mais seulement à la demande et entre deux snapshots. Il compare les
deux arborescences et saute d'un coup tout sous-dossier dont
l'empreinte est identique des deux côtés : seuls les fichiers
réellement modifiés sont lus. C'est ce qui garde git diff rapide sur
un dépôt de milliers de commits.
Les identifiants SHA : l'empreinte digitale de chaque version
Chaque objet de Git porte un nom calculé à partir de son contenu : son
SHA. Commit, fichier ou dossier, tout objet est identifié par une
empreinte (un hash)
de 40 caractères hexadécimaux dans le format par défaut, SHA-1, et
de 64 caractères dans le format SHA-256, présenté plus bas.
Voici l'empreinte complète d'un commit, en SHA-1 :
1e28c5e26a9e43fcd96ed0d8827ef57060d045c2
Ce nom n'est pas tiré au hasard : Git le calcule à partir du
contenu. La commande git hash-object le montre sur un simple texte :
il suffit d'ajouter un seul caractère pour obtenir une empreinte
entièrement différente.
Le SHA n'est pas seulement une étiquette. Il apporte deux garanties
qui expliquent la robustesse de Git :
Intégrité : si un objet est corrompu (disque défaillant,
transfert réseau interrompu), son contenu ne correspond plus à son
empreinte, et git fsck le signale. Comme chaque commit contient
l'empreinte de son parent, modifier un ancien commit change
l'empreinte de tous ceux qui suivent.
Unicité en pratique : deux contenus différents ne produisent pas la
même empreinte dans un dépôt réel. Depuis l'attaque SHAttered de
2017, Git utilise une version durcie de SHA-1, qui détecte les
collisions fabriquées.
SHA-1 est le format par défaut, pas une propriété du modèle. Le projet
Git a déjà prévu d'en changer, et tout ce que vous apprenez ici reste vrai
avec un autre algorithme : seule la longueur des empreintes
change. Votre dépôt vous dit lequel il utilise :
Fenêtre de terminal
gitrev-parse--show-object-format
sha1
SHA-256 existe déjà : git init --object-format=sha256 crée un
tel dépôt depuis Git 2.29. Ses empreintes font 64 caractères au
lieu de 40. Les forges courantes ne savent pas toutes héberger ce
format : réservez-le à l'expérimentation pour l'instant.
Format
Longueur de l'empreinte
Taille de .git/refs/heads/<branche>
SHA-1 (défaut aujourd'hui)
40 caractères
41 octets
SHA-256
64 caractères
65 octets
Glissez pour voir
Une branche est un petit fichier qui contient l'empreinte d'un
commit, plus un saut de ligne : d'où les 41 octets en SHA-1. Ce
chiffre est un détail d'implémentation, pas une propriété des
branches. La propriété, elle, ne bouge pas : une branche est une
référence vers un commit, et c'est pour cela qu'elle ne coûte presque
rien.
En pratique, vous verrez surtout des SHA abrégés, comme dans la
sortie de git log --oneline :
b1d8e9c Ajout de la page d'accueil
1e28c5e Création du fichier README
Le commit 1e28c5e est celui dont l'empreinte complète figure plus haut :
Git accepte une empreinte abrégée tant qu'elle reste non ambiguë
dans le dépôt. Il affiche 7 caractères par défaut et en ajoute
automatiquement quand le dépôt grossit.
Avant d'entrer dans l'historique, un changement passe par trois
zones : le répertoire de travail, la zone de staging et le
dépôt. C'est le concept le plus important de ce guide, parce que
chaque commande de base fait passer un changement d'une zone à l'autre.
Les trois états de Git : git add fait passer les fichiers modifiés du répertoire de travail à la zone de staging, git commit les enregistre dans le dépôt .git ; git restore --staged et git restore font le chemin inverse.git addgit commitgit restore --stagedgit restore fichierRépertoire de travailfichiers modifiésZone de stagingprochaine photoDépôt .githistorique complet
Le Working Directory est le dossier de votre projet tel que vous le
voyez sur votre disque. Quand vous ouvrez un fichier dans votre
éditeur et que vous le modifiez, vous travaillez dans cette zone :
Git voit la modification, mais ne l'a encore enregistrée nulle part.
La Staging Area,
aussi appelée Index, est la zone où vous préparez votre prochain
commit. git add y copie l'état actuel d'un fichier : le
fichier reste dans votre répertoire de travail, et l'index garde la
version que vous avez ajoutée.
Ce point explique un piège classique : si vous modifiez de nouveau le
fichier après git add, le prochain commit contiendra la version
ajoutée, pas la dernière. git status --short l'affiche avec
deux lettres, MM : une modification indexée, puis une autre non
indexée.
MM index.html
M style.css
L'intérêt de cette zone est de choisir ce qui entre dans un commit.
Vous avez modifié dix fichiers, mais trois seulement concernent la
même fonctionnalité : vous n'indexez que ces trois-là, et le
commit qui suit ne portera qu'eux.
Le Repository est la base de données de Git, stockée dans le
dossier .git/ à la racine du projet. Git y conserve tous les
commits, les branches, les tags et la configuration locale du
dépôt.
git commit y enregistre un nouveau snapshot, construit à partir
de l'index. Ce commit est identifié par son SHA et ne se modifie
plus : « corriger » un commit en crée en réalité un nouveau, avec une
autre empreinte.
Les trois zones se traversent toujours dans le même ordre, et
chaque étape a sa commande :
Vous modifiez un fichier dans votre éditeur. Il est modifié
dans le Working Directory.
Vous exécutez git add pour copier son état dans la Staging
Area. Il est indexé (staged).
Vous exécutez git commit pour enregistrer le snapshot dans le
Repository. Il est committé.
Pour savoir où en sont vos fichiers, git status décrit chaque zone.
Ici, index.html a été modifié puis ajouté, et style.css
modifié sans être ajouté :
Fenêtre de terminal
gitstatus
On branch main
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: index.html
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: style.css
La rubrique Changes to be committed liste la Staging Area :
c'est le contenu du prochain commit. La rubrique Changes not staged for commit liste ce qui n'existe encore que dans le répertoire de
travail. Git y rappelle même la commande de chaque passage.
Un commit est un petit objet texte que vous pouvez lire. La commande
git cat-file -p affiche son contenu brut : un lien vers son
arborescence, un lien vers son parent, son auteur, son
committer et son message.
Fenêtre de terminal
gitcat-file-pHEAD
tree 359fa95ef2a6931d2543bf7840a980e7b3ca22f9
parent 1e28c5e26a9e43fcd96ed0d8827ef57060d045c2
author Alice Martin <alice@exemple.fr> 1791966600 +0200
committer Alice Martin <alice@exemple.fr> 1791966600 +0200
Ajout de la page d'accueil
Chaque ligne a un rôle précis. L'empreinte du commit n'y figure pas :
elle est calculée à partir de ce texte, ce qui la rend impossible à
modifier sans changer le commit lui-même.
Champ
Contenu
Dans l'exemple
tree
Empreinte de l'arborescence complète, le snapshot
359fa95…
parent
Empreinte du ou des commits précédents
1e28c5e…
author
Qui a écrit les modifications, et quand
Alice Martin, puis la date en secondes
committer
Qui a créé le commit, et quand
souvent la même personne
message
La description du changement
Ajout de la page d'accueil
Glissez pour voir
Le champ tree mène au snapshot. git cat-file -p 'HEAD^{tree}'
le montre : chaque fichier y est un blob désigné par son empreinte, et
un fichier inchangé d'un commit à l'autre garde la même empreinte,
donc le même objet.
Le champ parent crée la chaîne de l'historique : chaque commit
désigne son prédécesseur, ce qui forme un graphe orienté. Le
premier commit du projet n'a pas de parent ; un commit de merge
en a deux.
Avec Git, presque toutes les opérations se font sur votre machine.
Votre copie contient l'historique complet du projet, là où
Subversion interroge le serveur pour afficher l'historique ou
créer une branche. Les conséquences au quotidien :
Un contenu committé est très difficile à perdre, un contenu jamais
committé ne l'est pas. Git garde la trace des positions successives de
HEAD dans le reflog : même après la suppression d'une branche,
ses commits restent récupérables tant qu'ils y figurent, soit 30 jours
par défaut pour un commit qui n'est plus rattaché à aucune branche.
La leçon pratique pour un débutant : committez souvent. Un commit,
même imparfait, se retrouve et se corrige ; un travail resté dans le
répertoire de travail n'a aucune copie dans Git.
Les questions qui reviennent le plus chez les débutants tiennent
presque toutes à la zone où se trouve un changement. Le tableau y
répond en partant du symptôme.
Question
Réponse
« Quelle différence entre git add et git commit ? »
git add copie l'état d'un fichier dans la Staging Area. git commit enregistre le contenu de la Staging Area dans le Repository.
« Pourquoi ma modification n'apparaît pas dans git log ? »
Elle n'a pas été committée. git status montre dans quelle zone elle se trouve.
« Mon commit ne contient pas ma dernière modification »
Vous avez modifié le fichier aprèsgit add. Relancez git add, puis committez (MM dans git status --short).
« C'est quoi ce numéro après chaque commit ? »
Le SHA, l'empreinte unique du commit, calculée à partir de son contenu.
« Je peux annuler un git add ? »
Oui : git restore --staged <fichier> retire le fichier de la Staging Area sans toucher à vos modifications.
« Si je supprime un fichier, Git le perd ? »
Non, s'il a été committé au moins une fois : il reste dans l'historique et se récupère.
Vérifiez que l'essentiel de ce guide est acquis. Les questions portent
uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
10 questions
6 min.
70% requis
Informations
Le chronomètre démarre au clic sur Démarrer
Questions à choix multiples, vrai/faux et réponses courtes
Vous pouvez naviguer entre les questions
Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
⏱️--:--
0 / 10
Vérification
(0/0)
--:--
0%
0Correctes
0À revoir
0:00Temps
-Niveau
Score par domaine
Un domaine regroupe plusieurs guides et reçoit plusieurs questions : son score est plus fiable qu'un score par thème, qui porte souvent sur une seule question.
Bilan
Points forts
Aucun sujet réussi à 80 % sur au moins deux questions pour l’instant.