Tag Archives: merge

[FR] Un contrôleur de source, ce n’est pas un simple système de fichiers!

Cela peut sembler évident, mais tout le monde n’est pas sensibilisé à cela: toute opération sur une branche va se répercuter sur les branches parentes lors des merges. Il faut donc, lorsque l’on réalise une opération dans une branche, penser que cela aura des répercutions bien plus tard!

Il n’oublie jamais! Smile

Voici un exemple (vécu):

Gérard est un développeur de l’équipe, on lui a assigné un bug le #567 sur l’application App_X qui est dans la release R3 du soft. Jusque là: rien d’anormal. Gérard tire une branche de toute la release pour réaliser sa correction, y compris App_Y qui n’a rien à voir avec le bug.

image

Gérard ce dit que c’est idiot de voir pour la correction les 2 projets. On va alors croire que la correction est à la fois dans App_X et App_Y. Gérard décide alors de supprimer App_Y dans sa branche: simple “nettoyage”. Gérard choisit donc d’effectuer un “delete” sur App_Y:

image

Cela donne alors cet état:

image

Tout a l’air OK comme cela. Gérard corrige le bug et merge dans la release. Et là, c’est le drame:

image

Comme je le disais au début: TFS (comme toute contrôleur de source) n’oublie rien. Le delete n’était pas la solution (le “delete” n’est généralement pas la bonne décision!). Qu’aurait du faire Gérard?

Déjà Gérard aurait du avoir l’option suivante activée:

image

Il aurait alors vu que le dossier était marqué comme supprimé dans TFS. Cela lui aurait surement mis la puce à l’oreille:

image

Gérard avait en fait 2 options:

  • ne rien faire (des fois c’est la meilleur des options): pour une branche le plus important ce ne sont pas les fichiers que l’on a branché, mais ce qu’il y a dans l’historique.
  • demander une destruction du projet dans sa branche: contrairement au “delete” qui crée une opération pour supprimer des fichiers. La destruction de fichiers fait comme si les fichiers détruits n’avaient jamais existé, donc aucun historique!

Cela ce passe en ligne de commande:

image

Et donc au moment du “merge”: aucune opération d’effacement est crée:

image

Contrairement à un “delete”, le “destroy” est irréversible et est réservé que dans ces cas exceptionnels. De même un “delete” doit rester rare: supprimer un fichier revient à supprimer du code, donc supprimer de la valeur et surtout perdre l’historique. Cela est d’autant plus vrai pour un projet complet. Il est plus interessant de créer un dossier spécifique qui recevra l’ensemble des projets décommissionnés plutot que de les détruire et de marquer ce dossier en lecture seule.

Alors comment identifier ces changesets qui peuvent contenir ce genre d’opérations. Généralement je les retrouve avec les commentaires suivants: “cleaning”, “refactoring”…  et tout ce qui peut induire des changements dans la structure du code.

Bonne chasse!

 

End of line

[FR] Branches, bugs, et chef de projet! Ou comment faire voyager les changesets dans le contrôleur de source sans faire de “baseless merge”.

Voici la situation: Bob bosse sur un bug de la version R1 du soft, la correction est prète mais le chef de projet décide que ce bug ne sera pas corrigé dans la V1: la V2 est déjà sorti, et  il ne veux plus que des corrections de sécurité sur la V1. Par contre le bug existe dans la version en cours de développement, il faut donc corriger cette version.

 

Voici une image du contrôleur de source:

image

Si c’était possible, il faudrait faire un merge entre la branche R1-BUG_345 et la Main. Mais ce n’est possible qu’en mode baseless (Let me google that for you Smile ). Mais cette opération n’est pas forcément la plus simple car elle n’utilise pas les informations que TFS possède sur l’origine des fichiers: il est tout à fait possible qu’entre la R1 et la Main actuelle, les fichiers qu’il faut fusionner aient été renommés ou déplacés, et là, le baseless merge ne vas pas trop nous aider. Autre possibilité: utiliser le merge de TFS tout en compensant: nous allons effectuer 2 merges jusqu’à la main et ensuite faire en sorte d’annuler nos modifications dans R1 et surtout acter cette modification dans la Main. Pour cela nous allons utiliser la ligne de commande de TFS 2010 (la fonction était dans les powertools dans les versions précédèntes).

Dans Visual Studio j’effecture les opérations suivantes:

  • merge R1-BUG_345 –> R1: changeset 22
  • merge R1 –> Main du changeset 22 : changeset 23

Maintenant nous avons notre correction dans la main. Il ne reste plus qu’à la supprimer de la branche R1. Pour cela nous allons donc utiliser la commande “tf rollback”:

tf rollback /changeset:C22~C22 /recursive /keepmergehistory

image

Voici l’état des pending changes:

image

On remarque bien que l’état est “Rollback”! Regardons l’historique du fichier en question:

image

 

J’ai ajouté l’option /keekmergehistory pour indiquer à TFS que je ne veux plus que le changeset 22 soit appliqué si je remerge la branche R1-BUG_345 dans R1.

On pourrait penser que tout est bon maintenant, mais il manque une étape: si je merge la branche R1 dans la Main, le code va être annulé comme dans R1! Il y a maintenant 2 possibilités pour corriger cela:

  • Solution 1: faire le merge dans la main et refaire un rollback avec l’option /keepmergehistory: 2 opérations
  • Solution 2: faire croire que le merge de R1  vers Main est effectué via un /discard dans le merge: 1 opération.

Prenons la solution 2: tf merge /recursive /discard /version:C24 “$/MSF Agile Test/Release/R1” “$/MSF Agile Test/Main”

image

Historique devient comme suit:

image

Les commentaires sont importants pour bien comprendre ce qui s’est passé.

Nous avons donc réussi notre mission: Rien dans R1 et le bug corrigé dans la Main. Un conseil pour ces opérations: travailler si possible sur un seul changeset à la fois ou un groupe de changetset assez proche de la latest d’une branche: cela vous évitera les conflits pour la résolution du code.

J’ai utilisé l’option /keekmergehistory, mais sans cette option le rollback est très utile pour:

  • un développeur:  pour annuler un changeset un peut trop rapidement fait,
  • pour un gestionnaire de l’usine: pour annuler un changeset qui fait planter la build si le développeur ne peux pas corriger de suite: c’est un peu notre arme anti-plantage de build Smile.

@+

[FR] J’ai installé TFS 2010, et après ? Mise en prod: it’s the final countdown!

Un moment critique de la vie d’un projet est le moment de la livraison. Ce moment est d’autant plus critique (certains diraient douloureux)  que le nombre de livraison est faible. Généralement on livre au minimum une fois Smile.

Comment je livre, et qu’est ce que je livre?

Il y a la recette de grand-mère, et la recette du chef.

Dans la recette de grand-mère, nous avons un développeur (pas toujours le même). Quelque soit sa bonne volonté, un développeur ne livrera jamais 2 fois le logiciel de la même façon, et surtout la compilation dépendra de sa machine et il y a de bonnes chances qu’il oublie quelque chose.

Dans la recette du chef, nous avons une build. La build c’est un peu le super développeur en ce qui concerne la compilation, il fera toujours tout de la même façon, autant de fois que l’on veut et à n’importe quelle heure de la journée. Ce qui veut dire que l’on a pas besoin d’attendre le dernière moment pour préparer l’installeur.

Cela veut aussi dire que l’on le lance pas forcément la build lorsque l’on a terminé, mais que c’est plutôt la build qui va nous dire si nous avons terminés. La build:

Tout cela sera la base de notre livraison.

 

Est-ce que cela fait ce que cela doit faire et est-ce que je n’ai rien oublié?

Pour le premier point, c’est simple: via les rapports de TFS et les workitems… si tout est bien renseigné! Lorsque l’on a un doute, il va falloir analyser le source.

Prenons un exemple. Une application avec une main, et 1 release: R1. Un fix est fait dans la branche R1 (changeset 14) et est mergé dans la main (changeset 15). Une branche de release R2 a été créé. La question est la suivante: est-ce que bug est corrigé dans la R2? Dans le langage TFS, la question devient: est-ce que le changeset du bug a été fusionné dans la branche R2.

Première étape: regardé ce que devient le code du changeset 14 (celui de notre correction). Dans VS 2010, nous avons la possibilité d’avoir une vue historique de l’évolution d’un changeset concernant les merges:

image

Le changeset 14 a été mergé dans le changeset 15 dans la main. Nous savons donc que la correction a été reporté dans la main. Regardons maintenant le changeset 15:

image

Bonne nouvelle, il a été fussionné dans R2 dans le changetset 16! La correction est donc bien dans la nouvelle branche de release.

 

C’est en prod et maintenant?

Maintenant que tout est en prod. Que peux faire TFS pour nous, en plus des workitems de bug? Comme je n’ai écrit plus haut, la build génère les symboles de debug et les liens avec le source. Cela va être extrêmement pratique car il n’est pas question de fournir les symboles de débug avec l’installation du programme! Cela veut aussi dire que lors qu’un correctif doit être livré, il devra aussi être compilé avec la build pour avoir ces informations: il faut donc une build pour chaque branche de livraison.

Si deux releases nécessitent des environnements différents, ne prenez pas de risque: utiliser 2 machines de builds. Une machine de build n’a pas forcément besoin d’être puissante: un PC inutilisé fera l’affaire du moment que son environnement est contrôlé.

Un dernier conseil pour finir: bien suivre le branching guide pour ne pas avoir de problèmes!

 

@+

[FR] Organisation du controleur de source

Quelque soient les noms que l’on donnent, on a tous à un moment ou à un autre à livrer des versions complètes du logiciel planifiées ou pas. On parle alors généralement de “Release”,”Service Pack”, “Fix”… En parallèle à cela, on a généralement une version en cours de développement contenant plusieurs fonctionnalités développées en parallèles dans plusieurs équipes. Bien organiser son contrôleur de source pour gérer cela est primordial et il n’y a pas le droit à l’erreur. Fort heureusement, il n’y a pas 10000 possibilités. Le Visual Studio Team Foundation Server Branching Guide 2010 sur Codeplex contient tout un ensemble de bonnes pratiques pour gérer cela:

image

Ces documents (documentation, poster, slides) ont les avantages suivants:

  • définir précisément les concepts et la structure du contrôleur de source,
  • définir les processus ou du moins une base de processus adaptable à votre structure.

Ensuite tout n’est pas gagné: il faut bien éduquer les équipes pour

  • qu’elles identifient les branches dans lesquelles elles doivent travailler et pour quelles raisons,
  • qu’elles adoptent des bonnes pratiques d’utilisation de TFS pour ne pas se tromper par l’utilisation de plusieurs workspaces par exemple (cela sera abordé dans un autre billet)

@+