En tant qu'éditeur de logiciel, le Source Code Control System est notre outil principal avec lequel nous travaillons quotidiennement. Il est absolument vital pour nous de connaître l'historique des modifications faites au sein de nos sources. Depuis le début nous utilisions subversion avec trac comme interface online.

L'avantage de subversion est que c'est un outil relativement simple à comprendre et à utiliser. En gros, à part les notions de update et de commit, il n'y a pas grand chose d'autre à savoir. De manière générale, tout le monde travaille (commit) directement dans la branche principale et récupère les modifications des autres utilisateurs (update). Au final, l'interface trac n'a même pas besoin d'être utilisée pour le travail courant.

Le point important est qu'avec subversion, une fois qu'un commit a été fait, il est directement envoyé au serveur et il est définitif, ce qui n'est pas (forcément) le cas avec git et cela provoque vite des conflits problématiques si on garde le même processus de travail qu'avec subversion.

Donc un passage à git n'est pas un simplement changement d'outil, mais une évolution de la méthode de travail ! Non content de devoir apprendre de nouveaux concepts, il va également falloir changer ses habitudes sous peine de se trouver confronté sans arrêt à des conflits. Sans entrer dans les détails techniques, voici comment nous avons procédé afin d'effectuer ce passage de manière la plus fluide possible.

Etape 1: déterminer le workflow

Il existe plusieurs workflows différents. Pour notre part, nous avons opté pour un gitflow légèrement adapté:

  • la branche master est protected (personne ne peut publier des commits dessus)
  • tout développement (bugfix/feature/...) se fait dans une nouvelle branche créée à partir de la version la plus récente du master
  • toute nouvelle branche implique la création d'une Merge Request sur le master (ou sur une branche stable pour les backports)
  • la nomenclature des branches doit suivre certaines règles (par exemple feature/<client>/<nom_feature> ou bien fix/<client>/<no_ticket>)
  • les branches stable/<no_version> sont protected
  • pour les backports, une nouvelle branche backport/<no_version> est créée à partir de la dernière version stable/<no_version> et les merge commits nécessaires sont cherry-pickés depuis le master

Etape 2: maîtriser git en ligne de commande

Le fait que l'historique ne soit pas définif dans une branche fait qu'un client git graphique ne saura pas réagir correctement. Il sera également très compliqué, voir impossible de gérer le cas uniquement en mode graphique.

Il est donc indispensable de connaître les commandes git de base (add,commit,push,pull,rebase,reset,checkout) et de comprendre comment résoudre certains cas normaux (spécialement lors d'un rebase). De plus, il est quasiment impossible de perdre son travail avec git s'il a été committé, même en faisant une (et même plusieurs) fausse manipulation ensuite (merci reflog).

Etape 3: choisir une interface online

Contrairement à trac, les interfaces git en ligne sont beaucoup plus puissantes et grandement utiles ! Nous avons testé entre autres gitea puis nous avons finalement opté pour gitlab CE. Cette interface est immédiatement devenue notre centre névralgique !

En effet, désormais plutôt que d'établir des spécifications par email ou de discuter de certaines modifications via IRC, tout se fait dans gitlab. Cela nous permet un bien meilleur suivi et également de savoir qui est impacté par quoi. Les Merge Requests (ou Pull Request sur GitHub) nous permettent également de faire du code review avant de merger les modifications sur le master.

Etape 4: tester et documenter

La migration subversion vers git est one-way: une fois effectuée et que les gens ont commencé à bosser avec, plus question de faire un retour en arrière. Il est donc primordial que le workflow défini à l'étape 1 soit testé et documenté avec l'interface choisie à l'étape 3.

De notre coté, nous avons rédigé un document avec les points suivants:

  • différences principales entre subversion et git
  • application d'un workflow du début à la fin
  • FAQ pour résoudre les cas récurrents

Etape 5: migrer

Nous avons simplement prévenu tout le monde de la date de migration. Etant donné le temps d'import (~45'000 commits), nous avons prévu un vendredi afin d'avoir quelques jours en rab en cas de pépin. Comme nous avions déjà testé l'import durant l'étape 4, nous étions assez confiants et tout s'est bien passé.

Il existe différents outils pour reprendre l'historique subversion dans git. Evidemment, cela se passe bien quand les standards ont été respectés, ce qui n'était pas le cas au début à cause notamment de notre inexpérience avec subversion. Nous avons donc du établir plusieurs règles de reprise afin de récupérer la majeure partie de notre historique.

Au final, nous n'avons perdu que quelques commits du tout début, mais sans que cela n'ait d'impact. Ce sujet technique fera d'ailleurs probablement l'objet d'un autre billet.

Etape 6: monter en puissance

Une fois que les outils sont en place et que les gens commencent à bosser dessus, il est temps de monter tout cela en puissance. Nous avons travaillé sur deux axes principaux jusqu'à maintenant:

  • mettre en places des tests automatiques lancés automatiquement sur chaque branche
  • effectuer les backports automatiquement (en fonction de labels dans les Merge Request)

Ces deux points nous ont permis de gagner énormément sur plusieurs aspects:

  • consistance: la majorité des incohérences sont détectées avant d'être mergées
  • formatting: les sources sont uniformisées (UTF-8, seulement des espaces pour l'indentation, CR pour les retours lignes, ...)
  • formation: un nouveau collaborateur apprend directement de ses erreurs en committant
  • qualitatif: code review, distribution des connaissances entre nous, ...

Rétrospective

Cela fait maintenant 6 mois que la migration a été effectuée et nous n'avons eu aucun problème technique. Malgré quelques menues réticences dues aux nouvelles manipulations nécessaires, tout le monde a très vite pris ses marques.

Il est encore un peu tôt pour faire le point en terme de production réelle. En effet, les tests pré-migration et la migration elle-même nous a pris du temps, mais pas tant que ça au final. Nous en avons par contre investi beaucoup dans les tests de consistance et anti-régression depuis le passage a git.

La seule chose que je regrette de subversion est le système des droits d'accès et des checkout sélectifs. Il était possible de ne récupérer qu'un sous-dossier du repo, soit pour limiter la taille des données à récupérer, soit car certains dossiers n'étaient pas autorisés. Dans git, ces fonctionnalités ne sont tout simplement pas possibles: si quelqu'un a accès au repo, il a accès à tout son contenu, même celui qu'il n'est pas censé modifier.

Au final, cette migration était vraiment indispensable ! Cela nous a permis de nous mettre à jour avec des outils performants au top de la technologie actuelle. De plus ces outils nous permettent d'améliorer la fiabilité de nos produits et nous épargnent des tâches rébarbatives de vérification et de backport.