• # Mensongeries

    Posté par . En réponse au journal "Scaling Mercurial at Facebook". Évalué à 3. Dernière modification le 10 janvier 2014 à 10:56.

    En fait Facebook n'a pas migré de Git vers Hg mais de SVN vers Hg.

    Au départ leurs code est hébergé sous SVN et ils souhaitaient continuer à fonctionner avec les caractéristiques de cet outil, tout en adoptant les avantages des DVCS. Ils ont donc toujours un dépôt central SVN mais clonent sous Git en local.

    Le souci qu'ils rencontrent est un grand classique des équipes qui bossent sous SVN et qui ne veulent pas se prendre la tête à recréer un dépôt pour chaque nouveau projet. On se crée un sous-répertoire avec ses branches et tag ou alors un sous-répertoire sous trunk, branches et tags.

    Quand on bosse avec SVN on fait juste un checkout du bon sous-répertoire et c'est marre.

    Lorsqu'on utilise un dvcs, soit en clonant, soit en migrant l'historique à plat on rencontre plein de soucis.

    Déjà, cloner un dépôt entier pour ne travailler que sur une sous-partie négligeable ça prend des plombes.
    Ensuite on se retrouve à extraire tout à plat une arbo avec tous les projets qui servent à rien y compris le contenu des tags et branches.
    Enfin, chaque commit fait un hash de tout le contenu alors que l'on travaille sur une portion disjointe.

    Petit retour d'expérience

    Pour travailler sur des sous-ensemble les DVCS ne proposent que 3 solutions.

    1 N'extraire que les derniers niveaux de commits (1 niveau correspond alors à une simple snapshot de SVN)
    2 Ne cloner qu'une branche
    3 Ne checkouter qu'un sous-répertoire et travailler dessus.

    La première solution a pour avantage d’alléger le clone. Mais elle présente l'inconvénient de travailler à la mode SVN avec les même contraintes que cet outil (pas d'historique local) et en venant de SVN, on se retrouve toujours avec l'arborescence à plat des projets et toutes les branches , tags , ...
    A chaque fois qu'un dev d'un projet commite et push il pollue les devs des autres projet qui doivent faire des rebase/merge fast forward pour du code qui ne les concernent pas.

    La 3ème solution ne convient pas car elle ne fait que masquer les répertoires inutiles.
    Déjà, elle n'est possible qu'en ligne de commande. (Les IDEs ne l'implémentent pas). ensuite ça ne résout aucun des problèmes de performances (les clones sont toujours complets, les commit sur tout le contenu, ...)

    Pour s'en sortir, lorsqu'on a rencontré ce pb sur un projet voici les solutions envisageables.

    1- Créer un dépôt par projet et remonter l'historique.

    Ceci présente 2 contraintes. L'importation est trèèèèès longue et il faut que le dépôt initial soit propre en terme d'architecture (Par exemple, si 2 projets séparés dans 2 branches distinctes ont par la suite été gérés dans une même branche, ca ne marche pas).

    La démarche:

    git svn clone --tags --branches svn://<mon-depot-svn> <mon-depot-git-local>
    Au besoin, ajouter l'option authors-file pour faire correspondre les comptes svn avec les auteurs de commit Git. Le fichier mes-auteurs.txt doit être renseigné.
    git svn clone --tags --branches --authors-file=mes-auteurs.txt svn://<mon-depot-svn> <mon-depot-git-local>
    Vérifier le contenu du dépôt local et recommencer l'import si besoin. Faire le ménage (suppression/renommage des tags/branches inutiles). 
    Pusher ses modifs sur le serveur central
    git remote add server http://git..../<mon-depot-git-central>
    git push --all server
    git push --tags server
    

    2 - Utiliser le clone par branche (point 2)

    D'abord Migrer l'historique SVN tel quel dans Git dans un dépôt legacy. Créer un autre dépôt propre puis créer une branche par branche active de projet dans laquelle on recopie la dernière révision de la branche active du projet. On expurge tous les répertoires des autres projets. On commit et on pushe sur le dépôt central.
    Ensuite il suffit de cloner les bonnes branches pour ses besoins.
    Ceci reste tout de même contraignant par rapport à la façon de travailler avec SVN puisqu’il faut manipuler les branches avec des conventions de nommage. Ce n'est pas dans les habitudes des développeurs venant de SVN.
    Cette solution est à appliquer lorsque le code est trop imbriqué (comme décrit plus haut). Pour les modules biens disjoints, on peut appliquer la première solution pour les isoler dans un dépôt (et utiliser submodule si besoin)

    Voilà.
    Encore une fois une bonne architecture et une bonne gestion de conf peuvent aider à sauver des BB phoques.

    Nos petits amis de FB, n'ont visiblement pas envie de se prendre la tête avec cette migration (ou ont une archi toute pourite ???). Ils préfèrent filer un coup de main au projet Hg (parce que c'est plus simple pour eux AMHA, pas parce qu'il préfèrent Hg à l'usage, j'imagine que c'est plus facile de déployer un plugin en interne que de convaincre une communauté) en optimisant le point 3. Notamment ils font en sorte que les commits ne s'applique sur des hash des fichiers modifiés et non sur tout le contenu et ensuite ils optimisent le cache pour ne travailler que sur le sous-graphe connexe plutôt que sur tout l'historique.

    Tant mieux pour ce projet libre. Mais pas sûr qu'ils échappent à terme à ne plus travailler comme des gorets (un vendredi on peut se permettre un petit troll) et à migrer.