在颠覆工作副本中重命名目录的明智方法
Posted
技术标签:
【中文标题】在颠覆工作副本中重命名目录的明智方法【英文标题】:A sane way to rename a directory in subversion working copy 【发布时间】:2011-04-25 20:56:32 【问题描述】:虽然精通 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
在 repo 上远程重命名它然后更新我的工作副本似乎很脑残:
url=$(svn info | grep -e '^URL:' | sed 's/^URL: //') svn mv $url/foo $url/bar
svn update
是否有一种认可的、更简化的方式来重命名我丢失的文件夹?这种特别令人惊讶的树冲突状态背后的根本原因是什么?
【问题讨论】:
你能发布确切的树冲突消息吗? 我以前也见过这种行为,但我不确定是什么原因造成的。是不是当你添加一个目录并在提交之前重命名它? 我也遇到过这种行为,一直无法找出原因。我一直把它归结为“SVN 的工作方式”。它让我发疯。 Albin,消息在 GNU 屏幕缓冲区范围外丢失:/ vext01,dir add 在svn mv
之前被提交到svn 方式。里面的文件收到工作并在svn mv
之前提交。
【参考方案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。
你的情况一定有其他问题。
编辑: 正如 Lloeki 在 cmets 中指出的那样
要重现该行为,您还需要更新并提交文件夹中包含的文件,但不更新文件夹本身。
文件提交在 repo,但本地元数据不是 更新(一如既往,请参阅 svn 在任何提交后记录),因此是 dir 元数据在 rev n-1。它跟随 svn 不会提交,因为 元数据差异,它不会更新 因为确实有冲突 目录:更新元数据与删除。
这种行为是“预期的”,而“解决方案”是在发出svn rename
命令之前更新工作副本。
【讨论】:
发现“其他东西”实际上是问题的一部分:) 现在修改 New Text Document.txt,提交它,然后 mv 目录并再次提交。 @Lloeki,是的,通过修改文本文件再现了树冲突。在我看来,这确实是一个错误,您是否在subversion.apache.org 搜索了问题跟踪器和/或在那里提交了错误报告? 我最终找到了原因,这以一种颠覆的方式说得通:文件提交在 repo 上创建了一个新的 rev n,但是本地元数据没有更新(因为它已经总是如此,在任何提交后查看svn log
),因此目录元数据位于rev n-1。由于元数据差异,svn 不会提交,并且它不会更新,因为目录上确实存在冲突:更新元数据与删除。
既然你让我上轨道,更新你的答案,我会验证它。
上面的“svn mv my_dir new_dir”对我有用。之后我可以使用 windows gui 中的普通 svn commit【参考方案2】:
好的,我遇到了这个问题 - 最后可以通过一个简单的终端会话来重建问题:如果你 svn mv
(移动/重命名)一个文件,就会出现问题;然后提交该更改;然后(没有首先执行svn update
),svn mv
先前提交的移动/重命名文件的父目录 - 最后在更改目录名称时执行svn commit
-或者正如accepted answer 所说:“您还需要更新并提交文件夹中包含的文件,但不要更新文件夹本身”;但所有这些都在父(或者更确切地说,祖先)目录中执行。这是演示问题的命令行日志:
$ 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 .
来完成提交操作。
【讨论】:
【参考方案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】:可以想到这样一种场景,即存储库中的目录已被其他用户更改。重命名工作副本中的同一文件夹可能会在提交期间触发树冲突。
Resolving conflicts 展示了如何解决颠覆中的“树冲突”。
【讨论】:
我处于一个单独的开发人员场景中,没有发生外部变化。以上是关于在颠覆工作副本中重命名目录的明智方法的主要内容,如果未能解决你的问题,请参考以下文章