Git – GIT2

Git 2 – collaborer

GIT2 · jeudi 22 octobre 2026

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

jeudi 22 octobre 2026
Git – GIT2

Au programme 🎯

En GIT1, git n'a jamais quitté votre ordinateur. Aujourd'hui, nous allons travailler à plusieurs : avec d'autres dépôts, avec GitHub, avec des collègues, et avec des agents de code.

Quand Quoi
0:00 – 0:20 récap de GIT1 : je pose les questions, vous répondez
0:20 – 0:55 les dépôts distants : clone, fetch, merge, push
0:55 – 1:15 GitHub : ce qu'il ajoute à git, le fork et upstream
1:15 – 1:25 pause
1:25 – 1:45 les workflows : git ne prend pas parti, les équipes si
1:45 – 1:55 stash, blame, écrire un message de commit
1:55 – 2:10 git worktree, à l'heure des agents
2:10 – 3:05 atelier : une fiche, une pull request, une review, un conflit
jeudi 22 octobre 2026
Git – GIT2

1 · Ce que nous savons déjà

Le récap de GIT1 : je pose la question, vous répondez, puis la slide suivante donne la réponse

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 1 / 13

Expliquez ce qu'est un commit.

jeudi 22 octobre 2026
Git – GIT2

Un commit : des modifications, et un état

  • on commite des modifications : celles que l'on a placées dans l'index ;
  • en retour, le commit reçoit un hash (a9bfd1f…) qui désigne un état complet du projet, un seul, et qui ne changera plus ;
  • revenir à n'importe quel commit est donc instantané : on retrouve le projet entier tel qu'il était ;
  • même hash chez deux personnes = exactement le même projet, au fichier près.
jeudi 22 octobre 2026
Git – GIT2

🙋 Question 2 / 13

Qu'est-ce que l'historique d'un projet git ?

jeudi 22 octobre 2026
Git – GIT2

L'historique est un graphe 🌳

a7d36397ac8892093450a a9bfd1fmerge 12ed6ff… main garniture deux enfants : une branche naît deux parents : un merge
  • chaque commit connaît son parent ; mis bout à bout, les commits forment une chaîne ;
  • la chaîne peut se séparer (une branche) puis se rejoindre (un merge, commit à deux parents) ;
  • git log --oneline --graph --all la dessine dans le terminal ; git show <hash> montre un commit et son diff ; HEAD~1 désigne le parent de HEAD.
jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

git add enregistre le fichier dans l'historique.

jeudi 22 octobre 2026
Git – GIT2

❌ Faux

git add enregistre le fichier dans l'historique.

Faux : add remplit l'index ; c'est commit qui écrit l'historique.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 3 / 13

Expliquez ce qu'est l'index.

jeudi 22 octobre 2026
Git – GIT2

L'index : le brouillon du prochain commit

  • git add f copie l'état actuel de f dans l'index ; git commit enregistre l'index, pas vos fichiers ;
  • une modification faite après le add n'est donc pas dans le commit, tant qu'on ne refait pas add ;
  • l'intérêt : ne commiter qu'une partie de ce que l'on a modifié (un fichier sur trois, voire quelques lignes avec git add -p) ;
  • git restore --staged f retire f de l'index, sans toucher au fichier.

💡 Juste après un git add, git diff n'affiche rien : working tree et index sont égaux. C'est git diff --staged qui montre ce que le commit contiendra.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 4 / 13

Expliquez le trio working tree, index, HEAD.

jeudi 22 octobre 2026
Git – GIT2

Le trio : working tree, index, HEAD

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

Presque toutes les commandes de GIT1 déplacent des choses entre ces trois cases. Quand une commande vous surprend, demandez-vous laquelle elle vient de toucher.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 5 / 13

Que vous dit git status ?

jeudi 22 octobre 2026
Git – GIT2

Lire git status

$ git status
On branch main                           ← la branche courante
Changes to be committed:                 ← dans l'index : partira au prochain commit
	modified:   README.md
Changes not staged for commit:           ← modifié, mais pas encore "add"
	modified:   recettes/crepes.md
Untracked files:                         ← git ne connaît pas ce fichier
	notes.tmp
  • git status compare les trois cases du trio et vous dit ce qui diffère ;
  • les lignes entre parenthèses (masquées ici) soufflent la commande pour revenir en arrière : lisez-les ;
  • git status -s en tient sur deux colonnes : l'index à gauche, le working tree à droite (M, A, ??).

💡 Le réflexe : git status avant et après chaque commande, et git diff --staged avant chaque git commit.

jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

git commit sans add préalable n'enregistre rien de nouveau.

jeudi 22 octobre 2026
Git – GIT2

✅ Vrai

git commit sans add préalable n'enregistre rien de nouveau.

Vrai : le commit enregistre l'index ; rien d'indexé, « nothing to commit ».

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 6 / 13

À quoi sert le fichier .gitignore ?

jeudi 22 octobre 2026
Git – GIT2

.gitignore : ce qu'on ne versionne pas

__pycache__/
.venv/
.env
*.png
!logo.png
  • un fichier texte à la racine, commité, un motif par ligne ; les fichiers ignorés disparaissent de git status ;
  • on n'y met ni ce qui se régénère (caches, environnements, sorties de calcul) ni ce qui est secret (clés, mots de passe) ;
  • on part d'un modèle (celui de l'outil, ou ceux de GitHub) plutôt que de l'écrire de tête.

⚠️ Un .env déjà commité ne disparaît pas en l'ajoutant au .gitignore : il reste suivi (git rm --cached .env), et surtout il reste dans l'historique. Une clé publiée est une clé à changer.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 7 / 13

Vrai ou faux : une branche est une copie du projet.

Puis expliquez ce qu'est une branche pour git.

jeudi 22 octobre 2026
Git – GIT2

❌ Pas une copie : un pointeur

                         ┌─ garniture
                         ▼
a7d3639 ← 7ac8892 ← 093450a ← a9bfd1f ← 12ed6ff
                                   ▲
                                   └─ main ◀── HEAD
  • une branche = 41 octets dans .git/refs/heads/ : le hash d'un commit ; elle avance à chaque commit ;
  • HEAD dit sur quelle branche vous êtes ; git switch <b> le déplace, et les fichiers suivent ;
  • git switch -c <b> crée et y va ; git branch -d <b> supprime (refuse si non fusionnée) ;
  • git switch --detach <hash> : HEAD détachée, pour regarder le passé ; switch -c pour garder ce qu'on y a fait.

💡 Une branche coûte 41 octets : aucune raison de s'en priver, une par idée, par essai, par bug.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 8 / 13

git merge garniture crée parfois un nouveau commit, parfois aucun. Expliquez pourquoi.

jeudi 22 octobre 2026
Git – GIT2

Fusionner : deux cas

Fast-forward : main n'a pas bougé depuis la création de la branche ; git avance le pointeur, aucun commit créé.

avant : … ← a9bf (main) ← 12ed (garniture)
après : … ← a9bf ← 12ed (main, garniture)

Merge commit : les deux branches ont avancé ; git crée un commit à deux parents, en comparant à l'ancêtre commun.

*   fcd6 Merge branch 'sauce'
|\
| * 1782 Annonce la section sauces
* | 12ed Ajoute les garnitures
|/
* 0934 Ajoute la tarte

💡 Seule la branche courante bouge : git merge sauce depuis main fait avancer main, jamais sauce.

jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

Un merge fast-forward crée un commit.

jeudi 22 octobre 2026
Git – GIT2

❌ Faux

Un merge fast-forward crée un commit.

Faux : le pointeur avance, aucun commit n'est créé.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 9 / 13

Expliquez ce qu'est un conflit.

jeudi 22 octobre 2026
Git – GIT2

Le conflit : git vous pose une question

Un conflit survient quand les deux branches ont modifié les mêmes lignes depuis leur ancêtre commun. Git ne devine pas : il fusionne tout le reste, et vous laisse trancher ce bloc-là.

<<<<<<< HEAD
Cuisson : 3 min par face, à feu vif.      ← votre branche
=======
Cuisson : 1 min 30 par face.              ← la branche fusionnée
>>>>>>> cuisson

💡 Deux branches qui modifient le même fichier à cent lignes d'écart ne sont pas en conflit : git raisonne par zones de lignes, pas par fichier.

jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

Deux branches qui modifient le même fichier sont forcément en conflit.

jeudi 22 octobre 2026
Git – GIT2

❌ Faux

Deux branches qui modifient le même fichier sont forcément en conflit.

Faux : seulement si elles touchent les mêmes lignes : git raisonne par zones, pas par fichier.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 10 / 13

Comment sort-on d'un conflit ?

jeudi 22 octobre 2026
Git – GIT2

Le conflit : en sortir

  1. ouvrir le fichier, choisir ou combiner, supprimer les trois marqueurs ;
  2. git add <fichier> : « c'est réglé » ;
  3. git commit : le message « Merge branch … » est pré-rempli.

💡 Tant que vous n'avez pas fait git add + git commit, vous restez « en cours de merge » : git status vous le rappelle.

Renoncer, à tout moment avant le commit : git merge --abort remet tout comme avant le merge.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 11 / 13

Vous avez modifié un fichier, et vous voulez revenir à sa dernière version commitée. Comment faire ?

jeudi 22 octobre 2026
Git – GIT2

restore : jeter des modifications

$ git restore recettes/crepes.md            ← le fichier redevient celui de l'index
$ git restore --staged recettes/crepes.md   ← annule un add : l'index redevient égal à HEAD
  • restore <f> recopie l'index dans le fichier ; restore --staged <f> recopie HEAD dans l'index : ce sont les deux flèches "retour" du trio ;
  • ⚠️ git restore <f> est irréversible : ces modifications n'existaient nulle part ailleurs, rien ne les retrouvera.
jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

Un git restore fichier malheureux se rattrape.

jeudi 22 octobre 2026
Git – GIT2

❌ Faux

Un git restore fichier malheureux se rattrape.

Faux : une modification jamais commitée n'existait nulle part ailleurs : elle est perdue.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 12 / 13

Vous venez de commiter, le commit est raté, et vous ne l'avez pas encore poussé. Comment le défaire ?

jeudi 22 octobre 2026
Git – GIT2

amend et reset : réécrire ce qui n'est pas partagé

$ git commit --amend             ← refait le dernier commit (message, fichier oublié)
$ git reset --soft HEAD~1        ← « décommite » : tout reste prêt à être recommité
$ git reset HEAD~1               ← défait le commit et le add ; les fichiers restent modifiés
$ git reset --hard HEAD~1        ← tout disparaît, y compris les modifications non commitées ⚠
  • reset fait reculer la branche ; le mode dit ce qu'on fait de l'index et du working tree ;
  • tout cela réécrit l'historique : permis, tant que personne d'autre n'a ces commits ;
  • un commit retiré par reset n'est pas effacé pour autant : l'annexe reflog montre comment le retrouver.
jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

git reset --hard ne touche qu'à l'historique, jamais à vos fichiers.

jeudi 22 octobre 2026
Git – GIT2

❌ Faux

git reset --hard ne touche qu'à l'historique, jamais à vos fichiers.

Faux : --hard recule aussi l'index et le working tree : les modifications non commitées sont perdues.

jeudi 22 octobre 2026
Git – GIT2

🙋 Question 13 / 13

Cette fois, le commit raté a déjà été poussé, et vos collègues l'ont tiré. Comment l'annuler ?

jeudi 22 octobre 2026
Git – GIT2

revert : annuler sans réécrire

$ git revert a9bfd1f
[main f65d87e] Revert "Précise la cuisson des crêpes"
  • revert ne supprime rien : il ajoute un nouveau commit qui applique le changement inverse ;
  • l'historique reste vrai, et vos collègues le reçoivent par un simple pull ;
  • reset réécrit le passé, revert ajoute au présent : dès qu'un commit est partagé, c'est revert.
jeudi 22 octobre 2026
Git – GIT2

🙋 Vrai ou faux ?

On annule un commit déjà partagé avec revert.

jeudi 22 octobre 2026
Git – GIT2

✅ Vrai

On annule un commit déjà partagé avec revert.

Vrai : revert ajoute un commit inverse, sans réécrire l'histoire.

jeudi 22 octobre 2026
Git – GIT2

Défaire : la carte

Je veux… Commande Rattrapable ?
jeter mes modifications d'un fichier git restore <f> ⚠️ non : elles n'existaient nulle part ailleurs
annuler un add git restore --staged <f> oui, le fichier est intact
refaire mon dernier commit git commit --amend oui (cf. annexe reflog)
reculer en gardant le travail git reset --soft / --mixed oui (cf. annexe reflog)
tout effacer jusqu'à un commit git reset --hard <c> les commits oui, le travail non commité non
annuler un commit déjà poussé git revert <c> rien n'est effacé : un commit inverse s'ajoute

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

jeudi 22 octobre 2026
Git – GIT2

2 · Les dépôts distants

clone, fetch, merge, push : échanger avec une autre copie du dépôt

jeudi 22 octobre 2026
Git – GIT2

🖐️ Hands-on 1 — cloner le carnet (2 min)

Le dépôt d'exercice de la séance, le carnet de recettes de GIT1, est sur GitHub. Récupérez-le pendant que je vous explique ce qui se passe :

  1. ouvrez un terminal (Git Bash sous Windows), placez-vous dans votre dossier de travail : cd ~/mines (ou ce qui vous sert) ;
  2. git clone https://github.com/raphaelpra/git-carnet.git ;
  3. cd git-carnet, puis ls.
jeudi 22 octobre 2026
Git – GIT2

Git est distribué 🌍

💻 mon ordi
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
☁️ GitHub : raphaelpra/git-carnet
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
💻 votre ordi
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
  • le carnet est né sur mon ordi, en GIT1 ; je l'ai poussé sur GitHub ; vous venez de le cloner. Il existe maintenant en trois copies, et chacune contient tout l'historique : git log vous montre mes commits ;
  • sans réseau, tout marche chez vous : commiter, créer une branche, fusionner, revenir en arrière ;
  • GitHub n'est qu'une copie complète de plus, sur un serveur. Rien, techniquement, ne la distingue des deux autres : c'est l'équipe qui décide qu'elle fait foi. C'est tout le sujet de cette partie.
jeudi 22 octobre 2026
Git – GIT2

git clone

$ git clone https://github.com/raphaelpra/git-carnet.git
Cloning into 'git-carnet'...
$ cd git-carnet
$ git branch -a
* main                              ← votre branche, à vous
  remotes/origin/HEAD -> origin/main
  remotes/origin/cuisson
  remotes/origin/garniture
  remotes/origin/main               ← la dernière position connue de main là-bas
  remotes/origin/sauce

clone fait quatre choses d'un coup :

  1. copie tout le .git/ distant (tous les commits, toutes les branches) ;
  2. enregistre l'URL sous le nom origin ;
  3. crée une branche de suivi origin/<b> pour chaque branche distante ;
  4. crée votre main locale, posée au même endroit, et la lie à origin/main.
jeudi 22 octobre 2026
Git – GIT2

Un dépôt distant : une autre copie, ailleurs

💻 votre ordi
● ─ ● ─ ● ─ ●
.git/ : tout l'historique
☁️ origin = github.com/raphaelpra/git-carnet
● ─ ● ─ ●
une autre copie du dépôt, ailleurs

Un dépôt distant (remote) est une autre copie complète du même dépôt, ailleurs : sur GitHub, sur un serveur, chez un collègue.

Rien n'est synchronisé en continu : les deux copies ne se parlent que lorsque vous tapez fetch, pull ou push. Entre deux, chacune vit sa vie.

jeudi 22 octobre 2026
Git – GIT2

Un remote : un surnom pour une URL

Pour ne pas retaper l'URL à chaque fois, git lui donne un surnom. origin est celui que git clone donne au dépôt d'où l'on vient : ce n'est pas un mot-clé, juste une convention.

$ git remote -v
origin  https://github.com/raphaelpra/git-carnet.git (fetch)
origin  https://github.com/raphaelpra/git-carnet.git (push)
  • git push origin main se lit donc « envoie main à l'URL surnommée origin » ;
  • on peut avoir plusieurs surnoms, vers plusieurs dépôts : nous y viendrons dans cette partie.
jeudi 22 octobre 2026
Git – GIT2

🖐️ Hands-on 1 (suite) — explorer le clone (5 min)

Dans git-carnet, cloné tout à l'heure :

  1. git remote -v : quel surnom, quelle URL ?
  2. git log --oneline --graph --all : repérez HEAD, main, et des étiquettes que nous n'avons pas expliquées : origin/main, origin/sauce… ;
  3. git switch -c echauffement, modifiez le README.md, add, commit ;
  4. git switch main, git merge echauffement : fast-forward ou merge commit ? pourquoi ?
  5. git branch -d echauffement, puis git status : que veut dire Your branch is ahead of 'origin/main' by 1 commit ?

C'est la question de la slide suivante.

jeudi 22 octobre 2026
Git – GIT2

Les branches de suivi : origin/main

À la fin du hands-on, chez vous :

origin/main main ◀ HEAD le carnet, tel que cloné votre commit echauffement
  • origin/main est une photo de la position de main sur origin, prise lors du dernier clone, fetch, pull ou push ;
  • elle est en lecture seule : on ne commite pas dessus, on la compare, on la fusionne ;
  • ahead by 1 commit : votre main a un commit que origin/main n'a pas ; rien n'est parti tant que vous n'avez pas fait push.
jeudi 22 octobre 2026
Git – GIT2

Pendant ce temps, sur mon ordi 💻

Je fais deux commits dans mon clone du carnet, et je les pousse sur GitHub :

$ git switch main
$ printf '# Galettes\n\n- 250 g de farine de sarrasin\n' > recettes/galettes.md
$ git add recettes/galettes.md && git commit -m "Ajoute les galettes"   ← commit 1
$ sed -i 's/- 30 g de sucre/- 30 g de sucre\n- 1 gousse de vanille/' recettes/tarte.md
$ git commit -am "Ajoute la vanille à la tarte"                         ← commit 2
$ git push
$ git log --oneline --graph main origin/main

Sur GitHub, les deux commits sont là : https://github.com/raphaelpra/git-carnet/commits/main

jeudi 22 octobre 2026
Git – GIT2

Et chez vous ?

$ git status
On branch main
Your branch is ahead of 'origin/main' by 1 commit.

Rien n'a bougé : ni vos fichiers, ni votre graphe, ni origin/main. Mes commits sont sur GitHub, mais votre dépôt ne le sait pas encore.

origin/main ne bouge jamais toute seule : il faut aller voir.

jeudi 22 octobre 2026
Git – GIT2

🖐️ À vous : git fetch, puis le graphe

$ git fetch
$ git log --oneline --graph main origin/main

Vous devez voir, chez vous, exactement ce graphe :

origin/main main ◀ HEAD 2 commits du prof, rapatriés par fetch ancêtre commun 1 commit à vous, pas encore poussé
  • fetch a rapatrié mes 2 commits et déplacé origin/main ; votre main et vos fichiers n'ont pas bougé ;
  • git status : Your branch and 'origin/main' have diverged, and have 1 and 2 different commits each.
jeudi 22 octobre 2026
Git – GIT2

fetch, pull, push

Commande Ce qu'elle fait Touche à vos fichiers ?
git fetch rapatrie les nouveaux commits, déplace origin/* non, jamais
git pull fetch puis merge origin/main dans votre branche oui
git push envoie vos commits, déplace main là-bas (et origin/main ici) non
$ git fetch
$ git status
Your branch and 'origin/main' have diverged,
and have 1 and 2 different commits each, respectively.
$ git log --oneline --graph main origin/main      ← regarder avant de décider
$ git merge origin/main                          ← fusionne leurs commits avec le mien

Le réflexe : fetch, regarder le graphe, puis décider. Sur une histoire qui diverge, faites fetch + merge vous-même : git pull y refuse de choisir à votre place (Need to specify how to reconcile divergent branches).

jeudi 22 octobre 2026
Git – GIT2

La recette de GIT1, enfin expliquée

La dernière étape du TP GIT1 proposait de publier git-homework sur GitHub en suivant une recette. Ligne à ligne :

$ git remote add origin git@github.com:VOUS/git-homework.git   ← donne le surnom origin à cette URL
$ git push -u origin main                                       ← envoie main, crée origin/main, lie les deux
$ git remote -v                                                 ← vérifie
  • le dépôt GitHub devait être créé vide, sans README ni .gitignore : sinon GitHub crée un premier commit de son côté, et vos deux histoires n'ont aucun ancêtre commun (push refusé ; l'annexe autres dépôts montre comment les réunir) ;
  • -u (upstream) mémorise le lien : git status peut ensuite dire ahead / behind ;
  • la seule vraie preuve que tout est parti : un git clone frais, ailleurs.
jeudi 22 octobre 2026
Git – GIT2

🖐️ Hands-on 2 — intégrer mes commits (3 min)

Dans git-carnet, votre main et origin/main ont divergé : 1 commit à vous, 2 à moi.

  1. git merge origin/main : l'éditeur s'ouvre pour le message du merge, enregistrez, fermez ;
  2. git log --oneline --graph main origin/main : dessinez ce que vous voyez ;
  3. git status : que veut dire ahead by 2 commits ?

Question : git a créé un commit de plus. Lequel, et pourquoi ?

Vous ne pouvez pas pousser sur git-carnet : c'est mon dépôt. Vous pousserez dans l'atelier, sur votre propre copie sur GitHub (un fork, partie 3). Ce qui arrive quand deux personnes poussent sur le même dépôt, je vous le montre.

jeudi 22 octobre 2026
Git – GIT2

Démo (1/2) : deux collègues, un seul dépôt

Sur mon ordi, trois dossiers : un dépôt qui joue le rôle de GitHub, et deux clones, comme deux collègues.

💻 alice/
● ─ ● ─ ●
un clone
☁️ github.git/
● ─ ● ─ ●
joue GitHub
💻 bob/
● ─ ● ─ ●
un autre clone

Bob commite et pousse le premier :

$ cd bob
$ echo "Bob" >> README.md && git commit -am "Bob signe le README"
$ git push
jeudi 22 octobre 2026
Git – GIT2

Démo (2/2) : Alice pousse à son tour

Alice n'a pas fait fetch depuis le push de Bob :

$ cd ../alice
$ echo "note" >> recettes/tarte.md && git commit -am "Alice précise la tarte"
$ git push
 ! [rejected]        main -> main (fetch first)
hint: Updates were rejected because the remote contains work that you do not have locally.

Le refus n'est pas une panne : git refuse d'écraser le travail de Bob. Alice fait ce que vous avez fait au hands-on 2 : fetch, merge, puis elle repousse.

git status dit… Ça veut dire On fait
up to date with 'origin/main' rien à échanger (à la date du dernier fetch !) rien
ahead by 2 commits vous avez 2 commits qu'origin n'a pas push
behind by 3 commits origin a 3 commits que vous n'avez pas pull
have diverged les deux fetch, merge, push
jeudi 22 octobre 2026
Git – GIT2

3 · GitHub

Un hébergeur de dépôts git, et tout ce qu'on a construit autour

jeudi 22 octobre 2026
Git – GIT2

Git n'est pas GitHub

Git (2005) : un logiciel, sur votre ordi.

  • il gère l'historique : commits, branches, merge ;
  • il échange avec d'autres copies : clone, fetch, push ;
  • il marche hors ligne, sans compte, sans site web.

Tout ce que vous avez fait jusqu'ici, c'est git.

GitHub (2008, Microsoft depuis 2018) : un site, qui héberge des dépôts git.

  • une copie toujours allumée, joignable par tous : origin ;
  • des comptes, et qui peut pousser où ;
  • de quoi discuter avant de fusionner : pull requests, review ;
  • autour : issues, tests automatiques (Actions), sites web (Pages).

Le git-carnet de GitHub est un dépôt git ordinaire : une clé USB aurait fait l'affaire. GitLab ou Codeberg font comme GitHub, avec les mêmes commandes git.

jeudi 22 octobre 2026
Git – GIT2

S'authentifier

GitHub doit savoir qui pousse. Deux façons, selon l'URL du remote :

URL Comment on prouve qui on est
https://github.com/vous/projet.git au premier push, une fenêtre de connexion GitHub s'ouvre dans le navigateur ; git retient la réponse (Git Credential Manager, installé avec Git for Windows)
git@github.com:vous/projet.git (SSH) une clé SSH : ssh-keygen -t ed25519, puis la clé publique (~/.ssh/id_ed25519.pub) dans Settings → SSH keys
$ ssh -T git@github.com
Hi vous! You've successfully authenticated, but GitHub does not provide shell access.
  • le mot de passe du compte GitHub ne marche plus pour push depuis 2021 : si git vous le demande (sur Mac, souvent), voir l'annexe gh ;
  • git remote set-url origin <url> change l'URL d'un remote existant.
jeudi 22 octobre 2026
Git – GIT2

Contribuer : collaborateur ou fork

Collaborateur : le propriétaire vous donne le droit d'écrire dans son dépôt.

  • vous clonez son dépôt : origin = son dépôt ;
  • vous poussez vos branches directement chez lui ;
  • typique d'une équipe, d'un projet de groupe.

Fork : une copie du dépôt, sur votre compte, où vous avez tous les droits.

  • origin = votre fork, upstream = l'original ;
  • vous poussez sur votre fork, vous proposez par une PR ;
  • typique du logiciel libre : n'importe qui peut proposer, sans droit d'écriture.

Un fork n'est rien d'autre qu'une copie du dépôt, faite par GitHub sur votre compte (bouton Fork), qui garde le lien avec l'original.

jeudi 22 octobre 2026
Git – GIT2

Un fork, deux remotes : origin et upstream

upstreaml'original, en lecture originvotre fork, à vous 💻 votre cloneun seul .git fetchpushFork (sur GitHub)
$ git clone https://github.com/vous/projet.git                        ← origin = votre fork
$ git remote add upstream https://github.com/original/projet.git      ← upstream = l'original
$ git fetch upstream
$ git log --oneline main..upstream/main      ← ce que l'original a et que votre fork n'a pas
$ git merge upstream/main                    ← l'intégrer, puis git push : votre fork est à jour

upstream n'est qu'un surnom de plus, comme origin : un remote de plus, ses branches de suivi (upstream/main), dans le même .git.

jeudi 22 octobre 2026
Git – GIT2

🖐️ Hands-on 3 — à la place de Camille (7 min)

Camille a forké le carnet : https://github.com/raphaelpra/git-carnet-camille. Depuis, j'ai poussé mes 2 commits sur l'original. Mettez-vous à sa place, et mettez son fork à jour :

  1. cd .., git clone https://github.com/raphaelpra/git-carnet-camille.git, cd git-carnet-camille ;
  2. git remote add upstream https://github.com/raphaelpra/git-carnet.git, puis git remote -v ;
  3. git fetch upstream, puis git branch -r ;
  4. git log --oneline main..upstream/main : qu'a l'original que le fork de Camille n'a pas ?
  5. git merge upstream/main (l'éditeur s'ouvre : enregistrez, fermez) ; ls recettes/ ;
  6. git log --oneline --graph -6.

Question : Camille ne peut pas pousser sur git-carnet. Comment me proposerait-elle son correctif des œufs ?

C'est le geste de l'atelier, étape 8. Ici, pas de push : ce fork-là est à moi.

jeudi 22 octobre 2026
Git – GIT2

Anatomie d'une pull request

Une pull request (PR) dit : « voici ma branche, voulez-vous l'intégrer dans la vôtre ? »

  • base ← head : raphaelpra/…:main ← vous/…:fiche/stash ; on lit cette ligne avant de cliquer ;
  • la PR suit la branche : chaque git push sur fiche/stash ajoute ses commits à la PR, sans rien rouvrir ;
  • Conversation, Commits, Checks (les tests automatiques), Files changed (le diff, où l'on commente une ligne) ;
  • review : Comment, Request changes ou Approve ;
  • le bouton Merge : fait le git merge côté GitHub, une fois la PR approuvée.

En clair : la PR est un git merge qu'on a rendu discutable. Elle n'existe pas dans git, seulement sur GitHub.

jeudi 22 octobre 2026
Git – GIT2

Pause ☕

10 minutes, puis les workflows, trois outils, worktree et l'atelier

jeudi 22 octobre 2026
Git – GIT2

4 · Git ne prend pas parti

Les commandes sont les mêmes pour tous ; la façon de s'en servir à plusieurs est une décision d'équipe

jeudi 22 octobre 2026
Git – GIT2

Une boîte à outils, pas une méthode

Git vous donne des branches, des remotes, merge et rebase. Il ne dit rien de :

  • quel dépôt fait foi (git est distribué : aucun clone n'est plus « vrai » qu'un autre) ;
  • qui a le droit de pousser sur main, et si quelqu'un relit avant ;
  • combien de temps vit une branche, comment elle s'appelle ;
  • comment on livre une version, comment on corrige en urgence ;
  • merge ou rebase, et à quel moment.

Chaque équipe répond à ces questions par un workflow. Aucun n'est « le bon » : chacun répond à un souci précis, et le paie d'un prix. Passons-en trois en revue, du plus simple au plus outillé.

jeudi 22 octobre 2026
Git – GIT2

1. Le dépôt central : tout le monde sur main

💻 Alice
main
☁️ le dépôt central
● ─ ● ─ ● ─ ●
une seule branche : main
💻 Bob
main

Le souci résolu : partager du code, tout simplement. C'est le modèle des outils d'avant git (CVS, SVN), et celui de votre premier projet de groupe : un dépôt GitHub, tout le monde collaborateur, tout le monde pousse sur main.

Le prix :

  • push refusé en boucle dès qu'on est trois (fetch first), et des pull qui créent des merge commits partout ;
  • personne ne relit : une erreur poussée est immédiatement chez tout le monde ;
  • main est souvent cassée, puisque c'est là qu'on travaille.

Parfait à deux sur un petit projet ; ça craque vite au-delà.

jeudi 22 octobre 2026
Git – GIT2

2. Une branche par sujet, une PR pour entrer

fiche/stash → PR n° 1 correctif-sommaire → PR n° 2 fiche/blame → PR n° 3 main

Le GitHub flow (2011), celui de la plupart des équipes aujourd'hui, et celui de notre atelier :

  1. main est toujours en état de marche : on ne travaille jamais dessus ;
  2. une branche courte par sujet, poussée tôt ; une PR dès qu'on veut un avis ;
  3. review par un collègue + tests automatiques (Checks) ; puis merge, et on supprime la branche.

Le souci résolu : relire avant d'intégrer, garder main saine. Le prix : une étape de plus ; et une branche qui traîne trois semaines finit en conflit avec tout le monde.

jeudi 22 octobre 2026
Git – GIT2

3. Fork et PR : contribuer sans droit d'écriture

Même schéma que le précédent, mais la branche vit sur votre fork, pas dans le dépôt de référence :

upstream (le projet)  ◀── PR ───  origin (votre fork)  ◀── push ───  votre PC
        │                                                               ▲
        └──────────────────────── fetch upstream ───────────────────────┘

Le souci résolu : des milliers de contributeurs qui ne se connaissent pas (le noyau Linux, Python, numpy…). Le mainteneur ne donne les clés à personne ; n'importe qui peut proposer, lui seul décide.

Le prix : deux remotes à tenir à jour (git fetch upstream souvent), et votre fork qui prend du retard si vous l'oubliez.

C'est le modèle de l'atelier tout à l'heure : vous forkez raphaelpra/git-atelier-2026, vous poussez sur votre fork, vous proposez par PR.

jeudi 22 octobre 2026
Git – GIT2

Mettre sa PR à jour (1/2) : main a avancé

Vous avez ouvert votre PR ; depuis, j'ai mergé celles de deux camarades :

upstream/main fiche/stash (votre PR) 2 PR des autres, mergées depuis là où vous êtes parti
  • votre branche part d'un main qui n'existe plus ; GitHub affiche This branch is out-of-date, ou This branch has conflicts si vous avez touché les mêmes lignes ;
  • c'est à vous de la mettre à jour : c'est votre branche, sur votre fork.
jeudi 22 octobre 2026
Git – GIT2

Mettre sa PR à jour (2/2) : faire entrer le nouveau main

upstream/main fiche/stash ◀ HEAD 2 PR des autres, mergées depuis le merge : il ramène les 2 commits des autres
$ git fetch upstream                  ← rapatrie le main du dépôt de référence
$ git merge upstream/main             ← conflit ? corriger, git add, git commit
$ git push                            ← la PR se met à jour toute seule
  • le même merge qu'en GIT1, avec une branche distante comme source ; vrai pour tous les workflows à PR, fork ou pas (origin/main au lieu d'upstream/main) ;
  • l'autre école réécrit la branche par rebase pour garder la PR en ligne droite : annexe rebase.
jeudi 22 octobre 2026
Git – GIT2

Récapitulons 🎯

Workflow Le souci qu'il résout Son prix Typiquement
dépôt central, tout sur main partager, sans cérémonie push refusés, main cassée, aucune relecture à deux, un petit projet
branches + PR (GitHub flow) relire et tester avant d'intégrer ; main toujours saine une étape de plus ; les branches longues divergent la plupart des équipes
fork + PR contribuer sans droit d'écriture deux remotes à tenir à jour le logiciel libre, notre atelier

🙋 Votre prochain projet de groupe, à quatre, pendant trois semaines : lequel choisissez-vous ?

Ma réponse : branches + PR, un relecteur, main protégée. Ce qui compte surtout, c'est de le décider ensemble le premier jour, et de l'écrire dans le README.

jeudi 22 octobre 2026
Git – GIT2

Trois outils du quotidien

stash, blame, et l'art du message de commit

jeudi 22 octobre 2026
Git – GIT2

stash : mettre de côté

Vous êtes au milieu d'une modification, et il faut changer de branche maintenant (git refuse : vos modifications entreraient en collision) :

$ git stash push -m "essai de graphique"     ← range les modifications, working tree propre
$ git switch main                            ← … le correctif urgent …
$ git switch analyse
$ git stash list
stash@{0}: On analyse: essai de graphique
$ git stash pop                              ← rétablit, et retire de la pile
  • git stash tout court marche aussi, sans message : vous ne saurez plus dans une semaine ce que c'était ;
  • -u pour embarquer aussi les fichiers non suivis (untracked) ;
  • ⚠️ le stash est une pile qu'on oublie : au-delà de quelques minutes, préférez un vrai commit sur une branche, ou un worktree (partie 5).
jeudi 22 octobre 2026
Git – GIT2

blame : qui a écrit cette ligne, et pourquoi

Dans git-carnet-camille (hands-on 3) :

$ git blame recettes/crepes.md
7ac8892 (Raphael Prasquier 2026-09-10 10:00:00 +0200  3) - 250 g de farine
b6c47e3 (Camille           2026-10-15 09:00:00 +0200  4) - 4 œufs
7ac8892 (Raphael Prasquier 2026-09-10 10:00:00 +0200  5) - 50 cl de lait
7ac8892 (Raphael Prasquier 2026-09-10 10:00:00 +0200  6)
a9bfd1f (Raphael Prasquier 2026-09-10 12:00:00 +0200  7) Cuisson : 3 min par face, à feu vif.
$ git blame -L 4,7 recettes/crepes.md       ← seulement les lignes 4 à 7
$ git show b6c47e3                          ← le commit entier : son message, ses autres changements

Le nom est mal choisi : l'intérêt n'est pas de trouver un coupable, mais de retrouver le pourquoi d'une ligne étrange avant d'y toucher. Et ce pourquoi n'existe que si le message de commit le dit.

🧰 VS Code : l'extension GitLens affiche le blame de la ligne courante, en gris, au bout de la ligne ; sur GitHub, le bouton Blame au-dessus d'un fichier.

jeudi 22 octobre 2026
Git – GIT2

Écrire un message de commit

Corrige la moyenne quand la liste est vide          ← ≤ 50 caractères, à l'impératif

moyenne([]) levait ZeroDivisionError et faisait     ← une ligne vide, puis le pourquoi
planter le rapport du lundi. On renvoie désormais
None, que l'appelant affiche comme « pas de données ».
  • la première ligne complète la phrase « ce commit… » : « Ajoute la fiche stash », pas « ajouté fiche », ni « fix », ni « wip » ;
  • le quoi est dans le diff ; le message dit le pourquoi, qu'on ne peut pas deviner en lisant le code ;
  • un commit = un sujet : si le message contient « et », ce sont probablement deux commits (git add -p pour découper un fichier en morceaux) ;
  • le lecteur, c'est celui qui fera blame dans six mois : le plus souvent, vous.

git commit sans -m ouvre l'éditeur : c'est là qu'on écrit un corps de message.

jeudi 22 octobre 2026
Git – GIT2

5 · git worktree, à l'heure des agents

Plusieurs branches extraites en même temps, dans un seul dépôt

jeudi 22 octobre 2026
Git – GIT2

Le souci : un seul trio, une seule branche à la fois

Le trio de GIT1 n'existe qu'en un exemplaire : vous ne pouvez avoir qu'une branche extraite à la fois. Pour un humain, changer de tâche oblige à stash, à un commit « wip », ou à un second clone.

Pour des agents de code (Claude Code, Codex, Cursor…), qui travaillent seuls plusieurs minutes et que l'on lance à plusieurs, c'est rédhibitoire. Dans un seul dossier :

  • leurs modifications se mélangent dans le même working tree ;
  • l'index est partagé : le git add de l'un part dans le commit de l'autre ;
  • si l'un fait git switch, les fichiers changent sous les pieds de tous les autres.

Il faut à chaque agent son propre trio, sans cloner trois fois le dépôt.

jeudi 22 octobre 2026
Git – GIT2

L'idée : un .git, plusieurs working trees

un seul .git les objets, les branches, les remotes projet/ projet-bug/ projet-tests/ main fix/moyenne tests/rapport son HEAD, son index, ses fichiers son HEAD, son index, ses fichiers son HEAD, son index, ses fichiers
  • chaque dossier a son trio complet et sa branche extraite ; tous partagent le même .git ;
  • un commit fait dans projet-bug/ est immédiatement visible depuis projet/ (git log --all) : pas de push, pas de fetch ;
  • créer un worktree coûte la place des fichiers extraits, pas celle de l'historique.
jeudi 22 octobre 2026
Git – GIT2

Les commandes, et leurs pièges

$ git worktree add ../projet-bug -b fix/moyenne          ← nouveau dossier, nouvelle branche
$ git worktree add ../projet-tests -b tests origin/main  ← depuis un point précis
$ git worktree list
/home/vous/projet        3f9a1c2 [main]
/home/vous/projet-bug    3f9a1c2 [fix/moyenne]
$ git worktree remove ../projet-bug                      ← refuse s'il reste du travail non commité
$ git branch -d fix/moyenne                              ← la branche, elle, survit au dossier
  • le dossier se met à côté du dépôt (../), jamais dedans ;
  • ⚠️ une branche n'est extraite que dans un worktree à la fois (already used by worktree) ;
  • ⚠️ les fichiers ignorés ne suivent pas : .venv/, node_modules/, .env sont à recréer dans chaque dossier ;
  • rangez : remove dès que la branche est mergée.
jeudi 22 octobre 2026
Git – GIT2

Un agent = un worktree = une branche = une PR

1. la tâche 2. un worktree, une branche 3. l'agent 4. la PR 5. vous 6. ranger
« corrige la moyenne » worktree add ../projet-bug -b fix/moyenne édite, teste, commite, seul dans son dossier « Corrige la moyenne » relisez le diff, testez merge, worktree remove, branch -d
  • les outils d'agents font souvent ce worktree add pour vous : il faut savoir ce qu'ils font dessous, pour ranger, retrouver un travail, ou reprendre la main ;
  • chaque agent a son dossier, sa branche, ses tests : rien ne se mélange, et un agent qui s'égare se jette avec son worktree, sans toucher aux autres ;
  • la PR de la partie 4 retrouve tout son sens : c'est le moment où un humain relit ce qu'une machine a écrit. Plus on lance d'agents, plus la relecture devient le vrai travail.

C'est ainsi que je travaille au quotidien : une demi-douzaine de worktrees ouverts, un agent dans chacun, et mon temps passe en review.

jeudi 22 octobre 2026
Git – GIT2

🖐️ Hands-on 4 — deux tâches en parallèle (5 min)

Dans git-carnet :

  1. git worktree add ../git-carnet-essai -b essai ;
  2. cd ../git-carnet-essai, modifiez un fichier, add, commit ;
  3. git worktree list ; puis cd ../git-carnet et git log --oneline --all : le commit d'essai est là, sans push ;
  4. depuis git-carnet, essayez git switch essai : lisez le message ;
  5. git worktree remove ../git-carnet-essai, puis git branch -d essai : refusé ? pourquoi ? (merge d'abord, ou -D).

Vous referez exactement cela dans l'atelier, étape 9, pour une deuxième fiche pendant que la première attend sa review.

jeudi 22 octobre 2026
Git – GIT2

Atelier (55 min) : une fiche, une PR, une review 🛠️

Le dépôt de classe : https://github.com/raphaelpra/git-atelier-2026. Consignes pas à pas sur le site (page de la séance).

  1. fork + clone, upstream = le dépôt de classe ;
  2. une branche fiche/<commande>, une fiche « une commande git en 10 lignes » depuis fiches/_modele.md ;
  3. une ligne à la fin de SOMMAIRE.md (tout le monde écrit au même endroit : le conflit est voulu) ;
  4. push sur votre fork, PR, relecteur mentionné : @votre-voisin-de-droite ;
  5. vous relisez la PR de votre voisin de gauche : un commentaire sur une ligne, puis Approve ;
  6. conflit : fetch upstream, merge upstream/main, push ;
  7. je merge les PR approuvées et sans conflit ; s'il reste du temps, une 2e fiche dans un worktree.

C'est moi qui merge (je suis le mainteneur) ; chaque merge crée un conflit chez tous les autres : c'est le but.

jeudi 22 octobre 2026
Git – GIT2

Ce qu'il faut retenir 📌

  • un remote est un surnom pour un autre clone ; origin/main est la photo de sa position au dernier fetch ;
  • fetch, regarder le graphe, puis décider ; pull = fetch + merge ;
  • on intègre un autre dépôt en l'ajoutant comme remote : fetch, regarder, puis merge ;
  • GitHub ajoute à git ce qui est social : forks, PR, review, protections ;
  • git ne prend pas parti : chaque workflow répond à un souci, et le paie ; décidez-le en équipe, le premier jour ;
  • mettre sa PR à jour : fetch upstream, puis merge upstream/main (le rebase : en annexe) ;
  • worktree : un dossier par tâche (ou par agent), un seul .git.
jeudi 22 octobre 2026
Git – GIT2

Pour aller plus loin 📚

  • Pro Git, chapitres 2.5 (remotes), 3.5 (branches distantes), 5 (workflows distribués), 6 (GitHub) : https://git-scm.com/book/fr/v2 ;
  • GitHub flow : https://docs.github.com/fr/get-started/using-github/github-flow ;
  • git help worktree ; learngitbranching, onglet distant : le meilleur moyen de voir fetch, pull et push ;
  • sur le site, les annexes rebase (rejouer ses commits, la règle d'or), reflog (retrouver un commit perdu), autres dépôts (cherry-pick, histoires sans ancêtre commun) et gh (GitHub en ligne de commande).

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

jeudi 22 octobre 2026