有没有 Subversion 命令可以重置工作副本?

131
有没有一条Subversion命令可以将工作副本“重置”到存储在仓库中的状态?类似于 git reset --hard 或者(哈,硬重置 Git 也不会删除未加版本控制的文件!) rm -rf wc && svn co <url> wc
更新:我不是想简单地还原,因为这样做不能删除工作副本中的额外文件。我真正想要的是像删除工作副本并重新检出一样的操作,只是不需要再次下载数据。(显然我不介意失去所有未提交的更改。)

撤销工作副本中的所有更改? - mauris
6
您可以使用 git clean -xdf 命令来删除源代码控制之外的内容。 - vcsjones
1
@vcsjones:谢谢,git clean的man页面正好引用了我正在寻找的内容:“这可以被用来(可能与git reset一起)创建一个原始的工作目录以测试干净的构建。”可惜Subversion似乎没有内置类似的功能。 - zoul
9个回答

198
您可以使用以下命令进行递归还原: svn revert --recursive . 没有办法(除非编写一个创造性的脚本)删除不受源代码控制的东西。我认为您能做到的最接近的方法是遍历所有文件,然后使用svn list的结果进行grep,如果grep失败,则删除它。 编辑: 创意脚本的解决方案在这里:自动删除Subversion未版本化文件 因此,您可以创建一个将revert与链接问题中最适合您的答案组合的脚本。

3
在进行下一步操作之前,你可能需要先运行svn cleanup命令清理工作副本。这是我在合并失败或其他情况下清理工作副本的标准做法。 - Mike Miller
乌龟还在清理对话框中提供了一个“删除未版本化文件”的选项。 - v.oddou
2
如果“删除未版本控制的文件”可以通过命令行使用,那就太好了。特别是对于自动化构建来说。 - C. Tewalt
3
请看我的回答... --remove-unversioned 是用于 svn cleanup 的删除未版本化文件的命令。 - Denny Weinberg

45

撤销已跟踪的文件

svn revert . -R

清理未跟踪的文件

svn status | rm -rf $(awk '/^?/{$1 = ""; print $0}')

-rf 初看可能会让人感到害怕,但一旦理解,其原因并非如此:

  1. 只有完全没有被跟踪的目录才会匹配传递给 rm 的模式
  2. 必须使用 -rf,否则这些目录将不会被删除

要恢复然后清理(即 OP 的问题)

svn revert . -R && svn status | rm -rf $(awk '/^?/{$1 = ""; print $0}')

为了持续的使用方便

将永久别名添加到您的.bash_aliases文件中

alias svn.HardReset='read -p "destroy all local changes?[y/N]" && [[ $REPLY =~ ^[yY] ]] && svn revert . -R && rm -rf $(awk -f <(echo "/^?/{print \$2}") <(svn status) ;)'

第二个代码片段似乎对我不起作用:awk: fatal: error reading input file '-': Input/output error - hbogert
我不得不在awk命令中转义?,否则它会匹配svn status输出中的所有行。 - gpanders

25

使用以下命令删除本地副本中的所有内容:

rm -r your_local_svn_dir_path/*

然后使用以下命令递归地还原所有内容。

svn revert -R your_local_svn_dir_path

这种方法比删除整个目录然后重新检出要快得多,因为文件是从您本地的 SVN 元数据中恢复的。甚至不需要网络连接。


4
svn cleanup --remove-unversioned 会更快。 - Znik

13

删除未版本化的文件并还原所有更改:

svn revert D:\tmp\sql -R
svn cleanup D:\tmp\sql --remove-unversioned

输出:

D         D:\tmp\sql\update\abc.txt

2
这是最佳答案,没有额外的脚本。它是通用的,并且与许多svn版本兼容。 - Znik
我也需要/想要 svn cleanup --remove-ignored。不过,这里的答案仍然是最好的。 - Michael Burr

7
svn revert . -R

重置所有内容。

svn revert path/to/file

对于单个文件


1
这不会删除工作副本中的额外未版本化的文件,是吗? - zoul
@zoul 我不这么认为,但是不要引用我说的话,因为我已经有一段时间没有使用 SVN 了。 - Abe Voelker
不幸的是,它无法触及未被跟踪的文件。请尝试使用“svn revert -R your_local_svn_dir_path”。 - Znik

3

纯Windows cmd/bat解决方案:

svn cleanup .
svn revert -R .
For /f "tokens=1,2" %%A in ('svn status --no-ignore') Do (
     If [%%A]==[?] ( Call :UniDelete %%B
     ) Else If [%%A]==[I] Call :UniDelete %%B
   )
svn update .
goto :eof

:UniDelete delete file/dir
IF EXIST "%1\*" (
    RD /S /Q "%1"
) Else (
    If EXIST "%1" DEL /S /F /Q "%1"
)
goto :eof

2

最简单的方法是从操作系统中删除工作副本,然后再次检出它,但显然这不是一个单一的命令。


非常缓慢。这就是为什么我在寻找绕过它的方法。 - zoul

2
非常快速和简单,可以完全满足您的需求。
svn status | awk '{if($2 !~ /(config|\.ini)/ && !system("test -e \"" $2 "\"")) {print $2; system("rm -Rf \"" $2 "\"");}}'

/(config|.ini)/ 是为了我的个人目的而设置的。

在 svn 命令中添加 --no-ignore 可能是一个好主意。


2
这太糟糕了。那Windows用户怎么办?显然,Subversion在被认真视为版本控制工具之前还需要做一些工作。 - Warren P

1

删除未跟踪的文件

我能够通过以下方式在bash中列出svn st报告的所有未跟踪的文件:

echo $(svn st | grep -P "^\?" | cut -c 9-)

如果你感觉幸运,你可以用rm替换echo来删除未被跟踪的文件。或者,如果你感到不太幸运,可以手动复制要删除的文件。

我使用@abe-voelker的答案来还原剩余的文件:https://dev59.com/X2025IYBdhLWcg3wHSGn#6204601


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接