如何通过工作项链接targetRef URI获取变更集?及两类SCM链接类型差异咨询
Rational Team Concert中两类SCM工作项链接的区别与问题解决
一、com.ibm.team.filesystem.workitems.change_set 与 com.ibm.team.workitem.linktype.scm.tracksChanges 的区别
这两个都是RTC中工作项和SCM变更集关联的链接类型,但本质逻辑差异很大:
com.ibm.team.filesystem.workitems.change_set:属于直接关联类型,是手动在变更集里绑定工作项、或者提交代码时选择关联工作项后生成的链接。它是双向直接绑定,关联数据直接存储在系统中,只要变更集没有被彻底删除,基本都能通过fetchCompleteItem正常获取到目标对象。com.ibm.team.workitem.linktype.scm.tracksChanges:属于间接追踪类型,大多是自动生成的——比如工作项关联了某个流,流中提交的变更集会被系统自动标记为该工作项追踪的对象;或者通过流程规则自动关联。这类链接依赖系统索引或间接引用关系,一旦变更集被移动、删除,或者系统索引失效,就会出现你遇到的fetchCompleteItem返回null或“数据库中无对应数据”的异常。
二、解决tracksChanges链接调用fetchCompleteItem异常的问题
针对这类间接链接,不要直接依赖fetchCompleteItem获取目标对象,建议按以下方式处理:
- 先区分链接类型:遍历链接时先判断链接ID,对不同类型做差异化处理;
- 异常降级处理:如果遇到
tracksChanges链接抛出异常,直接跳过该链接或者记录日志,避免影响整体流程; - 通过URI解析获取变更集:这类链接的
targetRef是指向变更集的URI,我们可以解析这个URI,再通过SCM API主动查询变更集(这部分下面详细说明)。
三、通过工作项链接的targetRef URI获取变更集的方法
tracksChanges链接的targetRef格式通常是scm:changeset:<变更集UUID>:<仓库UUID>,我们可以解析这个URI提取关键信息,再通过SCM API查询变更集,具体代码示例如下:
for(Object wI : links){ ILink link = (ILink) wI; String linkTypeId = link.getLinkTypeId().getIdentifier(); // 处理直接关联的变更集链接 if ("com.ibm.team.filesystem.workitems.change_set".equals(linkTypeId)) { try { Object targetItem = link.fetchCompleteItem(monitor); if (targetItem instanceof IChangeSet) { IChangeSet changeSet = (IChangeSet) targetItem; // 这里编写你的变更集处理逻辑 } } catch (TeamRepositoryException e) { // 处理直接关联的异常,比如记录日志 e.printStackTrace(); } } // 处理追踪类型的变更集链接 else if ("com.ibm.team.workitem.linktype.scm.tracksChanges".equals(linkTypeId)) { URI targetUri = link.getTargetRef(); // 确认是SCM类型的URI if ("scm".equals(targetUri.getScheme())) { String schemePart = targetUri.getSchemeSpecificPart(); String[] uriSegments = schemePart.split(":"); // 解析出变更集UUID和仓库UUID if (uriSegments.length >= 3 && "changeset".equals(uriSegments[1])) { String csUuidStr = uriSegments[2]; String repoUuidStr = uriSegments.length >= 4 ? uriSegments[3] : null; try { // 获取仓库管理器 IRepositoryManager repoManager = (IRepositoryManager) getService(IRepositoryManager.class); IRepository scmRepo = null; // 通过仓库UUID找到对应的SCM仓库 if (repoUuidStr != null) { scmRepo = repoManager.getRepository(UUID.fromString(repoUuidStr)); } else { // 如果没有仓库UUID,可以从当前上下文获取默认仓库,或根据场景调整 continue; } // 查询变更集 if (scmRepo instanceof IScmRepository) { IChangeSetManager csManager = ((IScmRepository) scmRepo).getChangeSetManager(); IChangeSet changeSet = csManager.fetchChangeSetById(UUID.fromString(csUuidStr), monitor); // 这里编写你的变更集处理逻辑 } } catch (Exception e) { // 处理解析或查询异常,比如变更集不存在、无权限等 e.printStackTrace(); } } } } }
内容的提问来源于stack exchange,提问作者Rinkal Garg
相关产品推荐
相关产品推荐

