public async override Task <string> GetGitHubValue(GitHubClient client, RepoModel repo) { // var apiOptions = new ApiOptions(); //var stats = await client.Repository.Commit.GetAll(repo.Owner, repo.Name); //return stats.LastOrDefault()?. return(DateTime.MinValue.ToString()); }
public static List <SimpleFileChange> DoGitChangedFilesRetrieve(RepoModel repoModel, int numberOfCommits = 15) { var result = new List <SimpleFileChange>(); var iniFile = new IniFile(FormMain.OptionsIni); var defaultPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "source", "repos"); var slnSearchPath = iniFile.ReadString(OptionsForm.PreferencesSection, "RepoPath", defaultPath); using (var repo = new Repository(repoModel.Path)) { foreach (var commit in repo.Commits.Take(numberOfCommits)) { foreach (var parent in commit.Parents) { foreach (var change in repo.Diff.Compare <TreeChanges>(parent.Tree, commit.Tree)) { result.Add(new SimpleFileChange { FileChangeKind = change.Status.ToString(), Path = Path.Combine(slnSearchPath, repoModel.Name, change.Path.Replace('/', '\\')), ChangeAuthor = commit.Author.Name, DateChanged = commit.Author.When.LocalDateTime, Message = commit.MessageShort, Sha = commit.Sha }); } } } } return(result); }
public static List <SimpleCommit> DoGitCommitHistoryRetrieve(RepoModel repoModel, int numberOfCommits = 15) { var result = new List <SimpleCommit>(); using (var repo = new Repository(repoModel.Path)) { foreach (var c in repo.Commits.Take(numberOfCommits)) { var mergeString = c.Parents.Count() > 1 ? string.Join(" ", c.Parents.Select(p => p.Id.Sha.Substring(0, 7)).ToArray()) : ""; var changeCount = 0; c.Parents.ForEach(x => changeCount += repo.Diff.Compare <TreeChanges>(x.Tree, c.Tree).Count); result.Add(new SimpleCommit { Id = c.Id.ToString(), Merges = mergeString, Author = $"{c.Author.Name} <{c.Author.Email}>", Date = c.Author.When.LocalDateTime, Message = c.Message, ChangeCount = changeCount }); } } return(result); }
public static void DoGitBranchCheckout(RepoModel repoModel, string branchName) { using (var repo = new Repository(repoModel.Path)) { Debug.WriteLine($"{repoModel.Name} active branch: {repo.Head.UpstreamBranchCanonicalName}"); //var branchNameNoRefHead = // repo.Head.UpstreamBranchCanonicalName.Replace("refs/heads/", ""); //repoModel.BranchName = branchNameNoRefHead; //var branchesList = new List<string>(); ////Get local branches //foreach (var b in repo.Branches.Where(b => !b.IsRemote)) //{ // var tempBranchNameNoRefHead = // b.UpstreamBranchCanonicalName.Replace("refs/heads/", ""); // branchesList.Add(tempBranchNameNoRefHead); //} var branch = repo.Branches[branchName]; if (branch == null) { return; } var currentBranch = Commands.Checkout(repo, branch); } }
public static string GetRepoModelRemoteUrl(RepoModel repoModel) { using (var repo = new Repository(repoModel.Path)) { return(repo.Network.Remotes.First().Url); } }
public async Task Run([ActivityTrigger] RepoModel model, ILogger log) { log.LogInformation($"Saving item with ID {model?.Id} to Database {_appConfig.SqlConnectionString}..."); // Simulate long running Activity await Task.Delay(3000); }
public async override Task <string> GetGitHubValue(GitHubClient client, RepoModel repo) { var stats = await client.Activity.Starring.GetAllStargazers(repo.Owner, repo.Name); // var trafficRequest = new RepositoryTrafficRequest(TrafficDayOrWeek.Week); // await client.Repository.Traffic.GetViews(repo.Owner, repo.Name, trafficRequest); return((stats?.Count ?? 0).ToString()); }
public async override Task <string> GetGitHubValue(GitHubClient client, RepoModel repo) { var trafficRequest = new RepositoryTrafficRequest(TrafficDayOrWeek.Week); // var stats = await client.Repository.Traffic.GetClones(repo.Owner, repo.Name, trafficRequest); var stats = await client.Repository.Traffic.GetViews(repo.Owner, repo.Name, trafficRequest); return((stats?.Uniques ?? 0).ToString()); }
private static bool IsRemoteServerConnectionOK(RepoModel repoModel, SummaryRecord summaryRecord) { if (IsSiteAccessible(repoModel.RemoteURL)) { return(true); } summaryRecord.Result = "Error"; summaryRecord.Message = $"Could not connect to remote server: {repoModel.RemoteURL}"; return(false); }
public static async Task GetRepoModelSolutionsList(RepoModel repoModel, string reposPath, CancellationToken ct) { await Task.Run(() => { try { var solutionsList = Directory .EnumerateFiles(repoModel.Path, "*.sln", SearchOption.AllDirectories).ToList(); repoModel.SetSolutionsList(solutionsList); if (!Processor.IsValidSearchPath(repoModel.Path)) { return; } var modelSolutionList = (from solutionPath in solutionsList let solutionDirectory = Path.GetDirectoryName(solutionPath) where solutionDirectory != null select new ModelSolution(solutionPath)).ToList(); var dependentRepoNamesList = new List <string>(); foreach (var modelSolution in modelSolutionList) { foreach (var modelProject in modelSolution.ProjectList) { var truncatedPath = Path.GetFullPath(modelProject.FullPath) .Replace(reposPath, "").TrimStart('\\').Split('\\')[0]; if (Path.GetFileName(repoModel.Path) != truncatedPath) { dependentRepoNamesList.Add(truncatedPath); } } } //Do this weird thing for distinct items for mixed cases var tempDependentRepoNamesList = new List <string>(); foreach (var repoName in dependentRepoNamesList) { if (tempDependentRepoNamesList.Any(x => string.Equals(x, repoName, StringComparison.CurrentCultureIgnoreCase))) { continue; } tempDependentRepoNamesList.Add(repoName); } repoModel.SetDependentRepoNamesList(tempDependentRepoNamesList); } catch (Exception ex) { Debug.WriteLine($"GetRepoModelSolutionsList: {ex.Message}"); } }, ct); }
public RepoModel CreateRepo(CreateRepoInput insertRepo) { var newRepo = new RepoModel { Id = System.Guid.NewGuid().ToString(), Name = insertRepo.Name, MaximumLastCommitDate = insertRepo.MaximumLastCommitDate }; return(_repoService.Insert(newRepo)); }
public static string GetToolsFolder() { string pathToConfig = Path.Combine(PathHelper.GetUserProcessingFolder(), "repo.config"); if (!File.Exists(pathToConfig)) { return("localhost"); } RepoModel model = JsonConvert.DeserializeObject <RepoModel>(File.ReadAllText(pathToConfig)); return(model.FolderName); }
public static void DoGitReset(RepoModel repoModel, ref SummaryRecord summaryRecord) { if (!IsRemoteServerConnectionOK(repoModel, summaryRecord)) { return; } using (var repo = new Repository(repoModel.Path)) { Commands.Stage(repo, "*"); repo.Reset(ResetMode.Hard, repo.Head.Tip); } }
public static string GetRepoPreferredSolution(RepoModel repoModel) { var iniFile = new IniFile(FormMain.RepoPropertiesIni); var fileName = iniFile.ReadString(repoModel.Name, "PreferredSolution", ""); if (!string.IsNullOrEmpty(fileName)) { return(!File.Exists(fileName) ? string.Empty : fileName); } var slnList = repoModel.GetSolutionList(); return(slnList.Count == 1 ? slnList.First() : string.Empty); }
public static void DoGitFetch(RepoModel repoModel, ref SummaryRecord summaryRecord) { if (!IsRemoteServerConnectionOK(repoModel, summaryRecord)) { return; } using (var repo = new Repository(repoModel.Path)) { var hasUserNameOrPassword = GetUserNameAndPassword(out var userName, out var password, repoModel.RepoSourceType); const string logMessage = ""; var options = new FetchOptions(); if (hasUserNameOrPassword) { options.CredentialsProvider = (url, usernameFromUrl, types) => new UsernamePasswordCredentials { Username = userName, Password = password }; } foreach (var remote in repo.Network.Remotes) { var refSpecs = remote.FetchRefSpecs.Select(x => x.Specification); try { Commands.Fetch(repo, remote.Name, refSpecs, options, logMessage); } catch (Exception ex) { if (!hasUserNameOrPassword) { summaryRecord.Result = "Error"; summaryRecord.Message = "Need to configure repository connection credentials."; } else { summaryRecord.Result = "Error"; var message = ex.Message.Replace("too many redirects or authentication replays", "Incorrect username or password"); summaryRecord.Message = message; } } } } }
public RepoPropertiesForm(RepoModel aRepoModel) { InitializeComponent(); repoModel = aRepoModel; var optionsIniFile = new IniFile(FormMain.OptionsIni); Width = optionsIniFile.ReadInteger("RepoPropertiesWindow", "Width", 1000); Height = optionsIniFile.ReadInteger("RepoPropertiesWindow", "Height", 600); var isMaximized = optionsIniFile.ReadBool("RepoPropertiesWindow", "IsMaximized", false); WindowState = isMaximized ? FormWindowState.Maximized : FormWindowState.Normal; }
public static string GetFirstSelectedBatchFileName(RepoModel repoModel) { var iniFile = new IniFile(FormMain.RunBatchIni); foreach (var batFile in Directory.EnumerateFiles(repoModel.Path, "*.bat", SearchOption.AllDirectories).ToList()) { if (iniFile.ReadBool(repoModel.Path, batFile, false)) { return(Path.GetFileName(batFile)); } } return(string.Empty); }
public static void SetRepoPath(string repo) { string pathToConfig = Path.Combine(PathHelper.GetUserProcessingFolder(), "repo.config"); RepoModel model = !File.Exists(pathToConfig) ? new RepoModel() : JsonConvert.DeserializeObject <RepoModel>(File.ReadAllText(pathToConfig)); model.FolderName = repo; if (!Directory.Exists(Path.GetDirectoryName(pathToConfig))) { Directory.CreateDirectory(Path.GetDirectoryName(pathToConfig)); } File.WriteAllText(pathToConfig, JsonConvert.SerializeObject(model)); }
public static int GetBatchFileCount(RepoModel repoModel) { var batFiles = Directory.EnumerateFiles(repoModel.Path, "*.bat", SearchOption.AllDirectories).ToList(); var batchToRunCount = 0; var iniFile = new IniFile(FormMain.RunBatchIni); foreach (var batFile in batFiles) { if (iniFile.ReadBool(repoModel.Path, batFile, false)) { batchToRunCount++; } } return(batchToRunCount); }
public static async Task GetRepositoryChanges(RepoModel repoModel, CancellationToken ct) { await Task.Run(() => { try { //Todo: SX_Core and AutoDEMO_DemoFiles take 20+ seconds var stopWatch = new Stopwatch(); stopWatch.Start(); using (var repo = new Repository(repoModel.Path)) { var statusOptions = new StatusOptions { IncludeIgnored = false, IncludeUnaltered = false, IncludeUntracked = false, Show = StatusShowOption.WorkDirOnly, //don't check index dir for performance RecurseIgnoredDirs = false, RecurseUntrackedDirs = false, ExcludeSubmodules = true }; //this is slower?! statusOptions = new StatusOptions(); var repoStatus = repo.RetrieveStatus(statusOptions); GetFileStatusInfo(repoStatus, out var Changes, out var ChangeString); repoModel.ChangeString = ChangeString; repoModel.Changes = Changes; stopWatch.Stop(); var ts = stopWatch.Elapsed; Debug.WriteLine($"GetRepositoryChanges: {repoModel.Name} - {ts.Hours:D2}h:{ts.Minutes:D2}m:{ts.Seconds:D2}s:{ts.Milliseconds:D3}ms"); } } catch (Exception ex) { Debug.WriteLine($"GetRepoModelSolutionsList: {ex.Message}"); } }, ct); }
public static async Task GetRepositorySize(RepoModel repoModel, CancellationToken ct) { await Task.Run(() => { try { repoModel.SizeString = "0 bytes"; var stopWatch = new Stopwatch(); stopWatch.Start(); repoModel.SizeString = BytesToFormattedString(GetDirectorySize(repoModel.Path)); stopWatch.Stop(); var ts = stopWatch.Elapsed; Debug.WriteLine($"GetRepositorySize: {repoModel.Name} - {ts.Hours:D2}h:{ts.Minutes:D2}m:{ts.Seconds:D2}s:{ts.Milliseconds:D3}ms"); } catch (Exception ex) { Debug.WriteLine($"GetRepoModelSolutionsList: {ex.Message}"); } }, ct); }
public static async Task GetInterRepoReferences(RepoModel repoModel, CancellationToken ct) { await Task.Run(() => { try { repoModel.NumberOfFilesString = "0"; var stopWatch = new Stopwatch(); stopWatch.Start(); var ts = stopWatch.Elapsed; Debug.WriteLine($"GetRepoNumberOfFiles: {repoModel.Name} - {ts.Hours:D2}h:{ts.Minutes:D2}m:{ts.Seconds:D2}s:{ts.Milliseconds:D3}ms"); } catch (Exception ex) { Debug.WriteLine($"GetRepoModelSolutionsList: {ex.Message}"); } }, ct); }
public static async Task GetRepoNumberOfFiles(RepoModel repoModel, CancellationToken ct) { await Task.Run(() => { try { repoModel.NumberOfFilesString = "0"; var stopWatch = new Stopwatch(); stopWatch.Start(); repoModel.NumberOfFilesString = Directory.GetFiles(repoModel.Path, "*.*", SearchOption.AllDirectories).ToList().Count.ToString(); stopWatch.Stop(); var ts = stopWatch.Elapsed; Debug.WriteLine($"GetRepoNumberOfFiles: {repoModel.Name} - {ts.Hours:D2}h:{ts.Minutes:D2}m:{ts.Seconds:D2}s:{ts.Milliseconds:D3}ms"); } catch (Exception ex) { Debug.WriteLine($"GetRepoModelSolutionsList: {ex.Message}"); } }, ct); }
public IndexModule(IGithubUserRepository githubUserRepository, IDeploymentRepository deploymentRepository, IRootPathProvider rootPathProvider) { this.githubUserRepository = githubUserRepository; this.rootPathProvider = rootPathProvider; this.snowPreCompilerPath = rootPathProvider.GetRootPath() + "PreCompiler\\Sandra.Snow.Precompiler.exe"; Post["/"] = parameters => { var payloadModel = this.Bind <GithubHookModel.RootObject>(); //Check if user is registered var githubhookfromUsername = payloadModel.repository.owner.name; var githubhookfromRepo = payloadModel.repository.url; if (!githubUserRepository.UserRegistered(githubhookfromUsername, githubhookfromRepo)) { return(HttpStatusCode.Forbidden); } var deploymentModel = deploymentRepository.GetDeployment(githubhookfromUsername); DeployBlog(deploymentModel); return(200); }; Get["/"] = parameters => { return(View["Index"]); }; Get["/repos"] = parameters => { return(View["Repos"]); }; Get["getrepodata/{githubuser}"] = parameters => { var githubUser = (string)parameters.githubuser; var client = new RestClient("https://api.github.com"); var request = new RestRequest("users/" + githubUser + "/repos"); request.AddHeader("Accept", "application/json"); var response = client.Execute <List <GithubUserRepos.RootObject> >(request); var repoDetail = response.Data //.Where(x => x.fork == false) .Select( x => new RepoDetail { Name = x.name, AvatarUrl = x.owner.avatar_url, Description = x.description, HtmlUrl = x.html_url, UpdatedAt = DateTime.Parse(x.pushed_at).ToRelativeTime(), CloneUrl = x.clone_url }); var viewModel = new RepoModel { Username = githubUser, Repos = repoDetail }; return(viewModel); }; Post["initializedeployment"] = parameters => { var model = this.BindAndValidate <DeploymentModel>(); if (!this.ModelValidationResult.IsValid) { return(400); } DeployBlog(model); deploymentRepository.AddDeployment(model); Thread.Sleep(2500); return("deployed"); }; Post["/alreadyregistered"] = parameters => { var model = this.Bind <AlreadyRegisteredModel>(); var alreadyRegistered = deploymentRepository.IsUserAndRepoRegistered(model.AzureDeployment, model.Repo, model.Username); var keys = new List <string>(); keys.Add(model.AzureDeployment ? "azurerepo" : "ftpserver"); return(new { isValid = !alreadyRegistered, keys = keys }); }; }
public void Remove(RepoModel repoToBeDeleted) => _repos.DeleteOne(x => x.Id == repoToBeDeleted.Id);
public RepoModel Update(RepoModel updatedRepo) { _repos.ReplaceOne(x => x.Id == updatedRepo.Id, updatedRepo); return(updatedRepo); }
public RepoModel Insert(RepoModel newRepo) { _repos.InsertOne(newRepo); return(newRepo); }
public IndexModule(IGithubUserRepository githubUserRepository, IDeploymentRepository deploymentRepository, IRootPathProvider rootPathProvider) { this.githubUserRepository = githubUserRepository; this.rootPathProvider = rootPathProvider; this.snowPreCompilerPath = rootPathProvider.GetRootPath() + "PreCompiler\\Sandra.Snow.Precompiler.exe"; Post["/"] = parameters => { var payloadModel = this.Bind<GithubHookModel.RootObject>(); //Check if user is registered var githubhookfromUsername = payloadModel.repository.owner.name; var githubhookfromRepo = payloadModel.repository.url; if (!githubUserRepository.UserRegistered(githubhookfromUsername, githubhookfromRepo)) return HttpStatusCode.Forbidden; var deploymentModel = deploymentRepository.GetDeployment(githubhookfromUsername); DeployBlog(deploymentModel); return 200; }; Get["/"] = parameters => { return View["Index"]; }; Get["/repos"] = parameters => { return View["Repos"]; }; Get["getrepodata/{githubuser}"] = parameters => { var githubUser = (string)parameters.githubuser; var client = new RestClient("https://api.github.com"); var request = new RestRequest("users/" + githubUser + "/repos"); request.AddHeader("Accept", "application/json"); var response = client.Execute<List<GithubUserRepos.RootObject>>(request); var repoDetail = response.Data //.Where(x => x.fork == false) .Select( x => new RepoDetail { Name = x.name, AvatarUrl = x.owner.avatar_url, Description = x.description, HtmlUrl = x.html_url, UpdatedAt = DateTime.Parse(x.pushed_at).ToRelativeTime(), CloneUrl = x.clone_url }); var viewModel = new RepoModel { Username = githubUser, Repos = repoDetail }; return viewModel; }; Post["initializedeployment"] = parameters => { var model = this.BindAndValidate<DeploymentModel>(); if (!this.ModelValidationResult.IsValid) { return 400; } DeployBlog(model); deploymentRepository.AddDeployment(model); Thread.Sleep(2500); return "deployed"; }; Post["/alreadyregistered"] = parameters => { var model = this.Bind<AlreadyRegisteredModel>(); var alreadyRegistered = deploymentRepository.IsUserAndRepoRegistered(model.AzureDeployment, model.Repo, model.Username); var keys = new List<string>(); keys.Add(model.AzureDeployment ? "azurerepo" : "ftpserver"); return new { isValid = !alreadyRegistered, keys = keys }; }; }
public static async Task GetRepoGitInfoAsync(RepoModel repoModel, CancellationToken ct) { await Task.Run(() => { try { var iniFile = new IniFile(FormMain.OptionsIni); var azureDevOpsHostUrl = iniFile.ReadString(OptionsForm.AuthenticationSection, "AzureDevOpsHostUrl", ""); var stopWatch = new Stopwatch(); stopWatch.Start(); using (var repo = new Repository(repoModel.Path)) { //Active branch name var branchNameNoRefHead = repo.Head.UpstreamBranchCanonicalName.Replace("refs/heads/", ""); repoModel.BranchName = branchNameNoRefHead; var remote = repo.Network.Remotes.FirstOrDefault(); if (remote != null) { repoModel.RemoteURL = remote.Url; if (remote.Url.Contains("github.com")) { repoModel.RepoSourceType = RepoSourceTypeEnum.GitHub; } else { if (!string.IsNullOrEmpty(azureDevOpsHostUrl) && remote.Url.Contains(azureDevOpsHostUrl)) { repoModel.RepoSourceType = RepoSourceTypeEnum.AzureDevOps; } else { repoModel.RepoSourceType = RepoSourceTypeEnum.Unknown; } } } repoModel.ChangeString = ""; repoModel.Changes = "-"; if (repoModel.SkipScan) { return; } //Commit ahead/behind var commitsAhead = repo.Head.TrackingDetails.AheadBy; var commitsBehind = repo.Head.TrackingDetails.BehindBy; repoModel.CommitsAheadBehind = $"+{commitsAhead}/-{commitsBehind}"; var commit = repo.Head.Commits.First(); if (commit != null) { repoModel.LastChange = commit.Author.When.ToLocalTime().DateTime; repoModel.CommitMessage = $"{commit.Author.Name}: {commit.Message}"; } var branchesList = new List <string>(); //Get local branches list // ReSharper disable once LoopCanBeConvertedToQuery foreach (var b in repo.Branches.Where(b => !b.IsRemote)) { var tempBranchNameNoRefHead = b.UpstreamBranchCanonicalName.Replace("refs/heads/", ""); branchesList.Add(tempBranchNameNoRefHead); } repoModel.SetBranchesList(branchesList); stopWatch.Stop(); var ts = stopWatch.Elapsed; Debug.WriteLine($"GetRepoGitInfoAsync: {repoModel.Name} - {ts.Hours:D2}h:{ts.Minutes:D2}m:{ts.Seconds:D2}s:{ts.Milliseconds:D3}ms"); } } catch (Exception ex) { Debug.WriteLine($"GetRepoActiveBranchNameAsync: {ex.Message}"); } }, ct); }
public static async Task <List <RepoModel> > ScanForRepositoriesAsync(string repoSearchPath, bool useGitFolders = true) { var repoModelList = new List <RepoModel>(); await Task.Run(() => { var searchRootDirectories = Directory.EnumerateDirectories(repoSearchPath, "*", SearchOption.TopDirectoryOnly).ToList(); var iniFile = new IniFile(FormMain.OptionsIni); iniFile.ReadSectionValues(SkipRepoBrowseForm.SkipReposSection, out var repoSectionValuesList); foreach (var searchRootDirectory in searchRootDirectories) { var gitFolder = Path.Combine(searchRootDirectory, ".git"); if (Directory.Exists(gitFolder) && useGitFolders) { // var repoPath = Path.GetDirectoryName(gitFolder); var repoModel = new RepoModel { Name = Path.GetFileName(Path.GetDirectoryName(gitFolder)), Path = searchRootDirectory, SkipScan = repoSectionValuesList.Contains(searchRootDirectory) }; repoModelList.Add(repoModel); } if (Directory.Exists(gitFolder) || useGitFolders) { continue; } // var repoPath = Path.GetDirectoryName(gitFolder); var nonGitRepoModel = new RepoModel { Name = Path.GetFileName(Path.GetDirectoryName(gitFolder)), Path = searchRootDirectory, SkipScan = repoSectionValuesList.Contains(searchRootDirectory) }; repoModelList.Add(nonGitRepoModel); //var gitFolderList = Directory // .EnumerateDirectories(searchRootDirectory, ".git", SearchOption.TopDirectoryOnly).ToList(); //foreach (var gitFolder in gitFolderList) //{ // var repoPath = Path.GetDirectoryName(gitFolder); // var repoModel = new RepoModel // { // Name = Path.GetFileName(Path.GetDirectoryName(gitFolder)), // Path = repoPath, // SkipScan = repoSectionValuesList.Contains(repoPath) // }; // repoModelList.Add(repoModel); //} } }); return(repoModelList); }
public static void DoGitPull(RepoModel repoModel, ref SummaryRecord summaryRecord) { if (!IsRemoteServerConnectionOK(repoModel, summaryRecord)) { return; } using (var repo = new Repository(repoModel.Path)) { var hasUserNameOrPassword = GetUserNameAndPassword(out var userName, out var password, repoModel.RepoSourceType); try { var options = new PullOptions { FetchOptions = new FetchOptions { CredentialsProvider = (url, usernameFromUrl, types) => new UsernamePasswordCredentials { Username = userName, Password = password } } }; // User information to create a merge commit //Todo: Change this to be actual email var signature = new Signature( new Identity(userName, $"{userName}@gmail.com"), DateTimeOffset.Now); // Pull var mergeResult = Commands.Pull(repo, signature, options); switch (mergeResult.Status) { case MergeStatus.Conflicts: summaryRecord.Message = "The merge had conflicts. Resolve them before continuing."; break; case MergeStatus.FastForward: summaryRecord.Message = $"Fast forward to commit: {mergeResult.Commit.Author} {mergeResult.Commit.Message}"; break; case MergeStatus.NonFastForward: summaryRecord.Message = $"Non-fast forward to commit: {mergeResult.Commit.Author} {mergeResult.Commit.Message}"; break; case MergeStatus.UpToDate: summaryRecord.Message = "The branch was already up-to-date."; break; default: Debug.WriteLine($"Unknown mergeResult: {mergeResult.Status}"); break; } } catch (Exception ex) { if (!hasUserNameOrPassword) { summaryRecord.Result = "Error"; summaryRecord.Message = "Need to configure repository connection credentials."; } else { summaryRecord.Result = "Error"; var message = ex.Message.Replace("too many redirects or authentication replays", "Incorrect username or password"); summaryRecord.Message = message; } } } }