Subversion:如何查找所有未合并到主干的修订版本?

55

分支源是发布周期中常见的源代码管理场景之一。尽快合并是一个好习惯。因此,我们有一个人为因素:分支被关闭,但有些人忘记将一些东西合并回主干。

问:是否有一种“一键式”方法可以获取未从分支X合并到主干的所有修订号?

(注意:我不需要这些修订号来查找要合并的内容,我需要它们来创建自动化验证,提醒人们确保他们没有忘记将某些内容合并到主干。合并本身不是问题。)

似乎svn mergeinfo命令无法帮助这里。如果合并不是在根级别上执行的话,则传递分支和主干的根将失败(这是一个常见的情况)。

欢迎使用脚本、工具或任何类型的svn挂钩作为解决方案。

P.S.

SVN的最新版本。不需要争论这种情况有多常见或好;)


我很惊讶这个问题还没有答案!在mergeinfo被引入之前,这确实是一件困难的事情,但现在我期望得到的答案应该是像“傻瓜,你应该学会如何使用谷歌,这是链接”的回答。奇怪而令人失望。 - Dandikas
11个回答

70

如果你使用的是相对较新版本的Subversion(我认为是1.5或更高版本)并且使用mergeinfo子命令,那么这非常容易实现。

svn mergeinfo --show-revs eligible svn://repo/branches/your-branch-name svn://repo/trunk

这将向您展示所有符合条件的修订版本,可以从分支“your-branch-name”合并到主干。

来源:http://svnbook.red-bean.com/en/1.5/svn.ref.svn.c.mergeinfo.html


从@tmont的问题来看,“svn mergeinfo”命令似乎无法提供帮助。如果合并操作不是在根级别执行的(这是一种常见情况),则传递分支和主干的根目录将失败。“--show-revs eligible”仅会列出从“已合并内容”到“尚未合并内容”的更改清单,但所提到的子文件夹提交失败仍然存在。 - Dandikas
7
“and it is a common scenario” 翻译为:“这是一个常见的错误,将分支/合并在不同的级别上!请始终在分支开始的那个级别上进行合并。一定要这样做。” - bebbo
3
svn mergeinfo 命令中有一个 -R(递归)选项(至少在当前版本中),它应该会包括较低级别执行的合并。我们通常尝试在顶层进行合并操作(提交可以在较低级别或仅包括某个目录中的文件进行,但合并总是在顶层进行),所以我实际上没有测试过它。 - Adam
我曾经被术语搞混了一会儿,这里的“level”是指“目录层级”,对吗? - Ed Randall

7
简短回答:我不这么认为。
长篇回答:我最终编写了一个Python脚本来回答这个问题。每当开发人员合并更改集时,他们需要在日志消息中放置“merged rXXX”。(这是在svn:mergeinfo存在之前)该脚本解析所有现有的svn分支+主干,并递归扫描所有“merged”链接,输出每个开发人员尚未合并的更改列表。
【更新】@tmont的答案现在更好了,因为每个人都有一个支持 svn mergeinfo --show-revs eligible svn merge --record-only 的svn版本,用于记录逻辑修复的时间。

@Nathan Kidd 这正是我正在寻找的!唯一的区别是,我希望它可以在没有特殊注释的情况下工作,因为现在我们已经有了 svn:mergeinfo 属性。 - Dandikas
1
如果我再次编写它,我不确定我会使用svn:mergeinfo。原因是我们关注的不是特定的差异被合并,而是应用于问题的逻辑修复。有时,如果分支分歧足够大,我们会修复问题并将其标记为“已合并”,但实际上我们没有应用任何原始差异;另一种方法用于修复相同的问题。手动日志消息方法可以让您执行此操作,而svn:mergeinfo则不能这样做。 - Nathan Kidd
1
明白了。我们的工作流程在合并方面略有不同。也就是说,如果开发人员提交了一个分支的修复(无论是一个提交还是多个提交),他们会立即将其合并到主干上。这种方法有很多优点,但也有一个严重的弱点——人为因素。任何分支中的修复都可能在更大的压力和更少的时间下完成。然而,我们仍然必须确保人们(开发人员也是人)知道他们可能已经忘记了合并某些内容。 - Dandikas
1
合并信息问题有解决方案。那就是使用“svn merge --record-only”记录在树的不同部分完成的合并,或者在没有实际合并而是逻辑修复应用的情况下进行记录。然后,您可以使用“--show-revs eligible”获取仍在等待合并的事项列表。 - Ari Maniatis

2

我知道你的情况可能已经太晚了,但是我为这种情况所做的是建立一个合并提交的约定,以便以后可以识别它们。例如,“合并[1234]:...(完整的提交日志 1234)...”。然后,我可以在稍后的 svn 日志中使用脚本解析它。

为确保您的整个团队都这样做,将合并约定制成脚本并将其放入您的项目中。(例如,./scripts/merge 1234)。人们通常会欣赏这一点,尤其是如果脚本通过自动查找源 URL 等方式使合并比原始 svn 命令更容易。

祝你好运。


这似乎是所需的内容,但我不想在注释方面制定约定,因为我们从SVN v1.5开始拥有mergeinfo属性。 - Dandikas
我听到你的意见。我也希望那样做可以解决问题,但是我还没有看到1.5合并处理程序能够做到除了让情况更加复杂之外的其他事情。 - Mat Schaffer

1

我不会担心需要合并的具体更改编号,而是只看差异:

首先,将分支与主干同步(或查看将要合并的内容):

cd branch-dir
svn merge --reintegrate http://svnrepo/path-to-trunk .
svn ci -m'making this branch current'

cd ../trunk-dir
svn merge --dry-run http://svnrepo/path-to-trunk http://svnrepo/path-to-branch .
svn ci -m'merging in all unmerged changes from <branch>'

记住,svn合并命令看起来就像svn差异命令 - 你创建一个差异/补丁,然后将其应用到特定位置。上面的合并命令只是在说“取出主干和分支之间的所有差异,并将它们应用到主干的工作副本中”。因此,您可以轻松地将第二个合并命令更改为邮件通知的差异。

不要忘记在每种情况下提交之前检查差异,以确保没有发生任何错误。您可能还需要解决一些冲突。


@Ether,对于合并的简短解释不错;)我知道如何合并(即这不是问题)。我对源代码维护很感兴趣,并希望获得有关“未合并”的自动化答案。然后,答案将通过电子邮件发送给忘记合并的人。 - Dandikas
@Dandikas:我修改了我的答案,让我的意思更加清晰。 - Ether

1

很抱歉,我现在没有在家里启动我的SVN服务器来测试这个,但是这个命令可以吗:

svn log --verbose

你能解析哪个?我不确定合并回主干后的输出,但你可能可以通过解析日志(使用脚本,我没有因为我是唯一使用我的SVN服务器的人)并阅读所有已检入的文件,然后查找指示文件已合并到主干的关键字?

如果我今晚有时间,我会尝试在家里检查它。


0
根据Ether上面的回复,从您想要检查未合并修订版本的分支开始。
svn merge --dry-run http://svnrepo/path-to-merge-source .  \
| grep Merging                                             \
| sed 's/--- Merging//'                                    \
| sed 's/into.*//'                                         \
| sort -u                                                  \
| sed 's/ through r/:/'                                    \
| sed -e :a -e N -e 's/\n//' -e ta                         \
| sed 's/ r/ -r/g'                                         \
| sed 's|^|svn log http://svnrepo/path-to-merge-source |'

1
如果你发现自己在第二和第三行中使用了类似grep和sed的东西,请尝试这个简单的优化:sed -n 's/--- Merging//p' - Nathan Kidd

0
出于这个原因,CVS 创建了一个标签来标记分支的根 :) 对于 SVN,应该如下所示:
+ trunk / project1
+ tags / project1-b1-root
+ branches / project1-b1

注意事项:

  1. 从主干同时创建标签project1-b1-root和分支project1-b1
  2. 不允许任何人提交到project1-b1-root(可以限制tags/路径的操作)。
  3. 当所有人都声称已经将所有内容放入主干时,您需要对project1-b1-rootproject1-b1进行差异比较,并尝试将其应用于主干:已经应用的更改将被静默跳过,对于剩下的差异或冲突,您将会看到。

@dma_k 的第三步需要人工干预。我真的需要像 svn mergeinfo 一样返回一个简单的合并修订版本列表(或未合并)。在您的情况下,获取合并结果后需要进一步手动调查以找出未合并的修订版本和作者。 - Dandikas

0

svn merge --dry-run会给你需要的详细信息吗?


不行 :( 干运行会告诉我们是否运行合并将产生冲突。再次,您可以尝试找出未合并的修订版本,但这更像是一个游戏,而不是可以安排在分支关闭时自动运行的“一键”操作。 - Dandikas

0
由于缺乏万能解决方案,纪律性的方法是记录已合并的内容和来源。

只要在同一项目上工作的开发人员不超过10人,就会返回True。如果团队很大,你可以更改编码工作流程或手动检查(糟糕)。 - Dandikas
1
不要啊!由于缺乏万能解决方案,我们必须自己开发。最佳实践是可工作的代码。 - Pavel Radzivilovsky
@Pavel 如果有许多其他有趣的事情想要开发,对于这个问题,一个可能会喜欢转而使用git。 - amit kumar

0

我使用Wicket和SVNKit编写了Java Web应用程序,用于查找未合并的分支修订版本,它可以根据您的需要进行定制... link

screeno


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