¿Cómo exportar el historial de revisión de mercurial o git a cvs?

Voy a trabajar con otras personas en el código de un proyecto que usa cvs. Queremos usar un vcs distribuido para hacer nuestro trabajo y cuando terminemos o tal vez de vez en cuando queramos comprometer nuestro código y todo nuestro historial de revisión a cvs. No tenemos acceso de escritura al repository cvs del proyecto, por lo que no podemos comprometernos con mucha frecuencia. ¿Qué herramienta podemos usar para exportar nuestro historial de revisión a cvs? Actualmente estábamos pensando en usar git o mercurial, pero podríamos usar otros vcs distribuidos si pudiera facilitar la export.

Afortunadamente para aquellos de nosotros que todavía estamos obligados a usar CVS, git proporciona herramientas muy buenas para hacer exactamente lo que queremos hacer. Mis sugerencias (y lo que hacemos aquí en $ work):

Creando el Clon Inicial

Utilice git cvsimport para clonar el historial de revisiones de CVS en un repository de git. Yo uso la siguiente invocación:

 % git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \ -A /path/to/authors/file cvs_module_to_checkout 

La opción -A es opcional, pero ayuda a que el historial de revisión importado de CVS se vea más parecido a un git (consulte man git-cvsimport para get más información sobre cómo se configura esto).

Dependiendo del tamaño y el historial del repository de CVS, esta primera import tomará MUCHO time. Puede agregar un -v al command anterior si desea la tranquilidad de que algo está sucediendo de hecho.

Una vez que se complete este process, tendrá una twig master que debe reflejar HEAD de CVS (con la exception de que git cvsimport ignora por omisión los últimos 10 minutos de confirmaciones para evitar la captura de una confirmación que está a medio terminar). A continuación, puede usar git log y friends para examinar todo el historial del repository como si hubiera estado usando git desde el principio.

Ajustes de configuration

Hay algunos ajustes de configuration que harán que las importaciones incrementales de CVS (así como las exportaciones) sean más fáciles en el futuro. Estos no están documentados en la página del git cvsimport , así que supongo que podrían cambiar sin previo aviso, pero, FWIW:

 % git config cvsimport.module cvs_module_to_checkout % git config cvsimport.r cvs % git config cvsimport.d $CVSROOT 

Todas estas opciones se pueden especificar en la línea de command para que pueda saltear este paso de forma segura.

Importaciones incrementales

La subsiguiente git cvsimport debería ser mucho más rápida que la primera invocación. Sin embargo, realiza un cvs rlog en cada directory (incluso aquellos que solo tienen files en Attic ) por lo que aún puede tomar unos minutos. Si ha especificado las configuraciones sugeridas anteriormente, todo lo que necesita hacer es ejecutar:

 % git cvsimport 

Si no ha configurado sus configuraciones para especificar los valores pnetworkingeterminados, deberá especificarlos en la línea de command:

 % git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout 

De cualquier manera, dos cosas a tener en count:

  1. Asegúrate de estar en el directory raíz de tu repository de git. Si está en cualquier otro lugar, intentará hacer un nuevo cvsimport que nuevamente tomará para siempre.
  2. Asegúrese de estar en su twig master para que los cambios se puedan fusionar (o volver a establecer) en sus twigs locales / temáticas.

Hacer cambios locales

En la práctica, recomiendo realizar siempre cambios en las twigs y solo fusionarlos con master cuando esté listo para exportar esos cambios al repository de CVS. Puede usar cualquier flujo de trabajo que desee en sus sucursales (fusión, rebase, aplastamiento, etc.) pero, por supuesto, se aplican las reglas estándar de rebase: no vuelva a establecer la base si alguien más ha basado sus cambios en su sucursal.

Exportación de cambios a CVS

El command git cvsexportcommit permite exportar una única confirmación al server CVS. Puede especificar una ID de confirmación única (o cualquier cosa que describa una confirmación específica como se define en man git-rev-parse ). A continuación, se genera un diff, se aplica a un pago de CVS y luego (opcionalmente) se compromete a CVS utilizando el cliente cvs real. Puede exportar cada microcompromiso en sus twigs de tema, pero generalmente me gusta crear una confluencia de fusión en un master actualizado y exportar esa única fusión a CVS. Cuando exporta un commit de fusión, tiene que indicarle a git cuál commit parent usar para generar el diff. Además, esto no funcionará si su fusión fue un avance rápido (consulte la sección "CÓMO FUNCIONA LA COMBINACIÓN" de man git-merge para get una descripción de una fusión de avance rápido), por lo que debe usar --no-ff opción cuando se realiza la combinación. Aquí hay un ejemplo:

 # 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 

Puede ver lo que significa cada una de esas opciones en la página del manual para git-cvsexportcommit . Usted tiene la opción de configurar la opción -w en su configuration de git:

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

Si el parche falla por alguna razón, mi experiencia es que (desafortunadamente) probablemente será mejor que copie manualmente los files modificados y se comprometa a usar el cliente cvs. Sin embargo, esto no debería suceder si se asegura de que el master esté actualizado con CVS antes de fusionar su twig de tema.

Si la confirmación falla por alguna razón (problemas de networking / permissions, etc.), puede tomar el command impreso en su terminal al final de la salida de error y ejecutarlo en su directory de trabajo CVS. Por lo general, se ve algo como esto:

 % cvs commit -F .msg file1 file2 file3 etc 

La próxima vez que haga un git cvsimport (esperando al less 10 minutos), debería ver el parche de su compromiso exportado reimportado en su repository local. Tendrán ID de confirmación diferentes ya que la confirmación de CVS tendrá una timestamp diferente y posiblemente un nombre de confirmador diferente (dependiendo de si configuró un file de autores en su cvsimport inicial).

Clonando tu clon de CVS

Si tiene más de una persona que necesita hacer el cvsimport , sería más eficiente tener un solo repository git que realice el cvsimport y tener todos los demás repositorys creados como un clon. Esto funciona perfectamente y el repository clonado puede realizar compromisos de cvsexport exactamente como se describió anteriormente. Sin embargo, hay una advertencia. Debido a la forma en que CVS se compromete con diferentes identificadores de confirmación (como se describe arriba), no desea que su sucursal clonada rastree el repository central de git. Por defecto, así es como git clone configura su repository, pero esto se remedia fácilmente:

 % git clone [CENTRAL_REPO_HERE] % cd [NEW_GIT_REPO_DIR_HERE] % git config --unset branch.master.remote % git config --unset branch.master.merge 

Después de eliminar estas configuraciones, tendrá que decir explícitamente dónde y qué extraer cuando desee get nuevas confirmaciones del repository central:

 % git pull origin master 

En general, he encontrado que este flujo de trabajo es bastante manejable y la "mejor opción" al migrar completamente a git no es práctico.

No debe confiar ciegamente en cvsimport y verificar si el tree importado constring con lo que está en el repository de CVS. Lo he hecho compartiendo el nuevo proyecto usando el plug-in de eclipse CVS y descubrí que había inconsistencias.

Dos confirmaciones que se realizaron en less de un minuto con el mismo post de confirmación (para revertir un file borrado incorrectamente) se agruparon en una confirmación grande, que dio como resultado un file perdido del tree.

Pude resolver este problema modificando el parámetro 'fuzz' a less de un minuto.

ejemplo:

 % git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \ -A /path/to/authors/file cvs_module_to_checkout -z 15 

línea de background: revise su tree después de importar

Además de la respuesta de Brian Phillips: también hay git-cvsserver que funciona como server CVS pero en realidad accede al repository de git … pero tiene algunas limitaciones.