stream 简介
Stream(流)是 Jazz 源代码管理系统中的重要成员,体现项目开发中的一个版本,由一个或者多个 component( 组件)构成。流的建立使得团队成员在不同的版本之间进行代码的共享与管理,满足项目迭代开发中代码管理的需要,促进团队成员之间更好的协作。组件是代码共享与管理的基本单位,由一个文件或者文件夹所构成,团队成员可以通过使用流中的组件进行代码的共享。
多个 stream 的应用场景
目前,软件开发中迭代开发非常普遍,项目的开发经常涉及两个或多个版本。即在一个版本尚未发布就需要进入下一个软件版本的开发,这样使得项目开发人员需要同时维护多个软件版本。特别是一个缺陷需要在多个版本上解决,这样在这些不同的软件版本上进行代码同步就成为团队开发人员日常的工作内容。如何简化代码同步的流程,提高多个软件版本代码同步的效率以及减少在多个软件版本中由于代码同步引起的缺陷数,对于降低软件开发成本和提高软件质量具有重要的意义。
RTC 对多 stream 代码同步的支持
源代码管理与共享是项目开发中的重要内容,而 RTC 作为主流的源代码管理工具,对项目的源代码的管理与共享提供了很好的机制。在实际的项目开发过程中,项目拥有者需要在远程 Jazz 服务器上创建 stream,项目开发人员在远程 Jazz 服务器上基于此 stream 创建自己的版本库工作空间。除此之外,开发人员还需要在本地的机器上创建自己的本地工作空间。开发人员通过 Check-in 操作将本地工作空间的改动同步到远程 Jazz 服务器上的自己的版本库工作空间,通过 Deliver 操作将远程版本库工作空间的代码同步到团队共享的 stream 上。其他团队人员则通过 Accept 操作将代码从 stream 同步到自己远程的版本库工作空间,并通过 Load 操作将版本库工作空间的源代码下载到本地的工作空间。依此类推,RTC 就可以同时管理多个 stream 并进行有效的共享,其具体的源代码管理与共享机制如图 1 所示:
图 1. RTC 中多 stream 源代码管理与共享机制
通过 RTC 中对源代码的管理与共享机制可以看出,如果不进行任何修改与配置,在多个 stream 上,开发人员只能通过单独维护每个 stream 上的源代码,并在这些 stream 上进行代码的来回复制达到多 stream 上的源代码同步,这样无疑增加了维护和同步多个 stream 上的源代码成本。事实上 RTC 可以通过更改相应的 flow target(目标流指向)来简化多 stream 上的源代码同步,有效的提高项目开发的效率。
总的来说,RTC 对多 stream 上源代码的同步提供了三种方式:各 stream 单独同步,stream 由低版本向高版本同步及 stream 由高版本向低版本同步,具体操作如下图所示(图中以两个 stream 为例,多个 stream 可以依此进行类推):
图 2. 各 stream 单独同步
图 3. stream 由低版本向高版本同步
图 4. stream 由高版本向低版本同步
从图 2 可以看出,同步 stream1 和 stream2 上的源代码需要在每个 Local workspace 上 Check-in 相应的代码,在同步第二个 stream 时需要从一个 Local workspace 上拷贝源代码到另一个 Local workspace 上,这样加大了开发人员的工作量,并且增加了一些由拷贝源代码所造成的缺陷。图 3 与图 4 的同步机制没有多大差别,图 3 所示的为源代码从低版本(stream1)向高版本(stream2)同步,开发人员先将代码提交到 stream1,然后改变 stream2 的目标流指向,接受之前提交到 stream1 上的变更集,最后通过 Jazz Server 上的 Repository workspace 将变更集提交到 stream2 上。图 4 所示为源代码从高版本(stream2)低高版本(stream1)同步,具体过程与低版本(stream1)向高版本(stream2)同步相反。由于高版本往往会包含低版本没有实现的功能,所以对于多 stream 的源代码同步,采用从低版本向高版本同步的方式遇到的潜在的源代码冲突相对较少,开发人员解决这些冲突并合并变更集所付出的成本也随之降低。因此,在实际项目开发中,对于多 stream 的源代码同步,采用低版本(stream1)向高版本(stream2)同步的方式最佳。
RTC 中多 stream 代码同步的示例
由于多 stream 从低版本中向高版本同步时潜在的冲突最少,因此本文将以这种同步方式作为示例说明如何在两个 stream 实现源代码的同步。对于三个或三个以上 stream 的代码同步,读者可以依此类推。在示例中,我们拥有两个 stream,6.3.1.1 和 6.3.2。并且我们已经创建好两个 stream 上对应的两个我们自己的版本库工作空间。
无代码冲突情况下的代码同步
打开 Pending Changes 视图,在 6.3.1.1 版本库工作空间上有个新的可交付变更集,右击选择 deliver 对其进行交付,具体操作如图 5 所示:
图 5. 交付变更集界面
打开更新版本的 6.3.2 版本库工作空间,更改其 Flow Targets 到 6.3.1.1 stream。如图 6 所示,将 6.3.1.1 stream 置成当前 flow target 且是默认 flow target,然后确认保存。
图 6. 版本库工作空间界面
保存后结果如图 7 所示。
图 7. 更改 Flow Target 界面
如图 8 所示,此时再次查看 Pending Changes,6.3.2 版本库工作空间已经指向 6.3.1.1 stream,刚才在 6.3.1.1 版本库工作空间中交付的变更集出现在 6.3.2 版本库工作空间的可接受变更集中。此时该变更集与 6.3.2 版本库工作空间中代码不存在冲突,可以直接选择接受。
图 8. 接受 Incoming 变更集界面
接受后,将 6.3.2 版本库工作空间的 flow target 改回 6.3.2 stream ,如图 9 所示:
图 9. FlowTarget 配置界面
从图 10 中可以看出,在 Pending Changes 中,6.3.2 版本库工作空间中有了新的可交付变更集,该变更集正是 6.3.1.1 版本库工作空间之前交付的变更集。由于不存在冲突,我们可以直接将该变更集交付到 6.3.2 stream 中,从而实现两个 stream 上针对该变更集的源代码同步。在下一节中我们将给出存在代码冲突的同步示例,为了模拟这种情况,我们暂且不交付此变更集。
图 10. 交付 Outgoing 变更集界面
有代码冲突情况下的代码同步
同样,打开 Pending Changes 视图,在 6.3.1.1 版本库工作空间提交一个新的变更集模拟代码冲突,右击选择 deliver 对其进行交付,具体操作如图 11 所示:
图 11. 交付 Outgoing 变更集界面
更改 6.3.2 版本库工作空间 flow target 到 6.3.1.1 stream。从 Pending Changes 视图中可以看到 6.3.1.1 版本库工作空间中新提交的变更集。该变更集前出现橙色高亮,说明该变更集和 6.3.2 版本库工作空间中可交付的变更集存在代码冲突。具体操作如图 12 所示:
图 12. 接受 Incoming 变更集界面
选择接受该变更集,此时会弹出是否自动解决冲突的对话框如图 13,我们这里建议选择 Resolve Later,以防止出现代码合并错误的情况发生。下面我会给出具体的情况说明在接受冲突变更集后如何 Resolve。Resolve 有两种方法:自动合并和手动合并。什么时候选择自动合并,什么时候需要手动合并,这对于维护代码的同步和准确性十分重要。
图 13. 冲突提示界面
选择 Resolve Later 后,将 6.3.2 版本库工作空间的 flow target 改回 6.3.2 stream。如图 14 所示,出现未解决代码冲突。双击打开冲突比较视图。
图 14. 未解决冲突界面
如果视图中仅有蓝色标识,说明没有严重冲突。如图 15 所示,可以选择 Auto Merge 自动合并代码。
图 15. 自动解决冲突操作
图 15 大图
如果视图中有红色标识,说明存在严重冲突,自动合并代码将导致代码错乱。如图 16 所示,将红色部分右侧代码拷贝覆盖到左侧,手工完成覆盖后,选择 Resolve As Merge 完成合并。
图 16. 手动解决冲突界面
图 16 大图
在弹出的对话框中选择 OK 确定手动合并操作,如图 17 所示:
图 17. 手动解决冲突确认界面
这样合并完成后,6.3.2 版本库工作空间可交付变更集如图 18 所示。此时可看到被合并的原变更集后出现 1 merged 字样,合并操作完成。对其交付后,6.3.1.1 stream 和 6.3.2 stream 在该变更集存在冲突的情况下实现了代码同步。
图 18. 交付合并后变更集界面
撤销已交付的错误代码
在同步两个或多个 stream 的时候,很可能误将不属于本 stream 的代码 deliver 到 stream 上。如果错误交付的代码过多的话,手动去删除错误交付的代码将会需要花费很大的工作量来将代码还原到原来的状态。而且,还会带来代码被错误修改的风险。而 RTC 提供了一种回退(Reverse)的功能,将错误交付的代码自动清除掉,并恢复到原来的状态。
回退(Reverse)功能的具体操作步骤如下:
- 右击错误提交的代码所相关的 work iteam,并单击弹出的 Reverse 菜单。
图 19. work iteam 的回退
- 点击 Reverse 菜单后,会弹出如下图 20 所示的窗口,指示修改前的文件将会在 Pending Patches 以 patch 的形式显示出来。然后,点击 OK 按钮。
图 20. 添加到 Pending Changes
- 如图 21 所示,在 patch 中你可以通过双击 java 文件来查看原来文件里的内容和错误交付代码后的文件的差异,来查看是否是你想要恢复的结果。
图 21. Patch 显示界面
- 将这个 patch 添加到现有的 workspace 上面,从而将原有的变更集先恢复到本地的 workspace 上。
图 22. 合并 Patch 界面
- 原有的文件将会作为未提交的文件显示出来。
图 23. 未解决冲突界面
- 通过将原有的代码重新 check-in 和 deliver,从而将被错误修改的代码从项目组共享的 stream 上删除出去。
图 24. Check-in 变更集界面
如果将代码错误提交到 stream 后,有其他开发人员提交了自己的代码,这个时候要进行回退的时候,需要查看需要回退的文件是否和其他开发人员修改的文件有冲突。如果有冲突,可以通过前面提过的方法进行代码冲突的整合;或者把错误提交代码以后其他开发人员提交的代码先回退回去,在把错误提交的代码从 stream 上删除以后,重新将其他开发人员提交的代码 deliver 到 stream 上。
致谢
衷心的感谢钱巧能工程师在本文大纲方面的讨论所提供的意见和支持。
结束语
本文详细介绍了 RTC 代码同步的原理,并且比较了目前 RTC 中多 stream 上代码同步的几种方法,最后以具体示例说明了如何在 RTC 中进行多 stream 的代码同步,解决代码同步中出现的冲突及如何撤销错误的代码同步。读者可以通过阅读本文,掌握各种在 RTC 中多 stream 代码同步的方法,并根据项目实际情况选择,灵活运用,提高项目开发的整体效率。