使用Mercurial执行历史构建

时间:2011-06-29 22:14:10

标签: date logging build mercurial

背景

我们使用中央存储库模型来协调团队中所有开发人员之间的代码提交。我们的自动夜间构建系统每天凌晨3点都有一个代码提交截止日期,当它将中央仓库中的最新代码提取到自己的本地存储库时。

几周前,我们进行了一次构建,其中包括回购的修订版1 。那时,构建系统没有以任何方式跟踪用于执行构建的存储库的修订(现在,幸运的是)。

  -+------- Build Cut-Off Time
   |
   |
   O    Revision 1

在构建截止时间之前的一小时,开发人员从存储库中分支并在他们自己的本地副本中提交了新的修订。他们没有在切断之前将其推回中央仓库,因此它没有包含在构建中。这将是下图中的修订版2

  -+------- Build Cut-Off Time
   |
   | O  Revision 2
   | |
   | |
   |/
   |
   O    Revision 1

构建之后一小时,开发人员将他们的更改推回到中央仓库。

   O    Revision 3
   |\
   | |
  -+-+----- Build Cut-Off Time
   | |
   | O  Revision 2
   | |
   | |
   |/
   |
   O    Revision 1

因此,修订版1进入构建版本,而修订版2中的更改将包含在第二天早上的版本中(作为修订版3的一部分)。到目前为止,非常好。

问题

现在,今天,我想重建原始版本。看似明显的步骤是

  1. 确定原始版本中的修订
  2. 更新到该修订版,
  3. 执行构建。
  4. 问题来自第1步。如果没有单独记录的存储库修订,我怎样才能明确确定原始版本中使用的repo修订版本?所有修订都在同一个命名分支上,不使用任何标记。

    log命令

      hg log --date "<cutoff_of_original_build" --limit 1
    

    提供修订版本2 - 而不是修订版1,它位于原始版本中!

    现在,我理解为什么会这样做 - 修订版2 现在最接近构建截止时间的修订版 - 但它并没有改变我无法识别的事实正确的修订版本。

    因此,如果我不能使用--date命令的log选项来查找正确的历史版本,还有哪些其他方法可用于确定正确的历史版本?

3 个答案:

答案 0 :(得分:6)

考虑到撤消文件中的历史记录现在已经消失了(我唯一可以想到的就是可以给出指示),我认为将其缩小到特定版本的唯一方法就是蛮力方法

如果可能的修订范围有点大,并且构建的大小或其他非日期方面的变化线性或接近线性,您可以使用bisect命令基本上做一个二进制搜索来缩小你正在寻找的修订版(或者可能只是接近它)。在bisect停止测试的每个版本中,您将构建该版本并测试您用于比较当晚生成的预定构建的任何方面。根据测试结果,甚至可能不需要建造。

如果它真的像你描绘的图形一样简单,并且可能性的范围很短,你可以从可能的最新版本开始,然后向后走一些修订版,对其进行测试原始构建。

对于比较两个构建的最终测试,散列测试构建并将其与原始构建的散列进行比较可能有效。如果夜间构建机器上的编译和同一版本的机器上的编译生成二进制相同的构建,则可能必须使用二进制差异(例如使用xdeltabsdiff)并寻找最小的差异。


Mercurial没有您想要的信息:

Mercurial不会开箱即用,可以记录和跟踪有关存储库的所有操作,例如pushpullupdate。如果是这样,它将产生大量的日志信息。它确实提供了可用于执行此操作的钩子。

它也不关心你对工作目录的内容做什么,比如打开文件或编译,所以当然它根本不会跟踪它。这根本不是Mercurial所做的。

错误地知道预定构建的确切内容是错误的。你暗示同意,因为你现在记录了这些信息。之前缺乏这些信息只是简单地回过头来咬你,而且没有简单的方法。 Mercurial没有您需要的信息。如果中央存储库只是一个共享目录而不是可能跟踪活动的Web托管存储库,那么有关构建内容的唯一信息就是编译版本。无论是在源代码中声明的某些元数据成为构建的一部分,像文件大小这样天真的方面,还是你真的被困在哈希文件中,你都无法轻易得到答案。

也许你不需要测试每个版本;可能有一些修改你可以肯定不是候选人。知道编译的时间仅仅是作为测试修订范围的上限的一个因素。你知道那段时间之后的修改可能不是候选人。您不知道的是构建服务器从中拉出服务器时被推送到服务器的内容。但是你确实知道那天的修订是最有可能的。您还知道并行未命名分支的修订不太可能是线性修订和合并的候选者。如果有很多并行的未命名分支,并且您知道所有开发人员以特定方式合并,您可能知道parent1或parent2下的修订是否应该基于测试。

如果您可以从源代码中解析元数据以与您对特定构建的了解进行比较,那么您甚至不需要编译。

您可以自动搜索。使用线性搜索最简单:设计的启发式更少。

底线只是 Mercurial 在这种情况下没有魔术按钮来帮助。

答案 1 :(得分:1)

道歉,回答自己的问题可能是不好的形式,但没有足够的空间在评论栏中正确回应。


对Joel来说,有几点:

首先 - 我的意思是真诚的 - 感谢您的回复。您提供了一个被考虑的选项,但最终被拒绝了,因为它太复杂而无法应用于我的构建环境。

其次,你在那里得到了一点讲道。在这个问题中,据了解,由于没有单独记录的存储库修订版,因此需要“一些努力”来确定正确的修订版本。在回答Lance的评论(上图)时,我同意记录40字节的存储库哈希是存档必要构建信息的“正确”方式。但是,这个问题是关于 CAN 做什么 IF 你没有这些信息。

很明显,我在StackOverflow上发布了我的问题有两个原因:

  1. 我认为其他人之前必须遇到这种情况,或许有人可能已经确定了获取必要信息的方法。所以,值得一试。
  2. 信息共享。如果其他人在将来遇到这个问题,他们将有一个明确解释问题的在线参考,并讨论了可行的补救方案。

  3. 解决方案

    最后,也许我最感谢Chris Morgan,他让我考虑使用中央服务器的mercurial-server日志。使用这些日志和一些脚本,我能够明确地确定在构建时推送到中央存储库的修订集。所以,我要感谢克里斯和所有回复的人。

答案 2 :(得分:0)

正如乔尔所说,这是不可能的。但是,某些解决方案可以帮助您:

  • 维护夜间构建修订数据库(日期+变更集ID)
  • 构建服务器可以自动标记它基于(每晚/)
  • 的修订版本
  • 切换到Bazaar,它以不同方式管理版本号(分支版本的格式为REVISION_FORKED.BRANCH_NUMBER.BRANCH_REVISION,因此您的更改编号2将为1.1.1