Last active
April 7, 2021 14:41
-
-
Save BlythMeister/65fb84b190ddc4825974e00fbb5464ec to your computer and use it in GitHub Desktop.
Repo Migrate Folder With History
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Main() | |
{ | |
var originalRepo = "[email protected]:_**_/_**_.git"; | |
var originalRepoBranch = "master"; | |
var newRepo = "[email protected]:_**_/_**_.git"; | |
var newRepoBranch = "master"; | |
var workInProgressDir = @"C:\Temp\RepoCopy"; | |
var relativeFolderToMigrate = "src/path"; | |
MigrateRepo(originalRepo, originalRepoBranch, newRepo, newRepoBranch, workInProgressDir, relativeFolderToMigrate); | |
} | |
private void MigrateRepo(string originalRepo, string originalRepoBranch, string newRepo, string newRepoBranch, string workInProgressDir, string relativeFolderToMigrate) | |
{ | |
var runId = Guid.NewGuid().ToString(); | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"RunId: {runId}"); | |
var runDirectory = Path.Combine(workInProgressDir, runId); | |
var fromRepoPath = Path.Combine(runDirectory, "FromRepo"); | |
var fromRepoCleanUpPath = Path.Combine(runDirectory, "FromRepoCleanUp"); | |
var toRepoPath = Path.Combine(runDirectory, "ToRepo"); | |
EnsureDirectoryClean(runDirectory); | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"Creating filtered version of {originalRepo}"); | |
RunGit(workInProgressDir, $"clone {originalRepo} {fromRepoPath}"); | |
RunGit(fromRepoPath, "remote rm origin"); | |
RunGit(fromRepoPath, $"checkout {originalRepoBranch}"); | |
RunGit(fromRepoPath, $"filter-branch --subdirectory-filter {relativeFolderToMigrate} -- --all"); | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"Moving {fromRepoPath} content back into the relative folder of {relativeFolderToMigrate}"); | |
var subDirs = Directory.GetDirectories(fromRepoPath); | |
var subFiles = Directory.GetFiles(fromRepoPath); | |
var newLocationRoot = Path.Combine(fromRepoPath, relativeFolderToMigrate); | |
Console.WriteLine($"Creating Dir: {newLocationRoot}"); | |
Directory.CreateDirectory(newLocationRoot); | |
foreach (var subDir in subDirs) | |
{ | |
if(subDir.EndsWith(".git")) continue; | |
var relativeSubDir = subDir.Replace(fromRepoPath, "").Substring(1); | |
var newLocation = Path.Combine(fromRepoPath, relativeFolderToMigrate, relativeSubDir); | |
Console.WriteLine($"Moving Dir: {subDir} -> {newLocation}"); | |
Directory.Move(subDir, newLocation); | |
} | |
foreach (var subFile in subFiles) | |
{ | |
var relativeSubFile = subFile.Replace(fromRepoPath, "").Substring(1); | |
var newLocation = Path.Combine(fromRepoPath, relativeFolderToMigrate, relativeSubFile); | |
Console.WriteLine($"Moving File: {subFile} -> {newLocation}"); | |
File.Move(subFile, newLocation); | |
} | |
RunGit(fromRepoPath, $"add ."); | |
RunGit(fromRepoPath, $"commit -m \"Revert folder structure post filter\""); | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"Merging filtered version of {originalRepo} into {newRepo}"); | |
RunGit(workInProgressDir, $"clone {newRepo} {toRepoPath}"); | |
RunGit(toRepoPath, $"remote add FromRepo {fromRepoPath}"); | |
RunGit(toRepoPath, $"pull FromRepo {originalRepoBranch}", true); | |
RunGit(toRepoPath, $"branch feature/RepoMigrate origin/{newRepoBranch}"); | |
RunGit(toRepoPath, "checkout feature/RepoMigrate"); | |
RunGit(toRepoPath, $"merge FromRepo/{originalRepoBranch} --allow-unrelated-histories"); | |
RunGit(toRepoPath, "remote rm FromRepo"); | |
RunGit(toRepoPath, "push origin feature/RepoMigrate"); | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"Cleaning {originalRepo}"); | |
RunGit(workInProgressDir, $"clone {originalRepo} {fromRepoCleanUpPath}"); | |
RunGit(fromRepoCleanUpPath, "branch feature/RepoMigrate"); | |
RunGit(fromRepoCleanUpPath, "checkout feature/RepoMigrate"); | |
Directory.Delete(Path.Combine(fromRepoCleanUpPath, relativeFolderToMigrate), true); | |
RunGit(fromRepoCleanUpPath, $"add ."); | |
RunGit(fromRepoCleanUpPath, $"commit -a -m \"Remove migrated folder {relativeFolderToMigrate} as moved to {newRepo}\""); | |
RunGit(fromRepoCleanUpPath, "push origin feature/RepoMigrate"); | |
} | |
private void RunGit(string workingDirectory, string args, bool ignoreError = false) | |
{ | |
RunCommand(workingDirectory, "git", args, ignoreError); | |
} | |
private void RunCommand(string workingDirectory, string fileName, string args, bool ignoreError = false) | |
{ | |
Process process = new Process(); | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"WorkingDirectory: {workingDirectory}"); | |
Console.WriteLine($"Exec: {fileName} {args}"); | |
try | |
{ | |
process.StartInfo.FileName = fileName; | |
process.StartInfo.WorkingDirectory = workingDirectory; | |
process.StartInfo.Arguments = args; | |
process.StartInfo.RedirectStandardError = true; | |
process.StartInfo.RedirectStandardOutput = true; | |
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; | |
process.StartInfo.CreateNoWindow = true; | |
process.StartInfo.UseShellExecute = false; | |
process.EnableRaisingEvents = false; | |
process.OutputDataReceived += (sender, eventArgs) => WriteConsoleOutput("stdOut", eventArgs); | |
process.ErrorDataReceived += (sender, eventArgs) => WriteConsoleOutput("stdErr", eventArgs); | |
process.Start(); | |
process.BeginOutputReadLine(); | |
process.BeginErrorReadLine(); | |
process.WaitForExit(); | |
if(process.ExitCode == 0) | |
{ | |
Console.WriteLine($"SUCCESS: Process exited with code of {process.ExitCode}"); | |
} | |
else if (ignoreError) | |
{ | |
Console.WriteLine($"WARN: Process exited with code of {process.ExitCode}"); | |
} | |
else | |
{ | |
Console.WriteLine($"ERROR: Process exited with code of {process.ExitCode}"); | |
throw new Exception($"Process exited with non-zero exit code of {process.ExitCode}"); | |
} | |
} | |
finally | |
{ | |
process.Close(); | |
} | |
} | |
private void WriteConsoleOutput(string type, DataReceivedEventArgs eventArgs) | |
{ | |
if (eventArgs.Data != null) | |
{ | |
Console.WriteLine($"{type} : {eventArgs.Data}"); | |
} | |
} | |
private void EnsureDirectoryClean(string path) | |
{ | |
if (Directory.Exists(path)) | |
{ | |
Console.WriteLine("-----------------------------"); | |
Console.WriteLine($"Directory {path} already exists, delete manually"); | |
Console.WriteLine("Press enter to continue"); | |
Console.ReadLine(); | |
Directory.CreateDirectory(path); | |
} | |
else | |
{ | |
Directory.CreateDirectory(path); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment