---
title: Organiser le développement en équipe avec git
theme: ./_themes/5ika.css
verticalSeparator:
revealOptions:
transition: 'fade'
---
# **Organiser le développement en équipe avec git**
À la fin de la master class, les participants seront en mesure de :
- Comprendre comment et pourquoi utiliser un modèle de branche git
- Utiliser les outils de gestion de projet de GitHub liés à la base de code
- Effectuer des tâches simples avec Docker
---
# Tim Izzo
- Ingénieur IT et développeur
- Travail chez [Octree](https://octree.ch) et en tant qu'indépendant
- Enseigne les réseaux et la sécurité IT
- Approche minimaliste et écologique du développement
🦌 [5ika.ch](https://5ika.ch)
✉️ [tim@5ika.ch](mailto:tim@5ika.ch)
👔 [LinkedIn](https://www.linkedin.com/in/tim-izzo/)
---
Qui êtes-vous ?
---
**Vous êtes membre d'une équipe de développement devant développer un site web.**
Vous avez besoin de:
1. Organiser le développement à plusieurs pour ne pas vous marcher sur les pieds
2. Tester votre site web pendant le développement pour s'assurer que tout fonctionne à chaque étape
3. Déployer votre site web en production une fois qu'une version est prête
---
Pour comprendre les différentes étapes, nous allons toutes et tous collaborer
sur une même base de projet:
https://github.com/5ika/Deer
![Capture d'écran du site](img/deer.png)
---
# Créer un projet git
```bash
# Je me déplace dans le dossier qui contient mon site
cd /home/tim/projets/Deer
# J'initialise git pour ce dossier
git init
# J'ajoute toutes les modifications à la zone de staging
git add -A
# Je crée un premier commit
git commit -m "🎉 First commit"
```
> Pas besoin de réaliser cette étape de votre côté.
> Elle est à faire une seule fois par la personne qui initialise le projet.
---
# Synchroniser le projet avec GitHub
Dans un premier temps, je crée un nouveau projet sur GitHub
puis je connecte mon dépôt local avec le dépôt distant.
```bash
# Je configure un dépôt distant (en utilisant l'adresse SSH plutôt que HTTP)
git remote add origin git@github.com:5ika/Deer.git
# Je push la branche locale 'main' sur le dépôt distant
git push -u origin main
```
Le dépôt local correspond au dossier sur ma machine tandis que le dépôt distant correspond au projet GitHub.
> Pas besoin de réaliser cette étape de votre côté.
> Elle est à faire une seule fois par la personne qui initialise le projet.
---
# Récupérer le projet sur sa machine
🫵 **À vous !**
En tant que collaborateur/trice, vous pouvez récupérer le code du site
sur votre machine en le *clonant*.
```bash
# Je me déplace sur ma machine à l'endroit où je place mes projets
cd /home/tim/projets
# Je récupère le projet commun depuis GitHub
git clone git@github.com:5ika/Deer.git
# Je me déplace dans le nouveau dossier contenant le code
cd Deer
```
---
# Exploration
Les commandes suivantes nous permettent de constater ce qui se passe:
```bash
# Lister les fichiers et dossiers présents dans le projet
ls -la
# Voir les commits déjà faits sur le projet
git log
# Voir les modifications pas encore dans un commit
git status
```
Ces commandes ne modifient rien. Elles servent juste à voir.
On peut en abuser 😁
---
Nous avons désormais toutes et tous une copie du même projet
sur notre machine avec un seul commit: celui que j'ai fait.
Maintenant, **comment ajouter du nouveau code dans notre projet ?**
Que se passe-t-il si chacun.e fait un commit et le push sur GitHub ? 🤔
---
![](img/git_parallel.png)
---
# Les branches
Comme les commits forment une suite ordonnée, on appelle un ensemble de commits une **branche**.
Le dernier commit correspond à la version la plus actuelle de notre code.
On nomme ce commit le *HEAD*. C’est le bout de la branche.
![](img/git_branch.png)
Par défaut, quand rien n'est précisé, les commits sont automatiquement ajoutés à la branche nommée *main*.
---
# Les branches
Il est possible de créer plusieurs branches pour paralléliser le travail sur une même base de code.
![](img/git_branches.png)
---
# Créer une nouvelle branche
La commande suivante crée une nouvelle branche `my-new-branch` à partir du dernier
commit de la branche `main`.
```bash
git checkout -b my-new-branch
```
Tous les commits qui seront faits ensuite seront placés sur cette nouvelle branche.
---
# Se déplacer entre les branches
Si on retire le `-b` dans la commande, on indique qu'on souhaite juste se déplacer
d'une branche à une autre.
```bash
# Je me trouve sur la branche `my-new-branch`
git checkout main
# Je me trouve maintenant sur la branche `main`
git checkout my-new-branch
# Je me trouve sur la branche `my-new-branch`
git checkout one-more-branch # Erreur car la branche `one-more-branch` n'existe pas
git checkout -b one-more-branch
# Je me trouve sur la branche `one-more-branch`
```
---
Pour voir sur quelle branche on se trouve, on peut utiliser la commande suivante:
```
git branch
```
Cela retourne par exemple:
```bash
* main
my-new-branch
one-more-branch
```
J'ai donc 3 branches actuellement et je me trouve sur la branche *main* (celle indiquée par un `*`).
---
# Supprimer une branche
Pour supprimer une branche locale:
```bash
# D'abord, je me déplace sur une branche autre
git checkout main
# Ensuite, je retire la branche
git branch -d one-more-branch
# On peut vérifier avec
git branch
```
---
# Pusher une nouvelle branche
Quand on crée un nouvelle branche, elle n'existe que localement dans un premier temps.
Comme un commit, il faut la *pusher* sur GitHub pour qu'elle soit visible par les autres devs.
```bash
git push -u origin my-new-branch
```
Ici, on indique que l'on veut pusher la branche `my-new-branch` vers le dépôt distant
nommé `origin`.
`origin` est un alias correspondant à notre projet commun sur GitHub.
---
🫵 À vous maintenant de **créer une nouvelle branche** à partir de la branche *main* et de la **pusher sur GitHub**.
Pour qu'on puisse s'y retrouver, nommer cette branche avec votre prénom, sans accent, sans majuscule et sans espace.
Il faut donc entrer deux commandes que l'on a vu dans les slides précédentes.
> Vous pouvez constater sur GitHub que votre branche s'y trouve bien pour vérifier.
---
# Faire un commit
Désormais, nous avons toutes et tous une branche à notre nom sur notre machine et sur GitHub.
Pour le moment, cette branche est identique à la branche *main* car nous n'avons pas fait de
commit dessus.
🫵 De votre côté:
1. Modifiez un petit peu le CSS ou le HTML du projet. Par exemple, changer la couleur de la tête du cerf ou un autre élément.
2. Créez un nouveau commit avec votre modification (sur votre branche, pas sur *main*)
3. Pusher ce commit sur GitHub
4. Constater sur GitHub que votre commit est présent **au niveau de votre branche**
---
# Faire un commit
![](img/git_steps.png)
---
# Code review: C'est quoi ?
Dans une équipe de développement, pour assurer une bonne **qualité de code**
et éviter que chaque dev porte seul.e la responsabilité du code qu'il ou elle produit,
il est courant de faire du *code review*.
Cela consiste à faire relire son code par une autre personne de l'équipe afin de
s'assure que le code est bien fait, les choix sont bons, les règles de l'équipe
sont respectées et que le cahier des charges est remplie.
> Dans certains projets, il y a une personne spécifique qui s'occupe de faire
> tout le code review. On la nomme *Mainteneur/euse"*.
---
# Code review: C'est quand ?
En tant que dev, nous faisons généralement du code review au moment où nous souhaitons
que les modifications faites sur notre branche soient ajoutées sur la branche principale
(*main*).
Pour ce faire, nous créons une **Pull Request** sur GitHub. Une Pull Request est la
manière de demander à l'équipe de dev de **merger** notre branche dans la branche principale.
Cette fonctionnalité permet à des centaines de devs de collaborer sur un projet, notamment
dans le monde de l'Open-Source.
=> [Exemple avec le projet Caroster](https://github.com/octree-gva/caroster)
---
# Créer une Pull Request
On crée une Pull Request directement sur l'interface de GitHub, dans le menu *Pull Requests* du projet.
On nous demande d'indiquer deux branches:
- Un branche **source** qui correspond à la branche que l'on souhaite merger.
- Une branche **destination** qui correspond à la branche qui doit recevoir les changements. Généralement, c'est *main*.
🫵 **À vous** de créer une Pull Requests au niveau du projet GitHub commun pour demander que l'on merge
votre branche dans la branche *main*.
Note: Repasser sur quelques Pull Requests faites pour montrer la page d'une Pull Request et le système de commentaires
---
Imaginez la situation suivante :
1. Alice a modifié la couleur de la tête du cerf ([ligne 101 de style.css](https://github.com/5ika/Deer/commit/be7f148d518c61fc77d18eab2154dcf6443be185#diff-b78be019f1dc6d57753ea900c3805b114cd53ab7c0db836cc081836df1b99b7aR101)) dans sa branche
2. Bob a également modifié la couleur de la tête à la même ligne dans sa propre branche
3. Les deux devs font une Pull Requests pour demander que l'on merge leur branche dans *main*
Est-ce que vous voyez un problème ? 🤔
---
# Conflits
Cette situation s'appelle un **conflit**:
Comme Alice et Bob travaillent en même temps, ils ne savent pas ce que l'autre fait.
Quand on demande à git de merger leur travail, le programme ne sait pas comment faire car la machine
est incapable de définir lequel des deux à le + raison.
Il est donc nécessaire de passer par une action humaine pour résoudre cela.
1. On merge une première branche dans *main* (disons, celle d'Alice). GitHub nous indique un conflit au niveau de la branche de Bob.
2. Bob merge *main* (avec les modifications d'Alice) dans sa branche à lui.
3. Bob résout les conflits entre l'état actuel de *main* et ses modifications puis push les corrections.
4. On merge la deuxième branche dans *main*
---
# Éviter les conflits
Les conflits git ne sont pas désirables et en tant que dev, on cherche à en avoir le moins souvent possible.
Pour cela, quelques règles à respecter:
- Pullez souvent pour mettre à jour votre copie locale avec ce qu'il y a dans le dépôt commun
- Il est préférable de faire beaucoup de petits commits avec peu de modifications que des commits avec énormément de modification: plus facile à débugger, à lire, à commenter et à revenir en arrière
- Avoir une bonne gestion de projet pour éviter que deux personnes de l'équipe travaillent sur la même chose en même temps
---
# Gestion de projet avec GitHub
Suivant l'approche Agile / SCRUM, GitHub propose des outils au niveau d'un projet pour organiser le projet autour du code.
Il y a notamment deux outils très utiles :
- Les **Issues** qui permettent de lister des fonctionnalités à développer ou déclarer des bugs/problèmes
- Les "**Projects**" qui permettent d'organiser les issues
---
# Issues
Les issues sont très utilisées. Très grossièrement, cela correspond à la liste des tâches de développement à faire
pour faire avancer un projet.
Leur utilisation est très flexible et chaque projet s'organise comme il le souhaite.
En exemple dans ce cours, nous allons voir une utilisation compatible avec une approche Agile/SCRUM.
---
# Étape 1: Créer les issues
En début de projet, on crée une issue pour chaque fonctionnalité qu'on souhaite implémenter
dans l'itération Agile à venir.
🫵 Par équipe de 2, créez une issue décrivant une fonctionnalité originale à faire.
Évitez d'avoir la même qu'un autre binôme.
> Pas besoin de voir trop compliqué. Cela doit pouvoir être fait rapidement, en quelques lignes de CSS, HTML ou JS.
Une fois l'issue créée:
- Assignez les deux membres du binôme au niveau du champ *Assignees*
- Assignez l'issue au *projet* "Développement du site web"
- Au niveau du [projet Développement du site web](https://github.com/users/5ika/projects/1), glissez votre issue dans la colonne "In Progress"
Note: Faire un exemple en //
---
# Étape 2: Créer une branche
À chaque fois qu'on implémente une nouvelle fonctionnalité, décrite dans une issue, on crée une nouvelle branche
dans le dépôt avec un nom clair. Ces branches qui concernent de nouvelles fonctionnalités s'appellent
des **feature branches**.
🫵 Créez une branche sur laquelle vous allez prochainement modifier le code pour implémenter la fonctionnalité décrite
dans votre issue. Vous pouvez donnez un nom clair à la branche. Par exemple `ajout-3e-oeil`.
> Un seul des deux membres du binôme doit faire le travail mais les deux doivent comprendre ce qui est fait.
---
# Étape 3: Développer !
🫵 Sur votre machine, développez la fonctionnalité sur la bonne branche et pushez le ou les commits sur
GitHub.
---
# Étape 4: Créer une Pull Request
🫵
1. Créer une Pull Request pour merger votre branche dans *main*
2. Assigner le membre du binôme qui n'a pas fait le développement à la PR (Pull Request)
3. Sur la page projet "Développement du site web", glissez votre issue dans "In Review"
---
# Étape 5: Code Review
🫵 La personne assignée à la PR peut maintenant relire le code et éventuellement faire des commentaires
si le travail est incomplet ou incorrect.
Une fois que tout est bon, elle peut *merger* la Pull Request pour l'ajouter à *main*. Puis, on peut
déplacer l'issue dans la colonne "Done" sur le projet.
> À cette étape, il y aura surement des conflits et des résolutions à faire. Nous allons gérer cela
> au cas par cas.
---
# Bravo 🎉
Nous avons développé ensemble une nouvelle version du site web.
Le travail pratique d'aujourd'hui n'est pas si loin de la réalité.
En général:
- La création des issues est faite de manière plus réflechie en impliquant le Product Owner, le client et d'autres
rôles
- Le code review est une étape qui prend du temps et qui peut nécessiter plusieurs aller-retours
---
# Liaison entre commits et issues
Quand on crée une issue, il lui est attribué un numéro.
Par exemple, l'issue https://github.com/5ika/Deer/issues/1 a obtenu le numéro `1`.
Quand on fait un commit, dans le *commit message* on peut ajouter `#1` pour indiquer
que ce commit est lié à notre issue. GitHub est ensuite capable de comprendre cela
et de faire des liens sur l'interface.
C'est facultatif mais c'est très utile quand on avance dans un projet afin de
garder un historique cohérent et de pouvoir s'y retrouver dans le futur.
Note: Faire une démonstration
---
# Bugs 🐛
Les bugs font parties intégrantes du développement.
Ils peuvent être trouvés par différentes personnes: devs, testeurs, clients, utilisateurs/trices,
contributeurs/trices,...
Les issues servent également à relever et gérer les bugs: quand une personne rencontre un souci,
elle peut créer une issue détaillant son bug.
On peut ensuite gérer un bug comme une feature avec notre gestion de projet.
La modification du code relatif est faite sur une *fix branch* qui sera aussi soumise à
travers une Pull Request.
Note: Montrer des exemples d'issues bug dans un projet Open-Source sur GitHub
---
![Exemple de mauvaise issue de bug](img/bug_bad.png)
---
# Relever un bug
Quand on crée une issue de bug, il est important d'être le plus clair possible pour
faciliter la résolution.
Il est important de fournir:
- Une description claire du bug
- Les étapes permettant de **reproduire** le problème
- Une description de ce qui est attendu
- Des captures d'écran ou une vidéo pour montrer
[Exemple de bug dans le projet Strapi](https://github.com/strapi/strapi/issues/16539)
---
Sur un projet git, tout le monde est libre de créer des branches et les nommer comme il ou elle veut.
Quand on travaille à plusieurs et/ou sur une longue période, cela devient vite chaotique 💥.
![Branches chaos](img/branches_chaos.png)
---
En équipe, il faut donc se mettre d'accord sur une manière de gérer les branches afin
de rester efficaces.
On appelle cela un **modèle de branche** 🌳
---
Le modèle de branche le plus utilisé est le *Feature Branch Worflow*.
![](https://wac-cdn.atlassian.com/dam/jcr:09308632-38a3-4637-bba2-af2110629d56/07.svg?cdnVersion=1004)
... et c'est celui que nous avons déjà appris précédemment.
C'est le fait d'utiliser une autre branche que la principale pour faire des modifications:
feature branch, fix branch,...
> Ce modèle est la base des autres modèles, il est donc important de bien le comprendre.
> [Cette documentation](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) est
> particulièrement bien faite pour comprendre (en anglais).
---
# Feature Branch Worfklow
1. Je crée une branche annexe (feature ou fix) dans laquelle je fais mes modifications
2. Je crée une Pull Request pour demander que l'on merge ma branche dans *main*
3. Une autre personne vérifie mon code et je l'affine si nécessaire
4. L'autre personne valide la Pull Request et les commits de ma branche sont ajoutés à *main*
5. Je supprime ma branche annexe (si ce n'est pas fait automatiquement)
---
# L'ancien modèle 'Gitflow'
![Ancien modèle Gitflow](https://wac-cdn.atlassian.com/dam/jcr:34c86360-8dea-4be4-92f7-6597d4d5bfae/02%20Feature%20branches.svg?cdnVersion=1004)
---
# Et dans les projets Open-Source ?
Dans les projets Open-Source, il n'y a pas une équipe précise qui travaille sur le code car
tout le monde peut participer et proposer des modifications.
**Mais comment faire pour autoriser tout le monde à modifier le code sans perdre le contrôle de son app ?**
---
# Fork ! 🍴
GitHub nous permet de *forker* des projets.
"Forker" signifie *copier tout le projet et son historique vers son propre espace*.
En forkant un projet, j'obtiens une copie de tout le code de ce projet sur laquelle
j'ai le droit de faire ce que je veux.
Note: Faire un exemple de fork de Caroster
---
# Forking workflow
Le forking workflow est un modèle de branche très semblable au feature branch workflow
mais considère des branches qui ne sont pas dans le même projet.
---
Par exemple, je souhaite proposer une modification de code au projet Strapi.
Voilà les étapes qui je réalise:
1. Je fork le [dépôt de Strapi](https://github.com/strapi/strapi) pour obtenir [ma propre copie](https://github.com/5ika/strapi)
2. Sur la branche *main* de mon dépôt, je push des commits
3. Une fois que je suis satisfait des modifications, je crée [une Pull Request](https://github.com/strapi/strapi/pull/14280) au niveau du dépôt officiel de Strapi pour demander
aux devs de Strapi de merger la branche *main* de mon dépôt (`5ika:main`) dans la branche *main* du dépôt officiel (`strapi:main`)
Ensuite, un mainteneur de Strapi va regarder ce que je propose comme modification et me faire des commentaires.
Selon ses retours, je vais ajuster mon code jusqu'à ce que ça corresponde aux attentes du projet officiel
jusqu'à ce que la branche soit mergée.
---
🫵 Forkez le projet [Deer](https://github.com/5ika/Deer/) avec votre utilisateur GitHub et remarquez ce qui fait.
Vous pouvez maintenant modifier le code comme vous voulez, sur les branches que vous voulez car
vous êtes sur une copie du projet principal.
---
🫵 Faites un commit sur la branche *main* de vôtre copie de dépôt Deer avec une petite modification de code
puis créez une Pull Request au niveau du [dépôt principal](https://github.com/5ika/Deer/) pour me soumettre
votre proposition de changement.
---
Des questions concernant git et l'utilisation des branches ❓
---
# Oh Shit, Git !?! 💩
Git est puissant et très élastique mais il peut arriver qu’on se perde dans son utilisation et dans les pires des cas, qu’on perde des modifications.
Un site référencie les plus grosses mauvaises manipulations et comment les résoudre:
http://ohshitgit.com/