如何在SVN中获取文件/文件夹属性的历史记录?

24
什么是最简单的方法来确定文件或文件夹上的属性何时设置?基本上,我正在寻找一个类似于“svn blame”的等效工具,它可以用于属性。

log子命令使您能够获取文件或文件夹的完整历史记录,包括何时修改了属性。但是,它不区分属性修改和其他类型的修改,这当然也意味着它不会告诉您有关特定属性历史记录的任何信息。

状态命令区分属性和其他类型的修改,但仅适用于工作副本。

Blame本身仅支持文件,而不支持目录,并且仅适用于内容,而不适用于属性。

有什么想法?
5个回答

10
获取给定文件夹中属性何时更改的一种方法是:
svn log -v . |grep "   M /trunk/datacenter$" -B2

以下是输出结果:
r963 | someuser | 2013-08-26 20:32:37 +0200 (Mon, 26 Aug 2013) | 4 lines
Changed paths:
   M /trunk/datacenter
--
r908 | someotheruser | 2013-08-15 12:15:03 +0200 (Thu, 15 Aug 2013) | 1 line
Changed paths:
   M /trunk/datacenter
--
r413 | someuser | 2013-04-26 09:02:08 +0200 (Fri, 26 Apr 2013) | 1 line
Changed paths:
   M /trunk/datacenter

然后您可以查看每个修订版本以了解更改的内容:
$ svn diff -c963

在底部:
...

Property changes on: .
___________________________________________________________________
Modified: svn:ignore
## -22,3 +22,5 ##

 .idea
 .classpath
+
+dev-config.groovy

缺点:

  • 无法指定您感兴趣的属性
  • 繁琐

注意:不确定在所有情况下-B2是否足够,因为行"M /trunk/datacenter"可能不是第一行。


2
最佳答案,很久之前就点赞了。难以相信Subversion没有本地过滤日志以获取此类详细信息的方法。 - javabrett

9
我能想到的最好办法是编写一个小脚本或应用程序,使用svn propget命令将当前属性值转储到文本文件中,然后通过遍历版本记录将该属性值转储到另一个文本文件中并进行比较。一旦检测到更改,它会打印出修订号(实际上是使更改的较晚的修订号)以及提交者的用户名。
这是一个示例命令,用于在修订版80处转储字典目录的svn:ignore属性:
svn propget -r 80 svn:ignore dictionary

1
我会将缺乏更好的选择作为答案,表明目前还没有现成的方法来做到这一点。嗯,好吧。 - mr. w
这个很棒的地方在于提交那个修订版本的人不一定是改变属性的人。 - Dwight Holman
我不明白,@anonfunc,别人怎么可能改变属性?我认为包含新属性值的第一个修订版本总是提交更改的版本。 - Don Kirkby
假设我们的 SVN 版本是 80,最后一次提交者是 Bob。我运行了 svn propset svn:eol-style "LF" file 命令。这会修改 r80 的属性,但是提交者仍然是 Bob。接着 Alice 提交了 r81。我的属性更改没有得到自己的版本,我的名字也没有出现在对话中。 - Dwight Holman
1
@anonfunc,你真的尝试过吗?在svn 1.5中,它会将文件标记为我的工作副本中已修改的文件,并且我必须使用新版本提交更改。你是否混淆了像svn:authorsvn:date这样未被版本化的修订属性与像svn:eol-style这样被版本化的文件和目录属性?在SVN手册中有关于版本化和非版本化属性的描述。 - Don Kirkby
谢谢您的纠正。我之前不知道版本化和非版本化属性之间的区别,过去主要在svn:log上使用propset。 - Dwight Holman

1
#!/bin/bash
# This is not a great solution, but it works for gathering the data

CURRENT_REVISION=95300
OLDEST_REVISION=93000
URL="file:///home/svn/repo/project/dir/target.c"
PROPERTY_NAME="svn:externals"

for i in `seq $OLDEST_REVISION $CURRENT_REVISION`
do
  svn -r$i propget "$PROPERTY_NAME" "$URL" | sed -e "s/^/$i\t/"
done

0

我的svn-extensions工具箱现在有svn-prop-annotate和(作为专业化)svn-mergeinfo-annotate命令。它们的性能表现不佳(因为它们对每个潜在更改运行svn logsvn diff),并且可能仍然具有一些依赖关系和特殊性,适用于那些非常需要的人。

这里是一些示例输出:

$ svn-mergeinfo-annotate --author karkat -l 5
67645 ingo.karka    Merged /branches/1.50/foobar:r67488
67423 ingo.karka    Merged /branches/1.50/foobar:r67315,67331
67339 ingo.karka    Merged /branches/1.50/foobar:r67279
53320 ingo.karka    Merged /branches/foo-1.01:r53317

0

使用propgetproplist命令似乎非常慢。

对于我的目的,很容易在每个版本上执行svn diff --properties-only并将其存储。它存储了足够的信息,以便您可以编写其他脚本来执行任何比较/归因而不涉及网络问题或使propget/proplist变得如此缓慢。

#!/bin/bash

# 7273 being the highest revision in my repository
for j in {1..7273}; do
    i=$((j-1))
    echo "$i:$j"
    svn diff --properties-only -r $i:$j https://... > propdiff.$j.txt
done

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