在Subversion工作副本中重命名一个目录的一种理智的方法

虽然以某种方式精通VCS(普通的svn,git和git-svn用户),但我似乎无法围绕这个特殊的SVN行为。

每当我需要重新命名我的SVN工作副本中的一个目录从其他“干净”状态 – 即svn status没有返回和所有其他修改已提交 – 像这样(这是什么SVN文档build议):

 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 

在repo上远程重命名,然后更新我的工作副本似乎相当braindead:

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

是否有一个更好的,更简化的方式来重命名我失踪的文件夹? 这个特别令人惊讶的树木冲突状态背后的根源是什么?

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的评论中指出的那样

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

文件提交在repo上创build一个新的版本,但是本地元数据不会被更新(因为它总是,在任何提交之后,请参阅svn日志),因此dir元数据在rev n-1。 因此,svn不会因元数据差异而提交,并且不会更新,因为dir上确实存在冲突:更新元数据与删除。

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

好吧,我碰到了这个问题 – 最终可以通过一个简单的terminal会话重新构build问题:如果您使用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 up ; 请注意,在svn update命令之后, svn status -v报告的版本号如何变化:

 $ 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 . 能够完成提交操作。

这对我工作:

 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之前有一个干净的工作目录也可以做到。

人们可以想象一下其他用户在存储库中更改目录的场景。 重命名工作副本中的相同文件夹可能会在提交期间触发树冲突。

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