¿Cómo regreso a una versión anterior de nuestro código en Subversion?

486

Estoy trabajando en un proyecto con un amigo y quiero volver a una versión anterior de nuestro código y configurarlo para que sea el actual. ¿Cómo lo hago?

Estoy usando "anksvn" en vs08.

Tengo la versión que quiero en mi PC, pero el commit falla; El mensaje que recibo es "error de confirmación, el archivo o directorio está desactualizado".

También tengo el cliente de subversión en mi PC.

Chen Kinnrot
fuente

Respuestas:

783

Básicamente, debe "fusionarse al revés": aplique una diferencia entre la versión actual y la anterior a la versión actual (de modo que termine con una copia de trabajo que se parece a la versión anterior) y luego confirme nuevamente. Entonces, por ejemplo, para pasar de la revisión 150 (actual) a la revisión 140:

svn update
svn merge -r 150:140 .
svn commit -m "Rolled back to r140"

El Libro Rojo de Subversion tiene una buena sección sobre esto .

Jon Skeet
fuente
3
pero la fusión no anula mis cambios y la nueva revisión.
Chen Kinnrot
76
Si está utilizando TortoiseSVN, haga clic con el botón derecho en el archivo, seleccione Combinar, luego combine un rango de revisiones. En el cuadro de registro, escriba 140-150 y haga clic en la casilla de verificación inversa. Después de eso, comprométete como de costumbre. Esto realizará la misma operación que el ejemplo de Jon.
DavGarcia
8
Con eclipse y subclipse, puede hacer clic con el botón derecho en su proyecto, Equipo / Mostrar historial, luego seleccionar y luego las revisiones que desea "deshacer" y con otro botón derecho seleccionar "Revertir cambios de las revisiones seleccionadas".
fego
36
Para volver de la revisión de la cabeza, también puede escribir svn merge -r HEAD:140.
sschmeck
3
Las instrucciones de @ DavGarcia TortoiseSVN no eran adecuadas para mí, al menos para no revertir todos los archivos en una revisión (usando TortoiseSVN 1.8.8). Haga clic derecho en la carpeta, seleccione TortoisSVN-> Mostrar registro. Elija la (s) revisión (es) que desea revertir, haga clic derecho como decir "Revertir cambios de esta revisión". Cometer los cambios.
mhenry1384
178

Sólo se puede cometer nuevos cambios en la cabeza de la historia de la subversión.

La razón por la que no puede hacer nada directamente con la buena copia que tiene en su PC, es que sus .svncarpetas saben que es un código del pasado, por lo que requiere una actualización antes de cualquier confirmación.

Encuentra el buen número de revisión y revierte

  1. Encuentre el número de revisión de la copia anterior que desea.

    Obtenga su revisión actual con:

    svn info --show-item revision
    # or
    svn log
    

    O para verificar versiones anteriores de su proyecto, use:

    svn update -r <earlier_revision_number>

    hasta que encuentre el número de revisión correcto.

  2. Anote el buen número de revisión (suponiendo los 123ejemplos a continuación).

  3. Actualización a la última revisión:

    svn update
  4. Deshaga todos los cambios entre la revisión que desea y la última versión:

    svn merge -r HEAD:123 .
    svn commit "Reverted to revision 123"
    

    (lo mismo que la respuesta de Jon Skeet anterior).

Si no puede encontrar el número de revisión

Si no puede encontrar la copia anterior y solo desea confirmar los archivos actualmente en su PC:

  1. Haga una copia de su buena versión (pero sin ninguna .svncarpeta):

    cd ..
    rsync -ai --exclude=.svn  project/  project-good/
    
  2. Ahora asegúrese de tener la última versión:

    cd project
    svn update
    # or make a fresh checkout
    svn checkout <url>
    
  3. Copie su buena versión sobre la parte superior de la copia de trabajo.

    Este comando copiará y también eliminará cualquier archivo del árbol de trabajo que no esté en su copia correcta, pero no afectará las .svncarpetas existentes .

    cd ..
    rsync -ai --exclude=.svn --delete  project-good/  project/
    

    Si no tiene rsync, puede usarlo, cp -apero también deberá eliminar cualquier archivo no deseado manualmente.

  4. Deberías poder cometer lo que tienes ahora.

    cd project
    svn commit "Reverted to good copy"
    
joeytwiddle
fuente
2
svn no lo interpreta como una modificación, no puedo cometer eso.
Sandburg
svn merge -r HEAD: 12345. es el comando correcto para revertir, no hacer una actualización -r. Eres un loco.
Búho
Supongo que esta respuesta fue votada por personas que no pudieron encontrar su número de revisión, o que apreciaron la explicación principal. He actualizado la respuesta ahora para incluir ambos enfoques.
joeytwiddle
36

Solo usa esta línea

svn update -r yourOldRevesion

Puede conocer su revisión actual utilizando:

svn info

M.Othman
fuente
15
Esto no resuelve el problema. En cambio, esto produce el estado en que se encontraba el autor de la pregunta al momento de hacer su pregunta.
Ingo Schalk-Schupp
1
Si ha tenido la mala suerte de seguir este consejo, ejecute: "svn resolve --accept working -R".
Búho
27

La forma estándar de usar la combinación para deshacer el check-in completo funciona muy bien, si eso es lo que quieres hacer. Sin embargo, a veces, todo lo que quiere hacer es revertir un solo archivo. No hay una forma legítima de hacerlo, pero hay un truco:

  1. Encuentra la versión que deseas usando svn log.
  2. Use el subcomando de exportación de svn:

    svn export http: // url-to-your-file @ 123 / tmp / filename

(Donde 123 es el número de revisión para una buena versión del archivo). Luego mueva o copie ese archivo único para sobrescribir el antiguo. Registre el archivo modificado y ya está.

Cuenta
fuente
Con Tortoise-svn puedo hacer clic derecho en un solo archivo y fusionarlo. ¿Debería haber una manera de hacer esto usando svntambién?
lc.
10
svn cat -r 123 path-in-your-working-copy > path-in-your-working-copy
dash17291
8

Un poco más de la vieja escuela

svn diff -r 150:140 > ../r140.patch
patch -p0 < ../r140.patch

entonces lo habitual

svn diff
svn commit
Yauhen Yakimovich
fuente
5

Creo que esto es más adecuado:

Haga la fusión hacia atrás, por ejemplo, si el código confirmado contiene la revisión de la rev. 5612 a 5616, simplemente combínelo hacia atrás. Funciona en mi fin.

Por ejemplo:

svn merge -r 5616:5612 https://<your_svn_repository>/

Contendría un código combinado de regreso a la revisión anterior, entonces podría confirmarlo.

hpal
fuente
3

Esto es lo que hice y funcionó para mí.

Quiero deshacer los cambios en varias confirmaciones que hice para ciertos momentos y quiero ir al punto de confirmación anterior.

  1. Vaya a Equipo -> Mostrar historial.
  2. Haga clic con el botón derecho en el rango de revisiones que desea ignorar.
  3. Seleccione la opción "Revertir cambios".

Esto ejecutará una fusión inversa, deshaciendo los cambios en su copia de trabajo.

Solo revise el código y confirme.

Ziya
fuente
2

Haga clic derecho en la jerarquía más alta que desea revertir >> RevertoRevert to Revision

Yuval Adam
fuente
2

La mayoría de las respuestas anteriores han estado utilizando una combinación inversa, y esa suele ser la respuesta correcta. Sin embargo, hay una situación (que me acaba de ocurrir) en la que no está.

Accidentalmente cambié un archivo con terminaciones de línea Unix a terminaciones de línea DOS al hacer un pequeño cambio, y lo confirmé. Esto se deshace fácilmente, ya sea cambiando los finales de línea y confirmando nuevamente, o mediante una fusión inversa, pero tiene el efecto de hacer que la svn blamelista de mi edición sea la fuente de cada línea del archivo. (Curiosamente, TortoiseSVN en Windows no se ve afectado por esto; solo la línea de comando svn blame).

Si desea mantener el historial según lo informado por svn blame, creo que debe hacer lo siguiente:

  • Eliminar el archivo y confirmar.
  • En el repositorio, copie la copia buena anterior del archivo en el encabezado y confirme.
  • Restaure cualquier edición que desee conservar.

La eliminación da un poco de miedo, pero recuerda que siempre tienes el archivo guardado en el repositorio, por lo que restaurarlo no es gran cosa. Aquí hay un código para ilustrar los pasos. Suponga que xxxes el número de revisión de la última copia válida.

svn rm svn+ssh://path/to/file
svn copy svn+ssh://path/to/file@xxx svn+ssh://path/to -m"Restore good copy"
svn update
<restore the edits>
svn commit -m"Restore edits"

Tenga en cuenta que para una copia en el repositorio, el destino debe ser un directorio, no un nombre de archivo.

usuario2554330
fuente
1

Haga clic derecho en el proyecto> Reemplazar con> Revisión o URL> Seleccione la revisión específica que desea revertir.

Ahora confirme la versión del código de actualización local en el repositorio. Esto revertirá la base del código a la revisión específica.

KayV
fuente
1

Hay muchas respuestas peligrosas en esta página. Tenga en cuenta que desde la versión 1.6 de SVN, hacer una actualización -r puede causar conflictos en los árboles, que rápidamente se convierten en una pesadilla kafkeresca que posiblemente pierda datos y busque en Google información sobre conflictos en los árboles.

La forma correcta de volver a una versión es:

svn merge -r HEAD:12345 .

Donde 12345 es el número de versión. No olvides el punto.

Búho
fuente
0

Sincronice con la versión anterior y confírmelo. Esto debería funcionar.

Aquí también hay una explicación de deshacer cambios.

Mork0075
fuente
0

La respuesta de Jon Skeet es prácticamente la solución en pocas palabras, sin embargo, si eres como yo, es posible que quieras una explicación. El manual de Subversion llama a esto un

Cherry-Pick Merge

De las páginas del manual.

  1. Esta forma se denomina fusión 'cherry-pick': '-r N: M' se refiere a la diferencia en la historia de la rama fuente entre las revisiones N y M.

    Se puede usar un 'rango inverso' para deshacer los cambios. Por ejemplo, cuando el origen y el destino se refieren a la misma rama, una revisión previamente comprometida se puede 'deshacer'. En un rango inverso , N es mayor que M en '-r N: M', o la opción '-c' se usa con un número negativo: '-c -M' es equivalente a '-r M:'. Deshacer cambios como este también se conoce como realizar una 'fusión inversa'.


  • Si la fuente es un archivo, se aplican diferencias a ese archivo (útil para fusionar cambios anteriores). De lo contrario, si el origen es un directorio, el destino predeterminado es '.'.

    En uso normal, la copia de trabajo debe estar actualizada, en una sola revisión, sin modificaciones locales y sin subárboles conmutados.

Ejemplo:

svn merge -r 2983:289 path/to/file

Esto reemplazará la copia local [2983] (que, de acuerdo con la cita anterior, debe estar sincronizada con el servidor, es su responsabilidad) con la revisión 289 del servidor. El cambio ocurre localmente, lo que significa que si tiene un pago limpio, entonces los cambios se pueden inspeccionar antes de confirmarlos.

Jonathan Komar
fuente
-1

Lo siguiente me ha funcionado.

Tuve muchos cambios locales y necesitaba descartarlos en la copia local y verificar la última versión estable en SVN.

  1. Verifique el estado de todos los archivos, incluidos los archivos ignorados.

  2. Grep todas las líneas para obtener los archivos recién agregados e ignorados.

  3. Reemplace esos con //.

  4. y rm -rf todas las líneas.

    svn status --no-ignore | grep '^ [? I]' | sed "s / ^ [? I] //" | xargs -I {} rm -rf "{}"

shah1988
fuente