Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 915 minDébutant

Pull request et revue de code sur GitHub

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • ouvrir une pull request claire ;
  • faire et recevoir une revue de code ;
  • choisir entre les trois façons de fusionner une pull request ;
  • protéger la branche main d'un dépôt.

4 exercices corrigés1 schéma

Une pull request (PR) est une demande d'intégration : tu proposes de fusionner une branche dans une autre, et ton équipe relit les modifications, les commente et les approuve avant la fusion. GitLab appelle la même chose une merge request. Ce chapitre explique comment ouvrir une pull request utile, comment faire et recevoir une revue de code (commentaires, suggestions, approbation), les trois façons de fusionner, la protection de la branche main, et les équivalences avec GitLab et Gitea.

Pourquoi une pull request

Fusionner ta branche dans main sur ton poste puis pousser fonctionne, mais personne n'a relu ton code avant qu'il arrive dans la version de référence. La pull request ajoute une étape :

  1. tu pousses ta branche ;
  2. tu ouvres une pull request qui dit « voici ce que je propose d'intégrer dans main, et pourquoi » ;
  3. un coéquipier relit, commente, demande des corrections ; tu les apportes en poussant de nouveaux commits sur la même branche, et la pull request se met à jour toute seule ;
  4. les tests automatiques passent (chapitre 12) ;
  5. le relecteur approuve, et la branche est fusionnée.

Tant que la pull request n'est pas fusionnée, main n'est pas touchée. On attrape les erreurs avant qu'elles arrivent dans la version de référence, toute l'équipe sait ce qui change, et la discussion reste attachée au code, consultable des années plus tard. Pour toi, c'est aussi une trace : une pull request relue et fusionnée prouve le travail en équipe et la démarche de validation.

1. Créer une branchegit switch -cfeature/export2. Commiterdes petits commitsclairs3. Pousser, ouvrirune pull requestvers main4. Revue de codeet testsautomatiques5. Fusiondans mainaprès approbation6. Supprimerla branchemain déployablechangements demandés
Le GitHub Flow : une branche par sujet, une pull request, une revue, des tests, puis la fusion dans main

Ouvrir une pull request

Après git push -u origin feature/export, GitHub affiche dans le terminal un lien direct, et sur la page du dépôt un bandeau Compare & pull request. Dans le formulaire :

  • base est la branche qui reçoit (main), compare la branche qui propose (feature/export) ;
  • le titre dit ce que fait la pull request, comme un bon message de commit : « Ajoute l'export CSV des notes de frais » ;
  • la description donne le contexte et facilite la relecture.

Une bonne description répond à quatre questions :

markdown
## Pourquoi
Les comptables ressaisissent les notes dans leur tableur. Ticket #18.

## Ce qui change
- Nouvelle route `GET /notes/export?mois=2026-10` qui renvoie un CSV
- Bouton « Exporter » sur la page des notes validées
- Les montants sont au format français (virgule décimale, séparateur `;`)

## Comment tester
1. Se connecter avec le compte compta1
2. Page « Notes validées », bouton « Exporter »
3. Ouvrir le fichier dans un tableur : 14 lignes pour octobre 2026

## Points d'attention
Les notes refusées sont exclues de l'export : à confirmer avec la comptabilité.

L'écriture Closes #18 (ou Fixes #18, Resolves #18) dans la description relie la pull request à l'issue 18 : à la fusion dans la branche par défaut, l'issue est fermée automatiquement.

Dans la colonne de droite, tu désignes les relecteurs (Reviewers), la personne responsable (Assignees), des étiquettes (Labels) et l'éventuel jalon. Si ton travail n'est pas prêt mais que tu veux un premier avis, ouvre la pull request en brouillon (Create draft pull request) : elle ne peut pas être fusionnée tant que tu ne la marques pas Ready for review.

Avec GitHub CLI, tout se fait depuis le terminal :

bash
gh pr create --base main --title "Ajoute l'export CSV des notes de frais" --body-file description.md --reviewer hugo-dupre
gh pr list              # les pull requests ouvertes
gh pr checkout 23       # récupère la branche de la PR 23 pour la tester
gh pr view 23 --web     # l'ouvre dans le navigateur

La revue de code

La revue de code (code review) consiste à relire le code d'un autre avant son intégration. L'onglet Files changed d'une pull request affiche toutes les modifications. Le relecteur peut :

  • commenter une ligne ou un groupe de lignes, en cliquant sur le + dans la marge ;
  • proposer une modification exacte avec le bouton suggestion, qui insère un bloc ```suggestion dans le commentaire : l'auteur l'applique en un clic avec Commit suggestion, sans ouvrir son éditeur ;
  • cocher Viewed sur les fichiers déjà relus, pour suivre son avancement.

Un exemple de suggestion :

markdown
Le séparateur décimal doit suivre la locale française pour que le tableur lise les montants.

```suggestion
const montant = note.montant.toFixed(2).replace('.', ',');
```

Les commentaires d'une revue s'envoient ensemble, avec le bouton Review changes et l'une des trois conclusions :

ConclusionSignification
CommentDes remarques, sans se prononcer sur la fusion
ApproveLe code peut être fusionné
Request changesDes corrections sont nécessaires avant la fusion

L'auteur répond à chaque commentaire, corrige en poussant de nouveaux commits sur la branche, puis marque la conversation comme résolue (Resolve conversation) et redemande une relecture.

Ce que le relecteur vérifie, dans l'ordre :

  1. Le besoin. La pull request fait-elle ce que demande le ticket, et seulement ça ?
  2. La justesse. Cas limites (liste vide, montant nul, date au dernier jour du mois), gestion des erreurs.
  3. La sécurité. Requêtes préparées, droits vérifiés côté serveur, aucun secret dans le code (cours de sécurité des applications).
  4. Les tests. Le comportement nouveau est-il testé, les tests existants passent-ils ?
  5. La lisibilité. Noms clairs, fonctions courtes, pas de code mort ni de console.log oublié.

Comment commenter. On commente le code, pas la personne. Une question ouvre la discussion mieux qu'un ordre : « Que se passe-t-il si la liste est vide ? » plutôt que « Ça plante ». Distingue ce qui bloque de ce qui est un avis : beaucoup d'équipes préfixent les remarques facultatives par « Suggestion : » ou « Détail : ». Et dis aussi ce qui est bien fait.

Comment recevoir une revue. Une remarque sur ton code n'est pas une remarque sur toi. Réponds à chaque commentaire, même par « Corrigé dans 4e1f0a2 ». Si tu n'es pas d'accord, explique pourquoi : la revue est une discussion.

Les trois façons de fusionner une pull request

Le bouton vert de la pull request propose trois variantes, que l'administrateur du dépôt peut restreindre dans Settings :

BoutonCe qu'il faitHistorique de main
Create a merge commitFusionne avec un commit de fusion (--no-ff)Tous les commits de la branche, plus un commit Merge pull request #23 from …
Squash and mergeRegroupe tous les commits de la branche en un seulUn commit par pull request, au titre de la PR
Rebase and mergeRejoue chaque commit de la branche au-dessus de main, sans commit de fusionLinéaire, tous les commits de la branche, avec de nouvelles empreintes

Squash and merge est souvent le bon choix pour une petite équipe : tes commits intermédiaires (« wip », « corrige la revue ») disparaissent, et main contient un commit clair par fonctionnalité, facile à annuler avec git revert. Create a merge commit garde le détail des étapes. L'essentiel est que l'équipe choisisse une méthode et s'y tienne.

Après la fusion, clique sur Delete branch, et en local :

bash
git switch main
git pull
git branch -d feature/export     # -D si la PR a été fusionnée par squash ou rebase
git fetch --prune                # oublie les branches supprimées sur le serveur

Après un Squash and merge ou un Rebase and merge, les commits de ta branche n'existent pas tels quels dans main : git branch -d croit la branche non fusionnée et refuse. Utilise -D après avoir vérifié que la pull request est bien fusionnée.

Protéger la branche main

Une règle orale (« on ne pousse pas sur main ») finit toujours par être oubliée un soir de rendu. GitHub permet de l'imposer. Dans Settings, Rules, Rulesets (ou dans les règles de protection de branche classiques, Branches), crée une règle pour la branche main :

RègleEffet
Require a pull request before mergingLe push direct sur main est refusé ; tout passe par une pull request
Required approvals : 1Il faut au moins une approbation pour fusionner
Dismiss stale approvals when new commits are pushedUn nouveau commit après l'approbation exige une nouvelle relecture
Require status checks to passLes tests de l'intégration continue doivent être verts avant la fusion
Require conversation resolutionTous les commentaires de la revue doivent être résolus
Block force pushesPersonne ne peut réécrire l'historique de main
Restrict deletionsPersonne ne peut supprimer main

Un push direct est alors refusé :

text
remote: error: GH006: Protected branch update failed for refs/heads/main.
remote: error: Changes must be made through a pull request.
 ! [remote rejected] main -> main (protected branch hook declined)

Avec l'offre gratuite de GitHub, ces règles s'appliquent aux dépôts publics ; pour un dépôt privé, il faut GitHub Pro (gratuit avec le pack étudiant) ou un abonnement d'organisation. Un fichier CODEOWNERS, placé dans .github/, désigne automatiquement les relecteurs selon les fichiers modifiés : /api/ @lina-morel demande la relecture de Lina pour toute modification du dossier api/.

Équivalences avec GitLab et Gitea

En stage, tu travailleras peut-être sur GitLab, souvent installé sur les serveurs de l'entreprise, ou sur Gitea et Forgejo, légers et libres. Les commandes Git ne changent pas ; seuls les noms des fonctions de la forge diffèrent.

GitHubGitLabGitea, Forgejo
Pull request (PR)Merge request (MR)Pull request
Draft pull requestDraft merge requestPull request préfixée WIP: ou brouillon
IssueIssueIssue
Projects (tableau)Issue boardsProjects
GitHub Actions (.github/workflows/*.yml)GitLab CI/CD (.gitlab-ci.yml)Gitea Actions, Forgejo Actions : syntaxe proche de celle de GitHub Actions
Runner hébergé par GitHubRunner partagé de GitLab.com ou runner de l'entrepriseRunner (act_runner) à installer soi-même
Branch protection, rulesetsProtected branches, approval rulesBranch protection
OrganizationGroupOrganization
ForkForkFork
GitHub PagesGitLab PagesPas d'équivalent intégré
gh (GitHub CLI)glabtea

Une merge request GitLab fonctionne exactement comme une pull request : branche, description, revue, approbation, fusion. GitLab propose les mêmes options de fusion, dont le squash.

Exercices

Exercice 1 sur 4 Rédiger une pull request Réussi À revoir

Hugo a terminé la branche fix/12-filtre-date : la liste des notes filtrées par mois oubliait les notes du dernier jour du mois. La cause : la requête comparait la date à 2026-10-31 00:00:00. Il a corrigé la requête et ajouté un test. Rédige le titre et la description de sa pull request.

Voir la réponseMasquer la réponse de l'exercice 1

Une réponse possible :

Titre : Corrige le filtre par mois qui oubliait le dernier jour

markdown
## Pourquoi
Les notes du 31 octobre n'apparaissaient pas dans la liste d'octobre. Closes #12.

## Ce qui change
- La requête compare la date à `date < premier jour du mois suivant` au lieu de `date <= dernier jour à 00:00:00`
- Un test couvre une note datée du dernier jour du mois à 18 h

## Comment tester
1. `npm test` : le nouveau test passe
2. Créer une note datée du 31/10/2026 à 18:00, filtrer sur octobre 2026 : elle apparaît

## Points d'attention
Même correction à prévoir sur l'export CSV, qui utilise la même requête (ticket à créer).

Ce qui compte : un titre qui dit ce que fait la correction, la cause, le lien Closes #12, une procédure de test reproductible.

Tu avais trouvé ?

Exercice 2 sur 4 Faire une revue Réussi À revoir

Voici un extrait de la pull request de Lina :

javascript
app.delete('/notes/:id', async (req, res) => {
  console.log('suppression', req.params.id);
  await db.query(`DELETE FROM note WHERE id = ${req.params.id}`);
  res.send('ok');
});

Écris trois commentaires de revue, en indiquant pour chacun s'il bloque la fusion.

Voir la réponseMasquer la réponse de l'exercice 2
  1. Bloquant, sécurité. « L'identifiant est collé dans la requête SQL : une injection SQL est possible. Peux-tu passer par une requête préparée ? » Suggestion : await db.execute('DELETE FROM note WHERE id = ?', [req.params.id]);
  2. Bloquant, droits. « N'importe quel utilisateur connecté peut supprimer n'importe quelle note. Il faudrait vérifier que la note appartient à l'utilisateur, ou qu'il a le rôle comptable, et répondre 403 sinon. »
  3. Non bloquant. « Suggestion : retirer le console.log, et répondre 204 No Content (ou 404 si aucune ligne n'a été supprimée) plutôt que le texte ok, pour suivre les conventions REST. »

Tu avais trouvé ?

Exercice 3 sur 4 Quel bouton de fusion ? Réussi À revoir

La branche feature/export contient 9 commits : 3 commits qui racontent les étapes (« Ajoute la route d'export », « Ajoute le bouton », « Ajoute les tests de l'export ») et 6 commits de correction de revue (« corrige la revue », « oups »…). Pour chaque bouton, combien de commits ajoute la fusion à l'historique de main ? main a avancé depuis la création de la branche.

  1. Create a merge commit
  2. Squash and merge
  3. Rebase and merge
Voir la réponseMasquer la réponse de l'exercice 3
  1. 10 : les 9 commits de la branche, plus le commit de fusion.
  2. 1 : un seul commit qui regroupe toutes les modifications.
  3. 9 : les 9 commits, rejoués au-dessus de main, avec de nouvelles empreintes, sans commit de fusion.

Le meilleur résultat serait de nettoyer la branche avant la fusion avec un rebase interactif (les 6 corrections fusionnées dans les 3 commits d'étapes), puis Rebase and merge ou Create a merge commit. Sans nettoyage, Squash and merge donne un historique propre.

Tu avais trouvé ?

Exercice 4 sur 4 Protéger main Réussi À revoir

L'équipe de Sorbier Frais veut que : personne ne pousse directement sur main ; chaque modification soit approuvée par l'autre membre ; les tests passent avant toute fusion ; personne ne puisse réécrire l'historique de main. Le dépôt est privé, sur le compte personnel de Lina, qui a le pack étudiant. Quelles règles active-t-elle, et pourquoi le pack étudiant compte-t-il ici ?

Voir la réponseMasquer la réponse de l'exercice 4

Sur la branche main : Require a pull request before merging avec 1 approbation requise (et de préférence Dismiss stale approvals), Require status checks to pass en sélectionnant le job de tests, Block force pushes (et Restrict deletions). Le pack étudiant donne GitHub Pro : sans lui, les règles de protection ne sont pas disponibles sur un dépôt privé d'un compte gratuit.

Tu avais trouvé ?

Chapitre terminé !

Fais les 4 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Workflows Git, issues et Conventional CommitsRevoir le sommaire du cours