tsrc — un gestionnaire de dépôts git

Posté par  (site web personnel) . Édité par ZeroHeure, Pierre Jarillon, Davy Defaud, Benoît Sibaud et claudex. Modéré par patrick_g. Licence CC By‑SA.
Étiquettes :
31
5
août
2017
Gestion de versions

Gérer du code dans plusieurs dépôts différents est toujours un peu compliqué. Chez tanker.io nous avons une petite équipe de développeurs, et chacun des membres peut être amené à coder dans plusieurs langages (C++, Go et JavaScript, principalement). Comme une grande partie du code est encore propriétaire, nous utilisons une instance GitLab hébergée dans nos locaux.

Il existe plusieurs façons de gérer la synchronisation entre dépôts : la manière qui nous convient le mieux est d’avoir la même branche (ou le même tag) sur les dépôts concernés. Ceci nous a amené à développer notre propre outil, tsrc, qui est désormais disponible sur GitHub, sous licence BSD.

tsrc-banner

Pourquoi GitHub et pas GitLab ? Simplement parce que GitHub, bien que propriétaire, assure une meilleure visibilité au projet.

Nos contraintes :

  • bonne prise en charge de Windows (ce qui exclut repo ou gws) ;
  • un seul fichier central permettant de connaître la liste précise des dépôts à cloner et leur localisation (ce qui exclut les outils comme mu-repo, ou scm.py) ;
  • d’un autre côté, nous n’avons pas vraiment besoin de gestion des dépendances entre dépôts (ce que mu-repo gère bien), parce que nous préférons avoir un dépôt par langage ;
  • pas de dépôt « maître » contenant plusieurs sous‐dépôts (ce qui exclut git-submodule et git-subrepo).

Démonstration

Vous pouvez vous faire une idée précise de comment fonctionne tsrc en regardant la démonstration que nous avons publiée sur asciinema.

Installation

tsrc est codé en Python et naturellement disponible sur Pypi.

Il est utilisé par tous les membres de notre équipe, que ce soit sous GNU/Linux, macOS ou Windows. La version minimale requise pour tsrc est Python3.3. Notez que le support de Python 2.7 est exclu (simplement parce que Python3 est, de notre point de vue, un bien meilleur langage que Python2.7). Sur une distribution pas trop vieille (Python 3.3 étant sorti en 2012), un simple pip3 install tsrc --user fera donc l'affaire, après avoir rajouté ~/.local/bin dans votre PATH au besoin.

Utilisation

Clone initial

tsrc fonctionne en utilisant un fichier « manifest » en YAML :

repos:
  - src: foo
    url: git@gitlab.local:acme/foo

  - src: bar
    url: git@gitlab.local:acme/bar

Le « manifest » en question doit être présent dans un dépôt Git. Cela fait, vous pouvez récupérer les dépôts en utilisant :

$ tsrc init git@gitlab.local:acme/manifest

Mise à jour des dépôts

Vous pouvez mettre à jour tous les dépôts en utilisant :

$ tsrc sync

Un exemple de la sortie console :
tsrc-sync

Contrairement à repo, tsrc essaie par tous les moyens d’éviter la perte de données ou les effets inattendus. Par exemple, si votre branche a divergé ou que votre dépôt n’est pas « propre », tsrc préférera afficher un avertissement et vous laisser résoudre la situation par vous‐même.

Notez que si vous n’aimez pas le fait que tsrc « cache » les commandes git, vous pouvez utiliser l’option --verbose.

Gestion des « fusiodemandes » GitLab

Vous pouvez créer et accepter des « fusiodemandes » (merge requests) avec tsrc push après un peu de configuration. Pour l’instant, cela ne fonctionne qu’avec GitLab (puisque c’est ce que nous utilisons en interne), mais la prise en charge de Gerrit ou GitHub n’est pas exclue.

# Travail en cours sur ma-belle-branche
$ tsrc push --assignee david
# Crée une merge request assignée à David

# La revue est terminée, on prévient GitLab que la branche
# doit être fusionnée dès que l’intégration continue est passée :
$ tsrc push --accept

Bonus

tsrc contient aussi quelques commandes pratiques comme tsrc log ou tsrc foreach, mais cette dépêche est déjà assez longue. ;-)

Appel à contributions

Les retours sous toute forme sont les bienvenus, dans les commentaires ou directement sur GitHub.

Aller plus loin

  • # Super !

    Posté par  . Évalué à 3.

    A priori l’outil fait ce que j’ai toujours peiné à faire à la main jusque ici '

    Vous acceptez les contributions du coup ? Par exemple j’aimerais générer un yaml à partir de gitlab pour éviter de cloner les quelques… dizaines de dépôts présents…

  • # je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

    Posté par  . Évalué à 6.

    En lisant le titre, j'ai cru que c'était un nouveau gitlab écrit en python.

    Ensuite après avoir lu la totalité de la news, je ne comprends pas quel est le problème de coder dans différents langages et pourquoi cet outil résout ce problème.

    Si j'ai bien compris la news, c'est un outil en cli qui permet de faire ce qu'on peut faire en graphique avec gitlab ?

    • [^] # Re: je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

      Posté par  (site web personnel) . Évalué à 4.

      Ensuite après avoir lu la totalité de la news, je ne comprends pas quel est le problème de coder dans différents
      langages et pourquoi cet outil résout ce problème.

      Je vais essayer de clarifier en donnant plus de détails.

      Chez Tanker nous avons plusieurs dépôts:

      • Un client lourd en C++
      • Des serveurs en Go
      • Un SDK Javascript
      • Des applications web (toujours en Javascript)
      • De la documentation (avec mkdocs)
      • Des scripts de déploiement et d'intégration continue (en Python)

      Comme l'équipe maîtrise tous ces langages, il est pratique pour chaque développeur d'avoir toutes les sources en même temps sur sa machine.

      De même, lorsqu'un nouveau projet est créé, il est pratique de lancer tsrc sync pour cloner le nouveau projet plutôt que d'aller chercher l'URL sur GitLab.

      De plus, tsrc s'assure que les chemins relatifs entre projets sont toujours les mêmes.

      Cela simplifie beaucoup de choses, notamment en Go, ou le langage impose des contraintes sur l'arborescence des fichiers, ou pour les scripts de déploiement (par exemple quand on veut générer la documentation avant de la déployer).

      Enfin, avant chaque déploiement, nous pouvons lancer tsrc foreach -- git tag v0.2.0, ce qui nous permettra plus tard de savoir exactement le contenu de toutes les sources ayant participé à la génération de nos artefacts.

      J’espère avoir été plus clair.

      • [^] # Re: je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

        Posté par  . Évalué à 2.

        C'est quoi exactement qui vous empêchait de tout mettre dans le même repo ?

        • [^] # Re: je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

          Posté par  . Évalué à 1.

          Cela simplifie beaucoup de choses, notamment en Go, ou le langage impose des contraintes sur l'arborescence des fichiers, ou pour les scripts de déploiement (par exemple quand on veut générer la documentation avant de la déployer).

          Je crois qu’il a répondu :p

          • [^] # Re: je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

            Posté par  . Évalué à 2.

            Ok, j'ai raté cette partie, mais je ne connais pas assez GO pour comprendre. Avec un répertoire par langage tout en haut de l'arborescence on a le même résultat non ?

            Et pour le point sur la doc pareil je ne vois pas.

            À ce stade tout ça ressemble à une solution bien compliquée au niveau SCM pour régler un problème qui se trouve en fait au niveau outil de build.

            • [^] # Re: je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

              Posté par  . Évalué à 5.

              Bon, en me relisant je me rends compte que ma question peut sembler débile et mérite elle aussi un éclaircissement.

              L'auteur indique qu'in fine il tague tout avec le même label, ce que je traduit en : on ne gère qu'une seule version globale de tout ces repos.

              Je vois très bien l'intérêt de l'outil si on gère plusieurs softs certes distribués ensemble mais avec chacun son rythme de livraison. Si tout est livré par définition d'un bloc, alors un repo central semble plus adapté, et on fait les ajustements nécessaires sur la partie build

              J'ai (encore) raté un truc ?

              • [^] # Re: je ne suis pas sûr d'avoir saisi l'intérêt de l'outil

                Posté par  (site web personnel) . Évalué à 8.

                et on fait les ajustements nécessaires sur la partie build

                C'est justement ça qu'on a pas envie de faire (voir ci-dessous)

                Pourquoi pas monorepo ?

                Version courte: pour des raisons historiques, d'intégration, et aussi un peu philosophiques.

                Version longue:

                • Raison historique: Avant, on avait nos dépendances C++ (les fichiers .so, .a, .dylib et tous leur headers) pré-compilées dans un gros dépôt git. Du coup comme le dépôt était gros toutes les opérations (git status, par exemple) prenait du temps. Du coup c'était pratique d'avoir un deuxième dépôts avec juste nos sources à nous. (Depuis on est passé à conan

                • Intégration: nous utilisons gitlab-ci. Si tu as un seul dépôt qui mélange C++ et Javascript par exemple, il va falloir regarder quelle portion du code a été changée. (Lancer le build et les tests en C++ est long, et lancer tous les linters et les analyseurs statiques Javascript est long aussi: tu as envie de lancer uniquement ce qui concerne ce qui a changé. Du coup si t'es un peu obligé de hacker gitlab-ci pour rajouter ce genre de fonctionnalité.

                • La dernière raison est plus subtile. L'idée c'est qu'on veut avoir un système qui tienne la route même avec beaucoup de projets et beaucoup de développeurs. La solution du mono-repo fonctionne mais demande du travail spécifique (les problème d'intégration continue et de performance des gestionnaires de code ne sont que des exemples parmi d'autres). Du coup la solution que nous choisissons se rapproche des modes de développement open-source (pensez à Gnome ou KDE et leur myriade de projets séparés), ce qui nous permet à la fois de bénéficier des outils existants, mais aussi de partager nos problèmes (et nos solutions) avec le reste de la communauté open source.

  • # Possibilité de cloner une branche ou un tag ?

    Posté par  (site web personnel) . Évalué à 4.

    Il y a quelques mois je cherchais un outil me permettant de construire un workspace constitué de multiple projets git, en tirant soit une branche spécifique, soit un tag spécifique.

    L'idée était de pouvoir conserver la configuration de ce workspace en un seul fichier simple à lire et modifier. Le fichier de conf peut ensuite être lui-même versionné dans git, afin de pouvoir reconstruire un environnement cohérent versionné.

    Comme je n'avais rien trouvé qui me satisfasse, j'ai fini par bricoler un script minimaliste (quelques dizaines de lignes) en bash et M4, mais bon, j'aurais préféré ne pas avoir un tel outil à maintenir moi-même.

    tsrc semble se rapprocher de mon besoin. Est-il possible de spécifier une branche ou un tag au repo git qu'on veut cloner dans le workspace ? J'ai un peu parcouru la doc mais rien trouvé pour l'instant.

    • [^] # Re: Possibilité de cloner une branche ou un tag ?

      Posté par  (site web personnel) . Évalué à 4.

      L'idée était de pouvoir conserver la configuration de ce workspace en un seul
      fichier simple à lire et modifier. Le fichier de conf peut ensuite être
      lui-même versionné dans git, afin de pouvoir reconstruire un environnement
      cohérent versionné.

      C'est exactement le fonctionnement de tsrc, oui. Le fichier en question (manifest.yml) est versionné dans le dépôt "manifest".

      Est-il possible de spécifier une branche ou un tag au repo git qu'on veut cloner dans le workspace
      La gestion des branches est implémentée depuis peu:
      https://github.com/TankerApp/tsrc/pull/7

      Pour les tags je vais ouvrir une issue sur github, il y a plusieurs façons d'aborder le problème.

  • # Wstool

    Posté par  . Évalué à 6.

    Wstool (bien qu'intégré dans l'environnement ROS), fait exactement ceci

    • [^] # Re: Wstool

      Posté par  (site web personnel) . Évalué à 2.

      Arf. J'avais regardé ROS y a longtemps mais à l'époque la gestion des sources était très couplée au reste de l'écosystème ROS.

      Tu sais si ça marche bien sous Windows aussi ? C'est une contrainte importante pour nous…

  • # fusiodemandes?

    Posté par  (site web personnel) . Évalué à 8.

    Est-ce qu'il n'y a pas une meilleure traduction?

    Pour les pull requests, on dit poules requêtes en tribune slang. Dans la logique de cet argot, on pourrait dire:

    • immerge requête: on demande à immerger le nouveau code dans l'actuel.
    • gamberge requête: le nouveau code à intégrer demande réflexion.
    • cierge requête: après avoir passer 42h à comprendre comment lancer le code de linuxfr.org pour un patch de 3 lignes, on brûle un cierge en espérant ne pas avoir bossé pour rien.

    Le post ci-dessus est une grosse connerie, ne le lisez pas sérieusement.

    • [^] # Re: fusiodemandes?

      Posté par  . Évalué à 0.

      Est-ce qu'il n'y a pas une meilleure traduction?

      une demande d'intégration, une demande de fusion.

      C'est si incompréhensible que cela ?

  • # git-repo ?

    Posté par  (site web personnel) . Évalué à 2.

    Google a crée un outil au dessus de git, git-repo, pour gérer ce cas notamment pour Android (qui rassemble énormément de dépôts différents).

    Je l'ai déjà utilisé dans un contexte professionnel et cela fonctionne bien. Cela se couple aussi avec Gerrit pour la revue de code.

    Donc, pourquoi ne pas l'avoir choisi ?

    https://code.google.com/archive/p/git-repo/

    • [^] # Re: git-repo ?

      Posté par  (site web personnel) . Évalué à 2.

      Quelques éléments de réponse dans la faq.

      En gros:

      • Pas de support de Windows
      • Comportement parfois surprenant et/ou destructif

      Et une majorité de l'équipe préfère le mécanisme de merge requests à celui du fonctionnement par revue de patches individuels.

      • [^] # Re: git-repo ?

        Posté par  (Mastodon) . Évalué à 2. Dernière modification le 08 août 2017 à 13:25.

        Soit dit en passant si ça tourne sur le WSL (ce qui est très probablement le cas), c'est supporté par windows.

        Jami: beabb2b063da0a2f0a2acaddcd9cc1421245d5de

        • [^] # Re: git-repo ?

          Posté par  (site web personnel) . Évalué à 2.

          Certes, mais nous assurons aussi la compatibilité sur Windows 7 et 8, le WSL (sauf erreur) ne marche que sur Windows 10.

          D'autre part, nous essayons de minimiser le nombre d'outils à installer sur Windows (à la fois pour les développeurs et notre ferme de compilation), pour des questions d'efficacité et de maintenance.

          (Tu serais surpris du nombre de développeurs Windows/C++ pour qui installer Python3 en plus de Visual Studio est déjà vu comme une contrainte :P )

          • [^] # Re: git-repo ?

            Posté par  (Mastodon) . Évalué à 2.

            À un moment donné il va falloir les lâcher windows 7 et 8 cela-dit, dans moins de 3 ans c'est out.

            Jami: beabb2b063da0a2f0a2acaddcd9cc1421245d5de

          • [^] # Re: git-repo ?

            Posté par  . Évalué à 2.

            Si on installe VS 2017 en entier, on a déjà Python3.
            (voire, c'était déjà le cas avec VS 2015).

            :p

            "Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)

  • # Origine du nom tsrc ?

    Posté par  (site web personnel) . Évalué à 3.

    Que signifie tsrc?
    Cela sonne comme si on demandait Tes sources ?
    Quelle est la genèse de ce projet ?
    Qui a trouvé ce nom tsrc?
    Et qu'est que tsrc voulait dire à l'origine ?

    Commentaire sous licence Creative Commons Zero CC0 1.0 Universal (Public Domain Dedication)

    • [^] # Re: Origine du nom tsrc ?

      Posté par  (site web personnel) . Évalué à 5.

      Que signifie tsrc?

      Le t est pour Tanker (cf https://tanker.io)
      Le src est pour source, effectivement.

      Quelle est la genèse de ce projet ?

      Tout a commencé quand nous avons revu en profondeur les scripts utilisé pour l'intégration continue.

      À l'époque, il y a avait des bouts de scripts .sh et .bat. pour cloner les dépôts sur les machines de la ferme de compilation, compiler et lancer les tests.

      Pour des raisons de simplicité de maintenance, nous avons décidé d'exporter de les ré-écrire en Python.

      Ensuite, nous avons découvert qu'il était souhaitable que les développeurs puissent facilement reproduire ce qui se passe pendant l'intégration continue sur leur propres machines.

      Du coup, nous avons décidé d'exposer une partie des fonctionnalités des scripts de build (la gestion des sources, en l’occurrence) dans dans un outil en ligne de commande utilisable également par les développeurs de l'équipe.

      En parlant avec d'autres développeurs, nous nous sommes rendu compte qu'il y avait une demande sur ce genre d'outils et avons décidé de le partager avec la communauté.

      Cela sonne comme si on demandait Tes sources ?

      C'est voulu :)

      Qui a trouvé ce nom tsrc?

      Moi ;)

      • [^] # Commentaire supprimé

        Posté par  . Évalué à -4.

        Ce commentaire a été supprimé par l’équipe de modération.

  • # git submodule

    Posté par  . Évalué à 2.

    Quelle est la difference avec git submodule?

    • [^] # Re: git submodule

      Posté par  (site web personnel) . Évalué à 1.

      C'est pas le même workflow, pour employer un anglicisme.

      Avec submodule, tu as un dépôt parent et tu figes les commits des dépôts fils.

      C'est pratique quand tu veux re-compiler une lib dont tu as modifié les sources, ou quand tu veux factoriser du code entre plusieurs dépôts (les projets coreutils du gnu contiennent souvent un submodule gnulib, par exemple)

      Avec tsrc, tous les projets sont au même niveau, et tu vas t'arranger pour avoir des branches ou des tags cohérents.

      Par exemple, la branche 'master' de 'foo' sera toujours compatible avec la branche 'master' de 'bar', et donc
      'tsrc sync' te laissera dans un état cohérent. Ou bien, si tu veux reproduire un bug de la version 42, tu peux faire tsrc foreach git reset --v0.42

      Note également que l'approche "figer les commits des dépendances" fonctionne aussi dans tsrc depuis la version 0.2, puisque tu peux spécifier des 'fixed_ref' dans le fichier manifest.

  • # Ressemble à qisrc

    Posté par  (site web personnel) . Évalué à 3.

    Hum, ça ressemble beaucoup à qisrc

    • [^] # Re: Ressemble à qisrc

      Posté par  (site web personnel) . Évalué à 2.

      Le fait que ça soit écrit par la même personne y est sûrement pour quelque chose :)

      • [^] # Re: Ressemble à qisrc

        Posté par  (site web personnel) . Évalué à 2.

        Effectivement :).

        Mais vu que qisrc/qibuild sont libres, pour quelle raison pour ne pas les avoir réutilisés ? Qu'apporte tsrc que n'a pas qisrc ?

        • [^] # Re: Ressemble à qisrc

          Posté par  (site web personnel) . Évalué à 2.

          pour quelle raison ne pas les avoir réutilisés

          Comme expliqué dans le commentaire ci-dessus: Quelle est la genèse du project , à l'origine il n'était pas prévu de ré-implémenter qisrc, c'était juste du code pour les scripts d'intégrations continue.

          Ensuite, les frustrations autour de repo nous ont convaincus qu'il fallait changer d'outil, et j'ai profité de l'opportunité de recoder le projet "du début".

          Qu'apporte tsrc que n'a pas qisrc ?

          • qisrc est couplé à qibuild, qui est un framework de gestion de projets C++
          • qisrc est intégré à Gerrit, alors que tsrc s'intègre à GitLab
          • tsrc a un code beaucoup plus simple (7 fois moins de lignes que qisrc), et n'a gardé que l'essentiel des fonctionnalités.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.