现在的位置: 首页 > 综合 > 正文

hudson中subversion HEAD check out 的问题及疑惑

2014年06月02日 ⁄ 综合 ⁄ 共 1767字 ⁄ 字号 评论关闭

hudson中subversion HEAD check out 的问题及疑惑

近期发现一个问题,hudson执行任务时,经常不能获取到最新的代码,从而导致出现各种问题。 

日常开发中的典型例子:发现一个bug,修改代码,本地测试通过,提交代码到subversion,手工激活hudson构建,原本期望hudson获取到刚刚提交的代码并测试/打包/发布。结果事与愿违,测试的结果发现刚刚做出的修改似乎没有生效。正费解之时,再执行一次hudson构建,又成功了... 

经历过几次上述蹊跷遭遇之后,发现这个问题不是偶然。之后检查hudson的日志,发现问题的发现在最开始update / check out subversion代码时,明明已经提交的代码,hudson做update / check out时,居然没有update / check out下来!显示的subversion版本号也和subversion上实际的最新版本不一致,hudson总是要小一些,换言之,hudson update / check out的代码要比当前最新代码老一些。 

google一番,发现这个问题之前就有人遭遇过,hudson上甚至已经有了好几个关于这个问题的bug,比如 http://issues.hudson-ci.org/browse/HUDSON-1241 "force using HEAD SVN version for build"。问题的根源在于hudson 获取subversion代码的方式,hudson是通过时间戳的方式来获取代码,而不是我们一般认为的"最新代码"即"HEAD"。这种方式通常没有问题,因为获取当前时间戳,然后要求update / checkout这个时间戳前的代码,理论上也是可以拿到最新代码的。 

但是,如果hudson所在的服务器和subversion服务器时间不一致,这个机制就会出现问题: 

我们假设subversion服务器的时间是准确的,再假设当时时间是15:10分,开发人员A提交代码,subversion上当前这个最新提交的代码时间戳为15:10:00。然后开发人员A手工激活hudson进行构建。hudson在15:10:20时开始check out代码。如果hudson时间无误,则hudson会发出请求说要求获取时间戳在15:10:20之前的代码,这样这个实际提交时间为15:10:00的新代码就可以如期的被check out。但是如果hudson的时钟有误,由于某些原因导致时钟偏慢2分钟,即在hudson上,"当前时间"为"15:08:20",则hudson获取代码的请求为:获取时间戳为15:08:20之前的代码,此时时间戳为15:10:00的新代码就无法checkout。 

几分钟之后,疑惑的开发人员A再次激活hudson再次构建,假设此时时间时间是15:15:00,hudson慢两分钟为15:13:00。此时hudson发出请求: 获取时间戳为15:13:00之前的代码, 因此实际提交时间为15:10:00的新代码可以正常checkout,问题又在不知不觉被回避了。 

总结说,hudson 获取代码的机制不是我们直觉中的获取最新代码(即subversion中HEAD checkout),而是基于时间戳。由于这个方式通常如HEAD般工作,因此我们总是容易误解为是获取最新代码。当hudson的时钟晚于subversion时,悲剧就出现了。 

对这个问题,有几点疑惑: 

1. 不明白为什么hudson不采用最直接最简单最容易被人理解最不容易出误解的HEAD checkout,而要基于时间戳 

2. 这个问题很早就发生了,上面提到的bug 08年就被人提出, "Created: 31/Jan/08 05:37 AM   Updated: 01/Jul/10 11:06 AM",三年了类似的bug被多次提出,但是就是始终没有修复。 

修复的方式很简单,就改一个类的一行代码 

in Class: hudson.scm.SubversionSCM 

line 377: 
final SVNRevision revision = SVNRevision.create(timestamp); 
replace to: 
final SVNRevision revision = SVNRevision.HEAD; 

抱歉!评论已关闭.