Indirect Integrations
SUMMARY
This article explains how Perforce handles the integration of indirectly related files.
DETAILS
Codelines that have been branched from one another using the p4 integrate command are said to have a "parent/child" relationship or to be "directly related". Integration occurs when using the integrate command to propagate content (merge) between two directly related codelines (also called "branches"). When merging between directly related branches, Perforce is always able to easily determine which revisions have already been integrated between the two and to pick a suitable base for subsequent integrations. (See KB article #57 for details.)
As of release 2004.2, Perforce will also automatically identify common ancestry between "indirectly related" files. Indirectly related files are those files that have a "parent/grandchild" or indirect relationship. Perforce can use the common ancestor as a base for merges between these indirectly related files, just as it uses the common ancestor as the base for merges between directly related files. For more information on indirect integration credit algorithm in 2004.2 and later releases, see the Changes to P4 Integrate in 2004.2 white paper from the 2005 Perforce User Conference.
The remainder of this KB article discusses indirect integration logic in prior releases, paying particular attention to the logic that was introduced in release 2002.2 (which was then superceded by the improved common ancestor detection and usage in release 2004.2).
Indirect Integration Handling in v. 2004.1 and Before
As of release 99.2, attempts to integrate between codelines that are not directly related require the -i flag to succeed. In release 2002.2 thru 2003.2, the -I flag enables logic that attempts to distinguish between indirectly related files, which share a common ancestor, and unrelated files, which have no common ancestor, to find the common ancestor between indirectly-related files. This tech note compares the indirect integration logic from 2002.2 thru 2003.2 with that used in 2002.1 and previous releases.
For our examples we will use three codelines. The B codeline is a child of A, and C is a child of B.
Integrating from B to C is trivial in all releases, because the two codelines are directly related. However, going from A to C is an indirect integration, since the two have no direct relationship. Any server of release 99.2 or later requires the -i flag to be supplied for this integration to succeed. (The -i has no effect on direct integrations.)
Prior to release 2002.2, an indirect or "baseless" integration always took all revisions as the source revision range, hence the term "baseless", since the base normally comes from the first revision before the source revision range. During a baseless merge, the first revision of the range is used instead. (Remember also that "theirs" is always the last revision in the source range, and "yours" is always the open revision in the target.) If the "base" is far removed from "theirs" and "yours", or worse, not a true common ancestor, the resulting merge often requires manual intervention, either to resolve spurious conflicts or to fix incorrect decisions.
In the example illustrated below, the integration from A to C uses the first revision of A as the start of the integration, which is not the best choice for a common ancestor between the two codelines.
With the -I flag, Perforce attempts to find common ancestry on
the source codeline via indirect relationships, and schedule integrations accordingly.
In the below example, A#3 is detected as the real common
ancestor, and used as the base for the integration.
The common ancestor detection in 2002.2 thru 2003.2 only detects the common ancestor if it lies on the source of the integration. In some cases there is none to be found, in which case the old behavior of integrating all revisions is used. In the below example, the common ancestor between C and A is still A#3, but since C is the source of the integration, nothing on A can be used as a base.
It is always important when integrating indirectly to verify that the selected revisions produce a valid base, since unpredictable behavior may result during the p4 resolve step if the base is not a common ancestor. In the example above, the changes made in B#2 and B#3 will be ignored by the subsequent resolve unless special care is taken during the merge process, such as using a merge tool to manually accept the diffs from B.
If the source revision range that was automatically selected for the integration begins with an "add" or "branch" revision (typically #1, unless the file was deleted and re-added), the integration is "baseless". For example, if you run a "p4 integ -I" and get the following:
//your-client/A - integrate from //depot/C#1,#3
then you can identify this merge is a baseless integration and should examine the file history more closely to determine what the real relationship is between the "base", "theirs", and "yours" revisions.
Possible consequences of a truly baseless merge range from re-resolving conflicts (if the base is a common but distant ancestor) to incorrect decisions by the merge algorithm about which diffs to accept in the final merged file.
