Je vais travailler avec d'autres personnes sur le code d'un projet qui utilise cvs. Nous voulons utiliser un vcs distribué pour faire notre travail et quand nous aurons fini ou peut-être de temps en temps nous voulons engager notre code et tout notre historique de révision dans les cvs. Nous n'avons pas accès en écriture au référentiel cvs du projet, nous ne pouvons donc pas nous engager très fréquemment. Quel outil pouvons-nous utiliser pour exporter notre historique des révisions vers des CV? Actuellement, nous pensions utiliser git ou Mercurial mais nous pourrions utiliser un autre vcs distribué si cela pouvait faciliter l'exportation.
Heureusement pour ceux d'entre nous qui sont toujours obligés d'utiliser CVS, git fournit de très bons outils pour faire exactement ce que vous voulez faire. Mes suggestions (et ce que nous faisons ici chez $ work):
Utilisez git cvsimport
Pour cloner l'historique des révisions CVS dans un référentiel git. J'utilise l'invocation suivante:
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
-A /path/to/authors/file cvs_module_to_checkout
L'option -A
Est facultative mais elle aide à rendre votre historique de révision importé de CVS plus git-like (voir man git-cvsimport
pour plus d'informations sur la façon dont cela est défini vers le haut).
En fonction de la taille et de l'historique du référentiel CVS, cette première importation prendra TRÈS longtemps. Vous pouvez ajouter un -v à la commande ci-dessus si vous voulez avoir la tranquillité d'esprit que quelque chose se passe réellement.
Une fois ce processus terminé, vous disposerez d'une branche master
qui devrait refléter le CV HEAD (à l'exception que git cvsimport
Par défaut ignore les 10 dernières minutes) des validations pour éviter d’attraper une validation à moitié terminée. Vous pouvez ensuite utiliser git log
et vos amis pour examiner l’historique complet du référentiel comme s’il utilisait git depuis le début.
Il y a quelques ajustements de configuration qui faciliteront les importations incrémentielles de CVS (ainsi que les exportations) à l'avenir. Ceux-ci ne sont pas documentés sur la page de manuel git cvsimport
Donc je suppose qu'ils pourraient changer sans préavis mais, FWIW:
% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT
Toutes ces options peuvent être spécifiées sur la ligne de commande afin que vous puissiez ignorer cette étape en toute sécurité.
git cvsimport
Suivant devrait être beaucoup plus rapide que la première invocation. Cependant, il fait un cvs rlog
Sur chaque répertoire (même ceux qui n'ont que des fichiers dans Attic
) donc cela peut encore prendre quelques minutes. Si vous avez spécifié les configurations suggérées ci-dessus, il vous suffit d'exécuter:
% git cvsimport
Si vous n'avez pas configuré vos configurations pour spécifier les valeurs par défaut, vous devrez les spécifier sur la ligne de commande:
% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout
Quoi qu'il en soit, deux choses à garder à l'esprit:
cvsimport
qui prendra encore une fois.master
afin que les modifications puissent être fusionnées (ou rebasées) dans vos branches locales/de sujet.Dans la pratique, je recommande de toujours apporter des modifications aux branches et de ne fusionner vers master
que lorsque vous êtes prêt à réexporter ces modifications dans le référentiel CVS. Vous pouvez utiliser le flux de travail que vous souhaitez sur vos branches (fusion, rebasage, écrasement, etc.) mais bien sûr, les règles de rebasage standard s'appliquent: ne rebasez pas si quelqu'un a basé ses modifications sur votre branche.
La commande git cvsexportcommit
Vous permet d'exporter une seule validation vers le serveur CVS. Vous pouvez spécifier un ID de validation unique (ou tout ce qui décrit un commit spécifique tel que défini dans man git-rev-parse
). Un diff est ensuite généré, appliqué à une extraction CVS puis (éventuellement) validé dans CVS à l'aide du client cvs
réel. Vous pouvez exporter chaque micro commit sur vos branches de sujet, mais en général j'aime créer un commit de fusion sur un master
à jour et exporter ce seul commit de fusion vers CVS. Lorsque vous exportez un commit de fusion, vous devez indiquer à git quel parent de commit utiliser pour générer le diff. De plus, cela ne fonctionnera pas si votre fusion était une avance rapide (voir la section "COMMENT FONCTIONNE LA FUSION" de man git-merge
pour une description d'une fusion à avance rapide) afin que vous devez utiliser l'option --no-ff
lors de la fusion. Voici un exemple:
# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD
Vous pouvez voir ce que chacune de ces options signifie sur la page de manuel de git-cvsexportcommit . Vous avez la possibilité de définir l'option -w
Dans votre configuration git:
% git config cvsexportcommit.cvsdir /path/to/cvs/checkout
Si le patch échoue pour une raison quelconque, mon expérience est que vous serez (malheureusement) probablement mieux de copier les fichiers modifiés manuellement et de valider en utilisant le client cvs. Cependant, cela ne devrait pas se produire si vous vous assurez que master
est à jour avec CVS avant de fusionner votre branche de rubrique.
Si la validation échoue pour une raison quelconque (problèmes réseau/autorisations, etc.), vous pouvez prendre la commande imprimée sur votre terminal à la fin de la sortie d'erreur et l'exécuter dans votre répertoire de travail CVS. Cela ressemble généralement à ceci:
% cvs commit -F .msg file1 file2 file3 etc
La prochaine fois que vous effectuez un git cvsimport
(En attendant au moins 10 minutes), vous devriez voir le patch de votre commit exporté réimporté dans votre référentiel local. Ils auront des ID de validation différents, car la validation CVS aura un horodatage différent et éventuellement un nom de committer différent (selon que vous avez configuré un fichier d'auteurs dans votre cvsimport
initial ci-dessus).
Si plusieurs personnes ont besoin de faire le cvsimport
, il serait plus efficace d'avoir un seul référentiel git qui effectue le cvsimport et d'avoir tous les autres référentiels créés en tant que clone. Cela fonctionne parfaitement et le référentiel cloné peut exécuter cvsexportcommits comme décrit ci-dessus. Il existe cependant une réserve. En raison de la façon dont les validations CVS reviennent avec différents ID de validation (comme décrit ci-dessus), vous ne voulez pas que votre branche clonée suive le référentiel git central. Par défaut, voici comment git clone
Configure votre référentiel mais cela est facilement résolu:
% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge
Après avoir supprimé ces configurations, vous devrez indiquer explicitement où et quoi extraire lorsque vous souhaitez extraire de nouvelles validations du référentiel central:
% git pull Origin master
Dans l'ensemble, j'ai trouvé que ce flux de travail était assez gérable et la "meilleure chose suivante" lors de la migration complète vers git n'est pas pratique.
Vous ne devez pas faire confiance cvsimport à l'aveugle et vérifier si l'arborescence importée correspond à ce qui se trouve dans le dépôt CVS. Je l'ai fait en partageant le nouveau projet à l'aide du plug-in Eclipse CVS et j'ai constaté qu'il y avait des incohérences ..
Deux validations effectuées en moins d'une minute avec le même message de validation (afin de rétablir un fichier supprimé par erreur) ont été regroupées en une seule grande validation, ce qui a entraîné un fichier manquant dans l'arborescence.
J'ai pu résoudre ce problème en modifiant le paramètre "fuzz" à moins d'une minute.
exemple:
% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
-A /path/to/authors/file cvs_module_to_checkout -z 15
résultat: vérifiez votre arbre après l'importation
En plus de la réponse de Brian Phillips: il y a aussi git-cvsserver qui fonctionne comme le serveur CVS mais accède en fait au dépôt git ... mais il a quelques limitations.