Mon organisation envisage de passer de SVN à Git. Un argument contre le déplacement est le suivant:
Comment faisons-nous le versioning?
Nous avons une distribution SDK basée sur la plate-forme NetBeans. Comme les révisions SVN sont de simples chiffres, nous pouvons les utiliser pour étendre les numéros de version de nos plugins et versions du SDK. Comment gérons-nous cela lorsque nous passons à Git?
Solutions possibles:
Si quelqu'un d'autre a rencontré un problème similaire et l'a résolu, nous aimerions savoir comment.
Utilisez tags pour marquer les validations avec les numéros de version:
git tag -a v2.5 -m 'Version 2.5'
Poussez les balises en amont - cela ne se fait pas par défaut:
git Push --tags
Ensuite, utilisez la commande décrire :
git describe --tags --long
Cela vous donne une chaîne du format:
v2.5-0-gdeadbee
^ ^ ^^
| | ||
| | |'-- SHA of HEAD (first seven chars)
| | '-- "g" is for git
| '---- number of commits since last tag
|
'--------- last tag
Cela est venu sur quelques projets pour moi. La meilleure solution que j'ai eu jusqu'à présent est de générer un numéro de version comme celui-ci:
x.y. <nombre de validations> .r <git-hash>
En règle générale, il est généré par notre système de génération à l'aide d'une combinaison d'un fichier ou d'une balise statique pour obtenir les principaux numéros de révision, git rev-list HEAD | wc -l
(qui était plus rapide que l'utilisation de git log
), et git rev-parse HEAD
. Le raisonnement était le suivant:
Le numéro 2 est invisible pour la plupart des gens, mais est vraiment important et vraiment difficile avec le contrôle de source distribué. SVN vous y aide en vous donnant un numéro de révision unique. Il s'avère qu'un nombre de validations est aussi proche que possible, tout en résolvant par magie # 4 également. En présence de branches, ce n'est pas encore unique, auquel cas nous ajoutons le hachage, qui résout également parfaitement # 3.
La plupart de cela était destiné à accueillir le déploiement via le pip de Python. Cela garantissait que pip install
serait peut-être un peu étrange pendant le développement parallèle (c'est-à-dire que les packages de personnes sur différentes branches se mélangeraient, mais de manière déterministe), mais qu'après la fusion, tout était réglé. À moins de la présence d'un rebase exposé ou d'un amendement, cela a très bien fonctionné pour les exigences ci-dessus.
Au cas où vous vous poseriez la question, nous avons choisi de mettre le r devant le hachage en raison d'une certaine bizarrerie avec la façon dont Python gère les lettres dans les numéros de version (c'est-à-dire que ae est inférieur à 0, ce qui faire "1.3.10.a1234" <"1.3.10" <"1.3.10.1234").
C'est peut-être un peu exagéré, mais je vous ferai savoir comment nous procédons.
Nous utilisons une structure de branchement très similaire à this .
Hudson construit à partir de nos branches "développées" et incrémente les numéros de build à partir de 0. Le numéro de build est unique pour chaque projet et est étiqueté dans le contrôle de version. La raison en est que vous pouvez dire exactement de quelle génération de branche de développement 42 est issue, par exemple (chaque projet peut avoir plusieurs branches de développement en parallèle, car chaque projet peut avoir plusieurs équipes travaillant sur différents aspects du projet).
Lorsque nous décidons qu'une version particulière est suffisamment bonne pour être publiée, la validation qui a déclenché cette génération est étiquetée avec un numéro de version, qui est décidé par le marketing. Cela signifie que les équipes de développement ne se soucient pas du numéro de version final et que le marketing est libre de mélanger les numéros de version comme bon lui semble. Le numéro de version final et le numéro de build sont tous deux présents dans le produit publié.
Exemple: 2.1.0 build 1337
Cela signifie que, pour une version de produit spécifique, vous pouvez savoir quelle a été la dernière équipe à y avoir travaillé et vous pouvez interroger git pour toutes les validations menant à la publication afin de diagnostiquer un problème si vous en avez besoin.
Les versions sont identifiées en hachant les hachages SHA1 de tous les fichiers de l'arborescence de répertoires stockés au moment de l'archivage. Ce hachage est stocké à côté des hachages des enregistrements parents afin que l'historique complet puisse être lu.
Jetez un œil au processus d'utilisation de 'git-describe' via GIT-VERSION-GEN et comment vous pouvez l'ajouter via votre processus de construction lorsque vous balisez votre version.
Voici un blog sympa qui donne un exemple de comment obtenir ce que vous voulez:
http://cd34.com/blog/programming/using-git-to-generate-an-automatic-version-number/
Jon Purdy a la bonne idée. git flow
facilite également la gestion réelle de ces branches, et la gestion des branches est un argument pour passer à git
.
Commençons par un aperçu de base de git
, puisque vous venez de la perspective svn
- à -git
. Considérez dans git
ce qui suit:
master--...............-.....-..............-
\ / / /
---develop---------............../
\ /
--feature---
Ci-dessus, vous branchez master
vers develop
(désigné par le \
) et branchez develop
vers une branche feature
. Nous fusionnons ces branches (notées par /
), avec des validations (-
) le long d'une branche. (S'il n'y a pas de commit mais que la fusion est bien à droite, il y a .
indicateurs pour montrer que le prochain -
est le prochain commit).
Assez facile. Et si nous avons un correctif dans notre version principale?
master--...............-.....-................-...........-.........-
\ / / / \ /| /
\ / / / -hotfix-- V /
---develop---------............../..............-...----
\ / \ V /
--feature--- --feature2...----
Ci-dessus, develop
ramifié à partir de master
. Le bogue découvert dans master
a été corrigé en se ramifiant à partir de master
, en le corrigeant et en le fusionnant à nouveau dans master
. Nous avons ensuite fusionné master
en develop
, puis develop
en feature2
, qui a déplacé le nouveau code de hotfix
dans ces branches.
Lorsque vous fusionnez feature2
retour à develop
, son historique inclut develop
avec le hotfix
. De même, develop
est fusionné dans feature2
avec le nouveau code de master
, donc la fusion de develop
vers master
se fera sans accroc, car elle est basée sur cette validation dans master
à ce moment-là, comme si vous aviez créé une branche depuis master
à ce moment-là.
Voici donc une autre façon de procéder.
master--..........-........-
\ /\ /
---1.0-- --1.1--
Vos versions 1.0 sont marquées —1.0.1
, 1.0.2
, 1.0.3
, et ainsi de suite.
Voici maintenant une astuce: vous avez trouvé un bogue dans 1.0 et il affecte 1.1, 1.2 et 1.3. Que faire?
Vous dérivez votre dernière version maintenue ou la plus ancienne et la corrigez. Ensuite, vous fusionnez votre nouvelle branche hotfix
dans 1.3
— et dans 1.2
, 1.1
, et 1.0
. Ne branchez pas de chacune des branches de version de maintenance; ne fusionne pas 1.0
dans master
ou fusionnez master
dans 1.0
. Prenez la branche hotfix
et fusionnez-la dans toutes vos branches de version. S'il y a des conflits, il vous le dira; vérifiez votre code pour vous assurer que les modifications sont correctes (git diff
est votre ami).
Maintenant, ce changement spécifique est appliqué partout. La lignée est ramifiée, mais ça va. Ce n'est pas aléatoire. Marquer le 1.3
la tête en tant que 1.3.17, le fusionner dans chaque fonctionnalité en cours ramifiée à partir de 1.3
, et avance.
Le git flow
L'extension vous aide à gérer ces branches de maintenance, de fonctionnalités et de correctifs. Une fois que vous avez arrêté le flux de travail, cela est trivial et élimine énormément de problèmes dans la gestion du code source.
J'ai vu cela se faire sur des équipes de programmation, mais je n'ai pas travaillé aussi profondément en tant que programmeur moi-même, donc je continue de me familiariser avec le flux de travail quotidien.