101 votes

Comment exporter l'historique des révisions de mercurial ou git vers cvs ?

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 lorsque nous terminons ou peut-être de temps en temps, nous voulons commiter notre code et tout l'historique de nos révisions dans cvs. Nous n'avons pas d'accès en écriture au repo cvs du projet et nous ne pouvons pas commiter très fréquemment. Quel outil pouvons-nous utiliser pour exporter notre historique de révision vers cvs ? Actuellement, nous pensions utiliser git ou mercurial mais nous pourrions utiliser un autre vcs distribué si cela pouvait faciliter l'exportation.

238voto

Brian Phillips Points 7023

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 à $work) :

Création du clone initial

Utilice git cvsimport pour cloner l'historique des révisions CVS dans un dépôt 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

El -A est facultative, mais elle permet de rendre l'historique des révisions importé de CVS plus proche de celui de git (cf. man git-cvsimport pour plus d'informations sur la façon dont cela est mis en place).

Selon la taille et l'historique du dépôt CVS, cette première importation prendra un TRES long moment. Vous pouvez ajouter un -v à la commande ci-dessus si vous voulez avoir la certitude que quelque chose est en train de se passer.

Une fois ce processus achevé, vous aurez une master qui devrait refléter le HEAD de CVS (à l'exception de la branche git cvsimport par défaut, ignore les 10 dernières minutes de commits pour éviter d'attraper un commit qui est à moitié terminé). Vous pouvez alors utiliser git log et amis pour examiner l'historique complet du dépôt comme s'il avait utilisé git depuis le début.

Ajustements de la configuration

Il y a quelques ajustements de configuration qui rendront les importations incrémentielles depuis CVS (ainsi que les exportations) plus faciles à l'avenir. Elles ne sont pas documentées sur le site git cvsimport donc je suppose qu'ils pourraient changer sans préavis, mais, pour info.. :

% 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, vous pouvez donc sauter cette étape.

Importations incrémentielles

Par la suite, git cvsimport devrait être beaucoup plus rapide que la première invocation. Cependant, elle effectue un cvs rlog sur chaque répertoire (même ceux qui n'ont que des fichiers en Attic ), ce qui peut prendre quelques minutes. Si vous avez spécifié les configurations suggérées ci-dessus, tout ce que vous avez à faire est d'exécuter :

% git cvsimport

Si vous n'avez pas paramétré 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 :

  1. Assurez-vous que vous êtes dans le répertoire racine de votre dépôt git. Si vous êtes ailleurs, il essaiera de faire un nouveau cvsimport qui prendra encore une fois une éternité.
  2. Assurez-vous que vous êtes sur votre master afin que les changements puissent être fusionnés (ou rebasés) dans vos branches locales/sujets.

Apporter des changements locaux

En pratique, je recommande de toujours faire des changements sur les branches et de ne fusionner que vers master lorsque vous êtes prêt à exporter ces modifications vers le référentiel CVS. Vous pouvez utiliser le flux de travail que vous voulez sur vos branches (fusion, rebasage, écrasement, etc.) mais bien sûr les règles standard de rebasage s'appliquent : ne rebasez pas si quelqu'un d'autre a basé ses changements sur votre branche.

Exporter des changements vers CVS

El git cvsexportcommit vous permet d'exporter un seul commit vers le serveur CVS. Vous pouvez spécifier un seul ID de commit (ou tout ce qui décrit un commit spécifique tel que défini dans le fichier man git-rev-parse ). Un diff est alors généré, appliqué à un checkout CVS et ensuite (optionnellement) commité dans CVS en utilisant l'adresse réelle de l'utilisateur. cvs client. Vous pouvez exporter chaque micro-commande sur vos branches de sujet mais, en général, j'aime créer une commande de fusion sur une branche à jour. master et exporter ce seul commit de fusion vers CVS. Lorsque vous exportez un commit de fusion, vous devez indiquer à git quel commit parent utiliser pour générer la différence. De plus, cela ne fonctionnera pas si votre fusion était un fast-forward (voir la section "COMMENT FONCTIONNE UNE FUSION" du document man git-merge pour une description d'une fusion avec avance rapide), vous devez donc utiliser la fonction --no-ff lors de l'exécution 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 le site Web de la Commission européenne. Page de manuel de git-cvsexportcommit . Vous avez la possibilité de définir le -w dans votre configuration git :

% git config cvsexportcommit.cvsdir /path/to/cvs/checkout

Si le patch échoue pour une raison quelconque, mon expérience m'a montré qu'il est (malheureusement) préférable de copier manuellement les fichiers modifiés et de les valider à l'aide du client cvs. Cela ne devrait pas arriver, cependant, si vous vous assurez que master est à jour avec CVS avant de fusionner votre branche de sujet.

Si le commit échoue pour une raison quelconque (problèmes de réseau/permissions, etc), vous pouvez prendre la commande affichée dans 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 à quelque chose comme ceci :

% cvs commit -F .msg file1 file2 file3 etc

La prochaine fois que vous ferez un git cvsimport (en attendant au moins 10 minutes) vous devriez voir le patch de votre commit exporté réimporté dans votre dépôt local. Ils auront des ID de commit différents puisque le commit CVS aura un horodatage différent et peut-être un nom de committeur différent (selon que vous avez mis en place un fichier d'auteurs dans votre version initiale de CVS). cvsimport ci-dessus).

Cloner votre clone CVS

Si plus d'une personne a besoin de faire le cvsimport Il serait plus efficace d'avoir un seul dépôt git qui effectue le cvsimport et d'avoir tous les autres dépôts créés comme clone. Cela fonctionne parfaitement et le dépôt cloné peut effectuer des cvsexportcommits comme décrit ci-dessus. Il y a cependant un problème. En raison de la façon dont les commits CVS reviennent avec des ID de commit différents (comme décrit ci-dessus), vous ne voulez pas que votre branche clonée suive le dépôt git central. Par défaut, c'est ainsi que git clone configure votre dépôt, mais il est facile d'y remédier :

% 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 de quoi tirer lorsque vous voudrez tirer de nouveaux commits du dépôt central :

% git pull origin master

Dans l'ensemble, j'ai trouvé que ce flux de travail était tout à fait gérable et qu'il constituait la "meilleure solution suivante" lorsque la migration complète vers git n'était pas pratique.

22voto

shil88 Points 491

Vous ne devriez pas faire confiance cvsimport aveuglément et vérifier si l'arbre importé correspond à ce qui se trouve dans le repo CVS. J'ai fait cela en partageant le nouveau projet à l'aide du plug-in CVS d'eclipse et j'ai constaté qu'il y avait des incohérences

Deux commits effectués en moins d'une minute avec le même message de commit (afin de rétablir un fichier supprimé par erreur) ont été regroupés en un seul gros commit, ce qui a entraîné la disparition d'un fichier de l'arbre

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

la ligne de fond : vérifiez votre arbre après l'importation

3voto

Jakub Narębski Points 87537

En plus de la réponse de Brian Phillips : il y a aussi git-cvsserver qui fonctionne comme un serveur CVS mais qui accède au dépôt git... mais il a quelques limitations.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X