在Subversion工作副本中重命名目录的明智方法


68

尽管以某种方式精通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红皮书):

svn resolve --accept working -R .
svn commit

在存储库上远程重命名它,然后更新我的工作副本似乎很不明智:

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

是否有一种批准的,更简化的方式来重命名我丢失的文件夹?这种特别令人惊讶的树冲突状态背后的根本原因是什么?


您可以发布确切的树冲突消息吗?
Albin Sunnanbo 2010年

我以前也曾见过这种现象,但是我不确定是什么原因造成的。是在添加目录并在提交之前重命名它吗?
Edd Barrett

我也遇到这种现象,但无法找出原因。我一直把它归结为“ SVN的工作方式”。它让我疯狂。
Alex J

Albin,消息丢失超出GNU屏幕缓冲区范围:/
Lloeki

vext01,dir add在之前已提交到svn svn mv。内部的文件已收到工作,并且早于提交svn mv
Lloeki

Answers:


70

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输出。

在您的情况下,肯定还有其他错误。

编辑:
如Lloeki的评论中指出

要重现此行为,您还需要更新并提交包含在文件夹中的文件,而不更新文件夹本身。

文件提交会在存储库上创建一个新的修订版n,但是本地元数据不会更新(因为它始终如此,请参阅任何提交后的svn日志),因此目录元数据位于修订版n-1。因此,由于元数据差异,svn将不会提交,并且不会更新,因为dir确实存在冲突:更新元数据与删除。

行为是“预期的”,“解决方案”是在发出svn rename命令之前更新工作副本。


2
找到“其他”实际上是问题的一部分:)现在修改New Text Document.txt,提交,然后mv dir并再次提交。
Lloeki 2010年

1
@Lloeki,是的,通过修改文本文件可以重现树的冲突。在我看来,这真的像是个错误,您是否在subversion.apache.org上搜索了问题跟踪程序并/或在此处提交了错误报告?
Albin Sunnanbo 2010年

2
我最终找到了原因,这在某种程度上被颠覆了:文件提交在存储库上创建了一个新的修订版n,但是本地元数据未更新(因为它总是如此,请参阅svn log任何提交后再查看),因此目录元数据位于修订版中n-1个。因此,由于元数据差异,svn将不会提交,并且不会更新,因为dir确实存在冲突:更新元数据与删除。
Lloeki

1
由于您已将我带入正轨,因此请更新您的答案,我们将对其进行验证。
Lloeki

上面的“ svn mv my_dir new_dir”对我有用。之后,我可以使用Windows gui的普通svn commit
user_v 2012年

8

好的,我碰到了这一点-最终可以通过一个简单的终端会话来解决问题:如果您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

这对我有用:

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

可以想到这样一种情况,即目录库中的另一位用户已更改了该目录。在工作副本中重命名同一文件夹可能会在提交期间触发树冲突。

解决冲突显示了如何解决Subversion中的“树冲突”。


我处于一个孤独的开发人员场景,其中没有任何外部更改发生。
Lloeki 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.