Bringing you news, technical articles, and other useful content about Visual Studio ALM and Team Foundation Server
More videos »
In a recent support thread the use of cloaking or scoping was discussed to unblock a migration. This raised the question: “What is the difference and more importantly the impact of using one or the other?”
As Bill correctly stated, a good reason to have this discussion is that scoping a migration to the minimum amount of data that needs to be moved is a very powerful way to help ensure a successful migration. Simplicity is key!
When using the TFS Integration Tools to migrate version control data for the hypothetical project “space” from a source to a target, the default behaviour is to migrate everything as shown in the following illustration. The actions from the source are replayed for each branch, resulting in a mirror image of of the source version control structure and data on the target.
The source could represent state that has usually been accumulated over many years. Replaying this often long and complex history can prove to be a time consuming adventure that deserves another review before “clicking” the migration start button.
Recommendation from the guidance: Keep the migration load down by reducing number of filter paths in mapping and the complexity down, by avoiding a synchronization of branch/merge relationships and focusing on integration (main) branches only. In other words avoid replicating this type of tree structure:
Imagine a logical tree organized as shown below. If you only want to move main, you would change the filter to $/space/main and you would use a MergeScope of $/space/main. In fact, MergeScope should always match the filter to which it is associated. That isn’t an enforced rule, but it is really hard to think through what it means when that constraint does not hold. MergeScope is really the moral equivalent of a conflict resolution rule for a given path to tell the tool to convert branch to add and merge to edit. With it, you say something like – I’d like to move $/space/branch1 and any branch/merge information below it in the tree and I would like all branch/merge relationships outside of this path to be neatly trimmed (meaning, don’t raise a conflict, just do it). MergeScope defines the scope where we want branch/merge operations to be preserved and we’re using it here as if it defined the area of the tree we’d explicitly like to trim.
As shown in the above illustration, the result of this minor configuration tweak is that the migration will be told to trim all branch and merge relationships outside of the $/space/branch1 path. The version control actions from the source are replayed at the target, ignoring all actions that fall outside the merge scope path. The effect is that the branch from branch 1 to branch2, the forward integration and reverse integration between these two branches would converted to simple add/edit operations.
For example, a file added in branch2 and then merged/RI’ed to branch1 would normally appear in version control history with a branch change type. Branch2 does not exist on the target system since it is out of scope for our filter pair, so the branch-from source is not available. MergeScope tells the tool that it is fine to convert the change type to a simple add rather than trying to preserve the branch change type. The content of the branch-from file is available on the source system (naturally) and the tool fetches that file content and pends it as a simple add to the target. A similar thing happens with edits/delta in a merge.
This results in a target version control structure and history that has no knowledge of branch2.
If you need to move all branches under a path except a single branch you would do that using a cloaked path when configuring your source VC session. Note that a cloaked path is a filterstring as well, but with the “cloak” attribute.
Back to our hypothetical space team project.
The difference with cloaking is that the version control actions are not ignored as with merge scope and that you could cloak any branch in the tree. You will most likely to see migration conflicts as the Migration Tools will not be able to resolve branch and merge actions in the target system from the excluded branch.
The main concept to keep in mind when dealing with conflicts is that conflict resolution rules are scoped. By default, you will see conflicts listed in the admin user interface for each item that the tool has trouble moving and in the case illustrated above we will have three. Use the Add New Rule button under View Conflicts with a scope like $/main/branch1. You use the scoped rule that says it is ok to convert branch to add and merge to edit for everything under branch1.
Before you pick one or the other, we recommend that you perform a test migration with a slice of your data to ensure that you can validate the feasibility and the impact not using either, or selecting one of these fine tuning options.
To conclude, let’s summarise some of the options:
Reduce the number of branches
Simplify the tree hierarchy
Drop branch and merge change actions for all branches from a specific branch node onwards
Drop branch and merge change actions for a specific branch within the tree
Skip a specific branch that is potentially corrupted or missing
Thanks for the post. This helped clarify for me how the TFS integration handles branching, and how cloaking behaves, which is what I was searching for. Off to experiment a bit.