Gérer les bugs

Introduction

En parallèle de la gestion de projet standard nous avons souvent à gérer la maintenance des projets.

Pour nous organiser efficacement il nous faut distinguer les bugs des revues fonctionnelles :

  • Revue fonctionnelle (non urgent) : traitée comme une feature branch standard ou au sein d’une branche existante;

  • Bug critique et urgent : nécessite une organisation dédiée, à part du flux standard, mais sur le modèle du feature branching. Le terme souvent employé à cet effet est hotfix (en français correctif à chaud passe moins bien).

L’isolement des corrections sur des branches nous aidera à :

  • traiter nos corrections en plusieurs commits si cela s’avère nécessaire ;

  • utiliser les mécanismes de validations nous permettant de nous assurer de la qualité des corrections ;

  • favoriser la lecture de notre historique ;

  • extraire des correctifs pour les appliquer ailleurs.

../../../../_images/workflows_fixes.png

Workflow fixes

Testflow1 création de versions

Récupération des correctifs avec git cherry-pick

Une fois nos correctifs traités nous devrons parfois reporter certains d’un endroit à un autre.

Git propose deux approches à cet effet :

  • l’extraction (git format-patch) pour envoi éventuel par e-mail (git sendmail) et application ultérieure sur notre projet ou un autre (git apply/git am);

  • la duplication instantanée sur un même projet avec git cherry-pick

Nous discuterons ici de la seconde approche uniquement, la première étant rarissime dans des workflows usuels centrés sur les pull/merge requests et prédatant l’existence de systèmes type GitHub, GitLab, etc.

Elle reste toutefois très prisée dans les cercles du développement système bas niveau, car elle se prête un peu mieux aux signatures numériques et à leur outillage historique.

Si vous êtes intéressé par la première, nous vous recommandons de parcourir cette section du Git book .

Si nous nous inscrivons dans une logique de versions actives multiples comme vu précédemment avec une release-2 et une release-3, il n’est pas impossible qu’un problème sur la version 3 ne soit également présent sur la version 2 (ou inversement selon l’endroit où le bug est détecté en premier lieu). On aimerait alors reporter un ou plusieurs correctifs sans devoir reproduire le code manuellement.

On commencera alors par créer une branche de correction depuis l’endroit où l’on a détecté le bug (disons 3.1.0) pour y effectuer nos commits de correction.

../../../../_images/workflows_fixes_ex1.png

Workflow fixes 3.1.0

Une fois nos correctifs apportés, validés, fusionnés dans release-3 et tagués ( 3.1.1 ) pour être déployés, nous nous apercevons que le bug concerné est également présent dans notre version 2.

Report des modifications dans release-2

Nous souhaitons alors reporter les correctifs dans release-2.

 1# Création d'une branche hotfix-2.2.1 à partir de la branche 2.2.0
 2git checkout -b hotfix-2.2.1 2.2.0
 3# Application des changements dans hotfix-2.2.1
 4git cherry-pick -x commit-c
 5# finalisation via une « pull request » ou manuellement :
 6# on se place dans la branche 2.2.0
 7git checkout 2.2.0
 8git merge --no-ff hotfix-2.2.1
 9git tag 2.2.1
10# Suppression de la branche hotfix-2.2.1
11git branch -d hotfix-2.2.1
../../../../_images/workflows_fixes_ex2.png

Workflow fixes release 2.2.0

Report des modifications dans master

De même que pour la 3 nous passons à travers nos étapes de validation pour aboutir à un déploiement de cette nouvelle version 2.2.1.

Il en va de même pour un éventuel report sur notre branche de développement principale master :

1 # Création de la branche fix-master-3.0.0 à partir de master
2     git checkout -b fix-master-3.0.0 master
3     # Application des changements dans hotfix-2.2.1
4     git cherry-pick -x commit-c
5     # finalisation via une *pull request* ou manuellement :
6     git checkout master
7     git merge --no-ff fix-master-3.0.0
8     # Suppression de la branche provisoire
9     git branch -d fix-master-3.0.0

On se retrouve alors avec une version de master à jour et sur laquelle on pourra mettre à jour les branches en cours de développement si celles-ci nécessitent l’intégration des correctifs, grâce à la commande git rebase.

Report des modifications dans feat-subject-1 (git rebase)

L’exemple suivant montre une branche fonctionnelle en cours de développement nommée feat-subject-1 basée sur le tag de version 3.0.0 de master.

Cette dernière ayant évolué suite à l’application d’un correctif, nous rebasons feat-subject-1 sur master pour bénéficier de la mise à jour:

git rebase master feat-subject-1
../../../../_images/workflows_fix_feat_rebase.png

git rebase master feat-subject-1

Si la stratégie de rebase ne nous satisfait pas , nous pouvons à la place appliquer git cherry-pick.

../../../../_images/workflows_fix_feat_cherry_pick.png

Workflow fix feat cherry pick

Note

notez que notre branche étant en cours de développement nous pouvons y reporter directement les correctifs sans passer par une sous branche.

Cas particulier des commits multiples

Lors de rares occasions vous aurez à gérer une branche de correction intégrant plusieurs commits.

Admettons par exemple que notre branche hotfix-3.1.1 ait intégré 3 commits : x, y et z. Nous souhaitons récupérer l’intégralité sur une branche hotfix-2.2.1 pour fusionner dans release-2, mais sans créer de bruit/commit inutile.

Deux approches sont alors possibles pour faciliter le report.

La branche de correction n’a pas été fusionnée (squash)

Dans ce cas vous avez la possibilité de regrouper vos commits pour n’en produire qu’un définitif à l’aide du squash :

1     git checkout hotfix-3.1.1
2     git rebase -i HEAD~3
3     # on applique fixup sur chacune des lignes, sauf la première,
4     # c-à-d le commit-a
5     6     # puis on finalise via une **pull request** ou manuellement :
7     git checkout release-3
8     git merge

Reste alors à cherry-picker le commit unique de hotfix-3.1.1 sur la branche hotfix-2.2.1.

La branche a été fusionnée

On souhaite alors récupérer la totalité des commits x, y et z pour ne produire qu’un commit unique sur la branche destinataire :

1     git checkout -b hotfix-2.2.1
2     # on prend tous les commits de hotfix-3.1.1 mais sans finaliser le commit
3     git cherry-pick -x --no-commit --mainline 1 hotfix-3.1.1
4     git commit -m 'Report de correctif depuis 3.1.1'
5     # puis on finalise via une « pull request » ou manuellement :
6     git checkout release-2
7     git merge hotfix-2.2.1

Et voilà, le tour est joué !

Chapitres précédent/suivant