Разумный способ переименования каталога в рабочей копии 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
Есть ли санкционированный, более упорядоченный способ переименования папки, которую мне не хватает? Какова основная причина этого особенно удивительного состояния конфликта деревьев?
Ответы
Ответ 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
Можно подумать о сценарии, в котором каталог был изменен в репозитории другим пользователем. Переименование одной и той же папки в рабочей копии может вызвать конфликты дерева во время фиксации.
Разрешение конфликтов показывает, как разрешать "конфликты дерева" в подрывной деятельности.