Разумный способ переименовать каталог в рабочей копии Subversion - PullRequest
67 голосов
/ 15 октября 2010

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

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

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):

svn resolve --accept working -R .
svn commit

Дистанционное переименование в репозитории, а затем обновление моей рабочей копии выглядит довольно умственно:

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

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

Ответы [ 4 ]

68 голосов
/ 15 октября 2010

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 журнал после любого коммита), таким образом, dir метаданные в версии n-1. Следует что SVN не будет совершать из-за разница метаданных, и она не будет обновляться потому что действительно есть конфликт dir: обновление метаданных против удаления.

Поведение «ожидаемое», и «решение» заключается в обновлении рабочей копии перед выполнением команды svn rename.

8 голосов
/ 19 апреля 2013

ОК, я наткнулся на это - и, наконец, могу восстановить проблему с помощью простого терминального сеанса: проблема возникает, если вы 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

И, как сказал OP - если забыть сделать svn update перед новым перемещением / переименованием + фиксацией, и произошло «Подтверждение не удалось» - тогда можно использовать svn resolve --accept working -R ., чтобы иметь возможность завершить действие фиксации.

1 голос
/ 13 декабря 2012

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

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 также помогло бы.

0 голосов
/ 15 октября 2010

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

Разрешение конфликтов показывает, как разрешить «конфликты деревьев» в Subversion.

...