Blogs about Jazz

Blogs > Jazz Team Blog >

Improving usability when merging changes involving gaps

One of the advantages of using the SCM capabilities of Rational Team Concert (RTC) is the traceability of change sets across multiple streams and workspaces. When a developer completes a new feature or fixes a bug, they deliver one or more change sets to their team stream. These change sets can then be accepted into the workspaces of other users and propagated to other streams. Because SCM can uniquely identify each change set, the user is able to query whether a particular change set is present in a particular set of streams and workspaces using Locate Change Sets.

When a user accepts one or more change sets into their workspace, there are 3 possible outcomes:

  1. The change sets accept cleanly
  2. The change sets contain changes that conflict with changes in the user’s workspace
  3. There are gaps in the file histories that prevent the change sets from being accepted as-is

Conflicts occur fairly regularly, especially when multiple users are working on features or bug fixes that overlap with respect to the files involved. When conflicts occur, RTC provides the ability to resolve these conflicts in a way that preserves the traceability of the change sets being accepted. See Jazz Source Control – Resolving Conflicts for more details on conflict resolution.

Gaps are not as common in most day to day workflows but there are some workflows for which gaps occur more frequently.

  1. One common workflow where gaps are encountered is backporting bug fixes from a current release stream to a previous release stream. In this workflow, it is not uncommon for the bug fix to be built on top of change sets that should not be backported.
  2. Another workflow that often encounters gaps is accepting change sets from a work item to review changes. Gaps occur less frequently in this workflow since the developer and the reviewer are often working from the same stream but it can still occur if the developer has other changes in their workspace that have not been delivered to the stream.
  3. A workflow that is common in some organizations is to mix and match features in a build by accepting change sets from the corresponding work items. It is not uncommon in this workflow for an unwanted dependency between features to be introduced because of the order the features are created.

As of RTC 4.0.4, when a gap is encountered during an accept, the RTC client will offer to apply the changes as a patch. While this does allow the changes to be applied, there are a couple of disadvantages to this approach.

  1. There is no traceability from the change sets created from the patch and the original change sets.
  2. If there are multiple change sets being included, the resulting patch contains the changes for all the change sets, even if some could be accepted without a gap.
  3. It is often the case that the gap occurs in only a subset of the files in the change set. Applying the changes as a patch will cause potential gaps for all the files being patched. For example, the file b.txt in our example below does not have a gap.

To address the shortcomings mentioned above, we are working on a new gap workflow that, in essence, accepts one change set at a time and, for change sets that contain gaps, creates a new change set containing the equivalent changes. In addition, a link is maintained between the original (source) change set and the resulting change set. This approach:

  1. preserves traceability at the change set level
  2. accepts change sets that can be accepted and only creates new change sets for those change sets with gaps in the history of one or more files or folders
  3. preserves the history in the new change sets for files that do not have gaps

We have been working actively on this feature to improve the gap handling support when accepting change sets. This new feature is available in 4.0.5 M1 and we would love to get your feedback on the direction we have taken.

You can check out our videos to see what we have so far in action.

You can also check out our draft user documentation page for a more detail description of what the feature will provide and for a link to a beta build you can try out.

For those who are curious: What is a Gap?

In SCM, change sets that are delivered to a component in a stream (or accepted into a component in a workspace), can build on top of previously delivered change sets. For example, the following figure shows 3 change sets that build upon each other in a sequential manner.

Where SCM currently has issues is when accepting a change set into a history when the change set being accepted was built on top of another change set that is not present. The underlying history model of SCM requires that the history for each file be a graph with all paths leading back to the new file state for any file. The following figure shows the case where change set CS3 is being accepted into a component that has change set CS1 in it’s history but is missing change set CS2. In this case, CS3 cannot be accepted as is because the change for file a.txt is missing it’s predecessor from CS2. We refer to this as a gap in the history of file a.txt because it is not possible to find a path from the a.txt change in CS3 back to the file creation.

You might ask why we can’t just accept CS3 anyway. To understand why it is important to be able to trace the history back to the initial state, let’s look at an example of what the content of the file a.txt may be.

Assume the following is the initial content for a.txt in CS1.

This line introduced in CS1

The, CS2 adds a line and makes the content:

This line introduced in CS1
This line added in CS2 but not applicable everywhere

Finally, CS3 adds another line:

This line introduced in CS1
This line added in CS2 but not applicable everywhere
This line added in CS3 and everyone wants it

So, if CS3 was accepted into the history despite the gap, the a.txt would have the above contents including the undesired content from CS2. When CS3 is accepted on top of CS1, we would want the following content that includes the line from CS1 and CS3 but not the line from CS2.

This line introduced in CS1
This line added in CS3 and everyone wants it

Michael Valenta
Jazz SCM Developer