Git – GIT1

Git 1 – les bases

GIT1 · jeudi 17 septembre 2026

Raphael Prasquier – UE Python numérique, volet « Git »

jeudi 17 septembre 2026
Git – GIT1

Au programme 🎯

Vous faites déjà add, commit, push pour pe-homework, par recette. Aujourd'hui, nous allons comprendre ce que ces trois mots font vraiment, et apprendre à défaire une bêtise sans rien perdre.

Quand Quoi
0:00 – 1:50 slides + 4 « hands-on » : vous tapez en même temps que moi
pourquoi git · le trio · commits · branches · merge · conflits · rebase · défaire
1:50 – 2:00 pause
2:00 – 3:00 TP en autonomie : votre premier projet sous git
3:00 learngitbranching et le bonus

Ouvrez un terminal dès maintenant : git --version doit répondre (2.40 ou plus).

jeudi 17 septembre 2026
Git – GIT1

Vous versionnez déjà (sans le savoir) 📝

Avant, il y avait rapport_v2_FINAL_vraiment.docx. Puis Google Docs a mis un Historique des versions dans le menu Fichier : chaque enregistrement est une photo datée et signée.

Docs vous donne déjà… … mais bute sur
qui a changé quoi, et quand des photos prises sans vous demander, sans explication
revenir en arrière sans rien perdre un seul fichier, quand un projet en a des dizaines
comparer deux versions un historique en ligne droite : une seule idée à la fois
nommer une version un serveur obligatoire : sans réseau, plus d'historique

Git garde la colonne de gauche et lève chaque limite de droite. Surtout, son historique n'est pas une ligne mais un graphe : des branches qui s'écartent, puis se rejoignent. C'est le programme de la matinée.

⚠️ Git ne prend une photo que quand vous le demandez : pas d'enregistrement automatique.

jeudi 17 septembre 2026
Git – GIT1

Pourquoi git ? Un peu d'histoire

  • 2005 : Linus Torvalds écrit git en quelques semaines pour gérer le code du noyau Linux, après la perte de l'outil propriétaire qu'il utilisait ;
  • objectif : rapide, fiable, et sans serveur central obligatoire ;
  • aujourd'hui : le socle de GitHub, GitLab, et de quasiment tout le logiciel libre et de l'industrie.

Le monde informatique adore se diviser : Mac ou Windows, iPhone ou Android, Chrome ou Firefox, Claude ou ChatGPT, Netflix ou le cinéma, vim ou emacs, tabulations ou espaces… et, hors du clavier, pain au chocolat ou chocolatine.

Sur git, en revanche, le consensus est (presque) total : plus de neuf développeurs sur dix l'utilisent (enquête Stack Overflow). Apprendre git, c'est donc apprendre l'outil que vous retrouverez partout, quel que soit le langage, l'entreprise ou le camp choisi dans les querelles ci-dessus.

(presque) : Mercurial survit chez Meta, Google a son propre outil, et quelques irréductibles jurent par Fossil ou Pijul. Vous ne les croiserez pas cette année.

jeudi 17 septembre 2026
Git – GIT1

Idée n° 1 : un commit est une photo complète 📸

Un commit est une photo complète (snapshot) du projet, pas une liste de modifications. Trois arrêts sur image :

📸 commit 1
j'écris le README et les crêpes
📄 README.md v1
📄 crepes.md v1
 
📸 commit 2
je modifie les crêpes
📄 README.md v1 =
📄 crepes.md v2
 
📸 commit 3
j'ajoute la tarte, je retouche le README
📄 README.md v2
📄 crepes.md v2 =
📄 tarte.md v1

v1 nouveau   v2 modifié   v1 = inchangé : git ne le stocke pas une 2e fois, le commit pointe vers le même fichier.

En clair : chaque photo décrit tout le projet, sans pour autant tout recopier. Revenir au commit 2, c'est retrouver le carnet entier tel qu'il était, pas rejouer une suite de modifications.

jeudi 17 septembre 2026
Git – GIT1

Idée n° 2 : l'historique est un graphe 🌳

Chaque commit garde l'identifiant de son parent (le commit d'avant). Mis bout à bout, les commits forment une chaîne, et cette chaîne peut se séparer puis se rejoindre.

a7d36397ac8892093450a a9bfd1fmerge 12ed6ff… main garniture ici, deux enfants : une branche naît ici, deux parents : un merge
  • une branche fait partir une nouvelle chaîne depuis un commit ; un merge est un commit à deux parents ;
  • c'est exactement ce qui manquait à l'historique en ligne droite de Google Docs ;
  • tout cela (les photos, la chaîne des parents, le nom des branches) vit dans un dossier caché .git/ à la racine du projet ; git log --graph le dessine dans le terminal.
jeudi 17 septembre 2026
Git – GIT1

Idée n° 3 : git est distribué 🌍

Git est distribué : votre dossier contient tout l'historique, pas une copie de travail reliée à un serveur.

💻 votre PC
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
☁️ GitHub
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
💻 un collègue
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
  • GitHub n'est qu'un clone parmi d'autres, que l'on a choisi comme point de rendez-vous ;
  • sans réseau, tout marche : commiter, créer une branche, fusionner, revenir en arrière ;
  • push n'est qu'une synchronisation ; si le serveur disparaît, votre historique reste (contrairement au Google Docs de tout à l'heure).
jeudi 17 septembre 2026
Git – GIT1

Le trio : working tree, index, HEAD

C'est LA slide de la séance. Git jongle en permanence avec trois « états » de votre projet :

Nom Où Ce que c'est
working tree (répertoire de travail) vos fichiers sur le disque ce que vous éditez
index (staging area, « zone de préparation ») .git/index le brouillon du prochain commit
HEAD .git/HEAD le dernier commit, celui sur lequel vous êtes

Presque toutes les commandes du jour déplacent des choses entre ces trois cases. Quand une commande vous surprend, demandez-vous : « laquelle des trois vient-elle de toucher ? »

jeudi 17 septembre 2026
Git – GIT1

Le trio en mouvement

working tree vos fichiers, sur le disque index brouillon du prochain commit HEAD dernier commit, l'historique git add git commit git restore f git restore --staged f git diff git diff --staged
  • vers la droite, on enregistre ; vers la gauche, on défait (restore recopie la case de droite dans celle de gauche) ;
  • git status compare les trois cases et vous dit ce qui diffère ; git diff montre le détail.

💡 L'index vous permet de ne commiter qu'une partie de ce que vous avez modifié.

jeudi 17 septembre 2026
Git – GIT1

Le terminal : le minimum vital 🐚

Les commandes shell du cours (sous Windows, dans Git Bash) :

Commande Ce qu'elle fait
pwd affiche le dossier où vous êtes
cd carnet, cd .. entre dans un dossier ; remonte d'un cran
ls, ls -a liste les fichiers ; -a montre aussi les cachés (.git/)
mkdir carnet, touch f crée un dossier ; crée un fichier vide
cat notes.md affiche le contenu d'un fichier
echo "texte" > f écrit dans f, en écrasant son contenu
echo "texte" >> f ajoute une ligne à la fin de f
grep -r "motif" . cherche un texte dans tous les fichiers du dossier
a && b lance b seulement si a a réussi

💡 Tab complète les noms, ↑ rappelle la commande précédente, Ctrl+C interrompt.

jeudi 17 septembre 2026
Git – GIT1

Créer un dépôt : init, status

$ mkdir carnet && cd carnet
$ git init -b main
Initialized empty Git repository in /home/vous/carnet/.git/
$ git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)
  • tout git vit dans le dossier caché .git/ ; supprimez-le et le projet redevient un dossier ordinaire ;
  • -b main fixe le nom de la première branche (sinon master selon votre configuration) ;
  • git status est la commande à taper avant et après chaque autre commande, le temps d'apprendre.
jeudi 17 septembre 2026
Git – GIT1

Enregistrer : add, commit

$ echo "# Carnet de recettes" > README.md
$ git status -s
?? README.md                       ← inconnu de git (untracked)
$ git add README.md
$ git status -s
A  README.md                       ← dans l'index, prêt à être commité
$ git commit -m "Crée le carnet de recettes"
[main (root-commit) a7d3639] Crée le carnet de recettes
 1 file changed, 1 insertion(+)

add copie le fichier dans l'index ; commit prend une photo de l'index et la range dans l'historique, avec un message, un auteur et une date. Le fichier n'a pas bougé sur le disque.

🧰 VS Code : vue Source Control (Ctrl+Shift+G). Le + à côté d'un fichier fait git add ; le message puis Commit font git commit.

jeudi 17 septembre 2026
Git – GIT1

🖐️ Hands-on 1 — premier commit (5 min)

Dans un dossier neuf (il servira de bac à sable pour toute la matinée) :

  1. mkdir bac-a-sable && cd bac-a-sable && git init -b main
  2. créez notes.md avec une ligne de texte (éditeur ou echo) ;
  3. git status, puis git add notes.md, puis git status : lisez la différence ;
  4. git commit -m "Première note" ;
  5. modifiez notes.md, ajoutez une ligne, puis git status : que dit git ?
  6. git add notes.md && git commit -m "Deuxième note", puis git log --oneline.

⚠️ Si git commit ouvre un éditeur inconnu : Échap, :q!, puis git config --global core.editor "code --wait".

jeudi 17 septembre 2026
Git – GIT1

Lire git status

$ git status
On branch main
Changes to be committed:                 ← dans l'index (vert)
  (use "git restore --staged <file>..." to unstage)
	modified:   README.md
Changes not staged for commit:           ← dans le working tree seulement (rouge)
  (use "git add <file>..." to update what will be committed)
	modified:   recettes/crepes.md
Untracked files:                         ← git ne les connaît pas encore
	notes.tmp

Git vous souffle la commande pour revenir en arrière : lisez les lignes entre parenthèses. La forme courte, git status -s, tient sur deux colonnes : index à gauche, working tree à droite.

🧰 VS Code : Staged Changes est l'index, Changes le working tree ; les lettres U, M, A à droite des fichiers sont celles de status -s.

jeudi 17 septembre 2026
Git – GIT1

L'historique : git log (1/2)

$ git log                           ← le détail : 5 lignes par commit
commit a9bfd1f59efa6179f9a3d33fc937cee75158081e
Author: Raphael Prasquier <raphael@imagine-app.fr>
Date:   Thu Sep 10 12:00:00 2026 +0200

    Précise la cuisson des crêpes
…
$ git log --oneline                 ← une ligne par commit
a9bfd1f Précise la cuisson des crêpes
093450a Ajoute la tarte aux pommes et le sommaire
7ac8892 Ajoute la recette des crêpes
a7d3639 Crée le carnet de recettes

Chaque commit est identifié par un hash SHA-1 de 40 caractères ; les 7 premiers suffisent pour le désigner. Au besoin : --stat (fichiers touchés), -p (les diffs), -- fichier (l'histoire d'un seul fichier).

jeudi 17 septembre 2026
Git – GIT1

L'historique : git log (2/2), jusqu'au graphe

$ git log --oneline --graph                    ← dessiné, mais depuis HEAD seulement
$ git log --oneline --graph --all --decorate   ← toutes les branches, avec leur nom
* 9e21707 (cuisson) Réduit la cuisson des crêpes
| * 178222f (sauce) Annonce la section sauces
|/                                             ← une branche qui part
| * 12ed6ff (garniture) Ajoute les garnitures des crêpes
| * a9bfd1f (HEAD -> main) Précise la cuisson  ← vous êtes ici
|/
* 093450a Ajoute la tarte aux pommes et le sommaire
* 7ac8892 Ajoute la recette des crêpes
* a7d3639 Crée le carnet de recettes

💡 Trop long à taper ? Un alias, une fois pour toutes (🧰 VS Code dessine ce graphe dans Source Control, section Graph) :

$ git config --global alias.tree "log --oneline --graph --all --decorate"
$ git tree
jeudi 17 septembre 2026
Git – GIT1

Voir les changements : diff, show

$ git diff                    # working tree ↔ index : ce que je n'ai pas encore "add"
$ git diff --staged           # index ↔ HEAD : ce que le prochain commit contiendra
$ git diff HEAD~1             # working tree ↔ avant-dernier commit
$ git show a9bfd1f            # un commit : son en-tête + son diff
diff --git a/recettes/crepes.md b/recettes/crepes.md
@@ -4,6 +4,6 @@
 - 50 cl de lait

-Cuisson : 2 min par face.
+Cuisson : 3 min par face, à feu vif.

- : la ligne d'avant, + : celle d'après ; @@ -4,6 +4,6 @@ situe le bloc (à partir de la ligne 4, 6 lignes). HEAD~1 désigne le parent de HEAD, HEAD~2 le grand-parent.

🧰 VS Code : cliquer sur un fichier dans Source Control ouvre ce diff côte à côte, en couleurs.

jeudi 17 septembre 2026
Git – GIT1

Ce qu'on ne versionne pas : .gitignore (1/2)

Un fichier texte à la racine, commité, un motif par ligne :

# un commentaire commence la ligne (pas en fin de ligne !)
__pycache__/
.venv/
# les images produites par le code, sauf celle du projet
*.png
!logo.png
  • on ne commite pas ce qui se régénère (caches, environnements, sorties de calcul) ni ce qui est secret (clés, mots de passe) ;
  • les fichiers ignorés disparaissent de git status ;
  • ⚠️ un fichier déjà commité reste suivi : git rm --cached <f> pour l'oublier.

🧰 VS Code : les fichiers ignorés apparaissent grisés dans l'explorateur.

jeudi 17 septembre 2026
Git – GIT1

.gitignore (2/2) : ne l'écrivez pas de tête 🧭

Ce qu'il faut ignorer ne se devine pas : c'est une convention de vos outils. Improviser expose à des surprises.

Oublié… … et la surprise
.env ⚠️ vos clés d'API publiées, et gravées dans l'historique
.venv/ des milliers de fichiers, des centaines de Mo
.DS_Store les fichiers de votre Mac chez tous vos collègues
uv.lock ignoré à tort l'inverse : chacun installe des versions différentes

Partez donc d'un modèle, puis ajoutez vos lignes à vous :

  1. l'outil en génère souvent un : uv init, npm create vite, cargo new… ;
  2. sinon, les modèles de GitHub (proposés à la création d'un dépôt), ou gitignore.io pour combiner Python + macOS + VS Code.
jeudi 17 septembre 2026
Git – GIT1

Un commit est un snapshot, pas un diff

$ git cat-file -p a9bfd1f          # « montre-moi cet objet »
tree c52f0cf1c8177960488734248311264a2539ee65
parent 093450a4632ed7c6f08ed84c9b912c924e418ade
author Raphael Prasquier <raphael@imagine-app.fr> 1789034400 +0200

Précise la cuisson des crêpes

Un commit, c'est : un tree (la photo de l'arborescence), son parent, un auteur, un message. Le diff que vous montre git show est recalculé entre deux photos.

Conséquences utiles : revenir à n'importe quel commit est instantané ; deux commits qui contiennent le même fichier le stockent une seule fois. Le détail (.git/objects, blobs, trees) est dans l'annexe « les internes ».

jeudi 17 septembre 2026
Git – GIT1

Une branche est un pointeur

Une branche n'est pas une copie du projet : c'est un fichier de 41 octets dans .git/refs/heads/ qui contient le hash d'un commit. HEAD pointe vers la branche courante.

                         ┌─ garniture
                         ▼
a7d3639 ← 7ac8892 ← 093450a ← a9bfd1f ← 12ed6ff
                         ▲
                         └─ main ◀── HEAD

À chaque commit, la branche courante avance d'un cran. Créer une branche coûte donc… 41 octets, et il n'y a aucune raison de s'en priver : une branche par idée, par essai, par bug.

jeudi 17 septembre 2026
Git – GIT1

Changer de branche : switch (et checkout)

$ git branch                      # liste ; * marque la branche courante
$ git branch garniture            # crée, sans y aller
$ git switch garniture            # y va : HEAD bouge, les fichiers suivent
$ git switch -c sauce             # crée ET y va (le plus fréquent)
$ git switch main                 # retour
$ git branch -d garniture         # supprime (refuse si non fusionnée ; -D force)

git switch (2019) remplace l'ancien git checkout <branche>, que vous verrez partout dans les tutoriels et dans learngitbranching. Même effet ; checkout faisait aussi le travail de restore, d'où son remplacement par deux commandes plus claires.

⚠️ Avant de changer de branche : git status propre, ou git refusera si vos modifications entrent en collision.

🧰 VS Code : le nom de la branche est en bas à gauche ; un clic liste les branches et propose Create new branch…

jeudi 17 septembre 2026
Git – GIT1

HEAD détachée (detached HEAD)

$ git switch --detach 7ac8892      # ou : git checkout 7ac8892
HEAD is now at 7ac8892 Ajoute la recette des crêpes
$ git status
HEAD detached at 7ac8892

Vous êtes « sur » un commit, plus sur une branche : pratique pour regarder le passé, tester une ancienne version. Cependant, si vous commitez ici, aucune branche n'avance : ces commits ne sont retenus que par le reflog.

Deux sorties propres :

  • git switch main pour rentrer ;
  • git switch -c essai pour garder ce que vous venez de faire sur une nouvelle branche.
jeudi 17 septembre 2026
Git – GIT1

🖐️ Hands-on 2 — branches (5 min)

Toujours dans bac-a-sable :

  1. git switch -c idees, puis créez idees.md avec une ligne, add, commit ;
  2. ls : le fichier est là ; git switch main, puis ls : où est-il passé ?
  3. git log --oneline --graph --all : repérez HEAD, main, idees ;
  4. cat .git/HEAD, puis cat .git/refs/heads/idees : que contiennent-ils ?
  5. git switch --detach HEAD~1, git status, puis revenez sur main.

Question : au point 2, pourquoi idees.md a-t-il disparu sans message d'erreur ?

jeudi 17 septembre 2026
Git – GIT1

Fusionner : merge fast-forward

Sur main, on veut rapatrier garniture. Si main n'a pas bougé depuis la création de la branche, git se contente d'avancer le pointeur : c'est un fast-forward, aucun commit créé.

$ git switch main
$ git merge garniture
Updating a9bfd1f..12ed6ff
Fast-forward
 recettes/crepes.md | 5 +++++
 1 file changed, 5 insertions(+)
avant : … ← a9bfd1f (main) ← 12ed6ff (garniture)
après : … ← a9bfd1f ← 12ed6ff (main, garniture)
jeudi 17 septembre 2026
Git – GIT1

Fusionner : le merge commit

Si les deux branches ont avancé chacune de leur côté, git crée un commit à deux parents qui réunit les deux photos :

$ git merge sauce
Merge made by the 'ort' strategy.
 README.md | 4 ++++
$ git log --oneline --graph
*   fcd6c7a Merge branch 'sauce'
|\
| * 178222f Annonce la section sauces
* | 12ed6ff Ajoute les garnitures des crêpes
* | a9bfd1f Précise la cuisson des crêpes
|/
* 093450a Ajoute la tarte aux pommes et le sommaire

Git a comparé les deux branches à leur ancêtre commun (093450a) : chacune a changé un fichier différent, il a pris les deux. Pas de conflit.

jeudi 17 septembre 2026
Git – GIT1

Le conflit : anatomie

Un conflit survient quand les deux branches ont modifié la même ligne depuis l'ancêtre commun. Git ne devine pas : il vous laisse trancher.

$ git merge cuisson
Auto-merging recettes/crepes.md
CONFLICT (content): Merge conflict in recettes/crepes.md
Automatic merge failed; fix conflicts and then commit the result.
<<<<<<< HEAD
Cuisson : 3 min par face, à feu vif.      ← la version de ma branche (main)
=======
Cuisson : 1 min 30 par face.              ← la version de la branche fusionnée
>>>>>>> cuisson

Le reste du fichier est déjà fusionné ; seul ce bloc attend votre décision.

jeudi 17 septembre 2026
Git – GIT1

Le conflit : résolution

  1. ouvrez le fichier, choisissez (ou combinez) et supprimez les trois marqueurs :
    Cuisson : 1 min 30 par face, à feu vif.
    
  2. dites à git que c'est réglé : git add recettes/crepes.md ;
  3. git status doit dire All conflicts fixed but you are still merging ;
  4. terminez : git commit (le message « Merge branch 'cuisson' » est pré-rempli).

Pour renoncer à tout moment : git merge --abort remet le dépôt comme avant le merge.

💡 Un conflit n'est pas une panne : c'est git qui vous pose une question.

🧰 VS Code : au-dessus des marqueurs, Accept Current (votre branche), Accept Incoming (l'autre), Accept Both, ou Resolve in Merge Editor ; puis + et Commit.

jeudi 17 septembre 2026
Git – GIT1

🖐️ Hands-on 3 — un conflit exprès (5 min)

  1. sur main, changez la première ligne de notes.md, add, commit ;
  2. git switch idees, changez cette même première ligne autrement, add, commit ;
  3. git switch main && git merge idees : lisez le message ;
  4. git status, puis cat notes.md : repérez les trois marqueurs ;
  5. résolvez dans l'éditeur, git add notes.md, git commit ;
  6. git log --oneline --graph : le commit à deux parents est là.

Bonus si vous avez fini : refaites l'étape 3 sur une autre ligne et constatez que ce n'est plus un conflit.

jeudi 17 septembre 2026
Git – GIT1

rebase : rejouer au lieu de fusionner 🔁

Même situation que pour le merge commit : main et sauce ont avancé chacune de leur côté. Au lieu de les réunir par un commit à deux parents, rebase rejoue les commits de sauce au bout de main.

git merge sauce git rebase main 093450aa9bfd1f12ed6ffmerge 178222f 093450aa9bfd1f12ed6ffbe10b51 178222f deux parents la copie l'original, abandonné
  • à l'arrivée, le contenu est le même ; seule l'histoire change : une ligne droite, plus facile à lire ;
  • les commits rejoués sont des copies : même modification, mais un nouveau parent, donc un nouveau hash. L'original n'est plus pointé par aucune branche (le reflog le garde).
jeudi 17 septembre 2026
Git – GIT1

rebase en pratique

$ git switch sauce
$ git rebase main                   ← rejoue sauce au bout de main
Successfully rebased and updated refs/heads/sauce.
$ git switch main
$ git merge sauce                   ← plus rien à réunir : fast-forward
Updating 12ed6ff..be10b51
Fast-forward
  • en cas de conflit, on résout comme pour un merge, puis git add et git rebase --continue (pas commit) ; git rebase --abort remet tout comme avant ;
  • merge ou rebase ? Les deux sont corrects : merge garde l'histoire telle qu'elle s'est passée, rebase la rend lisible.

⚠️ La règle d'or : on ne rebase que des commits qui n'existent que chez vous. Des commits déjà partagés avec d'autres, on les fusionne. Nous verrons pourquoi en GIT2.

jeudi 17 septembre 2026
Git – GIT1

Défaire : la carte

Je veux… Commande Touche
jeter mes modifications d'un fichier git restore <f> working tree
retirer un fichier de l'index (annuler add) git restore --staged <f> index
refaire mon dernier commit (message, oubli) git commit --amend HEAD
revenir en arrière en gardant le travail git reset --soft / --mixed HEAD (+ index)
tout effacer jusqu'à un commit git reset --hard <c> les trois
annuler un commit déjà poussé git revert <c> crée un commit
retrouver un commit « perdu » git reflog —

Avant de défaire, une seule question : est-ce que ce commit a déjà été poussé ? Si oui, revert ; sinon, tout est permis.

jeudi 17 septembre 2026
Git – GIT1

restore : le working tree et l'index

$ echo boom >> README.md
$ git status -s
 M README.md
$ git restore README.md            # ⚠ irréversible : la modification n'existait nulle part ailleurs
$ git status -s
$ git add README.md                # …supposons qu'on l'ait ajouté par erreur
$ git restore --staged README.md   # l'index redevient égal à HEAD ; le fichier est intact
$ git restore --source HEAD~1 recettes/tarte.md   # ramène la version d'il y a un commit

restore <f> recopie l'index dans le fichier ; restore --staged <f> recopie HEAD dans l'index. Vous reconnaissez les deux flèches "retour" du schéma du trio. Ancienne forme : git checkout -- <f>.

🧰 VS Code : la flèche Discard Changes fait git restore, tout aussi irréversible ; le − sur un fichier indexé fait git restore --staged.

jeudi 17 septembre 2026
Git – GIT1

reset : déplacer HEAD (et la branche)

git reset <commit> fait reculer la branche courante ; le mode dit ce qu'on fait des deux autres cases.

Mode HEAD index working tree
--soft recule inchangé (les changements restent "add") inchangé
--mixed (défaut) recule recule inchangé (les changements restent, non "add")
--hard recule recule recule ⚠️ modifications non commitées perdues
$ git reset --soft HEAD~1     # "décommite" : tout est prêt à être recommité, autrement
$ git reset HEAD~1            # défait le commit et le add ; les fichiers restent modifiés
$ git reset --hard HEAD~1     # le commit disparaît de la branche… mais pas de git (cf. reflog)
jeudi 17 septembre 2026
Git – GIT1

revert : annuler sans réécrire

$ git revert a9bfd1f
[main f65d87e] Revert "Précise la cuisson des crêpes"
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline -2
f65d87e Revert "Précise la cuisson des crêpes"
a9bfd1f Précise la cuisson des crêpes

revert ne supprime rien : il crée un nouveau commit qui applique le changement inverse. L'historique reste vrai, et c'est la seule façon correcte d'annuler un commit que d'autres ont déjà récupéré.

reset réécrit le passé ; revert ajoute au présent. Dès qu'un commit est partagé : revert.

jeudi 17 septembre 2026
Git – GIT1

reflog : le filet de sécurité

Git note chaque déplacement de HEAD et le garde des semaines (30 à 90 jours), y compris vers des commits que git log ne montre plus :

$ git reset --hard HEAD~2
HEAD is now at 12ed6ff Ajoute les garnitures des crêpes
$ git reflog
12ed6ff HEAD@{0}: reset: moving to HEAD~2
dd98832 HEAD@{1}: commit (merge): Merge branch 'cuisson'
fcd6c7a HEAD@{2}: merge sauce: Merge made by the 'ort' strategy.
$ git reset --hard HEAD@{1}          # ou : git reset --hard dd98832
HEAD is now at dd98832 Merge branch 'cuisson'

Retenez bien : un commit n'est jamais perdu tant qu'il figure dans le reflog. Ce qui est perdu, c'est ce qui n'a jamais été commité (restore, reset --hard sur des modifications en cours).

jeudi 17 septembre 2026
Git – GIT1

🖐️ Hands-on 4 — perdre puis retrouver (5 min)

  1. git log --oneline : notez le hash du commit du haut ;
  2. git reset --hard HEAD~1 ; git log --oneline : il a disparu, et le fichier avec ;
  3. git reflog : retrouvez-le (ligne HEAD@{1}) ;
  4. git reset --hard HEAD@{1} ; git log --oneline : il est revenu ;
  5. git switch -c avant-reset HEAD@{2} : une branche posée sur un ancien état, pour le garder.

Question : à l'étape 2, où était passé ce commit, physiquement ? (indice : ls .git/objects)

jeudi 17 septembre 2026
Git – GIT1

Les 3 pièges du jour ⚠️

  1. Commiter sans regarder. git add . ramasse tout : le .venv/, les données de 300 Mo, le fichier avec la clé API. Réflexe : git status puis git diff --staged avant git commit.

  2. Confondre reset --hard et restore. restore jette des modifications jamais commitées : c'est définitif. reset --hard jette des commits : c'est rattrapable par reflog. Le vrai danger est donc restore (et reset --hard avec du travail non commité).

  3. Réécrire ce qui est partagé. rebase, reset ou --amend sur des commits que d'autres ont déjà : leur histoire et la vôtre ne se ressemblent plus. Réflexe : partagé ⇒ merge et revert.

Bonus : un conflit résolu se termine par git add + git commit, sinon vous restez « en cours de merge » pour toujours.

jeudi 17 septembre 2026
Git – GIT1

Et dans VS Code 🧰

Le récapitulatif des encadrés 🧰 vus en chemin, tout est dans la vue Source Control (Ctrl+Shift+G) :

Terminal VS Code
git status la liste Changes / Staged Changes
git add / git restore --staged le + / le − à côté du fichier
git commit -m la boîte de message + ✓
git diff cliquer sur un fichier modifié
git switch le nom de branche, en bas à gauche
git tree la section Graph de Source Control

Confortable, et je m'en sers ; mais quand quelque chose "ne marche pas", c'est le terminal qui dit pourquoi.

jeudi 17 septembre 2026
Git – GIT1

Retenez bien 📌

  • trois cases : working tree → index → HEAD, franchies par add puis commit ; status et diff les comparent ;
  • un commit est une photo complète, identifiée par un hash, qui connaît son parent ;
  • une branche est un pointeur de 41 octets ; switch déplace HEAD et les fichiers suivent ;
  • merge : fast-forward si l'une des branches n'a pas bougé, sinon commit à deux parents ; un conflit se règle à la main puis add + commit ;
  • rebase : rejoue vos commits au bout d'une autre branche, en ligne droite et avec de nouveaux hashes ; jamais sur des commits partagés ;
  • défaire : restore (fichiers), reset (commits locaux), revert (commits partagés), reflog (tout retrouver) ;
  • avant commit : git status ; avant merge ou rebase : git tree.
jeudi 17 septembre 2026
Git – GIT1

TP (1 h) : mon premier projet sous git

Sujet complet : tp.md sur le site du cours. En résumé :

  1. un petit projet à vous (carnet de recettes, mini-script Python + README…) ;
  2. 5-6 commits propres, un .gitignore pour les fichiers générés ;
  3. une branche, un merge fast-forward ; une seconde branche avec conflit, résolu ; une troisième, rejouée par rebase ;
  4. un revert, puis un reset --hard suivi d'une récupération par reflog ;
  5. pour le bonus : publier le dépôt sur GitHub, public, sous le nom exact git-homework ; le TP donne la recette pas à pas (expliquée en GIT2).

Rien n'est noté sur ce TP. En revanche, c'est dans git-homework que vous déposerez le bonus.

jeudi 17 septembre 2026
Git – GIT1

Bonus : learngitbranching 🎮

https://learngitbranching.js.org/?NODEMO=&locale=fr_FR : un git dessiné, à jouer dans le navigateur (il parle checkout, c'est l'ancien nom de switch).

  • +1 point : les 20 niveaux de l'onglet principal (intro1-4, rampup1-4, move1-4, mixed1-5, advanced1-3) ;
  • +1 point de plus : les 16 niveaux de l'onglet distant (remote1-8, remoteAdvanced1-8) ;
  • un niveau résolu avec show solution n'est pas compté par le jeu.

Pour rendre : sur le site, F12 → Console, tapez copy(exportLevelProgress()), collez dans un fichier solvedMap.json à la racine de git-homework, commit, push. Mercredi 21 octobre 2026, 18 h.

C'est déclaratif : je vous fais confiance. Pas de note de Git : le bonus s'ajoute à votre note de PE.

jeudi 17 septembre 2026
Git – GIT1

Pour aller plus loin 📚

  • Pro Git, S. Chacon & B. Straub, gratuit et en français : https://git-scm.com/book/fr/v2 ; les chapitres 2 et 3 couvrent exactement cette séance, le chapitre 10 l'annexe « les internes » ;
  • learngitbranching : https://learngitbranching.js.org/?NODEMO=&locale=fr_FR — le bonus, mais aussi la meilleure façon de voir rebase avant GIT2 ;
  • Oh Shit, Git!?! : https://ohshitgit.com/fr — « j'ai fait une bêtise, comment je répare ? », par situation ;
  • git help <commande> ou man git-reset : la documentation officielle est bonne, et locale.

Prochaine séance, GIT2 (22 octobre) : worktree, dépôts distants (clone, fetch, push, pull), fork et pull request, rebase interactif, atelier collaboratif.

Pour toute question, vous pouvez me contacter par email : raphael@imagine-app.fr.

jeudi 17 septembre 2026