Подтвердить что ты не робот

Разумный способ переименования каталога в рабочей копии subversion

Пока как-то разбирается в VCS (обычные svn, git и git -svn пользователь), я не могу показаться, что обволакивает это своеобразное поведение SVN.

Всякий раз, когда мне нужно переименовать каталог в моей рабочей копии SVN из другого "чистого" состояния, т.е. svn status ничего не возвращает и все другие изменения были совершены - вот так (что и предлагает документ svn):

svn mv foo bar
svn commit

SVN громко жалуется:

Adding         bar
Adding         bar/toto
Deleting       foo
svn: Commit failed (details follow):
svn: Item '/test/foo' is out of date

Как вы пожелаете:

svn update

Что дает:

   C foo
At revision 46.
Summary of conflicts:
  Tree conflicts: 1

Там конфликт дерева, в то время как никаких изменений со стороны третьих сторон не произошло. Очевидно, что единственный способ выйти из этого конфликта конфликтов дерева в общем случае (из svn red book):

svn resolve --accept working -R .
svn commit

Переименовать его удаленно на репо, а затем обновить мою рабочую копию, похоже, довольно странно:

url=$(svn info | grep -e '^URL:' | sed 's/^URL: //') svn mv $url/foo $url/bar
svn update

Есть ли санкционированный, более упорядоченный способ переименования папки, которую мне не хватает? Какова основная причина этого особенно удивительного состояния конфликта деревьев?

4b9b3361

Ответ 1

svn mv работает для меня:

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>

Извините за шведский выход svn.

В вашем случае должно быть что-то другое.

Edit:
Как отмечалось в комментариях Lloeki

Чтобы воспроизвести поведение, вам также необходимо обновить и зафиксировать файл, содержащийся в этой папке, но не обновить саму папку.

file commit создает новый rev n на репо, но локальные метаданные не обновлено (как всегда, см. svn log после любого фиксации), таким образом, dir метаданные находятся на обороте n-1. Следует что svn не будет совершать из-за metadata diff, и он не будет обновлять потому что действительно существует конфликт на dir: обновить метаданные и удалить.

Поведение "ожидается", а "решение" - обновить рабочую копию перед выдачей команды svn rename.

Ответ 2

ОК, я столкнулся с этим - и может, наконец, восстановить проблему с помощью простого сеанса терминала: проблема возникает, если вы svn mv (переместить/переименовать) файл; затем зафиксируйте это изменение; затем (без выполнения svn update), svn mv родительский каталог файла, чье перемещение/переименование было ранее зафиксировано, и, наконец, сделать svn commit при изменении имени каталога - или как отвечает: "вам также необходимо обновить и зафиксировать файл, содержащийся в папке, но не обновить саму папку"; но все это выполняется в родительском (или, скорее, предком) каталоге. Здесь журнал командной строки демонстрирует проблему:

$ 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

И так должно было быть - делать svn up после перемещения файла/переименования; обратите внимание, как номера версий, сообщенные svn status -v, изменяются после команды 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

И как сказал О.П.: Если вы забыли сделать svn update перед новым движением/переименованием + фиксацией, и произошла ошибка "Commit failed", то можно использовать svn resolve --accept working -R ., чтобы завершить действие фиксации.

Ответ 3

Это сработало для меня:

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

Я подозреваю, что существует множество других возможных путей, и чтобы обеспечить работу чистого каталога, прежде чем делать svn mv, он также выполнил бы трюк.

Ответ 4

Можно подумать о сценарии, в котором каталог был изменен в репозитории другим пользователем. Переименование одной и той же папки в рабочей копии может вызвать конфликты дерева во время фиксации.

Разрешение конфликтов показывает, как разрешать "конфликты дерева" в подрывной деятельности.