Question

Dans mon entreprise, nous utilisons un référentiel SVN pour contenir notre code C ++. La base de code est composée d’une partie commune (infrastructure et applications) et de projets clients (développés sous forme de plug-ins).

La structure du référentiel ressemble à ceci:

  • Infrastructure
  • App1
  • App2
  • App3
  • projet-pour-client-1
    • plugin App1
    • App2-plugin
    • Configuration
  • projet-pour-client-2
    • plugin App1
    • App2-plugin
    • Configuration

Une version typique d'un projet client inclut les données de projet et chaque projet utilisé (par exemple, Infrastructure).

La disposition réelle de chaque répertoire est -

  • Infrastructure
    • branches
    • tags
    • tronc
  • projet-pour-client-2
    • branches
    • tags
    • tronc

Et il en va de même pour le reste des projets.

Nous avons plusieurs problèmes avec la disposition ci-dessus:

  1. Il est difficile de démarrer un nouvel environnement de développement pour un projet client car il est nécessaire de vérifier tous les projets impliqués (par exemple: Infrastructure, App1, App2, projet-pour-client-1).
  2. Il est difficile de marquer une version dans un projet client pour la même raison que ci-dessus.
  3. Si un projet client doit modifier un code commun (par exemple, Infrastructure), nous utilisons parfois une branche. Il est difficile de savoir quelles branches sont utilisées dans les projets.

Existe-t-il un moyen dans SVN de résoudre l’un de ces problèmes? J'ai pensé à utiliser svn: externals dans les projets clients, mais après avoir lu cet article Je comprends que ce n'est peut-être pas le bon choix.

Était-ce utile?

La solution

Vous pouvez gérer cela avec svn: externals. Ceci est l'URL à une place dans un svn repo Cela vous permet d'extraire des parties d'un référentiel différent (ou du même). Une façon de l'utiliser est sous project-for-client2, vous ajoutez un lien svn: externals à la branche de l'infrastructure dont vous avez besoin, la branche d'app1 dont vous avez besoin, etc. Ainsi, lorsque vous extrayez project-for-client2, vous obtenez toutes les pièces correctes.

Les liens svn: externals sont versionnés avec tout le reste, ainsi, lorsque projet-pour-client1 est balisé, ramifié et mis à jour, les branches externes correctes seront toujours intégrées.

Autres conseils

Une suggestion est de changer la disposition des répertoires de

  • Infrastructure
    • branches
    • tags
    • tronc
  • projet-pour-client-1
    • branches
    • tags
    • tronc
  • projet-pour-client-2
    • branches
    • tags
    • tronc

à

  • branches
    • feature-1
      • Infrastructure
      • projet-pour-client-1
      • projet-pour-client-2
  • tags
  • tronc
    • Infrastructure
    • projet-pour-client-1
    • projet-pour-client-2

Il y a aussi quelques problèmes avec cette mise en page. Les branches deviennent énormes, mais au moins, il est plus facile de baliser des endroits spécifiques dans votre code.

Pour utiliser le code, il suffit simplement de vérifier le coffre et de travailler avec cela. Ensuite, vous n'avez pas besoin des scripts qui extraient tous les différents projets. Ils se réfèrent simplement à l'infrastructure avec "../ Infrastructure". Un autre problème avec cette disposition est que vous devez extraire plusieurs copies si vous voulez travailler sur des projets de manière totalement indépendante. Sinon, une modification de l'infrastructure d'un projet risque d'empêcher la compilation d'un autre projet tant que ce dernier n'est pas mis à jour également.

Cela pourrait rendre les versions un peu plus lourdes également et séparer le code de différents projets.

Oui, ça craint. Nous faisons la même chose, mais je ne peux pas vraiment penser à une meilleure mise en page.

Donc, nous avons un ensemble de scripts qui peuvent automatiser tout ce qui est lié à la subversion. Le projet de chaque client contiendra un fichier nommé project.list , contenant tous les projets / chemins de sous-version nécessaires à la construction de ce client. Par exemple:

Infrastructure/trunk
LibraryA/trunk
LibraryB/branches/foo
CustomerC/trunk

Chaque script ressemble alors à ceci:

for PROJ in $(cat project.list); do
    # execute commands here
done

Où les commandes peuvent être une extraction, une mise à jour ou une balise. C’est un peu plus compliqué que cela, mais cela signifie que tout est cohérent: extraire, mettre à jour et marquer devient une seule et même commande.

Et bien sûr, nous essayons d’agréger le moins possible, ce qui est la suggestion la plus importante que je puisse faire. Si nous devons créer une branche, nous allons essayer de travailler hors du tronc ou de la version précédemment balisée du plus grand nombre possible de dépendances.

Tout d'abord, je ne suis pas d'accord pour dire que les externes sont diaboliques. Bien qu'ils ne soient pas parfaits.

Actuellement, vous effectuez plusieurs extractions pour créer une copie de travail. Si vous utilisiez des utilisateurs externes, cela se produirait exactement, mais automatiquement et systématiquement à chaque fois.

Si vous dirigez vos références externes vers des balises (et / ou des révisions spécifiques) au sein des projets cibles, il vous suffit de baliser le projet actuel par version (car cette balise indiquerait exactement sur quelle externe vous vous dirigiez). Vous auriez également un enregistrement dans votre projet indiquant le moment exact où vous avez modifié vos références externes pour utiliser une nouvelle version d’une bibliothèque particulière.

Les externes ne sont pas une panacée - et comme le montre l'article, il peut y avoir des problèmes. Je suis sûr qu'il y a quelque chose de mieux que les externes, mais je ne l'ai pas encore trouvé (même conceptuellement). Certes, la structure que vous utilisez peut générer beaucoup d'informations et de contrôle dans votre processus de développement, l'utilisation d'externaux pouvant y contribuer. Cependant, les problèmes qu’il avait rencontrés n’étaient pas des problèmes de corruption fondamentaux: un accès propre résoudrait tout le problème et est plutôt rare (êtes-vous vraiment incapable de créer une nouvelle branche d’une bibliothèque dans votre référentiel?).

Points à prendre en compte - utilisation d’externes récursifs. Je ne suis pas vendu sur le oui ou le non de cela et ont tendance à aller avec une approche pragmatique.

Pensez à utiliser piston comme le suggère l'article. Je ne l'ai pas vu en action, je ne peux donc pas vraiment le commenter, il peut faire le même travail que les externes de manière plus efficace.

D'après mon expérience, je pense qu'il est plus utile de disposer d'un référentiel pour chaque projet individuel. Sinon, vous avez les problèmes que vous dites et, en outre, les numéros de révision changent si d'autres projets changent, ce qui pourrait prêter à confusion.

Uniquement s'il existe une relation entre des projets individuels, tels que des logiciels, des schémas matériels, de la documentation, etc. Nous utilisons un référentiel unique, de sorte que le numéro de révision permet de placer l'ensemble dans un état connu.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top