内容


Jazz 系列

开始使用 Jazz 源代码版本控制

Comments

系列内容:

此内容是该系列 # 部分中的第 # 部分: Jazz 系列

敬请期待该系列的后续内容。

此内容是该系列的一部分:Jazz 系列

敬请期待该系列的后续内容。

引言

软件开发团队使用一个非常大的文件库,这些文件表示所开发的软件系统的源代码。每个团队成员使用同一个文件库,并更改该库中的一个或多个文件,以添加新功能或修复错误。团队成员验证更改是正确的,然后与其他团队成员共享更改。同时,其他团队成员也在做同样的事情。软件配置管理工具帮助组织团队的文件、跟踪和共享更改,以及保持整个团队协同工作以实现共同目标。

本文的目的是帮助您开始使用 Jazz 中称为“Jazz 源代码版本控制”的软件配置管理组件。

本文档以教程的形式进行组织,并指导您完成一组源代码版本控制场景。因此,欢迎您使用自己的 Jazz 安装来按照本文进行操作。本文档将从 “Jazz 入门教程 ” 文档结束的位置继续,因此若要计划按本文进行操作,您应该首先阅读该文档。这样的话,本文依赖的所有设置和构件都已准备就绪。

下面是对本文档将如何展开讨论的概述:

  • 第二个团队成员将加入我们的示例项目并加载现有的代码。
  • 她将做出代码更改并交付该更改。
  • 然后第一个团队成员将接受该更改。
  • 然后两个团队成员将同时编辑同一个文件,并尝试交付他们的更改,从而导致冲突。
  • 您将看到他们如何通过合并和交付来解决冲突。
  • 还将介绍如何挂起正在进行的工作。

先决条件

与 Jazz 教程文档一样,本文假设您已经有已启动并正常运行的 Jazz 服务器和基于 Eclipse 的 Jazz 客户端,并且客户端能够访问服务器。如果尚未运行此客户端和服务器,请参阅 “Jazz Server 安装指南” 和 “Jazz 客户端安装指南”。然后,请参阅 “Jazz 入门教程” 以设置 Prelude 项目区域,并为包含成员 Chris 和 Jamie 的 Prelude 团队设置团队区域。

使用多个团队成员进行开发

在 “Jazz 入门教程” 中,我们了解到开发人员将其工作签入私有的存储库工作区,该工作区在更改集中跟踪逻辑相关的更改的集合。虽然更改安全地存储在存储库中,但是用户的更改没有与团队的其他成员共享,直到用户决定这样做为止。团队在中共享工作。开发人员决定何时将工作交付到流,以使其对团队的其他成员可用;他还决定何时在自己的存储库工作区中接受流中由其他成员贡献的工作。这样,他就可以根据选择与团队保持隔离或同步。

本部分将首先向该团队引入一名新成员。因此,假设 Chris 已经拥有 Eclipse 工作区,并处于 “Jazz 入门教程” 文档结束时的状态,请保持该 Eclipse 工作区启动并正常运行。在创建第二个 Eclipse 工作区以后,我们将在两个工作区之间来回切换,以了解项目状态对两个团队成员中的每个成员的情况如何。

新成员加入团队

创建新的 Eclipse 工作区

在 “Jazz 入门教程” 文档中,我们创建了用户 Chris 和 Jamie 作为 Prelude 团队的成员。到目前为止,我们一直在 Chris 的 Eclipse 工作区中工作。现在是引入 Jamie 的时候了,这是该团队的第二名团队成员。为此,我们需要在计算机上创建一个单独的 Eclipse 工作区。

  1. 将 Chris 的 Eclipse 工作区保持运行。
  2. 按照您在开始 “Jazz 入门教程” 时的相同方式再次启动 Eclipse。
  3. 当 Eclipse 提示您选择工作区时,请确保不要使用 Chris 正在使用的相同工作区。如果您提供唯一的文件夹名称,Eclipse 将创建该文件夹,同时为 Jamie 创建新工作区。

连接到存储库和项目区域

  1. 启动了 Jamie 的 Eclipse 工作区以后,确保在 Java 透视图中。如果此视图不是当前视图,请从菜单栏选择 Window > Open Perspective > Java
  2. 打开 Team Artifacts 视图,并按照 “Jazz 入门教程” 中的 Getting Started Using Jazz 部分的描述连接到项目区域。下面扼要重述一下相关步骤:

    • Team Artifacts 视图工具栏中选择 Connect to Project Areas 图标 Connect to Project Areas, 以调出 Connect to Project Areas 向导。
    • 确保在该向导第一页中选中 Create a new repository connection 并单击 Next
    • 通过输入服务器位置(http://<server>:<port>/jazz 形式的 URL)和用户 ID jamie 来定义存储库连接。单击 Next
    • 选择要连接到的项目区域。确保选择 Prelude 项目区域并单击 Finish

加入流

  1. Jamie 现在必须加入我们的团队区域的流。从 Team Artifacts 视图中,展开 Prelude 项目区域,并展开 Streams
  2. 选择我们的团队区域的流(标签为 Prelude (Prelude Team))
  3. 从上下文菜单中选择 New Repository Workspace
  4. 将显示一个向导对话框,可以通过此向导对话框命名 Jazz 将在您加入流时创建的存储库工作区。该存储库工作区镜像您在服务器上的本地更改。稍后,您也将通过服务器将更改交付给其他团队成员。将您的存储库工作区命名为 Jamie on Prelude 并单击 Next
  5. 该向导的下一页允许您选择要添加到存储库工作区的组件。确保选择 Prelude 组件并选中 Load workspace after creation 复选框。然后单击 Finish

    此时,Jazz 将把所有代码从 Prelude 流加载到 Eclipse 工作区中。这应该不会花太长的时间,因为 Chris 到目前为止仅开发了极少的代码。

交付更改

现在 Jamie 得到了 Prelude 流中的所有最新代码。下一步,我们让 Jamie 做出很小的代码更改,并将更改交付到流中,以使其对 Chris 可用。

  1. Package Explorer 视图中,一直展开到 Hello.java 源文件,并双击该文件以在编辑器中打开它。

  2. 现在编辑该源代码。假设 Jamie 仅轻微修改了输出的格式设置。因此编辑该代码并将以下行:

    System.out.println(now + ": Hello, World!");

    替换为以下代码行:

    System.out.println(now
    + ":\n   Hello, World!");
  3. 然后通过使用快捷键 Ctrl-s 保存文件。

  4. 您还应该运行该代码以确保没有任何输入错误。在 Package Explorer 视图中,选择 Hello.java。从其上下文菜单中,选择 Run As > Java Application

  5. 如果没有看到 Console 视图出现在右下角,可以通过从菜单栏选择 Window > Show View > Console 来强制显示该视图。您应该在 Console 视图中看到以下输出:

    Thu Dec 14 14:32:49 EST 2006:
       Hello, World!
  6. 此时,更改对 Jamie 的存储库工作区来说是本地的,还没有交付到流。要将更改交付到流,请转到 Pending Changes 视图,并单击 展开到更改 按钮以展开到更改。

  7. 通过从更改集的上下文菜单中选择 Edit Comment,从而为该更改集提供注释,例如 Add newline。然后通过从其上下文菜单中选择 Deliver 来交付该更改集。

自动签入

请注意,当您保存上面的代码更改时,将自动创建更改集,并自动签入您所做的更改,而不需要任何附加的手动步骤。虽然使用自动签入通常是最方便的工作方式,但是可以通过转到 Window > Preferences,单击 Jazz Source Control,并取消选中 Auto check-in local changes 复选框,从而选择禁用此功能。

  1. 试着禁用该功能以了解更改是如何进行管理的。禁用该功能并对 Hello.java 做出更改。待定的更改似乎与前面相似,只不过新的传出更改现在显示在 Unresolved 文件夹中:
  2. Unresolved 文件夹中的某个传出更改的上下文菜单中,您可以使用 Check-in 以签入更改,或者选择 Undo 以撤消更改。

即使您从来不禁用自动签入,如果希望临时离线工作(换句话说,就是没有连接到 Jazz 服务器),则了解 Unresolved 文件夹如何工作也是非常重要的。因为在您离线工作时,服务器不可用,从而无法自动创建更改集和执行签入,您在断开连接时所做的工作将累积在 Unresolved 文件夹中,直到您重新建立连接时为止。

撤消您在进行试验时可能已做的任何本地更改,并确保在继续之前重新选中 Auto check-in local changes 复选框。

接受更改

现在 Jamie 已将更改集交付到流,该更改集可供其他团队成员接受了。Jazz 决不强制更改,因此在 Chris 的情况下,Jamie 的传入更改集一经交付,Chris 即可看到该更改集。下面让我们演练一下:

  1. 此时,我们将切换到 Chris 的 Eclipse 工作区。只需最小化 Jamie 的 Eclipse 窗口,并定位到 Chris 的 Eclipse 窗口。该窗口应该已经以您结束 “Jazz 入门教程 ” 时的状态打开。
  2. Pending Changes 视图中,您可能已经注意到一个传入的更改集。如果没有在该视图顶部看到此指示,可以单击 刷新 按钮以刷新该视图。然后单击展开到更改按钮以展开到更改。可以进一步展开以查看 Jamie 更改的源文件:

  3. 如果愿意,可以双击该源文件以并排比较该文件的两个版本。在对传入的更改集感到满意之后,通过从更改集的上下文菜单中选择 Accept 来将其接受到自己的存储库工作区中。

  4. 可以再次运行该代码以查看控制台输出中的差异。

解决冲突

在开发人员处理不同的文件或一次仅处理一个文件的情况下,无需附加操作即可执行接受和交付工作。但是在开发人员同时处理同一个文件的情况下,又会如何呢?Jazz 源代码版本控制旨在使冲突解决尽可能简单。让我们通过 Chris 和 Jamie 来演练一个简单的冲突场景以了解基本情况。在我们的场景中,Chris 和 Jamie 将同时对同一个文件做出更改。然后他们将分别尝试交付他们的更改。

向同一个文件交付两个更改

下面首先让 Chris 对 Hello.java 文件做出较小的更改。

  1. 确保您是在使用 Chris 的 Eclipse 工作区。可以在 Pending Changes 视图中看到工作区指示:

  2. 现在定位并编辑 Hello.java 文件。应该还有一个编辑器已打开该文件。下面进行微不足道的更改。仅将输出中的冒号更改为 >>。

    System.out.println(now
    + ">>\n   Hello, World!");
  3. 然后保存更改并再次运行该代码。您应该能熟练地完成这些操作了!

下面在 Chris 交付其更改之前,让 Jamie 对同一个文件做出更改。

  1. 确保您是在使用 Jamie 的 Eclipse 工作区。同样,请检查 Pending Changes 视图以进行工作区确认。
  2. 定位并编辑 Hello.java 文件。让 Jamie 做出不同的更改。在此例中,让我们删除主函数之前的注释行。删除以下行:

    /**
     * @param args
     */
  3. 现在保存更改并再次运行该代码。

此时,Chris 和 Jamie 都将更改保存到了同一个文件。但是两人都还没有尝试将更改交付到流。

发现冲突

对于 Chris 和 Jamie,冲突解决任务将成为最后交付更改的人的职责。下面我们将让 Jamie 首先交付其更改,从而查看该原理的实际应用。

  1. 确保您是在 Jamie 的 Eclipse 工作区中。

  2. 在 Pending Changes 视图中,单击交付所有传出更改集按钮,以将所有传出更改集交付到流。

请注意,Jamie 毫无问题地将其更改集交付到了流中。这是因为是她先交付更改。下面让我们看看在 Chris 尝试交付更改时会发生什么情况。

  1. 确保您是在 Chris 的 Eclipse 工作区中。

  2. 通过单击刷新按钮 按钮以刷新 Pending Changes 视图。完成刷新后,Chris 可以看到 Jamie 的传入更改与他自己的传出更改之间的潜在冲突(之所以说“潜在”,是因为他还没有实际接受 Jamie 的更改集——到目前为止,他的工作区中仍然不存在冲突)。潜在的冲突由橙色箭头指示:

  3. 下面继续并通过从更改集的上下文菜单中调用 Deliver 来尝试交付 Chris 的更改。您将获得一个错误:

接受冲突更改集

下面按照错误消息中的建议进行操作,并让 Chris 接受传入更改集,这将把潜在冲突转变为实际冲突。然后我们将完成把 Chris 的传出更改与从流中接受的更改合并起来的过程。下面让我们逐步地完成该过程。

  1. 通过从上下文菜单中选择 Accept 来接受传入更改集。Pending Changes 视图现在将显示带有红色冲突标记的 Unresolved 文件夹。前面在禁用自动签入功能时,我们曾看到过 Unresolved 文件夹。此文件夹同时包含未签入的工作和具有需要解决的冲突的文件。在这两种情况下,该文件夹都提示您还需要做某些工作才能交付更改。

  2. 您可以展开该文件夹以查看冲突的详细信息。有冲突的文件上的工具提示提供了有关冲突性质的更多信息。

合并和解决

  1. 双击有冲突的文件以打开比较编辑器,您可以在其中并排查看该文件的冲突版本。

    正如该编辑器所指出的,您可以手动或自动合并这两个版本。让我们通过单击 Auto-Merge 按钮尝试自动合并。当警告对话框弹出时,单击 OK。然后保存结果。

  2. 下一步,单击 Resolve as Merged 按钮。这告诉 Jazz 您对合并结果感到满意,因此可以认为未解决的更改已完成。您可能会获得有关更改还未签入的警告。如果是这样,只需单击 Retry 按钮。完成此任务之后,更改就已合并到您的传出更改集之中。

    (请注意,在此例中,由于没有冲突的行,调出比较编辑器的手动步骤实际上是不必要的。我们完全可以从 Hello.java 的上下文菜单中执行 Auto-Resolve。)

此时,冲突已得到解决。剩下的工作就是交付传出更改了。继续并执行 Deliver

最后,冲突已得到解决,Chris 的所有更改已交付到流中。如果愿意,可以转到 Jamie 的 Eclipse 工作区并接受 Chris 的更改。

挂起传出更改集

Chris 现在正在向 Hello Prelude 项目添加一个重要功能。在 Chris 的工作区中,对 Hello.java 做出更改以表示该重要功能所做的工作(例如,添加注释)。将新的更改集命名为 Big Feature Work

Chris 正在马不停蹄地处理新的重要功能,这时经理通知他有一个关键错误需要修复:“Hello, World!!”输出中应该有两个而不是一个感叹号。Chris 的经理希望 Chris 放下手边的任何工作,并立即修改该关键错误。

Chris 正处于进行其他更改的途中,他不希望丢失这些更改,但是需要修复这个重要的错误。他可以在流中创建另一个工作区,但是需要花一些时间才能完成设置、重新加载文件等等。相反,他将挂起自己的更改,交付该关键错误的修复,然后恢复原先的更改集以继续进行先前所做的更改。

挂起更改集

  1. 首先,通过从上下文菜单中选择 Suspend 来挂起 Chris 的传出更改集。这将导致从 Chris 的 Eclipse 工作区中删除他的所有传出更改。这些更改仍然安全地保留在 Jazz 存储库中,只是临时从文件系统中删除,直到以后恢复它们时为止。

    请注意,Hello.java 文件已恢复到 Chris 做出编辑前的状态。

  2. 现在 Chris 可以修复该错误。更改 Hello.java 以使其具有非常重要的第二个感叹号,然后保存该文件。请注意,为此工作而创建了一个新的更改集。添加注释 Fix Critical Bug。现在可以在 Pending Changes 视图中同时看到这个新的更改集和挂起的更改集。(可能必须展开 Suspended 节点才能看到原先的更改集。)
  3. 通过从该传出更改集的上下文菜单中调用 Deliver 来交付错误修复。

恢复挂起的更改

现在 Chris 已经交付了错误修复,他可以恢复先前正在处理的更改了。在 Pending Changes 视图中的 Suspended 节点下面,从更改集的上下文菜单中选择 Resume。Chris 现在可以继续其更改工作。请注意,如果他的挂起的更改与为错误修复而做的更改发生冲突,则必须将这些更改合并在一起。在我们的示例中,由于我们仅使用一个源文件,更改当然会发生冲突。解决该冲突的过程与前面描述的过程完全相同。在具有多个文件的场景中,可以想象到,挂起的更改可能不会与修复关键错误所必需的更改相冲突。但是,您仍然需要挂起正在进行的工作,以便独立于其他更改对错误修复进行测试。

History 和 Change Explorer 视图

我们已了解了如何交付、接受和挂起更改集,以及如何检查和解决冲突。这其中大多数操作都是从 Pending Changes 视图中执行的。如果我们希望查看过去发生的情况,又该如何呢?这就是 History 视图派上用场的地方。

History 视图可用于检查单个文件的历史记录,或用于查看存储库工作区(或流)中某个组件的历史记录。在这两种情况下,都会显示一个更改集列表,并根据每个更改集被添加到工作区或流的相反时间顺序排列。对于整个组件的历史记录,该列表包含该工作区或流中影响该组件的所有更改集;对于单个文件的历史记录,该列表仅包含影响该文件的更改集。

  1. 要查看某个存储库工作区中的某个组件的历史记录,可以在 Team ArtifactsPending Changes 视图中的工作区中,从该组件的上下文菜单中选择 Show > History

    History 视图将打开:

    从此视图中,您可以看到是谁创建了每个更改集,是在何时创建的,以及您是在何时将其添加到存储库工作区的。

  2. 让我们将 Jamie 的存储库工作区中的 Prelude 组件的历史记录与流中的 Prelude 组件的历史记录做一下比较。转到 Team Artifacts,再次找到流,将其展开以查看 Prelude 组件,并调用 Show History

    请注意,流的历史记录显示了 Jamie 的工作区历史记录所没有的一个更改集:即 Chris 的 Fix critical bug 更改集。由于 Jamie 还未接受 Chris 的更改集,因此该更改集还没有在她的存储库工作区中。事实上,这就是我们前面在 Pending Changes 视图中看到的同一个传入更改集。

  3. 要查看存储库工作区中单个文件的历史记录,可以在 Package Explorer 中从文件的上下文菜单中或者从打开该文件的 Eclipse 编辑器的上下文菜单中选择 Team > Show History。 在我们的示例中,我们仅使用了单个文件,因此文件的历史记录和组件的历史记录非常相似。

现在我们查看了历史记录中的所有更改集,下面看一下与工作项 1(标签为 Adding a project - 1: Share code with SCM 的工作项)相关联的更改集的内部,以确定涉及到哪些文件。

  1. 通过在 History 视图中选择该行并从其上下文菜单中选择 Open in Change Explorer,从而在 Change Explorer 中打开它。
  2. 展开该更改集。可以在底部看到作为该更改集的一部分而创建的文件,以及工作项关联。还可以通过单击该关联来打开工作项。

将工作项与更改集关联的不同方法

Jazz 教程介绍了如何通过在 Pending Changes 中单击更改集并从其上下文菜单中选择 Associate Work Item...,从而将现有的工作项与更改集相关联。本部分将介绍一些在工作项和更改集之间建立关联的附加方法。具体选择哪一种方法将取决于什么方法对您工作所在的上下文最方便。

  • 拖放。如果已打开了某个工作项,可以通过将该工作项顶部显示的工作项编号拖拽到 Pending Changes,并将其放在那里的更改集上,从而将其与该更改集关联起来。

  • 动态创建工作项。要关联的工作项不需要预先存在。Associate Work Item... 对话框包含 Create new work item... 链接,可用于通过所填入的基本信息创建工作项,如下所示:

  • 交付期间关联Deliver and Resolve Work Item... 操作允许您在交付时自动解决与某个更改集关联的工作项,但是还可以在没有关联工作项的更改集上使用此操作,以便紧跟在交付/解决之前的上下文中建立与工作项的关联。甚至可以通过从 Deliver and Resolve Work Item... 对话框中选择 Create a new work item 来动态创建工作项,从而使您可以在一个操作中完成创建、关联、交付和解决。

  • 从 Team Advisor 进行关联。如果团队配置了在允许交付操作之前检查工作项或注释的流程,就像您在按照 Jazz 教程中的步骤操作以部署 Eclipse Way Process 时所做的那样,则交付某个不带注释的工作项的任何尝试都将在 Team Advisor 视图中标记为错误。该视图提供了 Quick Fix 操作以帮助您纠正错误。

通过导航到 Pending Changes 中的更改集节点下显示的工作项,并从其上下文菜单中选择 Remove,您还可以从更改集中删除工作项关联。

Jazz 源代码版本控制探索

本文已演示的内容仅触及到 Jazz 源代码版本控制所提供功能的皮毛。还有许多值得一提的高级主题。下面将略微探讨一下其中部分主题;“使用 Jazz 源代码版本控制进行多流开发” 中对许多主题进行了更详细的介绍。

  • 组件。存储库工作区或流可以具有多个独立的顶级组件,每个组件包含一个或多个文件树(即 Eclipse 项目)。这用于对大型文件库分区,并允许单独地处理每个组件。工作区中的每个组件具有自己的更改集历史记录,这些历史记录的累积定义了该组件的配置

    对于工作区和流所共有的组件,传入和传出更改集将逐个组件地在工作区和流之间流动。

  • 基准。特定工作区或流中的某个组件的不可变副本称为基准。基准表示某个组件在任何特定时间点的配置。基准用作固定的参考点,并且对于初始化流和工作区(它们从一组组件的给定点继续)以及对于在更粗粒度上(相比单独更改集的粒度)共享组件更改都是非常有用的。

    正如更改集一样,基准也表现为传入和传出基准。Pending Changes 视图显示了包括传入和传出基准的更改集集合,并且用户可以比较基准以确定基准之间的更改集差异。

  • 快照。可以创建存储库工作区的快照,以提供工作区在该时刻的状况的永久记录。快照实际上就是基准的集合,工作区中的每个组件有一个基准。

    快照通常用于记住重要的工作区配置,以便能够重新创建它们;例如,用于重现某个早期的构建。从中创建快照的工作区或流将记住快照。

  • 工作区间的流。存储库工作区可以建立与另一个团队成员的特别流,并从该用户的存储库工作区遴选更改集。

  • 多流协作。单个存储库工作区可以与多个流协作,并充当在流之间传输更改集的中介。

  • 完成的更改集。用户可以完成更改集以将其标记为已完成。对该工作区的后续更改必须在新的更改集中进行。用户将决定何时完成一个更改集,以及何时开始新的更改集。只有完成的更改集才能与其他流和工作区进行共享;交付操作会自动完成所有正在交付的更改集。

  • 丢弃工作集。用户可以从工作区中丢弃某个更改集,无论是放弃部分已选择抛弃的工作,还是临时从工作区中删除从流接受的更改集;换句话说,就是临时地“取消接受”该更改集。(在此情况下,该更改集将重新显示为来自流中的传入更改集。)


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Rational
ArticleID=368294
ArticleTitle=Jazz 系列: 开始使用 Jazz 源代码版本控制
publish-date=02092009