version-control cvs revert

version control - ¿Cómo revertir un gran cambio en CVS?



version-control (10)

¿Has intentado usar la opción -d ? (construir subdirectorios)

Por lo que puedo recordar, está implícito para cvs co , pero no para cvs up .

Uno de mis colegas ha desordenado completamente los contenidos de un directorio en nuestro repositorio principal de CVS. Necesito simplemente revertir todo el módulo al estado en que estaba al final del año pasado. ¿Cuál es el comando de CVS para hacer esto, por favor?

Él ha agregado y eliminado cientos de archivos, por lo que una simple "copia de los archivos del antiguo pago y envío" no es suficiente.

Tengo RTFM y STFW, y probé esto:

cvs co modulename # Note no -P option cvs up -jHEAD -jMAIN:2008-12-30 modulename

Pero eso no funciona: los nuevos archivos que creó se eliminan, pero los archivos y directorios antiguos no resucitan. (No lo cometí).

Probablemente pueda escribir un script de shell para esto, pero seguramente esta funcionalidad ya debe estar en CVS.

Actualización: algunas aclaraciones:

  • Puedo obtener un pago local del módulo en una fecha específica. La pregunta es cómo devolver eso a CVS.

  • Tengo copias de seguridad, pero el uso puntual de un sistema de control de revisiones como CVS es que se supone que es fácil obtener cualquier estado histórico. La próxima vez que ocurra algo como esto, tal vez no tenga la suerte de tener copias de seguridad (por ejemplo, las copias de seguridad son diarias, así que puedo perder hasta un día de trabajo).

  • Sé que CVS es viejo, y deberíamos pasar a algo más nuevo. Pero en un equipo grande con una gran cantidad de herramientas basadas en CVS (scripts de compilación y compilación, servidor de compilación nocturno, etc.), el costo de tiempo de tal movimiento es considerable. (Evaluación, actualización de scripts, pruebas, migración, capacitación, pérdida de tiempo del desarrollador, mantenimiento de ambos sistemas en paralelo, ya que CVS aún sería necesario para las sucursales antiguas). Por lo tanto, esto tiene que ser planeado y programado por la administración.

Actualización n. ° 2: Voy a comenzar una recompensa por esto. Para calificar para la recompensa tienes que explicar cómo revertir el uso de comandos CVS normales, no con un guión de shell hacky.

Actualización n. ° 3: el servidor es CVS 1.12.13 . El acceso es a través de pserver. Puedo usar la misma versión de CVS en una PC Linux o CVSNT 2.0.51d en Windows.



Hay varios problemas con CVS y los está golpeando con ese problema.

  1. CVS está orientado a archivos, no hay concepto de un conjunto de cambios o snasphot. Eso significa que los cambios como el que desea revertir son un poco difíciles de manejar. Los commits son atómicos dentro de un directorio determinado, no afuera.

  2. Los directorios no están versionados. Eso significa que los directorios vacíos se eliminarán (si actualiza con -P ) y que debe especificar -d para crearlos al finalizar / actualizar.

Por lo tanto, para responder a su pregunta, probablemente las fechas sean la única forma de tratar porque no usó etiquetas para crear la versión del conjunto de cambios de un hombre pobre.

Mi comentario sobre las copias de seguridad es que puede ser más fácil recuperar todo el repositorio de las copias de seguridad que intentar corregir cosas que CVS no es realmente bueno.

Le animo, pero ese es otro tema, a cambiar el control de la versión tan pronto como pueda. Créanme, he estado lidiando con CVS durante mucho tiempo dentro del proyecto FreeBSD y aprendo rápidamente lo odioso que es CVS ... Vea aquí algunos de mis puntos de vista sobre el software de control de versiones.


Creo que su segundo comando también debería ser un checkout, en lugar de una actualización. No puedo justificar esto con lógica, ya que no hay lógica en el mundo de CVS, pero me ha funcionado. Prueba esto:

cvs co -P modulename cvs co -P -jHEAD -jMAIN:2008-12-30 modulename

Si está revertiendo una rama que no sea HEAD, por ejemplo, X, pase el argumento -rX en ambos comandos:

cvs co -P -rX modulename cvs co -P -rX -jHEAD -jMAIN:2008-12-30 modulename


Gran problema, no tiene una respuesta completa, solo un consejo sobre su scripting para tratar los espacios en los nombres de los archivos.

En lugar de

find ... | xargs tar c - | ...

intenta poner

find ... | perl -e ''@names = <>;'' -e ''chomp @names;'' -e ''system( "tar", "c", "-", @names);'' | ...

De esta manera, la creación de su archivo (u operaciones similares) no sufrirá espacios en los nombres, el análisis argv del shell se omite antes de llamar a tar.

Una cosa más, en caso de que realmente funcione: si hay una utilidad CVS a SVN, úselo (supongo que tal utilidad extraerá los archivos eliminados del "ático CVS"), y si guarda cada momento en el tiempo como un punto de control de nivel de proyecto (ya que SVN lo hace, a diferencia de CVS), use SVN para buscar el momento adecuado en el tiempo. Mucho si ...


Todavía estoy interesado en saber si hay una manera más fácil. (Seguramente debe haber una manera más fácil). Lo que terminé haciendo fue, en una PC con Linux usando bash:

# Get woking copy we''re going to change cd ~/work rm -rf modulename cvs up -dP modulename cd modulename # Remove all files find . -name CVS -prune -o -type f -print | xargs cvs rm -f # Get the old revision cd ~ mkdir scratch cd scratch cvs -q co -D 2008-12-31 modulename cd modulename # Copy everything to the working dir and do "cvs add" on it find . -name CVS -prune -o -type f -print | / xargs tar c | / (cd ~/work/modulename && tar xv | / xargs cvs add) # Check everything is OK before we commit cd ~/work/modulename cvs -nq up # it gave me an error on readme.txt because I''d deleted and then added it, so: mv readme.txt x # save good rev cvs add readme.txt # resurrect the bad rev mv x readme.txt # clobber file with good rev # Commit it cvs commit -m "Revert all changes this year" # Delete now-empty directories cvs -q up -dP # Double-check everything is back how it was diff -ur -xCVS ~/scratch/modulename ~/work/modulename

Luego descubrí que aún había diferencias: mi colega había agregado nombres de archivos que contenían espacios, que no fueron eliminados por el proceso anterior. Tuve que eliminarlos por separado. (Debería haber usado find ... -print0 lugar de -print , y pasé el argumento -0 a xargs . Simplemente no me di cuenta de que había archivos con espacios).


En realidad, su enfoque inicial fue muy cercano a la solución. El problema es que esa unión basada en la fecha no maneja correctamente los archivos y directorios eliminados. Debe establecer una etiqueta para la base de código a la que desea unirse primero:

mkdir code_base1 && cd code_base1 cvs co -D "2008-12-30" modulename cvs tag code_base_2008_12_30

Ahora haz un join basado en etiquetas, restando todos los cambios entre ahora y 2008-12-30:

cd .. && mkdir code_base2 && cd code_base2 cvs co modulename cvs update -d -j HEAD -j code_base_2008_12_30 # use -d to resurrect deleted directories

Compare los contenidos de code_base1 y code_base2. Deben ser idénticos a excepción de la metainformación de CVS. Finalmente, ingrese el código como estaba en 2008-12-30 como nuevo HEAD:

cvs commit -m "Revert all changes this year"

Tenga en cuenta que etiquetar el código que desea unir como este no funcionará, porque rtag tampoco maneja los archivos y directorios eliminados correctamente, cuando usa -D:

cvs rtag -D "2008-12-30" code_base_2008_12_30 modulename


Podrías mirar en cvsps. Buscalo en Google.

Además, con la colcha (o los parchescripts de Andrew Morton, que es lo que comenzó como colcha) y cvsps, se puede tener una aproximación muy cercana de los conjuntos de cambios.

ver http://geocities.com/smcameron/cvs_changesets.html


Si usted o un colega se sienten cómodos con git, puede usar git cvsimport para crear un repositorio git cvsimport el repositorio de CVS. Revertir un commit / changeset en git es trivial (usando git revert ). Luego puede usar git cvsexportcommit para enviar el compromiso de revertir a CVS.

Esto puede git cvsimport demasiado complicado, pero en mi experiencia, git cvsimport y git cvsexportcommit funcionan muy bien una vez que tienes todo configurado. Terminas con todo el poder de Git personalmente a pesar de que el proyecto aún usa CVS.


Si tiene una copia de seguridad de su repositorio (los archivos RCS reales en el servidor, por ejemplo, en una cinta), puede restaurar esa carpeta en el servidor CVS al estado que tenía antes. No olvide detener el servidor CVS antes de hacer esto (y reinícielo después).