Skip to content

Commit 3edec49

Browse files
authored
Merge pull request #16 from Techsola/unblock_inner_renames
Finish implementing branch rename support
2 parents b3d389e + eab163e commit 3edec49

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

src/TfvcMigrator/PathUtils.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ public static string GetLeaf(string path)
5353
return index == -1 ? path : path[(index + 1)..];
5454
}
5555

56+
/// <summary>
57+
/// If <paramref name="path"/> is or starts with <paramref name="containingPath"/>, <paramref
58+
/// name="containingPath"/> is replaced with <paramref name="newContainingPath"/> in the returned path. Otherwise,
59+
/// the unmodified <paramref name="path"/> is returned.
60+
/// </summary>
61+
/// <exception cref="ArgumentException">Thrown if any of the paths ends with a trailing slash.</exception>
5662
public static string ReplaceContainingPath(string path, string containingPath, string newContainingPath)
5763
{
5864
if (path.EndsWith('/'))
@@ -65,11 +71,16 @@ public static string ReplaceContainingPath(string path, string containingPath, s
6571
throw new ArgumentException("Path should not end with a trailing slash.", nameof(newContainingPath));
6672

6773
if (!IsOrContains(containingPath, path))
68-
throw new ArgumentException("The specified containing path does not contain the specified path.");
74+
return path;
6975

7076
return newContainingPath + path[containingPath.Length..];
7177
}
7278

79+
/// <summary>
80+
/// If <paramref name="path"/> is or starts with <paramref name="containingPath"/>, the relative part of the path
81+
/// (if any) is returned. Otherwise, <see cref="ArgumentException"/> is thrown.
82+
/// </summary>
83+
/// <exception cref="ArgumentException">Thrown if any of the paths ends with a trailing slash.</exception>
7384
public static string RemoveContainingPath(string path, string containingPath)
7485
{
7586
if (path.EndsWith('/'))

src/TfvcMigrator/Program.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ private static async IAsyncEnumerable<MappingState> EnumerateMappingStatesAsync(
483483
var mapping = branchMappings[branch.SourceBranch];
484484

485485
mapping = PathUtils.IsOrContains(branch.SourceBranchPath, mapping.RootDirectory)
486-
? mapping.RenameRootDirectory(branch.SourceBranchPath, branch.NewBranch.Path)
486+
? mapping.ApplyRename(branch.SourceBranchPath, branch.NewBranch.Path)
487487
: mapping.WithSubdirectoryMapping(branch.NewBranch.Path, branch.SourceBranchPath);
488488

489489
branchMappings.Add(branch.NewBranch, mapping);
@@ -505,7 +505,13 @@ private static async IAsyncEnumerable<MappingState> EnumerateMappingStatesAsync(
505505
case RenameOperation rename:
506506
{
507507
if (!branchMappings.Remove(rename.OldIdentity, out var mapping)) throw new NotImplementedException();
508-
branchMappings.Add(rename.NewIdentity, mapping.RenameRootDirectory(rename.OldIdentity.Path, rename.NewIdentity.Path));
508+
509+
foreach (var (otherBranch, otherMapping) in branchMappings.ToArray())
510+
{
511+
branchMappings[otherBranch] = otherMapping.ApplyRename(rename.OldIdentity.Path, rename.NewIdentity.Path);
512+
}
513+
514+
branchMappings.Add(rename.NewIdentity, mapping.ApplyRename(rename.OldIdentity.Path, rename.NewIdentity.Path));
509515

510516
if (trunk == rename.OldIdentity) trunk = rename.NewIdentity;
511517
break;

src/TfvcMigrator/RepositoryBranchMapping.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,19 @@ public RepositoryBranchMapping(string rootDirectory, (string BranchDirectory, st
4242
/// </summary>
4343
public (string BranchDirectory, string TargetDirectory)? SubdirectoryMapping { get; }
4444

45-
public RepositoryBranchMapping RenameRootDirectory(string oldPath, string newPath)
45+
public RepositoryBranchMapping ApplyRename(string oldPath, string newPath)
4646
{
4747
if (!PathUtils.IsAbsolute(oldPath))
4848
throw new ArgumentException("Old path must be absolute.", nameof(oldPath));
4949

5050
if (!PathUtils.IsAbsolute(newPath))
5151
throw new ArgumentException("New path must be absolute.", nameof(newPath));
5252

53-
if (!PathUtils.IsOrContains(RootDirectory, oldPath))
54-
throw new InvalidOperationException("The rename does not apply to this mapping.");
55-
56-
if (SubdirectoryMapping is not null)
57-
throw new NotImplementedException("Research: Renaming and branching might behave differently when subdirectory mapping is involved.");
58-
5953
return new RepositoryBranchMapping(
6054
PathUtils.ReplaceContainingPath(RootDirectory, oldPath, newPath),
61-
subdirectoryMapping: null);
55+
SubdirectoryMapping is null ? null : (
56+
PathUtils.ReplaceContainingPath(SubdirectoryMapping.Value.BranchDirectory, oldPath, newPath),
57+
PathUtils.ReplaceContainingPath(SubdirectoryMapping.Value.TargetDirectory, oldPath, newPath)));
6258
}
6359

6460
public RepositoryBranchMapping WithSubdirectoryMapping(string branchDirectory, string targetDirectory)
@@ -76,8 +72,7 @@ public RepositoryBranchMapping WithSubdirectoryMapping(string branchDirectory, s
7672
if (PathUtils.IsOrContains(target, itemPath))
7773
return null;
7874

79-
if (PathUtils.IsOrContains(branch, itemPath))
80-
itemPath = PathUtils.ReplaceContainingPath(itemPath, branch, target);
75+
itemPath = PathUtils.ReplaceContainingPath(itemPath, branch, target);
8176
}
8277

8378
return PathUtils.IsOrContains(RootDirectory, itemPath)

0 commit comments

Comments
 (0)