Conserver un historique git propre

Le 4 Mars 2016
shell git

Le plus simple, c'est d'apprendre à utiliser git rebase et de configurer git pour faire ses git pull en utilisant plutot un rebase qu'un merge.

Voila comment configurer git : git config --global pull.rebase true

Pas convaincu ?

Exemple simpliste

Ça commence connement… Je git push quelques commits et le serveur m'envoit péter :

1
2
3
4
5
6
7
8
$ git push
To git@gitlab.com:debona/debona_fr.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to 'git@gitlab.com:debona/debona_fr.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Voila ! C'est la base, quelqu'un a commit avant moi. Nous sommes donc dans cette situation (mes commits sont en orange) :

Modification à récupérer

Si je fais un git pull, par défaut git va me créer un commit de merge. Voila ce qu'on va obtenir (commit de merge en gris) :

Commit de merge

Ce commit de merge n'apporte strictement rien à l'historique du code. Pire encore, on peut vite assister à un festival des commits de merge lorsqu'on travail à plusieur sur la même branche. Bref, c'est une véritable pollution de l'historique du dépot.

En choisisant de résoudre ses pull par un rebase, on demande à git de rejouer nos commits par dessus ceux récupérés. Cela permet de conserver un historique linéaire :

Historique réécrit

Et comment ça ce passe quand il y a un conflit ?

Personnellement, je préfère gérer les conflits lors d'un rebase que lors d'un merge. Quand on rencontre un conflit lors d'un gros merge on est vite noyé sous la tonne de modifications. L'avantage du rebase c'est qu'en rejouant nos commits, on va rélger les conflits en plusieurs étapes.

Bien sûr, il faut d'abord apprendre à utiliser git rebase avant de se lancer le pull rebase.

NB

Il ne faut pas voir cette astuce comme un git-flow. Il s'agit simplement d'une manière de gérer les pull différente de celle par défaut. Pour moi, c'est un complément indispensable. Quelque soit le git-flow suivi, il arrivera un moment ou un dévelopeur fera un pull sans avoir la dernière version. Il aura alors l'opportunité de polluer l'historique, ou de conserver un historique linéaire.