Git GitLab EE
Commit / Merge / Rebase / Workflow / Squash

Ordre du jour
• Intro
• Merge / rebase
• Workflow
• Rebase onto
• Rebase interactif et Squash
• Bonnes pratiques
• Conclusion
Le but de ce point est de parler GIT, certaines de ses principales notions et du Workflow à adopter.
Construire ensemble le workflow de demain !
Définition de Git
Svn vs Git
Définition de repository / Working Area/Staging Area
Définition de local repository / remote repository
Ce qui ne va pas être abordé dans cette présentation !
Concepts
Basiques
Le commit !
Le commit est l'unité de base de Git pour construire une chronologie d'un projet.
Définition
Le commit !
Le commit est l'unité de base de Git pour construire une chronologie d'un projet.
Définition
Un commit est considéré comme “Un Snapshot ou milestones” de l'état d'un projet Git.
Le commit !
Le commit est l'unité de base de Git pour construire une chronologie d'un projet.
Définition
Un commit est considéré comme “Un Snapshot ou milestones” de l'état d'un projet Git.
La “notion du temps est primordiale” dans la définition d'un commit.
Commit anatomie
sha1(
commit date
commit message
committer
author
author date
tree
)
Un commit = {} metadatas + project tree = un sha unique
La date du commit
Le message du commit
La personne qui commit
Le premier auteur du commit
Date de création du commit
Le tree de l'ensemble du projet
Commit anatomie
Un commit = {} metadatas + project tree = un sha unique
La date du commit
Le message du commit
La personne qui commit
Le premier auteur du commit
Date de création du commit
Le tree de l'ensemble du projet
sha1(
commit date
commit message
committer
author
author date
tree
)
Commit tree - Data Model

Merge & Rebase
Merge vs Rebase
Le but du merge est de fusionner les travaux de deux branches.
Le merge est une opération non-destructive, elle n'altère pas l'état des commits de la branche mergée.
Définition
Merge fast-forward - limites
//Avant | //Après
A----B----C (develop/HEAD) | A----B----C----1----2 (develop/HEAD, project)
\ |
1-----2 (project) | Le merge est une opération polluante à cause du commit créé sur la branche cible !
Il existe principalement deux méthodes de merge
Merge no-fast-forward
//Avant | //Après
A----B----C----D----E (develop/HEAD) | A----B----C----D----E----F (develop/HEAD)
\ | \ /
1-----2 (project) | 1-----2 (project)Avantages
-
Commits avec SHA unique
-
Simple à revert un merge
-
Gestion simplifiée des conflits
-
Préserver l'historique
Inconvénients
-
Pollution de l'historique
-
Effet guitare sur l'historique
Les + et - du merge
Le but du rebase est de changer la base d'une branche.
Le rebase est une opération destructive - elle altère l'état des commits de la branche rebasée.
Définition
Le rebase est une opération non-polluante !
Il existe plusieurs méthodes de rebase. (Rebase sans paramètres, rebase interactif, rebase onto…etc.)
Exemple de rebase
//Avant | //Après
A----B----C----D (develop/HEAD) | A----B----C----D----$1----$2 (develop/HEAD,project)
\ |
1---- 2 (project) |L'opération du rebase est souvent utilisée pour nettoyer l'historique des branches Git pour le rendre linéaire afin d'avoir une meilleure lisibilité.
$: indique le changement de SHA des commits.
Avantages
-
Rejouer les commit un par un
-
Modifier/supprimer des commit en cours du rebase
-
Aucune pollution de l'historique
-
Historique linéaire et lisible
-
Incite les contributeurs à nettoyer assez souvent l'historique des branches avant de les merge
Inconvénients
-
Modifie les SHA des commits
-
Difficile de revert un rebase
-
Le push force après rebase
Les + et - du rebase
merge vs rebase
En utilisant Git, la question qui se pose souvent à chaque début de projet :
Devons-nous fonctionner avec des merges ou des rebases ?
La réponse n'est surtout pas booléenne !
Il n'existe pas de solution magique adaptée à toutes les situations.
Ce qui peut aider à prendre une décision :
-
L'historique Git doit être concis, claire et facilement lisible !
-
Les pratiques doivent être homogènes au sein d'une équipe
-
Définir et suivre les règles du workflow de contribution
La Gestion de L'historique GIT
N'est pas
Importante
La Gestion de L'historique GIT
N'est pas
Est très Importante
À garder à l'esprit que l'historique Git est une forme de documentation technique du code.
Note!
Notre nouveau
Workflow Git
La définition d'un Workflow Git unique, pour l'ensemble des contributeurs, est indispensable pour garantir une meilleure collaboration et installer
des règles de contribution identiques pour tous
-
Les commits directs sur la branche master sont interdits
-
Les push force sur master sont désormais bloqués
-
L'utilisation des MR est obligatoire
-
Les rebase sont obligatoires avant d'accepter toute MR
-
Tous les merge sont en (--no-ff), sauf le merge de develop sur master
-
Seule la branche develop peut être merge sur master (en ff)
-
La branche develop est rebase sur master à chaque release - cf. process de release
Les lignes directives du workflow
-
Les branches projet sont créées à partir de develop
-
Les branches feature sont créées à partir des branches projet
-
Le premier commit sur la branche projet doit être facilement repérable et identifiable. (souvent, c'est celui du changement de version) !
-
Nouvelles règles de nommage des branches - cf. doc.
-
Nouvelle sémantique des messages des commits - cf. doc
Les lignes directives du workflow
Utilisation des MR
-
Lors du merge des travaux d'une branche feature avec la branche projet
-
Lors du merge d'une sous-branche d'un projet avec la branche projet
-
Lors du merge de la branche projet avec la branche develop
-
Lors du merge d'une branche mco (ou toute autre branche de maintenance) avec la branche develop
-
Lors du merge d'une branche hotFix avec la branche develop
Les lignes directives du workflow
La MR ne doit pas être accepté par le contributeur qui la créé.
Dans le nouveau GitLab EE, il ne sera pas possible d'accepter une MR si la branche source n'est pas rebase sur la branche destinataire.
Utilisation des merge & rebase
Les lignes directives du workflow
-
Les deux méthodes, merge et rebase, seront utilisées dans notre workflow
-
À chaque MR, un rebase est effectué suivi d'un merge
-
Les rebase & merge, dans le cadre d'une MR, sont effectués via l'interface
-
Le contributeur effectue un rebase localement seulement si GitLab n'arrive pas à rebase automatiquement.
-
Le rebase de develop sur master ne doit pas se faire via l'interface (suivre le process de release)
Dans le nouveau GitLab EE, le merge et rebase, lors d'une MR, seront effectués automatiquement via l'UI.
GitLab EE donne la main au contributeur s'il n'arrive pas à prendre une décision et/ou résoudre des conflits.
Quelques exemples !
Merge - Rebase / master - develop - feat
Workflow branche feat -> projet

Comment merge* la branche feature avec project ?
* Le merge doit passer par une MR


Cas 1
Cas 2
Workflow branche feat -> projet


Cas 1
Cas 2
Workflow branche feat -> projet
Workflow branche feat -> projet


merge sans rebase
rebase avant merge(--no-ff)

Workflow branche projet -> develop
Comment merge* la branche project avec develop ?
* Le merge doit passer par une MR
Cas 1
Cas 2


Workflow branche projet -> develop
Cas 1
Cas 2


Workflow branche projet -> develop
Cas 1
Cas 2


Workflow branche projet -> develop
Cas 1
Cas 2


Workflow branche projet -> develop

merge sans rebase
rebase avant merge (--no-ff)

Workflow branche projet -> develop

Workflow branche develop -> master
Comment merge* la branche develop avec master ?
* Le merge ne doit pas passer par une MR
Workflow branche develop -> master
Cas 1
Cas 2


Cas 3

Cas 1
Cas 2


Cas 3

Workflow branche develop -> master
Cas 1
Cas 2


Cas 3

Workflow branche develop -> master
Cas 1
Cas 2


Cas 3

Workflow branche develop -> master
Cas 1
Cas 2


Cas 3

Workflow branche develop -> master



merge sans rebase
rebase avant merge (--ff)
rebase avant merge (--no-ff)
Workflow branche develop -> master
Rebase --onto
Mieux maitriser son rebase !
Le rebase --onto facilite les rebase, même les plus complexes, sans subir les conséquences d'un rebase standard.
Il offre également une certaine souplesse dans la réorganisation des commits (supprimer, renommer, réordonner...etc.)
Définition
Dans certaines situations et avec une compréhension ambiguë du concept, l'action du rebase peut s'avérer complexe à réaliser.
Exemple
//État initial
A----B----C (master/ HEAD)
\
D---...---Y---Z (develop/HEAD)
\
1---2---3 (project/HEAD)Situation
Dans certaines situations et avec une compréhension ambiguë du concept, l'action du rebase peut s'avérer complexe à réaliser.
Exemple
//État initial
A----B----C (master/ HEAD)
\
D---...---Y---Z (develop/HEAD)
\
1---2---3 (project/HEAD)$: indique le changement de SHA des commits.
Situation
//Rebase develop sur master
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
x (/Ce lien est perdu*/)
1---2---3 (project/HEAD)Dans certaines situations et avec une compréhension ambiguë du concept, l'action du rebase peut s'avérer complexe à réaliser.
Exemple
//État initial
A----B----C (master/ HEAD)
\
D---...---Y---Z (develop/HEAD)
\
1---2---3 (project/HEAD)$: indique le changement de SHA des commits.
Situation
//Rebase develop sur master
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
x (/Ce lien est perdu*/)
1---2---3 (project/HEAD)//Rebase project sur develop (sans rebase --onto)
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
...\... (Chercher le plus ancien parent commun pour rebase*/)
1----2---3 (project/HEAD)Syntaxe du rebase --onto
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Syntaxe du rebase --onto
//Avant | //Après
A----B----C----D (develop) | A----B----C----D (develop)
\ | \
1----2 (project/HEAD) | $1----$2 (project/HEAD)
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Exemple 1 - Rebase onto standard
$: indique le changement de SHA des commits.
Syntaxe du rebase --onto
$ git checkout project
$ git rebase --onto D C
//Avant | //Après
A----B----C----D (develop) | A----B----C----D (develop)
\ | \
1----2 (project/HEAD) | $1----$2 (project/HEAD)
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Exemple 1 - Rebase onto standard
$: indique le changement de SHA des commits.
Syntaxe du rebase --onto
$ git checkout project
$ git rebase --onto D C
//Avant | //Après
A----B----C----D (develop) | A----B----C----D (develop)
\ | \
1----2 (project/HEAD) | $1----$2 (project/HEAD)
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Exemple 1 - Rebase onto standard
//Avant | //Après
A----B----C----D----E (develop) | A----B----C----D----E (develop)
\ | \
1----2----3----4 (project/HEAD) | $3----$4 (project/HEAD)Exemple 2 - Rebase onto avec suppression de commits
$: indique le changement de SHA des commits.
Syntaxe du rebase --onto
$ git checkout project
$ git rebase --onto D C
//Avant | //Après
A----B----C----D (develop) | A----B----C----D (develop)
\ | \
1----2 (project/HEAD) | $1----$2 (project/HEAD)
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Exemple 1 - Rebase onto standard
$ git checkout project
$ git rebase --onto D 2
//Avant | //Après
A----B----C----D----E (develop) | A----B----C----D----E (develop)
\ | \
1----2----3----4 (project/HEAD) | $3----$4 (project/HEAD)Exemple 2 - Rebase onto avec suppression de commits
$: indique le changement de SHA des commits.
Syntaxe du rebase --onto
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Exemple 3 - Situation abordée précédemment
$: indique le changement de SHA des commits.
//Rebase project sur develop (sans rebase --onto)
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
...\... (Chercher le plus ancien parent commun pour rebase*/)
1----2---3 (project/HEAD)//Rebase onto project sur develop
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
\
$1----$2---$3 (project/HEAD)Exemple 3 - Solution
Syntaxe du rebase --onto
git rebase --onto <newparent> <oldparent> <feature-branch/until> |
Exemple 3 - Situation abordée précédemment
$: indique le changement de SHA des commits.
//Rebase project sur develop (sans rebase --onto)
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
...\... (Chercher le plus ancien parent commun pour rebase*/)
1----2---3 (project/HEAD)$ git checkout project
$ git rebase --onto $Z CURRENT_PARENT (ou $git rebase --onto develop CURRENT_PARENT)
//Rebase onto project sur develop
A----B----C (master/HEAD)
\
$D---...---$Y---$Z (develop/HEAD)
\
$1----$2---$3 (project/HEAD)Exemple 3 - Solution
CURRENT_PARENT: est le commit qui vient juste avant le premier commit de la branche project.
Les squash
Meld commits
Le squash consiste à regrouper n commits en 1 commit pertinent, compréhensible et cohérent.
Le but du squash est de rendre l'historique Git lisible, claire et pertinent.
Définition
Exemple d'historique Git
* e0d1c94 - 2022-09-30 (14 seconds)- feat(metier) sql create report request OK !!! (HEAD -> master)
* db37fe2 - 2022-09-30 (62 seconds)- feat(metier) oups!!! update 2 sql create report request
* 4f5e97f - 2022-09-30 (2 minutes)- feat(metier) update sql create report request
* 683d34b - 2022-09-30 (2 minutes)- feat(metier) add sql create report request
* 9ff0e10 - 2021-03-24 (1 year, 6 months)- chore(master) add .gitignore regenerate-*.batSituation
Lancer un rebase interactif (ou le faire sur IDE, autres outils..)
$ git rebase -i HEAD~4 (ou git rebase -i 9ff0e10)Suivre les étapes indiquées - cf. doc.
Résultats
* 78fd32c - 2022-09-30 (2 minutes)- feat(metier) add sql create report request (HEAD -> master)
* 9ff0e10 - 2021-03-24 (1 year, 6 months)- chore(master) add .gitignore regenerate-*.batLes bonnes pratiques
-
Effectuer souvent des rebases des branches courantes
-
Utiliser des messages de commit lisibles, cohérents et assez succincts
-
Réduire le nombre de commits
-
Nettoyer l'historique Git des branches avant d'ouvrir des MRs
-
Utiliser les squash
-
Utiliser le rebase --onto
-
Autres recommandations dans la future documentation
Certaines bonnes pratiques peuvent faciliter au quotidien la gestion du versioning des différents projets.
À noter
Questions ?
Si non, à vous de jouer !
R.O.T.I
Return On Time Invested





Évaluation, en temps réel, du retour sur le temps investi
Inutile : Une perte de temps, j'ai rien gagné, rien appris
Utile : Mais ça ne valait pas à 100% le temps investi
Moyen : Je n'ai pas perdu mon temps, sans plus !
Bon : J'ai gagné plus que le temps que j'y ai passé
Excellent : J'ai appris. Ça valait bien plus que le temps que j'y ai passé
Merci !
Git/GitLab
By Lyes CHIOUKH
Git/GitLab
Plongez au cœur de Git et GitLab EE à travers une présentation synthétique qui allie théorie et retours d’expérience. Vous y découvrirez les bases indispensables du versioning, la différence entre merge et rebase, ainsi que leurs usages stratégiques dans un workflow collaboratif. Des techniques avancées comme le rebase --onto, le squash ou le rebase interactif sont présentées pour aider à maintenir un historique propre et pertinent. L’accent est mis sur des règles claires, des pratiques homogènes et une gestion efficace des branches pour fluidifier le travail en équipe. Ce contenu, volontairement condensé, laisse de côté certaines notions plus poussées qui pourront être approfondies ultérieurement et sur demande.
- 239




