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

Posted

技术标签:

【中文标题】Subversion:如何找到所有未合并到主干的修订?【英文标题】:Subversion: howto find all revisions that are not merged to trunk? 【发布时间】:2011-01-13 13:06:03 【问题描述】:

发布周期的分支源是常见的源管理方案之一。尽快合并是一个好习惯。因此我们有一个人为因素:分支已关闭,但有人忘记将某些内容合并回主干。

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

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

似乎 svn mergeinfo 命令在这里无法提供帮助。如果不是在根级别执行合并,则通过分支和主干根将失败(这是一种常见情况)。

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

附言

最新版本的 SVN。无需争论这种情况有多普遍或有多好;)

【问题讨论】:

我很惊讶这个问题还没有答案!在引入 mergeinfo 之前,这确实是一件很难的事情,但现在我期待一个像“愚蠢的,你应该学习如何 google,这里是链接”这样的答案。奇怪又令人失望。 【参考方案1】:

出于这个原因,CVS 创建了一个标记来标记分支的根 :) 对于 SVN,它应该如下所示:

+ trunk / project1
+ tags / project1-b1-root
+ branches / project1-b1

注意事项:

    标签project1-b1-root和分支project1-b1同时从主干创建。 任何人都不应提交到 project1-b1-root(您可以将此操作限制为 tags/ 路径)。 当每个人都声称他已经把所有东西都放到了后备箱中时,您可以在 project1-b1-rootproject1-b1 之间进行区分并尝试将其应用于主干:已经应用的更改将被静默跳过,其余的您将看到差异或冲突。

【讨论】:

@dma_k 3 步需要人工交互。我真的需要像 svn mergeinfo 一样的东西,它返回一个简单的合并(或未合并)修订列表。在您获得合并结果后的场景中,需要进一步手动调查以找出未合并的修订版本以及作者是谁。【参考方案2】:

我不会担心需要合并的特定更改编号,而只需查看差异:

首先,使用主干更新侧分支(或查看将合并的内容):

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 merge 命令看起来就像 svn diff 命令——你创建一个 diff/patch,然后将它应用到一个特定的位置。上面的合并命令只是说“获取主干和分支之间的所有差异,并将它们应用于主干的工作副本”。因此,您可以轻松地将第二个合并命令更改为邮件通知的差异。

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

【讨论】:

@Ether 这是关于合并的一个很好的简短解释;)我确实知道如何合并(即这不是问题)。我对源代码维护感兴趣,并希望获得有关“未合并的内容”问题的自动答案。答案将邮寄给忘记合并的人。 @Dandikas:我已经修改了我的答案,以便更清楚我的意思。【参考方案3】:

如果您使用带有 mergeinfo 子命令的相对较新的 Subversion 版本(我认为是 1.5 或更高版本),您可以非常轻松地完成此操作。

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 仅将列表从“合并的内容”更改为“尚未合并”,但提到的子文件夹提交失败仍然存在。 "这是一个常见的场景" -> 在不同级别合并/分支是一个常见的错误!始终在您的分支开始的那个级别合并。总是。 svn mergeinfo 命令(至少在当前版本中)有一个-R(递归)选项,它应该包括执行较低的合并。我们尝试总是在顶层合并(提交可以在较低层执行,或者只包括某个目录中的文件,但总是在顶层合并)所以我还没有真正测试过。 我一时被术语弄糊涂了,这里的“级别”是指“目录级别”吧?【参考方案4】:

svn merge --dry-run 会为您提供所需的详细信息吗?

【讨论】:

nope :( 试运行会判断运行合并是否会产生冲突。同样,您可以尝试找出未合并的修订版,但这更像是一个游戏,而不是“一键式”可以安排在分支关闭时自动运行的操作。【参考方案5】:

我意识到你的情况可能为时已晚,但我为这类事情做的是为合并提交建立一个约定,以便以后可以识别它们。例如“正在合并 [1234]:...(1234 的完整提交日志)...”。然后我可以稍后用脚本从 svn log 中解析出来。

为确保您的整个团队都能做到这一点,请将合并约定制作成脚本并将其放入您的项目中。 (例如,./scripts/merge 1234)。人们通常甚至会欣赏这一点,如果脚本使合并比原始 svn 命令更容易通过自动找出源 url 之类的事情来加倍

祝你好运。

【讨论】:

这听起来像是需要的,除了我不想在 cmets 上做一个约定,因为我们从 SVN v1.5 开始就有 mergeinfo 属性 我听到了。我希望这也能奏效,但除了使情况复杂化之外,我还没有让 1.5 合并处理做任何事情。【参考方案6】:

简短回答:我不这么认为。

长答案:我最终编写了一个 python 脚本来回答这个问题。 每当开发人员合并变更集时,他们都需要将“merged rXXX”放入日志消息中。 (这是在 svn:mergeinfo 存在之前)该脚本解析所有实时 svn 分支 + 主干并递归扫描所有“合并”链接,输出每个开发人员尚未合并的更改列表。

[更新] @tmont 的答案现在更好了,因为每个人都有一个支持 svn mergeinfo --show-revs eligiblesvn merge --record-only 的 svn 版本,当您只想记录逻辑修复时。

【讨论】:

@Nathan Kidd 这正是我要找的!唯一的区别是我希望它可以在没有特殊注释的情况下工作,因为现在我们有了 svn:mergeinfo 属性。 @Dandikas 如果我要再写一次,我不确定我是否会使用 svn:mergeinfo。原因是我们关心的并不是某个特定的差异被合并,而是应用了该问题的逻辑修复。有时,如果一个分支分歧足够大,我们会修复问题并将其标记为“合并”,但实际上我们没有应用任何原始差异;使用单独的方法来解决相同的问题。手动日志消息方法可以让你做到这一点,svn:mergeinfo 没有那么多。 明白你的意思。我们的工作流程在尽快执行合并的方式上略有不同。 IE。如果开发人员将修复提交到一个分支(无论是一个提交还是多个,完成修复),他都会立即将它们合并到主干。这种方法有很多优点和一个严重的缺点——人为因素。分支中的任何修复都可能在更大的压力和更少的可用时间下执行。然而我们仍然必须保证,人们(开发人员是正确的)知道他们什么时候可能忘记合并某些东西。 有解决merginfo问题的办法。那就是“svn merge --record-only”来记录那些在树的不同部分完成的合并,或者没有实际合并而是应用逻辑修复的地方。然后,您可以使用“--show-revs 合格”来获取仍在等待合并的内容列表。【参考方案7】:

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

svn log --verbose

你可以解析哪个?我不确定合并回主目录后的输出,但您可能能够解析(使用脚本,我没有,因为我是唯一一个使用我的 SVN 服务器的人)日志并阅读所有已经签入的文件,然后寻找一个关键字表明该文件已被合并到main?

如果我有时间,我今晚回家后会尝试检查一下。

【讨论】:

【参考方案8】:

由于缺乏灵丹妙药,严格的方法是记录已合并的内容以及从何处合并。

【讨论】:

只要有 不!由于缺乏灵丹妙药,必须开发它。最好的程序是工作代码。 @Pavel 如果还有很多其他有趣的事情想要开发,对于这个问题,可能会想改用 git。【参考方案9】:

根据Ether的回复above,来自您要检查未合并修订的分支

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 |'

【讨论】:

如果您发现自己在第 2 行和第 3 行中使用了 grep 和 sed,请尝试以下简单优化:sed -n 's/--- Merging//p'【参考方案10】:

在创建 3 年后,我很喜欢你的主题。而且我相信您提出的任务仍然没有解决方案:)

我在$ svn help merge 中发现的建议是不要进行子树合并:

如果你只想合并一个子树,那么子树路径必须是 包含在 SOURCE 和 TARGET_WCPATH 中;这是不鼓励, 避免子树合并信息

所以我想解决方案是打破你进行子树合并的“常见场景”。

必须为合并操作建立一些控制,否则任何对一个分支具有读取权限和对另一个分支具有写入权限的人都可以从第一个分支到第二个分支。所以实际的问题是 - 如何控制子树合并))

【讨论】:

【参考方案11】:

我已经使用 Wicket 和 SVNKit 编写了 Java Web 应用程序,用于查找分支之间未合并的修订,可以对其进行自定义以执行任何您想要的操作...link

o

【讨论】:

以上是关于Subversion:如何找到所有未合并到主干的修订?的主要内容,如果未能解决你的问题,请参考以下文章

使用 TortoiseSVN 如何将更改从主干合并到分支,反之亦然?

在 Subversion 1.5 中将分支重新集成到主干时缺少范围错误消息

在 Subversion 中合并分支时的冲突预防

为啥我在 Subversion 中遇到树冲突?

将分支合并到主干

cvs2svn 和合并信息