TFS Migration Tools: Conflict resolution … a peak at the (less painful) future: Part 1
In the TFS Migration Tools – Getting Started hands-on-lab (HOL) document we introduced the basics, stepping around all possible conflicts with care. For this that know the Migration Toolkit (and its predecessor), the conflict resolution command line tool and the associated complexity are feared. The complexity makes the use of the product immensely frustrating and error prone … which is why we avoided conflicts for the 45-min HOL.
But our fathers were men, and their fathers were men … so we decided to rename the existing HOL as the “Basic Scenario” and are in the process of adding an “Advanced Scenario”. The new scenario undoes all our step-around-the-conflict setup and walks towards the Work Item Tracking (WIT) and version Control (VC) conflicts, tacking each one and using the opportunity to introduce the new Windows Presentation Framework (WPF) based user interface.
Undoing some of the safety nets
We assume that you have either completed the TFS Migration Tools Getting Started Hands-On Lab (HOL), or that you have perused the posts VSTS Rangers Project - TFS Migration Tools: Configuration Demystified, VSTS Rangers Projects – TFS Migration Tools: Getting Started Questions and Rangers Projects – TFS Migration Tools: Where has the link relationship vanished and why? as a backgrounder.
SampleConfig_CR.xml
1: <?xml version="1.0" encoding="utf-16"?>
2: <Configuration UniqueId="{7439CF38-BBF4-4B16-A8C9-B5CB3B5A82E5}"
3: FriendlyName="CR TR9 HOL">
4: <Providers>
5: <Provider FriendlyName="CR TFS 2010 Migration WIT Provider"
6: ReferenceName="04201D39-6E47-416f-98B2-07F0013F8455" />
7: <Provider FriendlyName="CR TFS 2010 VC Migration Provider"
8: ReferenceName="FEBC091F-82A2-449e-AED8-133E5896C47A" />
9: </Providers>
10:
11: <SessionGroup FriendlyName="CR Session Group Friendly Name"
12: SessionGroupGUID="{06D11897-EF77-4326-888F-96E4F856A2E3}"
13: WorkFlowType="OneDirectionalSynchronizationWithoutContextSync">
14: <MigrationSources>
15: <!-- WIT Migration Sources -->
16: <MigrationSource InternalUniqueId="A0E4FBE9-5E44-4D12-A274-958F259A9B6D"
17: FriendlyName="CR TFS2010B1X32T Source"
18: ServerIdentifier="TFS2010B1X32T Source"
19: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
20: SourceIdentifier="TP-A"
21: ProviderReferenceName="04201D39-6E47-416f-98B2-07F0013F8455">
22: <CustomSettings>
23: <!--<CustomSetting SettingKey="EnableBypassRuleDataSubmission" SettingValue="false" />-->
24: <!--<CustomSetting SettingKey="DisableAreaPathAutoCreation" SettingValue="" />-->
25: <!--<CustomSetting SettingKey="DisableIterationPathAutoCreation" SettingValue="" />-->
26: </CustomSettings>
27: <StoredCredential />
28: </MigrationSource>
29:
30: <MigrationSource InternalUniqueId="EF98D1AE-2101-444F-9FAB-DC9C354E861A"
31: FriendlyName="CR TFS2010B1X32T Target"
32: ServerIdentifier="TFS2010B1X32T Target"
33: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
34: SourceIdentifier="TP-C"
35: ProviderReferenceName="04201D39-6E47-416f-98B2-07F0013F8455">
36: <CustomSettings>
37: <!--<CustomSetting SettingKey="EnableBypassRuleDataSubmission" SettingValue="false" />-->
38: </CustomSettings>
39: <StoredCredential />
40: </MigrationSource>
41:
42: <!-- VC Migration Sources -->
43: <MigrationSource InternalUniqueId="13828D85-46F5-40A4-9A38-D95CF96B01DB"
44: FriendlyName="CR TFS2010B1X32T VC Source"
45: ServerIdentifier="TFS2010B1X32T VC Source"
46: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
47: SourceIdentifier="source system"
48: ProviderReferenceName="FEBC091F-82A2-449e-AED8-133E5896C47A">
49: <CustomSettings>
50: <SettingXml />
51: <SettingXmlSchema />
52: </CustomSettings>
53: </MigrationSource>
54:
55: <MigrationSource InternalUniqueId="9848394A-112D-4B8B-9866-0E309BB372CB"
56: FriendlyName="CR TFS2010B1X32T VC Target"
57: ServerIdentifier="TFS2010B1X32T VC Target"
58: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
59: SourceIdentifier="target system"
60: ProviderReferenceName="FEBC091F-82A2-449e-AED8-133E5896C47A">
61: <CustomSettings>
62: <SettingXml />
63: <SettingXmlSchema />
64: </CustomSettings>
65: </MigrationSource>
66: </MigrationSources>
67:
68: <Sessions>
69: <Session SessionUniqueId="CE189D49-EAA3-4CB9-883D-FC68F79656FF"
70: FriendlyName="CR WIT session"
71: LeftMigrationSourceUniqueId="A0E4FBE9-5E44-4D12-A274-958F259A9B6D"
72: RightMigrationSourceUniqueId="EF98D1AE-2101-444F-9FAB-DC9C354E861A"
73: SessionType="WorkItemTracking">
74: <!-- LAB1 -->
75: <CustomSettings />
76: <Filters>
77: <FilterPair>
78: <FilterItem MigrationSourceUniqueId="A0E4FBE9-5E44-4D12-A274-958F259A9B6D" FilterString="" />
79: <FilterItem MigrationSourceUniqueId="EF98D1AE-2101-444F-9FAB-DC9C354E861A" FilterString="" />
80: </FilterPair>
81: </Filters>
82: </Session>
83:
84: <!-- LAB 3
85: <Session SessionUniqueId="7092283E-8776-4458-A0BC-1A96385C635F"
86: FriendlyName="CR Version Control session"
87: LeftMigrationSourceUniqueId="13828D85-46F5-40A4-9A38-D95CF96B01DB"
88: RightMigrationSourceUniqueId="9848394A-112D-4B8B-9866-0E309BB372CB"
89: SessionType="VersionControl">
90: <CustomSettings>
91: </CustomSettings>
92:
93: <Filters>
94: <FilterPair>
95: <FilterItem MigrationSourceUniqueId="13828D85-46F5-40A4-9A38-D95CF96B01DB" FilterString="$/TP-A" />
96: <FilterItem MigrationSourceUniqueId="9848394A-112D-4B8B-9866-0E309BB372CB" FilterString="$/TP-C" />
97: </FilterPair>
98: </Filters>
99: </Session>
100: LAB 3 -->
101: </Sessions>
102:
103: <Linking EngineProviderReferenceName="04201D39-6E47-416f-98B2-07F0013F8455">
104: <!--<CreationTime>0001-01-01T00:00:00</CreationTime>-->
105: <CustomSettings>
106: <SettingXml />
107: <SettingXmlSchema />
108: </CustomSettings>
109: <LinkTypeMappings />
110: </Linking>
111:
112: </SessionGroup>
113: </Configuration>
In essence we created a new project TP-C, copied our SampleConfig.xml file, changed TP-B to TP-C, changed the WorkflowType to OneDirectionalSynchronizationWithoutContextSync for a one way synchronization with no context and commented out the EnableBypassRuleDataSubmission, which in essence disables the feature.
The EnableBypassRuleDataSubmission was enabled in the previous scenario where we tried to hide from conflicts. Is a property set in the WIT update document; if set to true, all the WITD rule evaluations, such as valid value list, state transition, are disabled for the submitted data.
Warning: Specifying false for the attribute SettingValue makes no difference as the current schema ignores that attribute. Either comment out the line or delete it … else you will be as puzzled as I was for a very long time.
When we now run the synchronization, we are stopped by a WIT conflict: “TFS WIT general conflict type”, which has raised its heads as a direct result of us not using the “EnableBypassRuleDataSubmission” rule anymore.
Using a manual rule to restore peace and order
We chose to create a manual rule in the session configuration file. We define an exclusion rule when moving WITs of type Bug and Task from the left source to the right target, resolving the WIT conflict on the State Change Date field.
SampleConfig_CR-Final.xml with the relevant changes applied
1: <?xml version="1.0" encoding="utf-16"?>
2: <Configuration UniqueId="{7439CF38-BBF4-4B16-A8C9-B5CB3B5A82E5}"
3: FriendlyName="CR TR9 HOL">
4: <Providers>
5: <Provider FriendlyName="CR TFS 2010 Migration WIT Provider"
6: ReferenceName="04201D39-6E47-416f-98B2-07F0013F8455" />
7: <Provider FriendlyName="CR TFS 2010 VC Migration Provider"
8: ReferenceName="FEBC091F-82A2-449e-AED8-133E5896C47A" />
9: </Providers>
10:
11: <SessionGroup FriendlyName="CR Session Group Friendly Name"
12: SessionGroupGUID="{06D11897-EF77-4326-888F-96E4F856A2E3}"
13: WorkFlowType="OneDirectionalSynchronizationWithoutContextSync">
14: <MigrationSources>
15: <!-- WIT Migration Sources -->
16: <MigrationSource InternalUniqueId="A0E4FBE9-5E44-4D12-A274-958F259A9B6D"
17: FriendlyName="CR TFS2010B1X32T Source"
18: ServerIdentifier="TFS2010B1X32T Source"
19: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
20: SourceIdentifier="TP-A"
21: ProviderReferenceName="04201D39-6E47-416f-98B2-07F0013F8455">
22: <CustomSettings>
23: <!--<CustomSetting SettingKey="EnableBypassRuleDataSubmission" SettingValue="false" />-->
24: <!--<CustomSetting SettingKey="DisableAreaPathAutoCreation" SettingValue="" />-->
25: <!--<CustomSetting SettingKey="DisableIterationPathAutoCreation" SettingValue="" />-->
26: </CustomSettings>
27: <StoredCredential />
28: </MigrationSource>
29:
30: <MigrationSource InternalUniqueId="EF98D1AE-2101-444F-9FAB-DC9C354E861A"
31: FriendlyName="CR TFS2010B1X32T Target"
32: ServerIdentifier="TFS2010B1X32T Target"
33: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
34: SourceIdentifier="TP-C"
35: ProviderReferenceName="04201D39-6E47-416f-98B2-07F0013F8455">
36: <CustomSettings>
37: <!--<CustomSetting SettingKey="EnableBypassRuleDataSubmission" SettingValue="false" />-->
38: </CustomSettings>
39: <StoredCredential />
40: </MigrationSource>
41:
42: <!-- VC Migration Sources -->
43: <MigrationSource InternalUniqueId="13828D85-46F5-40A4-9A38-D95CF96B01DB"
44: FriendlyName="CR TFS2010B1X32T VC Source"
45: ServerIdentifier="TFS2010B1X32T VC Source"
46: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
47: SourceIdentifier="source system"
48: ProviderReferenceName="FEBC091F-82A2-449e-AED8-133E5896C47A">
49: <CustomSettings>
50: <SettingXml />
51: <SettingXmlSchema />
52: </CustomSettings>
53: </MigrationSource>
54:
55: <MigrationSource InternalUniqueId="9848394A-112D-4B8B-9866-0E309BB372CB"
56: FriendlyName="CR TFS2010B1X32T VC Target"
57: ServerIdentifier="TFS2010B1X32T VC Target"
58: ServerUrl="https://TFS2010B1X32T:8080/tfs/defaultcollection"
59: SourceIdentifier="target system"
60: ProviderReferenceName="FEBC091F-82A2-449e-AED8-133E5896C47A">
61: <CustomSettings>
62: <SettingXml />
63: <SettingXmlSchema />
64: </CustomSettings>
65: </MigrationSource>
66: </MigrationSources>
67:
68: <Sessions>
69: <Session SessionUniqueId="CE189D49-EAA3-4CB9-883D-FC68F79656FF"
70: FriendlyName="CR WIT session"
71: LeftMigrationSourceUniqueId="A0E4FBE9-5E44-4D12-A274-958F259A9B6D"
72: RightMigrationSourceUniqueId="EF98D1AE-2101-444F-9FAB-DC9C354E861A"
73: SessionType="WorkItemTracking">
74: <CustomSettings>
75: <SettingXml>
76: <WITSessionCustomSetting>
77: <WorkItemTypes>
78: <WorkItemType LeftWorkItemTypeName="Bug" RightWorkItemTypeName="Bug" fieldMap="FM1" />
79: <WorkItemType LeftWorkItemTypeName="Task" RightWorkItemTypeName="Task" fieldMap="FM1" />
80: </WorkItemTypes>
81: <FieldMaps>
82: <FieldMap name="FM1">
83: <ExcludedFields>
84: <ExcludedField field="Microsoft.VSTS.Common.StateChangeDate" ExcludedFromSide="Right" />
85: </ExcludedFields>
86: </FieldMap>
87: </FieldMaps>
88: </WITSessionCustomSetting>
89: </SettingXml>
90: </CustomSettings>
91: <!--<CustomSettings />-->
92: <Filters>
93: <FilterPair>
94: <FilterItem MigrationSourceUniqueId="A0E4FBE9-5E44-4D12-A274-958F259A9B6D" FilterString="" />
95: <FilterItem MigrationSourceUniqueId="EF98D1AE-2101-444F-9FAB-DC9C354E861A" FilterString="" />
96: </FilterPair>
97: </Filters>
98: </Session>
99:
100: <Session SessionUniqueId="7092283E-8776-4458-A0BC-1A96385C635F"
101: FriendlyName="CR Version Control session"
102: LeftMigrationSourceUniqueId="13828D85-46F5-40A4-9A38-D95CF96B01DB"
103: RightMigrationSourceUniqueId="9848394A-112D-4B8B-9866-0E309BB372CB"
104: SessionType="VersionControl">
105: <CustomSettings>
106: </CustomSettings>
107:
108: <Filters>
109: <FilterPair>
110: <FilterItem MigrationSourceUniqueId="13828D85-46F5-40A4-9A38-D95CF96B01DB" FilterString="$/TP-A" />
111: <FilterItem MigrationSourceUniqueId="9848394A-112D-4B8B-9866-0E309BB372CB" FilterString="$/TP-C" />
112: </FilterPair>
113: </Filters>
114: </Session>
115:
116: </Sessions>
117:
118: <Linking EngineProviderReferenceName="04201D39-6E47-416f-98B2-07F0013F8455">
119: <!--<CreationTime>0001-01-01T00:00:00</CreationTime>-->
120: <CustomSettings>
121: <SettingXml />
122: <SettingXmlSchema />
123: </CustomSettings>
124: <LinkTypeMappings />
125: </Linking>
126:
127: </SessionGroup>
128: </Configuration>
We now re-run the synchronization by running MigrationConsole.exe SampleConfig_CR-Final.xml … huh … only to shake hands with the same conflict.
Confusion and panic is about to set in … until we realize that we changed the configuration file, but not the configuration in the migration database. We have to change the configuration unique ID to force a re-load of the complete configuration file and the session unique ID to force a re-load of the updated session configuration.
Update both GUIDs, re-run the migration console and voila, the WIT data starts flowing again.
As you can see the manual rule involves manually editing a XML file (not my favourite hobby) and manually updating the configuration file unique ID and the session unique ID, to ensure that the changes and moved to the migration database. A very tedious and humanoid error prone process.
Next time
Now that we have briefly explored the manual way of working with conflicts and setting up rules, we will explore the new conflict resolution tool. See you back shortly for a more user friendly and less painful conflict management experience.