Heureusement pour ceux d'entre nous qui sont encore 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
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' -A
option est facultative, mais elle permet de donner à votre historique des révisions importé de CVS un aspect plus git (voir man git-cvsimport
pour plus d'informations sur la configuration).
Selon la taille et l'historique du référentiel CVS, cette première importation prendra TRES 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 aurez une master
branche qui devrait refléter HEAD de CVS (à l'exception que git cvsimport
par défaut ignore les 10 dernières minutes de commits pour éviter d'attraper un commit à moitié terminé). Vous pouvez ensuite utiliser git log
et friends pour examiner l'historique entier du référentiel comme s'il utilisait git depuis le début.
Ajustements de configuration
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 git cvsimport
page de manuel, 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é.
Importations incrémentielles
La suite git cvsimport
devrait être beaucoup plus rapide que la première invocation. Cependant, il effectue un cvs rlog
sur chaque répertoire (même ceux qui ne contiennent que des fichiers Attic
), cela peut donc 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 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:
- Assurez-vous que vous êtes dans le répertoire racine de votre référentiel git. Si vous êtes ailleurs, il essaiera de faire un nouveau
cvsimport
qui prendra à nouveau une éternité.
- Assurez-vous que vous êtes sur votre
master
branche afin que les modifications puissent être fusionnées (ou rebasées) dans vos branches locales / thématiques.
Faire des changements locaux
En pratique, je recommande de toujours apporter des modifications sur les branches et de ne fusionner que master
lorsque vous êtes prêt à exporter ces modifications vers le référentiel CVS. Vous pouvez utiliser le workflow de votre choix 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 d'autre a basé ses modifications sur votre branche.
Exportation des modifications vers CVS
La git cvsexportcommit
commande vous permet d'exporter un seul commit vers le serveur CVS. Vous pouvez spécifier un seul ID de validation (ou tout ce qui décrit une validation spécifique telle que définie dans man git-rev-parse
). Un diff est ensuite généré, appliqué à une extraction CVS puis (éventuellement) validé dans CVS en utilisant le cvs
client réel . Vous pouvez exporter chaque micro-commit sur vos branches thématiques, mais en général, j'aime créer un commit de fusion sur un commit à jour master
et exporter ce commit de fusion unique 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" man git-merge
pour une description d'une fusion à avance rapide). Vous devez donc utiliser le--no-ff
option 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 la signification de chacune de ces options sur la page de manuel de git-cvsexportcommit . Vous avez la possibilité de définir l' -w
option dans votre configuration git:
% git config cvsexportcommit.cvsdir /path/to/cvs/checkout
Si le correctif échoue pour une raison quelconque, mon expérience est que vous ferez probablement (malheureusement) mieux de copier les fichiers modifiés manuellement et de les valider à l'aide du client cvs. Cependant, cela ne devrait pas se produire si vous vous assurez que master
CVS est à jour avant de fusionner votre branche thématique.
Si la validation échoue pour une raison quelconque (problèmes de 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
(attendre au moins 10 minutes), vous devriez voir le correctif de votre commit exporté réimporté dans votre référentiel local. Ils auront des ID de commit différents puisque le commit CVS aura un horodatage différent et éventuellement un nom de committer différent (selon que vous avez configuré un fichier auteurs dans votre initiale cvsimport
ci-dessus).
Cloner votre clone CVS
Si vous avez plus d'une personne devant faire le cvsimport
, il serait plus efficace d'avoir un seul référentiel git qui effectue le cvsimport et que tous les autres référentiels soient créés en tant que clone. Cela fonctionne parfaitement et le référentiel cloné peut effectuer des commandes cvsexport comme décrit ci-dessus. Il existe cependant une réserve. En raison de la manière 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
configurer 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 explicitement dire où et quoi extraire lorsque vous souhaitez extraire de nouveaux commits depuis le référentiel central:
% git pull origin master
Dans l'ensemble, j'ai trouvé que ce flux de travail était assez gérable et que la "prochaine meilleure chose" lors d'une migration complète vers git n'est pas pratique.