On utilise Git tous les jours. Cependant, savez-vous comment enregistrer votre travail sans le comiter? Ou encore comment nettoyer votre historique de commits? C’est quoi la différence entre un merge et un rebase? Ou encore comment faites-vous le distinguo entre un tag et une branche de release? La dernière fois qu’un collègue vous a parlé d’un pic à cerise, qu’en avez-vous pensé? Pourquoi votre collègue, sur GitHub, a-t-il fait un tag “Verified” sur ses commits et pas vous?
Cette présentation s’adresse à tous ceux utilisant Git avec une interface graphique ou en ligne de commande. On discutera des usages de base de Git, et via des cas pratiques, on verra comment utiliser Git pour résoudre nos problèmes.
Après une courte introduction sur comment utiliser Git pour aider vos collègues ou la communauté qui travaille sur le même projet, nous aborderons comment Git peut vous aider sur votre ordinateur à régler des problèmes courants.
À la fin de la présentation, vous aurez appris des commandes Git bien pratiques au quotidien et vous laisserez un historique propre dans vos projets.
7. Commit
Représente un changement
Possède un , plusieurs ou aucun commit parent
Est immutable – mais peut être modifié
Représenté par un Hash unique - 57a37d7d63147692dc959125e1f…
C1 C2
9. Tag
Représente un commit nommé
Est immutable
Utilisé pour définir des versions
C1 C2
C3 C4
feat1
main
v1.0.0
v1.0.1
10. Merge
Deux types : Fast Forward (ff) et 3-Way-Merge/recursive
Ramène une branche dans une autre
C1 C2
C3 C4
feat1
main
11. Merge – Fast Foward
Historique linéaire
Pas de conflit
C1 C2
C3 C4
feat1
main*
❯ git merge feat1
Updating
57a37d7..b667924
Fast-forward
12. Merge - Recursive
Historique non linéaire
Conflits possibles
Ajoute un commit de merge
❯ git merge feat1
Merge made by the
'recursive' strategy.
C1 C2
C3 C4
feat1
main*
CM
13. Merge - Recursive
cm possède deux parents
cm contient la résolution de conflits
au besoin
Commits de feat1 ajouté au dessus
de main
* commit cm (HEAD -> main)
| Merge: c2 c4
| |
| | Merge branch 'feat1’
| |
| * commit c4 (feat1)
| |
| * commit c3
| |
* | commit c2
|/
* commit c1
❯ git log --graph
14. Rejouer les commits précédents par rapport à une source
- Une branche
- Un commit
De manière interactive ou automatique
Peut être long et fastidieux
Garde un historique linaire vs un commit de merge
Rebase
15. Rebase – Synchroniser deux branches
c3 et c4 existent encore
Historique linéaire
Merge dans main linéaire
❯ git rebase main
Successfully rebased and
updated refs/heads/feat1.
C1 C2
C3 C4
feat1*
main
C3’ C4’
16. Merge ou Rebase pour synchroniser des branches ?
Dépend du contexte!
Merge Rebase
❌ Historique non linéaire ✅ Historique linéaire
✅ Résolution des conflits une seule fois ❌ Résolution des conflits pour chaque
commit de notre branche
✅ Plus rapide quand les deux branches
ont beaucoup de commits de différence
❌ Peut être très lent et compliqué
quand il y a beaucoup de commits d’écart
❌ L’historique de la branche de
destination ne doit pas être modifiée
18. Le titre du commit est à l’impératif
Commence par un verbe
Décrit le changement
Est court
- Mais peut posséder une description plus longue
Se termine sans ponctuation
Commence par une majuscule
Suit la convention de l’équipe / du projet
Commit – bonnes pratiques
19. Rebase – Nettoyer l’historique
Supprimer un commit
❯ git rebase -i c1
drop 0763ecd c2
pick 58ebee4 c3
C3’
C1
feat1
C3
C2
20. Rebase – Nettoyer l’historique
Regrouper des commits en un (squash)
❯ git rebase -i c1
pick 0763ecd c2
squash 58ebee4 c3
C3’
C1
feat1
C3
C2
21. Rebase – Nettoyer l’historique
Re-ordonner des commits
❯ git rebase -i c1
pick 58ebee4 c3
pick 0763ecd c2
C3’
C1
feat1
C3
C2 C2’
22. Modifier un commit
- Modifier le contenu
- Modifier le message
❯ git rebase -i c1
edit 0763ecd c2
pick 58ebee4 c3
Stopped at c2... c2
You can amend the commit now, with
git commit --amend '-S'
Once you are satisfied with your
changes, run
git rebase –continue
Rebase – Nettoyer l’historique
23. Dépend du contexte!
Merge ou Squash et Rebase pour ramener notre
travail dans la branche principale?
Squash & Rebase Merge
D’une branche de travail à une
branche principale
D’une branche principale à une autre
Rebase seulement quand les commits
sont propres et font du sens seul
Garder tous les commits de
l’historique
Garde un historique linéaire Évite les conflits lors d’un fix
24. Ramener les changements d’une branche dans une autre
Possibilité de valider (review) les changements
Possibilité d’automatisation (Continuous Integration)
Concept de Pull Request (PR)
25.
26. Récupérer un commit d’une autre branche
Sauvegarder des changements sans créer un commit
Restaurer une branche modifiée (Rebase ou autre)
Cas pratiques
27. Récupérer un commit d’une autre branche
Cherry-pick
❯ git cherry-pick c5
⚠ Ne pas squasher le commit avec un autre commit
C1 C2
C3 C4
feat1*
main C5
feat2
C5’
28. Lors d’un pull, rebase ou autres opérations
Lors d’un changement de branche
Tester quelque chose
=> git stash
Sauvegarder des changements sans créer un commit
29. Sauvegarder localement
Un peu comme un commit
Peut en avoir plusieurs
Git stash
❯ git stash list
stash@{0}: WIP on dep: 68602dd8 fix dependency
for migration app
stash@{1}: WIP on subscriptions: 59dfad10 try
to bypass ubuntu mirror
stash@{2}: WIP on add-pagination: c8441181 WIP
stash@{3}: WIP on develop: bf3312f5 Add
simpleHealthcheckController
31. Git stash – commandes utiles
❯ git diff stash@{1}
❯ git stash pop
❯ git stash pop stash@{3}
❯ git stash drop
32. Restaurer une branche modifiée
Revenir en arrière sans rebase
C1 C2
C3 C4
feat1*
main
❯ git reset c3
33. Restaurer une branche modifiée
Annuler un rebase ❯ git reset c4
C1 C2
C3 C4
feat1*
main
C3’ C4’
34. Git reflog
Journal de toutes les opérations faites sur les références
Expire après 90 jours (default)
35. e01311c (HEAD -> feat1) HEAD@{0}: rebase (finish):
returning to refs/heads/feat1
e01311c (HEAD -> feat1) HEAD@{1}: rebase (pick): c4
bde4c72 HEAD@{2}: rebase (pick): c3
ffaf854 (main) HEAD@{3}: rebase (start): checkout main
c84f051 HEAD@{4}: commit: c4
a1b26cd HEAD@{5}: commit: c3
b9c944f HEAD@{6}: checkout: moving from main to feat1
ffaf854 (main) HEAD@{7}: commit: c2
b9c944f HEAD@{8}: checkout: moving from feat1 to main
b9c944f HEAD@{9}: checkout: moving from main to feat1
b9c944f HEAD@{10}: commit (initial): c1
❯ git reflog show
36. Restaurer une branche modifiée
e01311c (HEAD -> feat1) feat1@{0}: rebase
(finish): refs/heads/feat1 onto
ffaf8547c6fa92ee2dec5e5ebfd594d7dede70b5
c84f051 feat1@{1}: commit: c4
a1b26cd feat1@{2}: commit: c3
b9c944f feat1@{3}: branch: Created from HEAD
❯ git reflog show feat1
Dernière opération avant le rebase
Filtre les entrées
37. Restaurer une branche modifiée
Annuler un rebase ❯ git reset feat1@{1}
C1 C2
C3 C4
feat1*
main
C3’ C4’
38. Restaurer une branche modifiée
Mais j’ai fait un commit après mon rebase
C1 C2
C3 C4 feat1*
main
C3’ C4’ C5
39. Restaurer une branche modifiée
Pas de problème, on reflog, reset et cherry-pick !
2b749ef (HEAD -> feat1) feat1@{0}: commit: c5
5656daa feat1@{1}: rebase (finish):
refs/heads/feat1 onto
c34eabdb1707a7a26889ea01dff20187be8b41c0
e9c810d feat1@{2}: commit: c4
cdaf3fe feat1@{3}: commit: c3
❯ git reflog show feat1
❯ git reset feat1@{2}
Dernière opéra2on avant le rebase
40. Restaurer une branche modifiée
Pas de problème, on reflog, reset et cherry-pick !
e9c810d (HEAD -> feat1) feat1@{0}: reset:
moving to feat1@{2}
2b749ef feat1@{1}: commit: c5
❯ git reflog show feat1
❯ git cherry-pick feat1@{1}
Le commit manquant
41. L’un n’empêche pas l’autre
Librairie : toujours avoir un tag par version
> Suivre le semver (x.y.z)
> Les tags sont immutables
>> NE JAMAIS SUPPRIMER UN TAG ET LE RECRÉER AVEC LE MÊME NOM <<
Application : une branche de release simplifie la gestion des hotfixs
Branche de prod vs tag ?