删除不必要的 svn: mergeinfo 属性

当我合并存储库中的内容时,Subversion 想要添加/更改许多 svn:mergeinfo属性到与我想要合并的内容完全无关的文件中。

关于这种行为的问题已经在 Stack Overflow 上提出过了:

从我对上述主题的理解来看,我的存储库中的许多文件似乎都有明确的 svn:mergeinfo属性,尽管它们本不应该具有这些属性。建议是减少数量,只将这些属性放在相关的文件/文件夹中。

因此,现在我的问题是: 如何轻松地删除这些不需要的属性?我使用 TortoiseSVN,但我不愿意手动检查/修复数百个文件。有没有更简单的方法去除那些不必要的 svn:mergeinfo属性?

另外,我是 没有,正在寻找 C + + SVN API 代码。

67988 次浏览

正如 这根线中提到的:

  • 大多数空合并信息(“空白”)可能是由工作副本到工作副本的复制/移动造成的,其中源项没有显式的合并信息。除非您使用的是1.6 SVN,否则使用 prodel 可能是解决方案: 自1.5.5以来,这些 WC-to-WC 副本不再在目标上创建空的 mergeinfo
  • 早期的 svn move (rename)重构操作也可以传播 mergeinfo,而不是将它们保留在根目录中
  • 有一个潜在的内存问题,由 案件3393跟踪,将在即将推出的1.6.2版本中修复,并在1.5版本中反向移植

如果确定要大量删除 mergeinfo 属性,可以使用以下 BASH 脚本。

FILES=`svn status |grep "^ M      " |sed s/" M      "// |tr '\n', ' '`
svn revert $FILES

它获取一个已更改文件的列表,过滤到只有 mergeinfo 更改,除去实际文件路径之外的所有内容,将每行一个路径转换为一个空格分隔的列表,然后在该列表上恢复调用。

这里有一个方法可以删除所有子树 svn: mergeinfo 属性:

svn propget svn:mergeinfo --depth=infinity
| grep -v "^/"
| grep -v "^\."
| cut -d- -f1
| xargs svn propdel svn:mergeinfo

为了便于复制/粘贴,所有这些都在一行中:

svn propget svn:mergeinfo --depth=infinity | grep -v "^/" | grep -v "^\." | cut -d- -f1 | xargs svn propdel svn:mergeinfo

要在运行之前预览这将影响哪些文件,请将最后一个“ prodel”更改为“ proget”,或者完全删除最后一个 xargs 管道。

我知道已经有一段时间了,但我也遇到过类似的问题。我使用 TortoiseSVN 1.6.7。碰巧这个属性是我工作副本的根目录。当我查看根目录下的属性并点击 delete on svn: mergeinfo 时,它询问我是否要递归地删除它。这消除了我所有的 svn: 合并信息错误。

这里有另一种方法来删除所有子树 svn: mergeinfo 属性,但不在根文件夹中(这是分支正常工作所必需的)。

从项目的根本做起:

svn propdel svn:mergeinfo -R
svn revert .
svn ci -m "Removed mergeinfo"

要对目录结构进行更改,应该是(非 DOS‘ find’only) :

find . -path "*/.svn" -prune -or -exec svn propdel svn:mergeinfo '{}' \;

运行一个连接到1.5服务器的1.6.12客户机时,我遇到了类似的问题; 项目中有一个子目录 ,它需要自己的 svn: mergeinfo,但是有121个这样的条目(包括下面的5个目录)。/var 与“ svn: 忽略 *”)似乎有些不合适。因此,最好有一个(例如 Python)脚本,它能够删除明显多余的合并信息,并告诉其他差异..。

由于我对盲目删除 svn:merge-info属性没有信心,我已经实现了一个工具来分析一个工作副本的当前情况,并从非根合并信息属性中删除尽可能多的合并修订。在额外的人工检查和控制之后,可以提交工作副本上的更改。

就是这里: Svn-clean-mergeinfo

不要犹豫,报告任何问题,使用它得到改进。

Subversion 1.10引入了一个专门用于该任务的新工具: svn-mergeinfo-normalizer

不仅仅是盲目地删除 mergeinfo 属性,还可以完成“丢失”的合并。

从根文件夹复制 mergeinfo 属性,然后对子文件夹执行合并,以获得相应的相对路径和完全相同的修订列表。(您可以(但不需要)只列出此列表与子文件夹中已有列表之间的差异。)

通常,这种合并最终应该只改变 mergeinfo 属性,而不是任何实际的文件。(如果它最终改变了文件,那么以前的合并之一必须只是部分合并,这可能会给您带来问题。)

这样做的结果应该是删除 mergeinfo 属性,一旦您让它们完全匹配。您可能还需要做相反的事情: 将只存在于子文件夹中的任何合并修订版本合并到根目录中(同样,您只需粘贴完整的列表,然后让 SVN 为您整理出差异)。

从存储库的根目录运行,删除 svn: mergeinfo 属性:

  • Bash 命令: svn propdel -R -q svn:mergeinfo `svn ls`
  • PowerShell 命令: svn propdel -R -q svn:mergeinfo (svn ls)

这个命令的好处:

  1. 它处理子树,但不处理根目录;
  2. 它处理隐藏(“点”)文件;
  3. 它忽略不受版本控制的文件。

附言。如果提交的文件带有空格(或其他不寻常的符号?) ,命令可能会失败在根目录的名称中。