Pourquoi vous ne devriez pas utiliser la Fork Queue de GitHub

GitHub propose une fonctionnalité qui peut sembler magique : la fork queue. Cette fonctionnalité est en soi assez simple à expliquer : elle affiche à l'écran tous les commits faits dans des forks de votre projet et vous permet, en quelques clics, d'appliquer ceux-ci à votre version du projet. Vu comme cela, c'est assez sympa. En pratique, je vous déconseille de l'utiliser. Nous allons voir pourquoi et comment faire sans.
Pourquoi ne dois-je pas utiliser la fork queue ?
La fonctionnalité de la fork queue est similaire à ce que vous pourriez faire manuellement avec git (et que nous détaillons plus bas). Elle prends les commits que vous cochez, en fait un [patch]/patch et commit celui-ci dans votre repository. C'est une fonctionnalité de GIT largement utilisée. C'est ainsi que vous serez ainsi invité à faire si vous soumettez un patch à rails.
Ici cependant, un petit problème se pose : vous pouvez visualiser le contenu du commit. Mais pas le tester. Dès que vous cochez et acceptez ce commit, celui-ci est validé dans votre repository distant et accessible à toute personne ayant accès au projet. En conséquent, si ce commit semble en apparence correct mais qu'il casse une autre fonctionnalité et que vous n'avez pas constaté cela au premier coup d'oeil, vous ne vous en rendrez compte que lorsque vous récupérerez à nouveau le contenu de votre projet et que vous exécuterez ses tests. Et si vous avez accepté plusieurs commits, vous risquez d'avoir beaucoup de mal à trouver lequel a implémenté ce bug et à le corriger.
Le fait qu'un commit passe correctement, c'est à dire qu'il ne crée pas de conflit lors de son merge ne signifie pas qu'il ne casse pas de fonctionnalité par ailleurs.
Oui mais je fais comment à la place ?
Grande question ! :) Tout d'abord vous devez vous imaginer que chaque repository GIT distant est en fait une branche différente. Lorsque vous faites un fetch, vous récupérez le contenu de cette branche.
Supposons que un utilisateur "joe" ait forké mon projet open source jack. Joe a donc son fork situé sur github à joe/jack. Il fait quelques commits puis pousse les modifications effectuées. Pour ma part, je veux placer ces modifications dans le repository principal.
git clone git@github.com:dmathieu/jack.git
Je commence par cloner le repository. A supposer que je ne l'ai pas encore ne local.
git remote add joe git://github.com/joe/jack.git
Ensuite je dois ajouter un nouveau repository distant, que je vais nommer joe. Je pourrai ainsi récupérer les derniers commits effectuée.
git fetch joe master:joe
Maintenant je récupère les commits effectués par joe sur son repository et les place dans une nouvelle branche locale, que je nomme joe.
git checkout joe
Je me rends dans cette nouvelle branche. Le répertoire courant de mon projet contient maintenant les modifications effectuées par joe. Je peux ainsi effectuer tranquillement les tests que je désire sur cette application et ainsi vérifier que toutes les modifications effectuées par joe sont correctes.
Une fois que tous mes tests sont effectués, je vais les valider dans ma branche master. Pour cela je dois remettre cette branche master comme branche active.
git checkout master
Puis je merge la branche joe dans celle-ci.
git merge joe
Tous les commits effectués par joe ont ainsi été approuvés dans ma branche master. Je n'ai plus qu'à pousser les commits ajoutés
git push origin master
C'est bien évidemment plus long et plus complexe que d'utiliser la Fork Queue. Mais la qualité de votre application s'y retrouvera puisque vous limiterez fortement le risque d'erreurs non désirées.
Et si je ne veux accepter que certains commits ?
Supposons que joe ait effectué deux commits. Un est intéressant. Quant à l'autre il casse tout ... Nous ne désirons pas accepter les deux, mais un seul. Pour cela, nous allons utiliser cherry-pick.
Cherry Pick nous permet de sélectionner un identifiant de commit et de l'approuver dans master. Commençons par trouver cet identifiant de commit. Avec joe comme branche active, tapez
git log
Qui vous retournera le log des derniers commits effectués. Supposons que vous ayez le log suivant :
commit 7797aec6a35d928045f2a90fdddd9001dbf1a567
Author: Joe Doe <joe.doe@example.com>
Date: Tue Jun 15 12:23:45 2010 +0200
Ca sers à rien ça
commit 1cd60cc03530cd88689f19e6c5e3fd5f95b4ed70
Author: Joe Doe <joe.doe@example.com>
Date: Tue Jun 15 11:56:38 2010 +0200
Ouh lala le méchant bug
commit 7feb18184cdeff2363d6b608201ac6431f53e070
Author: Damien Mathieu <damien@example.com>
Date: Tue Jun 15 11:49:52 2010 +0200
Release v1.0.0
Vous pouvez voir que chaque commit est identifié par un hash. C'est en passant ce hash que nous allons pouvoir identifier un commit en particulier et effectuer le cherry-pick. Retournez dans la branche master.
Puis nous incluons uniquement le premier commit de Joe.
git cherry-pick 1cd60cc03530cd88689f19e6c5e3fd5f95b4ed70
Et voila ! Vous n'avez pas mergé tous les commits de joe dans votre repository principal, mais que celui que vous désirez.
Conclusion
La fonctionnalité de Fork Queue est peut-être aisée lorsque votre projet est petit et que vous avez peu de commits différents ou de risques de dommages collatéraux. Mais dès que celle-ci commence à prendre de l'ampleur, vous devrez alors appliquer les commits de personnes tiers avec plus d'attention. La, la Fork Queue devient un ennemi et un facteur d'erreurs pour votre application. Utilisez la avec parcimonie !





