svn - revertir - Una manera sensata de cambiar el nombre de un directorio en copia de trabajo de subversión
tortoise svn server (4)
Aunque de alguna manera soy versado en VCS (usuario regular de svn, git y git-svn), no puedo entender bien este peculiar comportamiento de SVN.
Cada vez que necesito cambiar el nombre de un directorio en mi copia de trabajo SVN desde un estado "limpio", es decir, el svn status
no devuelve nada y todas las otras modificaciones se han confirmado, como eso (que es lo que sugiere el svn doc):
svn mv foo bar
svn commit
SVN se queja en voz alta:
Adding bar
Adding bar/toto
Deleting foo
svn: Commit failed (details follow):
svn: Item ''/test/foo'' is out of date
Como desées:
svn update
Lo que da:
C foo
At revision 46.
Summary of conflicts:
Tree conflicts: 1
Hay un conflicto de árbol, mientras que ningún cambio de terceros sucedió . Obviamente, la única manera de salir de este conflicto de árbol es genéricamente (del libro rojo svn):
svn resolve --accept working -R .
svn commit
Cambiar el nombre de forma remota en el repositorio y luego actualizar mi copia de trabajo parece bastante loco:
url=$(svn info | grep -e ''^URL:'' | sed ''s/^URL: //'') svn mv $url/foo $url/bar
svn update
¿Existe alguna manera sancionada y simplificada para cambiar el nombre de una carpeta que me falta? ¿Cuál es la causa raíz de ese estado de conflicto de árbol particularmente sorprendente?
Esto funcionó para mí:
vi someotherfile
...various changes to the other file
svn mv olddir newdir
svn commit -m"Moved olddir out of the way" olddir
svn commit -m"New location of olddir" newdir
svn update
svn commit -m"Changed someotherfile" someotherfile
Sospecho que había varias otras formas posibles, y que asegurar que hubiera un directorio de trabajo limpio antes de hacer el svn mv también lo habría hecho.
OK, me topé con esto, y finalmente puedo reconstruir el problema con una simple sesión de terminal: el problema ocurre si svn mv
(mover / renombrar) un archivo; luego cometer ese cambio; luego ( sin hacer una svn update
primero), svn mv
el directorio principal del archivo cuyo movimiento / cambio de nombre se había cometido previamente, y finalmente hacer un svn commit
en el cambio del nombre del directorio, o como dice la respuesta aceptada : " usted también necesita actualizar y confirmar un archivo contenido en la carpeta, pero no actualizar la carpeta "; pero todo esto se ejecuta en un directorio padre (o más bien, ancestro). Aquí está el registro de la línea de comandos que demuestra el problema:
$ cd /tmp
$ svnadmin create myrepo
$ svn co file:///tmp/myrepo myrepo-wc
Checked out revision 0.
$ cd myrepo-wc/
$ mkdir -p dir1/dir2/dir3
$ svn add dir1/
A dir1
A dir1/dir2
A dir1/dir2/dir3
$ svn ci -m ''add dir1/''
Adding dir1
Adding dir1/dir2
Adding dir1/dir2/dir3
Committed revision 1.
$ echo test1 >> dir1/dir2/dir3/test1.txt
$ echo test2 >> dir1/dir2/dir3/test2.txt
$ svn add dir1/
svn: warning: ''dir1'' is already under version control
$ svn add dir1/*
svn: warning: ''dir1/dir2'' is already under version control
$ svn add dir1/dir2/dir3/*
A dir1/dir2/dir3/test1.txt
A dir1/dir2/dir3/test2.txt
$ svn status
A dir1/dir2/dir3/test2.txt
A dir1/dir2/dir3/test1.txt
$ svn ci -m ''add dir1/dir2/dir3/*''
Adding dir1/dir2/dir3/test1.txt
Adding dir1/dir2/dir3/test2.txt
Transmitting file data ..
Committed revision 2.
$ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
A dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test2.txt
$ svn status
D dir1/dir2/dir3/test2.txt
A + dir1/dir2/dir3/test2X.txt
$ svn ci -m ''mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt''
Deleting dir1/dir2/dir3/test2.txt
Adding dir1/dir2/dir3/test2X.txt
Committed revision 3.
$ svn status
$ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
A dir1/dir2/dir3X
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
D dir1/dir2/dir3
$ svn status
D dir1/dir2/dir3
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
A + dir1/dir2/dir3X
D + dir1/dir2/dir3X/test2.txt
$ svn ci -m ''mv dir1/dir2/dir3 dir1/dir2/dir3X''
Deleting dir1/dir2/dir3
svn: Commit failed (details follow):
svn: Directory ''/dir1/dir2/dir3'' is out of date
$ svn status
D dir1/dir2/dir3
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
A + dir1/dir2/dir3X
D + dir1/dir2/dir3X/test2.txt
$ svn up
C dir1/dir2/dir3
At revision 3.
Summary of conflicts:
Tree conflicts: 1
Y así es como debería haber sido: hacer un svn up
después de que se haya svn up
el movimiento / cambio de nombre del archivo; observe cómo cambian los números de versión reportados por svn status -v
después del comando svn update
:
$ cd /tmp
$ rm -rf myrepo*
$ svnadmin create myrepo
$ svn co file:///tmp/myrepo myrepo-wc
Checked out revision 0.
$ cd myrepo-wc/
$ mkdir -p dir1/dir2/dir3
$ svn add dir1/
A dir1
A dir1/dir2
A dir1/dir2/dir3
$ svn ci -m ''add dir1/''
Adding dir1
Adding dir1/dir2
Adding dir1/dir2/dir3
Committed revision 1.
$ echo test1 >> dir1/dir2/dir3/test1.txt
$ echo test2 >> dir1/dir2/dir3/test2.txt
$ svn add dir1/dir2/dir3/*
A dir1/dir2/dir3/test1.txt
A dir1/dir2/dir3/test2.txt
$ svn status
A dir1/dir2/dir3/test2.txt
A dir1/dir2/dir3/test1.txt
$ svn ci -m ''add dir1/dir2/dir3/*''
Adding dir1/dir2/dir3/test1.txt
Adding dir1/dir2/dir3/test2.txt
Transmitting file data ..
Committed revision 2.
$ svn mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt
A dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test2.txt
$ svn status
D dir1/dir2/dir3/test2.txt
A + dir1/dir2/dir3/test2X.txt
$ svn ci -m ''mv dir1/dir2/dir3/test2.txt dir1/dir2/dir3/test2X.txt''
Deleting dir1/dir2/dir3/test2.txt
Adding dir1/dir2/dir3/test2X.txt
Committed revision 3.
$ svn status
$ svn status -v
0 0 ? .
1 1 username dir1
1 1 username dir1/dir2
1 1 username dir1/dir2/dir3
3 3 username dir1/dir2/dir3/test2X.txt
2 2 username dir1/dir2/dir3/test1.txt
$ svn up
At revision 3.
$ svn status -v
3 3 username .
3 3 username dir1
3 3 username dir1/dir2
3 3 username dir1/dir2/dir3
3 3 username dir1/dir2/dir3/test2X.txt
3 2 username dir1/dir2/dir3/test1.txt
$ svn mv dir1/dir2/dir3 dir1/dir2/dir3X
A dir1/dir2/dir3X
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
D dir1/dir2/dir3
$ svn status
D dir1/dir2/dir3
D dir1/dir2/dir3/test2X.txt
D dir1/dir2/dir3/test1.txt
A + dir1/dir2/dir3X
$ svn ci -m ''mv dir1/dir2/dir3 dir1/dir2/dir3X''
Deleting dir1/dir2/dir3
Adding dir1/dir2/dir3X
Committed revision 4.
$ svn status
$ svn status -v
3 3 username .
3 3 username dir1
3 3 username dir1/dir2
4 4 username dir1/dir2/dir3X
4 4 username dir1/dir2/dir3X/test2X.txt
4 4 username dir1/dir2/dir3X/test1.txt
$ svn up
At revision 4.
$ svn status -v
4 4 username .
4 4 username dir1
4 4 username dir1/dir2
4 4 username dir1/dir2/dir3X
4 4 username dir1/dir2/dir3X/test2X.txt
4 4 username dir1/dir2/dir3X/test1.txt
Y como dijo OP: si uno olvidara hacer la svn update
antes de un nuevo movimiento / cambiar el nombre + confirmar, y el " svn resolve --accept working -R .
" ocurrió, entonces uno puede usar svn resolve --accept working -R .
para poder terminar la acción de compromiso.
Uno podría pensar en un escenario donde el directorio ha sido cambiado en el repositorio por otro usuario. Renombrar la misma carpeta en su copia de trabajo puede desencadenar conflictos de árbol durante la confirmación.
La resolución de conflictos muestra cómo resolver ''conflictos de árbol'' en subversión.
svn mv
funciona para mí:
C:/svn/co>svn mv my_dir new_dir
A new_dir
D my_dir/New Text Document.txt
D my_dir
C:/svn/co>svn commit -m foo
Raderar my_dir
Lägger till new_dir
Arkiverade revision 2.
C:/svn/co>
Lo siento por la salida sueca de svn.
Debe haber algo más que esté mal en tu caso.
Editar:
Como se señala en los comentarios de Lloeki
Para reproducir el comportamiento, también necesita actualizar y confirmar un archivo contenido en la carpeta, pero no actualizar la carpeta.
La confirmación de archivo crea una nueva rev n en el repositorio, pero los metadatos locales no se actualizan (como siempre ha sido, ver svn log después de cualquier confirmación), por lo que los metadatos dir están en rev n-1. Se deduce que svn no se comprometerá debido a la diferencia de metadatos, y no se actualizará porque de hecho hay un conflicto en el directorio: actualización de metadatos contra eliminación.
El comportamiento es "esperado" y la "solución" es actualizar la copia de trabajo antes de emitir el comando svn rename
.