/// <summary> /// Runs a blocking force checkout to <paramref name="committish"/> /// </summary> /// <param name="committish">The committish to checkout</param> void RawCheckout(string committish) { Commands.Checkout(repository, committish, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force }); repository.RemoveUntrackedFiles(); }
/// <summary> /// Runs a blocking force checkout to <paramref name="committish"/> /// </summary> /// <param name="committish">The committish to checkout</param> /// <param name="progressReporter">Progress reporter <see cref="Action{T}"/></param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param> void RawCheckout(string committish, Action <int> progressReporter, CancellationToken cancellationToken) { logger.LogTrace("Checkout: {0}", committish); progressReporter(0); cancellationToken.ThrowIfCancellationRequested(); Commands.Checkout(repository, committish, new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force, OnCheckoutProgress = CheckoutProgressHandler(progressReporter) }); cancellationToken.ThrowIfCancellationRequested(); repository.RemoveUntrackedFiles(); }
/// <summary> /// Runs a blocking force checkout to <paramref name="committish"/> /// </summary> /// <param name="committish">The committish to checkout</param> /// <param name="progressReporter">Progress reporter <see cref="Action{T}"/></param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation</param> void RawCheckout(string committish, Action <int> progressReporter, CancellationToken cancellationToken) { logger.LogTrace("Checkout: {0}", committish); progressReporter(0); cancellationToken.ThrowIfCancellationRequested(); var checkoutOptions = new CheckoutOptions { CheckoutModifiers = CheckoutModifiers.Force, OnCheckoutProgress = CheckoutProgressHandler(progressReporter) }; void RunCheckout() => commands.Checkout( libGitRepo, checkoutOptions, committish); try { RunCheckout(); } catch (NotFoundException) { // Maybe (likely) a remote? var remoteName = $"origin/{committish}"; var potentialBranch = libGitRepo.Branches.FirstOrDefault( branch => branch.FriendlyName.Equals(remoteName, StringComparison.Ordinal)); cancellationToken.ThrowIfCancellationRequested(); if (potentialBranch == default) { throw; } logger.LogDebug("Creating local branch for {0}...", potentialBranch.FriendlyName); libGitRepo.CreateBranch(committish, potentialBranch.Tip); cancellationToken.ThrowIfCancellationRequested(); RunCheckout(); } cancellationToken.ThrowIfCancellationRequested(); libGitRepo.RemoveUntrackedFiles(); }
/// <inheritdoc /> #pragma warning disable CA1506 // TODO: Decomplexify public async Task <bool?> AddTestMerge( TestMergeParameters testMergeParameters, string committerName, string committerEmail, string username, string password, Action <int> progressReporter, CancellationToken cancellationToken) { if (testMergeParameters == null) { throw new ArgumentNullException(nameof(testMergeParameters)); } if (committerName == null) { throw new ArgumentNullException(nameof(committerName)); } if (committerEmail == null) { throw new ArgumentNullException(nameof(committerEmail)); } if (progressReporter == null) { throw new ArgumentNullException(nameof(progressReporter)); } logger.LogDebug( "Begin AddTestMerge: #{0} at {1} ({2}) by <{3} ({4})>", testMergeParameters.Number, testMergeParameters.TargetCommitSha?.Substring(0, 7), testMergeParameters.Comment, committerName, committerEmail); if (RemoteGitProvider == Api.Models.RemoteGitProvider.Unknown) { throw new InvalidOperationException("Cannot test merge with an Unknown RemoteGitProvider!"); } var commitMessage = String.Format( CultureInfo.InvariantCulture, "TGS Test merge #{0}{1}{2}", testMergeParameters.Number, testMergeParameters.Comment != null ? Environment.NewLine : String.Empty, testMergeParameters.Comment ?? String.Empty); var testMergeBranchName = String.Format(CultureInfo.InvariantCulture, "tm-{0}", testMergeParameters.Number); var localBranchName = String.Format(CultureInfo.InvariantCulture, gitRemoteFeatures.TestMergeLocalBranchNameFormatter, testMergeParameters.Number, testMergeBranchName); var refSpec = String.Format(CultureInfo.InvariantCulture, gitRemoteFeatures.TestMergeRefSpecFormatter, testMergeParameters.Number, testMergeBranchName); var refSpecList = new List <string> { refSpec }; var logMessage = String.Format(CultureInfo.InvariantCulture, "Test merge #{0}", testMergeParameters.Number); var originalCommit = libGitRepo.Head; MergeResult result = null; var sig = new Signature(new Identity(committerName, committerEmail), DateTimeOffset.UtcNow); await Task.Factory.StartNew( () => { try { try { logger.LogTrace("Fetching refspec {0}...", refSpec); var remote = libGitRepo.Network.Remotes.First(); progressReporter(0); commands.Fetch( libGitRepo, refSpecList, remote, new FetchOptions { Prune = true, OnProgress = (a) => !cancellationToken.IsCancellationRequested, OnTransferProgress = (a) => { var percentage = 50 * (((float)a.IndexedObjects + a.ReceivedObjects) / (a.TotalObjects * 2)); progressReporter((int)percentage); return(!cancellationToken.IsCancellationRequested); }, OnUpdateTips = (a, b, c) => !cancellationToken.IsCancellationRequested, CredentialsProvider = credentialsProvider.GenerateCredentialsHandler(username, password), }, logMessage); } catch (UserCancelledException) { } catch (LibGit2SharpException ex) { CheckBadCredentialsException(ex); } cancellationToken.ThrowIfCancellationRequested(); libGitRepo.RemoveUntrackedFiles(); cancellationToken.ThrowIfCancellationRequested(); testMergeParameters.TargetCommitSha = libGitRepo.Lookup(testMergeParameters.TargetCommitSha ?? localBranchName).Sha; cancellationToken.ThrowIfCancellationRequested(); logger.LogTrace("Merging {0} into {1}...", testMergeParameters.TargetCommitSha.Substring(0, 7), Reference); result = libGitRepo.Merge(testMergeParameters.TargetCommitSha, sig, new MergeOptions { CommitOnSuccess = commitMessage == null, FailOnConflict = true, FastForwardStrategy = FastForwardStrategy.NoFastForward, SkipReuc = true, OnCheckoutProgress = (a, completedSteps, totalSteps) => progressReporter(50 + ((int)(((float)completedSteps) / totalSteps * 50))), }); } finally { libGitRepo.Branches.Remove(localBranchName); } cancellationToken.ThrowIfCancellationRequested(); if (result.Status == MergeStatus.Conflicts) { var revertTo = originalCommit.CanonicalName ?? originalCommit.Tip.Sha; logger.LogDebug("Merge conflict, aborting and reverting to {0}", revertTo); RawCheckout(revertTo, progressReporter, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } libGitRepo.RemoveUntrackedFiles(); }, cancellationToken, DefaultIOManager.BlockingTaskCreationOptions, TaskScheduler.Current) .ConfigureAwait(false); if (result.Status == MergeStatus.Conflicts) { await eventConsumer.HandleEvent( EventType.RepoMergeConflict, new List <string> { originalCommit.Tip.Sha, testMergeParameters.TargetCommitSha, originalCommit.FriendlyName ?? UnknownReference, testMergeBranchName, }, cancellationToken) .ConfigureAwait(false); return(null); } if (commitMessage != null && result.Status != MergeStatus.UpToDate) { logger.LogTrace("Committing merge: \"{0}\"...", commitMessage); await Task.Factory.StartNew( () => libGitRepo.Commit(commitMessage, sig, sig, new CommitOptions { PrettifyMessage = true, }), cancellationToken, DefaultIOManager.BlockingTaskCreationOptions, TaskScheduler.Current) .ConfigureAwait(false); } await eventConsumer.HandleEvent( EventType.RepoAddTestMerge, new List <string> { testMergeParameters.Number.ToString(CultureInfo.InvariantCulture), testMergeParameters.TargetCommitSha, testMergeParameters.Comment, }, cancellationToken) .ConfigureAwait(false); return(result.Status != MergeStatus.NonFastForward); }