Skip to content

Commit 5b9c300

Browse files
authored
Ensure Accurate CreatedDate Handling Across Revisions (#3076)
This PR introduces better tracking for CreatedDate across work item revisions to ensure historical accuracy during migrations. During validation, we also identified that bulk-edited or bulk-imported work items can share identical CreatedDate values across revisions, which can lead to ordering issues during replay. A similar issue for ChangedDate has been discussed here: #2216 **Changes** Revision Management RevisionItem: Added CreatedDate and OriginalCreatedDate properties to the data contract. TfsWorkItemConvertor: Updated to map System.CreatedDate from TFS/ADO revisions into the RevisionItem. TfsRevisionManagerTool: Updated EnforceDatesMustBeIncreasing to validate and fix CreatedDate ordering. This also handles scenarios where bulk edits or imports caused multiple revisions to share the same timestamp, ensuring each replayed revision has a strictly increasing CreatedDate. **Testing** Verified that CreatedDate is correctly populated during revision extraction. Validated that TfsRevisionManagerTool correctly adjusts timestamps when conflicts occur, including cases where multiple revisions share identical CreatedDate values. Built and ran the solution to confirm functionality. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Revision tracking now captures creation date information alongside existing change date data, providing more detailed revision history. * **Improvements** * Strengthened date consistency validation that independently enforces chronological ordering for creation and change dates, ensuring all revision timestamps maintain proper sequential integrity. <sub>✏️ Tip: You can customize this high-level summary in your review settings.</sub> <!-- end of auto-generated comment: release notes by coderabbit.ai -->
2 parents 8e04476 + 35e1561 commit 5b9c300

File tree

4 files changed

+21
-9
lines changed

4 files changed

+21
-9
lines changed

src/MigrationTools.Clients.TfsObjectModel.Tests/Tools/TfsRevisionManagerTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ private static List<RevisionItem> GetWorkItemWithRevisions(DateTime currentDateT
1919
for (int i = startHours; i < endHours + startHours; i++)
2020
{
2121
DateTime dateTime = dateIncreasing ? currentDateTime.AddHours(i) : currentDateTime;
22-
revisions.Add(i, new RevisionItem() { Index = i, Number = i, ChangedDate = dateTime, OriginalChangedDate = dateTime });
22+
revisions.Add(i, new RevisionItem() { Index = i, Number = i, ChangedDate = dateTime, OriginalChangedDate = dateTime, CreatedDate = dateTime, OriginalCreatedDate = dateTime });
2323
}
2424

2525
return revisions.Values.ToList();

src/MigrationTools.Clients.TfsObjectModel/Endpoints/TfsWorkItemConvertor.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ private SortedDictionary<int, RevisionItem> GetRevisionItems(RevisionCollection
4949
Number = (int)x.Fields["System.Rev"].Value,
5050
ChangedDate = (DateTime)x.Fields["System.ChangedDate"].Value,
5151
OriginalChangedDate = (DateTime)x.Fields["System.ChangedDate"].Value,
52+
CreatedDate = (DateTime)x.Fields["System.CreatedDate"].Value,
53+
OriginalCreatedDate = (DateTime)x.Fields["System.CreatedDate"].Value,
5254
Type = x.Fields["System.WorkItemType"].Value as string,
5355
Fields = GetFieldItems(x.Fields)
5456
}).ToList();

src/MigrationTools.Clients.TfsObjectModel/Tools/TfsRevisionManagerTool.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,15 +77,23 @@ public List<RevisionItem> GetRevisionsToMigrate(List<RevisionItem> sourceRevisio
7777
public void EnforceDatesMustBeIncreasing(List<RevisionItem> sortedRevisions)
7878
{
7979
Log.LogDebug("TfsRevisionManagerTool::EnforceDatesMustBeIncreasing");
80-
DateTime lastDateTime = DateTime.MinValue;
80+
DateTime lastChangedDateTime = DateTime.MinValue;
81+
DateTime lastCreatedDateTime = DateTime.MinValue;
8182
foreach (var revision in sortedRevisions)
8283
{
83-
if (revision.ChangedDate == lastDateTime || revision.OriginalChangedDate < lastDateTime)
84+
if (revision.ChangedDate == lastChangedDateTime || revision.OriginalChangedDate < lastChangedDateTime)
8485
{
85-
revision.ChangedDate = lastDateTime.AddSeconds(1);
86-
Log.LogDebug("TfsRevisionManagerTool::EnforceDatesMustBeIncreasing[{revision}]::Fix", revision.Number);
86+
revision.ChangedDate = lastChangedDateTime.AddSeconds(1);
87+
Log.LogDebug($"TfsRevisionManagerTool::EnforceDatesMustBeIncreasing[{revision.Number}]::Fix ChangedDate");
8788
}
88-
lastDateTime = revision.ChangedDate;
89+
lastChangedDateTime = revision.ChangedDate;
90+
91+
if (revision.CreatedDate == lastCreatedDateTime || revision.OriginalCreatedDate < lastCreatedDateTime)
92+
{
93+
revision.CreatedDate = lastCreatedDateTime.AddSeconds(1);
94+
Log.LogDebug($"TfsRevisionManagerTool::EnforceDatesMustBeIncreasing[{revision.Number}]::Fix CreatedDate");
95+
}
96+
lastCreatedDateTime = revision.CreatedDate;
8997
}
9098
}
9199

@@ -171,4 +179,4 @@ public void AttachSourceRevisionHistoryJsonToTarget(WorkItemData sourceWorkItem,
171179
});
172180
}
173181
}
174-
}
182+
}

src/MigrationTools/DataContracts/RevisionItem.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ public class RevisionItem
99
public int Index { get; set; }
1010
public int Number { get; set; }
1111
public DateTime ChangedDate { get; set; }
12-
1312
public DateTime OriginalChangedDate { get; set; }
13+
14+
public DateTime CreatedDate { get; set; }
15+
public DateTime OriginalCreatedDate { get; set; }
1416
public string Type { get; set; }
1517
public Dictionary<string, FieldItem> Fields { get; set; }
1618
public Dictionary<string, EnricherData> EnricherData { get; set; }
1719
}
18-
}
20+
}

0 commit comments

Comments
 (0)