diff --git a/Vss2Git/GitExporter.cs b/Vss2Git/GitExporter.cs index 2193557..3b0785b 100755 --- a/Vss2Git/GitExporter.cs +++ b/Vss2Git/GitExporter.cs @@ -18,6 +18,7 @@ using System.Diagnostics; using System.Globalization; using System.IO; +using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading; @@ -381,7 +382,7 @@ private bool ReplayRevision(VssPathMapper pathMapper, Revision revision, { // renaming a file or a project that contains files? var projectInfo = itemInfo as VssProjectInfo; - if (projectInfo == null || projectInfo.ContainsFiles()) + if (projectInfo == null || (projectInfo.ContainsFiles() && projectInfo.Items.All(x => !x.Destroyed))) { CaseSensitiveRename(sourcePath, targetPath, git.Move); needCommit = true; @@ -389,7 +390,7 @@ private bool ReplayRevision(VssPathMapper pathMapper, Revision revision, else { // git doesn't care about directories with no files - CaseSensitiveRename(sourcePath, targetPath, Directory.Move); + CaseSensitiveRename(sourcePath, targetPath, CaseSensitiveDirectoryMove); } } else @@ -415,15 +416,16 @@ private bool ReplayRevision(VssPathMapper pathMapper, Revision revision, { if (sourcePath != null && Directory.Exists(sourcePath)) { + var isSamePath = sourcePath.Equals(targetPath, StringComparison.OrdinalIgnoreCase); if (projectInfo.ContainsFiles()) { - git.Move(sourcePath, targetPath); + git.Move(sourcePath, targetPath, isSamePath); needCommit = true; } else { // git doesn't care about directories with no files - Directory.Move(sourcePath, targetPath); + CaseSensitiveDirectoryMove(sourcePath, targetPath, isSamePath); } } else @@ -733,39 +735,24 @@ private void WriteStream(Stream inputStream, string path) } } - private delegate void RenameDelegate(string sourcePath, string destPath); + private delegate void RenameDelegate(string sourcePath, string destPath, bool force); private void CaseSensitiveRename(string sourcePath, string destPath, RenameDelegate renamer) { - if (sourcePath.Equals(destPath, StringComparison.OrdinalIgnoreCase)) - { - // workaround for case-only renames on case-insensitive file systems: - - var sourceDir = Path.GetDirectoryName(sourcePath); - var sourceFile = Path.GetFileName(sourcePath); - var destDir = Path.GetDirectoryName(destPath); - var destFile = Path.GetFileName(destPath); - - if (sourceDir != destDir) - { - // recursively rename containing directories that differ in case - CaseSensitiveRename(sourceDir, destDir, renamer); - - // fix up source path based on renamed directory - sourcePath = Path.Combine(destDir, sourceFile); - } + renamer(sourcePath, destPath, sourcePath.Equals(destPath, StringComparison.OrdinalIgnoreCase)); + } - if (sourceFile != destFile) - { - // use temporary filename to rename files that differ in case - var tempPath = sourcePath + ".mvtmp"; - CaseSensitiveRename(sourcePath, tempPath, renamer); - CaseSensitiveRename(tempPath, destPath, renamer); - } + private void CaseSensitiveDirectoryMove(string sourcePath, string targetPath, bool force) + { + if (force) + { + var tmpPath = targetPath + ".mvtmp"; + Directory.Move(sourcePath, tmpPath); + Directory.Move(tmpPath, targetPath); } else { - renamer(sourcePath, destPath); + Directory.Move(sourcePath, targetPath); } } } diff --git a/Vss2Git/GitWrapper.cs b/Vss2Git/GitWrapper.cs index 2b9569a..85595de 100755 --- a/Vss2Git/GitWrapper.cs +++ b/Vss2Git/GitWrapper.cs @@ -138,9 +138,18 @@ public void Remove(string path, bool recursive) GitExec("rm " + (recursive ? "-r " : "") + "-- " + Quote(path)); } - public void Move(string sourcePath, string destPath) + public void Move(string sourcePath, string destPath, bool force) { - GitExec("mv -- " + Quote(sourcePath) + " " + Quote(destPath)); + if (force) + { + var tempPath = destPath + ".mvtmp"; + GitExec("mv -- " + Quote(sourcePath) + " " + Quote(tempPath)); + GitExec("mv -- " + Quote(tempPath) + " " + Quote(destPath)); + } + else + { + GitExec("mv -- " + Quote(sourcePath) + " " + Quote(destPath)); + } } class TempFile : IDisposable