本作业指导书规范XXXXXX部XX组程序开发过程中,补丁管理的工作内容和流程。
补丁管理是程序开发和维护中的重要活动。补丁管理主要使用diff和patch工具程序进行,结合变更控制和bug管理、SVN/VSS代码版本管理和版本发布管理,能有效规范开发流程,提高维护和调试效率,帮助提高代码质量。
补丁管理的主要规则:
补丁管理使用的diff和patch可以从http://gnuwin32.sourceforge.net/下载得到。
diffutils工具包:diffutils-2.8.7-1-bin.zip和diffutils-2.8.7-1-dep.zip
patch工具包:patch-2.5.9-6-bin.zip
将diffutils工具包和patch工具解压缩到“D:\Program Files\Gnuwin32”目录
修改系统变量Path的设置,增加“D:\Program Files\Gnuwin32¥bin;”到Path变量值定义的最前面:
为简化命令输入,创建D:\Program Files\Gnuwin32¥bin¥mydiff.bat,内容如下:
@"D:\Program Files\Gnuwin32\bin\diff" -Nur --ignore-file-name-case -xDebug -xRelease -xEnv -x.svn -x_svn -xboost -xstlport -x*.ncb -x*.opt -x*.scc -x*.plg -x*.clw -x*.aps –x*.user -x*.org -x*.orig -x*.rej -x*.rar %1 %2 %3 %4 %5 %6 %7 %8 %9
如果补丁更新了boost或stlport,则将其中的-xboost或-xstlport删除后,再用其制作补丁文件。
通常要基于一个已确认可以正常运行的源代码版本和开发环境开始开发和调试工作,这个环境称为基线;基线代码用于制作补丁的基准目录,也称为补丁基线。
通常把补丁基线配置为开发主干的最新标签版本。
参考《SVN管理和使用作业指导书》中“导出版本”的内容,获取开发主干的最新版本标签作为补丁基线。
程序员对代码进行修改后,在生成补丁前应该确保修改的代码格式、变量和函数命名等符合项目编码规范的要求。
例如,XXXX客户端采用GC GreatCode工具统一代码格式,方便统计补丁修改的代码量。GC工具包可以从下联系我得到。
该工具可嵌入集成开发环境:
为英雄无敌客户端定制的GC.bat内容:
"D:\Program Files\GnuWin32\bin\GC.exe" -space_if- -no-space_cast_after- -code_len-80 -code_split_fctcall_style-1 -code_split_fctdef_style-2 -code_split_fctdecl_style-1 -code_split_for_style-1 -code_split_if_style-1 -code_constructor_style-1 -no-code_wizard_indent- -stmt_force_brace-1 -stmt_concat_else_2_stmt- -stmt_brace_style_decl-2 -stmt_brace_style-2 -stmt_switch_style-3 -stmt_switch_eol-1 -stmt_static_init_style-3 -no-cmt_add_gc_tag- -no-cmt_add_file- -cmt_c2cpp- -no-cmt_first_line_break_first- -no-cmt_first_line_break_last- -cmt_sep_len-79 -no-cmt_sep_break- -cmt_sep_eol_before-0 -code_align_max_blanks-1 -no-cmt_add_fct_def_class- -no-cmt_add_class_access- -cmt_decl_len-80 %1
建议主程序员在项目初期结合编码规范要求进行GC.exe选项定制,并监督项目开发人员遵照执行。项目编码规范以主程序员的要求为准。
假定补丁基线为\prj\XXXClient-0.56,当前工作目录为\prj\XXXClient,补丁对应bug#123,可采用以下命令生成补丁:
cd ¥prj
mydiff HeroClient-0.56 HeroClient > hobug123-0.56-wfy-rc1.diff
补丁文件命名规则:项目名字母缩写bug“Bug编号”-“基线版本号”-“补丁制作者名字缩写”-rc“补丁顺序号”.diff。补丁文件命名以《文件编号规则》为准,多次生成补丁必须保证补丁文件不重名。
项目名字母缩写:XXXXX项目名字母缩写为“xx”,XXX项目名字母缩写为“xx”;XXXX项目名字母缩写为”xx”。
补丁制作者名字缩写:可以采用SVN/VSS帐号名;应该很容易通过缩写分辨出补丁文件制作者。
“rc”是“Release Candidate”的缩写;对于同一bug同一基线的多次补丁文件,其补丁顺序号从1开始编号;如果更新了补丁基线版本号,则补丁顺序号从1开始重新编号。
文件名后缀.diff:表示是diff工具的输出。
制作补丁文件后应该自己先审核和调试,自测没有问题后再上传文件服务器,并通知主程序员安排审核。程序员根据审核意见进行修改,更新补丁。
补丁文件上传目录,还未开通文件服务器权限,或者文件服务器临时故障无法连接的,应将补丁文件发送给主程序员,事后再补充上传。
在审核或提交补丁时都需要将补丁应用到代码上,称为“打补丁”或patch。使用patch命令进行打补丁的操作:
cd ¥prj¥HeroClient
patch –p1 < ..¥hobug123-0.56-wfy-rc1.diff
要移除补丁,则在以上patch命令中增加“-R”选项:
patch –p1 –R < ..¥hobug123-0.56-wfy-rc1.diff
补丁审核按照Review作业指导书和Review检查清单进行。
审核通过的补丁由制作补丁的程序员负责提交(commit)到代码库中。相应的补丁提交日志信息应该注明补丁对应的bug编号和修改意图。例如:
应用Bug#249补丁,增加战斗层瞬间移动魔法功能:
1. 修改CTacticMap::SelectMagic(),增加选择瞬间移动魔法后的处理,先选择要移动的生物;
2. 修改CTacticMap::OnLButtonDown(),增加瞬间移动魔法选择己方生物和移动目标的处理;
3. 修改CTacticMap::InitializeCursors(),增加瞬移魔法鼠标指针初始化。
补丁修改意图应该简单明了,建议采用“增加……功能”、“修改……的问题”的句式进行描述。
由主程序员或指定的版本发布人员进行。
版本发布时应该在版本标签日志信息中说明版本补丁对应的bug编号和修改意图。这些信息是收集和整理提交补丁时的日志信息获得的。例如:
1. 应用Bug#160补丁,修改战略层英雄上船处理;
增加战略层CMsgWarArmyMoveTakeBoat消息;
删除战略层CMsgWarArmyTakeBoat消息;
2. 应用Bug#263补丁,增加战略层任务失败后显示动画光效功能;
3. 应用Bug#262补丁,增加战斗层生物防御后增加防御值功能;
修改战斗层CMsgBattleUnitDefend消息格式;
增加战斗层CMsgBattleSetDefenceAttr消息;
4. 应用Bug#264补丁,修改Win2000系统上交互层人物无法移动的问题。
具体操作参考《SVN管理和使用作业指导书》。
发布版本后,要将该版本中新提交的补丁文件保存到项目开发库patch目录下对应的版本文件夹,去掉补丁文件名中的“-rc*”(表示已经是正式的版本补丁,不是Release Candidate)。具体要求参考《文件编号规则》。
构造countAdd.bat内容如下:
@echo %1 >> add.txt
@gawk "/^\+/" "%1" | gawk "/[[:alnum:]]/" | gawk "!/^\+\+\+/" | gawk "!/^+[[:space:]]*#/" | gawk "!/^\+[[:space:]]*\/\//" | gawk "!/^\+[[:space:]]*\/\*/" | wc -l >> add.txt
直接使用find命令,或将其保存为count.bat文件使用:
find -type f -name "*.diff" -exec countAdd.bat "{}" ;
find需要安装GnuWin32的findutils工具包,gawk需要安装gawk工具包,wc需要安装coreutils工具包。
find工具包:findutils-4.2.20-2-bin.zip和findutils-4.2.20-2-dep.zip;
gawk工具包:gawk-3.1.3-2-bin.zip和gawk-3.1.3-2-dep.zip;
coreutils工具包:coreutils-5.3.0-bin.zip和coreutils-5.3.0-dep.zip。
通过规范化补丁管理,可以方便程序员进行bug定位和问题解决:
例如英雄无敌Bug#264:Win2000下进入交互层后无法操作鼠标。通过回溯客户端版本,确认问题最早出现在HeroClient-0.57版本。
通过检查开发库patch目录,发现该版本新增了3个补丁,只有Bug#255的补丁中有鼠标处理,基本可以确定是该补丁引入的问题。
还可以通过从基线中逐个移除或增加补丁的方式,确定嫌疑补丁。
通过审核发现Bug#255没有对新增成员变量进行初始化,通过查看补丁逻辑,可以确定是变量未初始化导致的问题。