是否可以仅从 SVN 存储库中签出在修订版或修订版范围内修改的那些文件,而不签出任何未修改的文件?
8 回答
现在有 afaik 直接获取更改的文件而不是全部的方法。
我的想法是:使用列表的详细输出(显示最后更改的版本),通过 awk 过滤它,然后检查其余部分。例如,要搜索版本 42 中更改的文件,我会使用它
VERSION=42
svn list -v -R -r $VERSION svn://... | awk "/^[ ]*$VERSION/ {print \$7}" > files_to_checkout
然后在 URL 上执行一个svn update -r $VERSION 'cat files_to_checkout'
(或一个 co,具体取决于您将在何处运行命令)。
编辑:更短:使用 svn diff 命令,并用 -x 和 --diff-cmd 替换 svn co 的 diff 命令。这需要一些参数转移黑客(我不会在这里详细说明),但只需要一行而不需要中间文件(你也可以在上面保存,但这会增加可读性)
我的建议与 flolo 建议的内容相同。但是,需要一个范围。您可以使用以下 shell 函数。
function checkout_files_in_revrange()
{
svn_url=$1;
start_rev=$2;
end_rev=$3;
for theCheckoutCanditate in `svn log -r $start_rev:$end_rev --verbose --incremental | grep " M " | cut -f5 -d' ' | cut -f3- -d/`
do
svn co $svn_url/$theCheckoutCandidate -q;
done
}
如果您使用带有 -v (详细选项)的 svn log:
svn log -r <revision> -v <path>
您将获得包含更改文件的输出:
r3 | ciaran | 2008-11-16 12:24:30 +0000 (Sun, 16 Nov 2008) | 1 line
Changed paths:
A /trunk/apache/apache.conf
A /trunk/application/controllers
Commit message goes here
您应该能够通过一些 grepping 等操作来生成一系列 svn co 命令。
我们在 MSBuild 脚本中执行此操作:
Step 1: - 使用 diff 命令获取修改文件列表,将输出重定向到目标目录中的临时文件 Step 2: - 将临时文件读入 itemGroup
<Exec command="$(svnExecutable) diff -r $(StartRevision):$(EndRevision) $(DOUBLE_QUOTES)$(SvnRepositoryPath)/$(DOUBLE_QUOTES) --no-diff-deleted --summarize > $(TempFilePath)" WorkingDirectory="$(WorkDirectory)" />
我不完全确定这是否可能,但你也可以这样做:
svn checkout --revision <revisionNumber>
得到一定的修改和
svn log --revision <revisionNumber>
列出修订中更改的所有文件
另一个回答你的问题的方法:
假设您有一个现有的工作副本,您应该只在包含您正在查看的文件的目录的根目录上使用“svn update”,因为它可以准确地检索当前修订版和 HEAD 修订版之间的更改,并使用尽可能少的数据。
较旧的源代码管理系统(如 CVS 和 VSS)向服务器询问每个文件,此文件是否已更改?,而颠覆只是将树的更改作为单个操作发送。当您将文件列表传递给 svn update 时,您没有这个优势。
因此,传输已更改内容的最有效方式就是更新。与工作副本的基本版本相比,这只会传输 HEAD 中更改的二进制差异。
如果您要解决的问题是svn update太慢,那么我们正在尝试解决 Subversion 1.7 的问题。
此版本将引入一种新的工作副本数据存储格式,这将使必须锁定整个工作副本(如更新)的简单操作更快。
在与大多数人建议的几乎相同的行中(但仅在具有 grep 和 awk 的系统中),您可以通过执行来获取列表
svn log -v --revision <revision_number> | grep "^ " | awk '{print $2}'
.
svn diff -r starting_revision:ending_revision_or_HEAD --summarize