Esempio n. 1
0
        public void Clone()
        {
            Log("Start cloning...");
            StringBuilder arguments = new StringBuilder("svn init --prefix=svn/ ");

            if (!string.IsNullOrWhiteSpace(Options.UserName))
            {
                arguments.AppendFormat("--username=\"{0}\" ", Options.UserName);
            }

            if (!Options.IncludeMetaData)
            {
                arguments.Append("--no-metadata ");
            }

            if (Options.NoMinimizeUrl)
            {
                arguments.Append("--no-minimize-url ");
            }

            var branches = Options.Branches == null ? new List <string>() : new List <string>(Options.Branches);
            var tags     = Options.Tags == null ? new List <string>() : new List <string>(Options.Tags);

            if (Options.RootIsTrunk)
            {
                // Non-standard repository layout.
                // The repository root is effectively trunk.
                //
                // Note: There's a bug of git svn init so that we cannot assign the svn url to --trunk.
                // We assign "/" to --trunk to tell git svn init we're using root as trunk.
                arguments.Append("--trunk=\"/\" ");
            }
            else
            {
                // Add each component to the command that was passed as an argument.
                if (!string.IsNullOrWhiteSpace(Options.SubpathToTrunk))
                {
                    arguments.AppendFormat("--trunk=\"{0}\" ", Options.SubpathToTrunk);
                }

                if (!Options.NoTags)
                {
                    if (tags.Count == 0)
                    {
                        // Fill default tags here so that they can be filtered later
                        tags.Add("tags");
                    }

                    // Process default or user-supplied tags
                    foreach (var t in tags)
                    {
                        arguments.AppendFormat("--tags=\"{0}\" ", t);
                    }
                }

                if (!Options.NoBranches)
                {
                    if (branches.Count == 0)
                    {
                        // Fill default branches here so that they can be filtered later
                        branches.Add("branches");
                    }

                    // Process default or user-supplied branches
                    foreach (var b in branches)
                    {
                        arguments.AppendFormat("--branches=\"{0}\" ", b);
                    }
                }
            }

            arguments.Append("\"" + _svnUrl + "\"");

            if (CommandRunner.RunGitSvnInteractiveCommand(arguments.ToString(), Options.Password) != 0)
            {
                string exceptionMessage = string.Format(ExceptionHelper.ExceptionMessage.FAIL_TO_EXECUTE_COMMAND, $"git {arguments.ToString()}");
                throw new MigrateException(exceptionMessage);
            }

            if (!string.IsNullOrWhiteSpace(Options.Authors))
            {
                string args = string.Format("{0} svn.authorsfile {1}",
                                            GitConfigCommandArguments, Options.Authors);
                CommandRunner.Run("git", args);
            }

            arguments = new StringBuilder("svn fetch ");
            if (!string.IsNullOrWhiteSpace(Options.Revision))
            {
                var    range = Options.Revision.Split(":");
                string start = range[0];
                string end   = range.Length < 2 || string.IsNullOrWhiteSpace(range[1]) ? "HEAD" : range[1];
                arguments.AppendFormat("-r {0}:{1} ", start, end);
            }

            if (Options.Exclude != null && Options.Exclude.Any())
            {
                // Add exclude paths to the command line. Some versions of git support
                // this for fetch only, later also for init.
                List <string> regex = new List <string>();
                if (!Options.RootIsTrunk)
                {
                    if (!string.IsNullOrWhiteSpace(Options.SubpathToTrunk))
                    {
                        regex.Add(Options.SubpathToTrunk + @"[\/]");
                    }

                    if (!Options.NoTags && tags.Count > 0)
                    {
                        foreach (var t in tags)
                        {
                            regex.Add(t + @"[\/][^\/]+[\/]");
                        }
                    }

                    if (!Options.NoBranches && branches.Count > 0)
                    {
                        foreach (var b in branches)
                        {
                            regex.Add(b + @"[\/][^\/]+[\/]");
                        }
                    }
                }

                string regexStr = "^(?:" + string.Join("|", regex) + ")(?:" + string.Join("|", Options.Exclude) + ")";
                arguments.AppendFormat("--ignore-paths=\"{0}\" ", regexStr);
            }

            if (CommandRunner.Run("git", arguments.ToString().Trim()) != 0)
            {
                throw new MigrateException($"Fail to execute command \"git {arguments.ToString()}\". Run with -v or --verbose for details.");
            }

            FetchBranches();

            Log("End clone.");
        }
Esempio n. 2
0
 public void OptimizeRepos()
 {
     CommandRunner.Run("git", "gc");
 }
Esempio n. 3
0
        public void FixBranches()
        {
            Log("Start fixing branches...");
            List <string> svnBranches = new List <string>();

            if (_metaInfo.RemoteBranches != null)
            {
                if (_metaInfo.Tags == null)
                {
                    svnBranches = _metaInfo.RemoteBranches.ToList();
                }
                else
                {
                    svnBranches = _metaInfo.RemoteBranches.Except(_metaInfo.Tags).ToList();
                }

                svnBranches.RemoveAll(b => !Regex.IsMatch(b.Trim(), @"^svn\/"));
            }

            if (Options.IsVerbose)
            {
                Log("To fix branches include:");
                foreach (var b in svnBranches)
                {
                    Log(b);
                }
            }

            if (Options.Rebase)
            {
                Log("Rebasing...");
                CommandInfo cmdInfo = CommandInfoBuilder.BuildGitSvnFetchCommandInfo(Options.UserName);

                int exitCode = 0;
                if (string.IsNullOrWhiteSpace(Options.UserName))
                {
                    exitCode = RunCommand(cmdInfo);
                }
                else
                {
                    exitCode = CommandRunner.RunGitSvnInteractiveCommand(cmdInfo.Arguments, Options.Password);
                }

                if (exitCode != 0)
                {
                    throw new MigrateException(string.Format(ExceptionHelper.ExceptionMessage.FAIL_TO_EXECUTE_COMMAND, cmdInfo.ToString()));
                }
            }

            // In case of large branches, we build a hash set to boost the query later.
            HashSet <string> localBranchSet = new HashSet <string>(_metaInfo.LocalBranches);

            if (Options.IsVerbose)
            {
                StringBuilder sb = new StringBuilder("We have following local branches:");
                sb.AppendLine();

                foreach (var b in _metaInfo.LocalBranches)
                {
                    sb.AppendLine(b);
                }

                Log(sb.ToString());
            }

            foreach (var b in svnBranches)
            {
                var  branch = Regex.Replace(b, @"^svn\/", "").Trim();
                bool isTrunkBranchOrIsLocalBranch = branch.Equals("trunk", StringComparison.InvariantCulture) ||
                                                    localBranchSet.Contains(branch);

                Log($"Current branch is {b}");
                Log($"Current branch without prefix: {branch}");
                Log($"IsTrunkBranchOrIsLocalBranch: {isTrunkBranchOrIsLocalBranch}");
                if (Options.Rebase && isTrunkBranchOrIsLocalBranch)
                {
                    string      localBranch = branch == "trunk" ? "master" : branch;
                    CommandInfo forceCheckoutLocalBranchCommandInfo = CommandInfoBuilder.BuildForceCheckoutLocalBranchCommandInfo(localBranch);
                    CommandInfo rebaseRemoteBranchCommandInfo       = CommandInfoBuilder.BuildGitRebaseRemoteSvnBranchCommandInfo(branch);

                    RunCommand(CommandInfoBuilder.BuildForceCheckoutLocalBranchCommandInfo(localBranch));

                    RunCommand(CommandInfoBuilder.BuildGitRebaseRemoteSvnBranchCommandInfo(branch));

                    continue;
                }

                if (isTrunkBranchOrIsLocalBranch)
                {
                    Log($"{branch} is trunk branch or local branch, skip.");
                    continue;
                }

                // Now checkout the remote svn branch.
                RunCommand(CommandInfoBuilder.BuildCheckoutSvnRemoteBranchCommandInfo(branch));
            }

            Log("End fixing branches.");
        }
Esempio n. 4
0
        public void FixTags()
        {
            string currentUserName  = string.Empty;
            string currentUserEmail = string.Empty;

            try
            {
                if (_metaInfo.Tags != null)
                {
                    Log("Reading user.name and user.email...");

                    CommandRunner.Run("git", $"{GitConfigCommandArguments} --get user.name", out currentUserName);
                    CommandRunner.Run("git", $"{GitConfigCommandArguments} --get user.email", out currentUserEmail);

                    Log($"user.name: {currentUserName}");
                    Log($"user.email: {currentUserEmail}");

                    foreach (string t in _metaInfo.Tags)
                    {
                        string tag = t.Trim();
                        Log($"Processing tag: {tag}");

                        string id = Regex.Replace(tag, @"^svn\/tags\/", "").Trim();
                        Log($"id: {id}");

                        string quotesFreeTag = Utils.EscapeQuotes(tag);
                        Log($"quotes free tag: {tag}");

                        string subject = Utils.RemoveFromTwoEnds(RunCommandIgnoreExitCode("git", $"log -1 --pretty=format:'%s' \"{quotesFreeTag}\""), '\'');
                        string date    = Utils.RemoveFromTwoEnds(RunCommandIgnoreExitCode("git", $"log -1 --pretty=format:'%ci' \"{quotesFreeTag}\""), '\'');
                        string author  = Utils.RemoveFromTwoEnds(RunCommandIgnoreExitCode("git", $"log -1 --pretty=format:'%an' \"{quotesFreeTag}\""), '\'');
                        string email   = Utils.RemoveFromTwoEnds(RunCommandIgnoreExitCode("git", $"log -1 --pretty=format:'%ae' \"{quotesFreeTag}\""), '\'');

                        string quotesFreeAuthor = Utils.EscapeQuotes(author);
                        CommandRunner.Run("git", $"{GitConfigCommandArguments} user.name \"{quotesFreeAuthor}\"");
                        CommandRunner.Run("git", $"{GitConfigCommandArguments} user.email \"{quotesFreeAuthor}\"");

                        string originalGitCommitterDate = Environment.GetEnvironmentVariable("GIT_COMMITTER_DATE");
                        Environment.SetEnvironmentVariable("GIT_COMMITTER_DATE", Utils.EscapeQuotes(date));
                        CommandRunner.Run("git", $"tag -a -m \"{Utils.EscapeQuotes(subject)}\" \"{Utils.EscapeQuotes(id)}\" \"{quotesFreeTag}\"");
                        Environment.SetEnvironmentVariable("GIT_COMMITTER_DATE", originalGitCommitterDate);

                        CommandRunner.Run("git", $"branch -d -r \"{quotesFreeTag}\"");
                    }
                }
            }
            finally
            {
                // We only change the git config values if there are @tags available.
                // So it stands to reason we should revert them only in that case.
                if (_metaInfo.Tags != null && _metaInfo.Tags.Any())
                {
                    // If a line was read, then there was a config value so restore it.
                    // Otherwise unset the value because originally there was none.
                    if (!string.IsNullOrWhiteSpace(currentUserName))
                    {
                        CommandRunner.Run("git", $"{GitConfigCommandArguments} user.name \"{currentUserName.Trim()}\"");
                    }
                    else
                    {
                        CommandRunner.Run("git", $"{GitConfigCommandArguments} --unset user.name");
                    }

                    if (!string.IsNullOrWhiteSpace(currentUserEmail))
                    {
                        CommandRunner.Run("git", $"{GitConfigCommandArguments} user.email \"{currentUserEmail.Trim()}\"");
                    }
                    else
                    {
                        CommandRunner.Run("git", $"{GitConfigCommandArguments} --unset user.email");
                    }
                }
            }
        }