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

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 展示了如何解决颠覆中的“树冲突”。

【讨论】:

我处于一个单独的开发人员场景中,没有发生外部变化。

以上是关于在颠覆工作副本中重命名目录的明智方法的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中重命名目录 [关闭]

django:如何在管理面板中重命名记录

[Linux] Linux中重命名文件和文件夹的方法(mv命令和rename命令)

如何在 JGit 中重命名文件

如何在 vscode 中重命名工作区?

如何在 MySQL 中重命名模式