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


Voy a trabajar con otras personas en el código de un proyecto que utiliza cvs. Queremos usar un vcs distribuido para hacer nuestro trabajo y cuando terminemos o tal vez de vez en cuando queremos enviar nuestro código y todo nuestro historial de revisiones a cvs. No tenemos acceso de escritura al repositorio cvs del proyecto, por lo que no podemos comprometernos con mucha frecuencia. ¿Qué herramienta podemos usar para exportar nuestro historial de revisiones a cvs? Actualmente estábamos pensando en usar git o mercurial pero podríamos usar otro vcs distribuido si pudiera hacer la exportación más fácil.

Author: skiphoppy, 2009-02-25

3 answers

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

Creando el Clon inicial

Use git cvsimport para clonar el historial de revisiones de CVS en un repositorio git. Utilizo 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 tu historial de revisiones importado de CVS se vea más parecido a git (ver man git-cvsimport para obtener más información sobre cómo se configura esto).

Dependiendo del tamaño y el historial del repositorio CVS, esta primera importación tomará mucho tiempo. Puede agregar a-v al comando anterior si desea la tranquilidad de que algo está sucediendo de hecho.

Una vez que se complete este proceso, tendrá una rama master que debería reflejar la CABEZA de CVS (con la excepción de que git cvsimport por defecto ignora los últimos 10 minutos de confirmaciones para evitar atrapar una confirmación eso está a medio terminar). Luego puede usar git log y amigos para examinar todo el historial del repositorio como si hubiera estado usando git desde el principio.

Ajustes de configuración

Hay algunos ajustes de configuración 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 de manual de 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 comandos para que pueda omitir este paso con seguridad.

Importaciones incrementales

git cvsimport posterior debe ser mucho más rápido que la primera invocación. Sin embargo, hace un cvs rlog en cada directorio (incluso aquellos que solo tienen archivos en Attic) por lo que todavía 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 predeterminados, deberá especificarlos en el línea de comandos:

% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout

De cualquier manera, dos cosas a tener en cuenta: {[35]]}

  1. Asegúrate de estar en el directorio raíz de tu repositorio git. Si estás en cualquier otro lugar, se tratará de hacer un fresco cvsimport que de nuevo tomará para siempre.
  2. Asegúrese de que está en su rama master para que los cambios se puedan fusionar (o rebasar) en sus ramas locales/temáticas.

Hacer Cambios Locales

En la práctica, recomiendo siempre hacer cambios en las ramas y solo fusionar a master cuando esté listo para exportar esos cambios al repositorio CVS. Puedes usar cualquier flujo de trabajo que quieras en tus ramas (fusionar, rebasear, aplastar, etc.) pero por supuesto se aplican las reglas de rebaseo estándar: no rebases si alguien más ha estado basando sus cambios en tu rama.

Exportar cambios a CVS

El comando git cvsexportcommit le permite exportar una sola confirmación al servidor CVS. Puede especificar un único ID de confirmación (o cualquier cosa que describa un commit específico tal como se define en man git-rev-parse). Luego se genera una diferencia, se aplica a un CVS checkout y luego (opcionalmente) se confirma a CVS usando el cliente cvs real. Puedes exportar cada micro commit en tus ramas de temas, pero generalmente me gusta crear una merge commit en un master actualizado y exportar esa única merge commit a CVS. Cuando exportas un commit merge, tienes que decirle a git qué padre de commit debe usar para generar el diff. Además, esto no funcionará si su fusión fue una avance rápido (consulte la sección "CÓMO FUNCIONA la FUSIÓN" de man git-merge para una descripción de una fusión de avance rápido), por lo que debe usar la opción --no-ff al realizar la fusión. He aquí 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 significan cada una de esas opciones en la página de manual de para git-cvsexportcommit. Tienes la opción de establecer la opción -w en tu configuración de git:

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

Si el parche falla por cualquier razón, mi experiencia es que (desafortunadamente) probablemente sea mejor copiar los archivos modificados manualmente y confirmar usando el cliente cvs. Sin embargo, esto no debería suceder si se asegura de que master esté actualizado con CVS antes de fusionar la rama de tema.

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

% cvs commit -F .msg file1 file2 file3 etc

El la próxima vez que haga un git cvsimport (esperando al menos 10 minutos) debería ver el parche de su confirmación exportada reimportada en su repositorio local. Tendrán diferentes identificadores de confirmación ya que la confirmación de CVS tendrá una marca de tiempo diferente y posiblemente un nombre de confirmación diferente (dependiendo de si configuró un archivo authors en su cvsimport inicial anterior).

Clonación de su CVS clon

Si usted tiene más de una persona que necesita hacer el cvsimport, sería más eficiente tener un repositorio git único que realiza el cvsimport y tiene todos los demás repositorios creados como un clon. Esto funciona perfectamente y el repositorio clonado puede realizar cvsexportcommits tal y como se describe anteriormente. Sin embargo, hay una advertencia. Debido a la forma en que las confirmaciones de CVS regresan con diferentes identificadores de confirmación (como se describió anteriormente), no desea que su rama clonada rastree el repositorio central de git. De forma predeterminada, así es como git clone configura su repositorio, pero esto es fácil remediado:

% 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 haber eliminado estas configuraciones, tendrá que decir explícitamente dónde y de qué extraer cuando desee extraer nuevas confirmaciones del repositorio 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áctica.

 239
Author: Brian Phillips,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-29 23:25:27

No debe confiar en cvsimport ciegamente y comprobar si el árbol importado coincide con lo que está en el repositorio CVS. He hecho esto compartiendo el nuevo proyecto usando eclipse CVS ' plug-in y encontré que había inconsistencias..

Dos confirmaciones que se hicieron en menos de un minuto con el mismo mensaje de confirmación (para revertir un archivo borrado erróneamente) se agruparon en una confirmación grande, lo que resultó en un archivo faltante del árbol..

Pude resolver este problema modificando el parámetro 'fuzz' a menos 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

En pocas palabras: compruebe su árbol después de importar

 21
Author: shil88,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-28 15:12:42

Además de Brian Phillips respuesta: también existe git-cvsserver que funciona como el servidor CVS, pero en realidad accede al repositorio git... pero tiene algunas limitaciones.

 3
Author: Jakub Narębski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-25 20:43:34