예제 #1
0
        async Task <IPullRequestModel> PushAndCreatePR(IRepositoryHost host,
                                                       ILocalRepositoryModel sourceRepository, IRepositoryModel targetRepository,
                                                       IBranch sourceBranch, IBranch targetBranch,
                                                       string title, string body)
        {
            var repo = await Task.Run(() => gitService.GetRepository(sourceRepository.LocalPath));

            var remote = await gitClient.GetHttpRemote(repo, "origin");

            await gitClient.Push(repo, sourceBranch.Name, remote.Name);

            if (!repo.Branches[sourceBranch.Name].IsTracking)
            {
                await gitClient.SetTrackingBranch(repo, sourceBranch.Name, remote.Name);
            }

            // delay things a bit to avoid a race between pushing a new branch and creating a PR on it
            if (!Splat.ModeDetector.Current.InUnitTestRunner().GetValueOrDefault())
            {
                await Task.Delay(TimeSpan.FromSeconds(5));
            }

            var ret = await host.ModelService.CreatePullRequest(sourceRepository, targetRepository, sourceBranch, targetBranch, title, body);

            usageTracker.IncrementUpstreamPullRequestCount();
            return(ret);
        }
예제 #2
0
        public IObservable <Unit> SwitchRemotes(IRepositoryModel destinationRepository, bool updateOrigin, bool addUpstream, bool trackMasterUpstream)
        {
            return(Observable.Defer(() => Observable.Return(new object())
                                    .ObserveOn(RxApp.MainThreadScheduler)
                                    .Select(_ => vsGitServices.GetActiveRepo()))
                   .SelectMany(async activeRepo =>
            {
                using (activeRepo)
                {
                    Uri currentOrigin = null;

                    if (addUpstream)
                    {
                        var remote = await gitClient.GetHttpRemote(activeRepo, "origin");
                        currentOrigin = new Uri(remote.Url);
                    }

                    await SwitchRemotes(activeRepo, updateOrigin ? destinationRepository.CloneUrl.ToUri() : null,
                                        currentOrigin, trackMasterUpstream);
                }

                if (updateOrigin)
                {
                    vsGitExt.RefreshActiveRepositories();

                    var updatedRepository = vsGitExt.ActiveRepositories.FirstOrDefault();
                    log.Assert(updatedRepository?.CloneUrl == destinationRepository.CloneUrl,
                               "CloneUrl is {UpdatedRepository} not {DestinationRepository}", updatedRepository?.CloneUrl ?? "[NULL]", destinationRepository.CloneUrl);
                }

                return Unit.Default;
            }));
        }
        /// <inheritdoc/>
        public async Task <string> GetPullRequestMergeBase(ILocalRepositoryModel repository, IPullRequestModel pullRequest)
        {
            var baseSha = pullRequest.Base.Sha;
            var headSha = pullRequest.Head.Sha;
            var key     = new Tuple <string, string>(baseSha, headSha);

            string mergeBase;

            if (mergeBaseCache.TryGetValue(key, out mergeBase))
            {
                return(mergeBase);
            }

            var repo = await GetRepository(repository);

            var remote = await gitClient.GetHttpRemote(repo, "origin");

            var baseRef    = pullRequest.Base.Ref;
            var pullNumber = pullRequest.Number;

            mergeBase = await gitClient.GetPullRequestMergeBase(repo, remote.Name, baseSha, headSha, baseRef, pullNumber);

            if (mergeBase == null)
            {
                throw new FileNotFoundException($"Couldn't find merge base between {baseSha} and {headSha}.");
            }

            mergeBaseCache[key] = mergeBase;
            return(mergeBase);
        }
예제 #4
0
 public IObservable <Unit> Push(ILocalRepositoryModel repository)
 {
     return(Observable.Defer(async() =>
     {
         var repo = gitService.GetRepository(repository.LocalPath);
         var remote = await gitClient.GetHttpRemote(repo, repo.Head.Remote.Name);
         return gitClient.Push(repo, repo.Head.TrackedBranch.UpstreamBranchCanonicalName, remote.Name).ToObservable();
     }));
 }
예제 #5
0
 public IObservable <Unit> Push(LocalRepositoryModel repository)
 {
     return(Observable.Defer(async() =>
     {
         using (var repo = gitService.GetRepository(repository.LocalPath))
         {
             var remoteName = repo.Head.RemoteName;
             var remote = await gitClient.GetHttpRemote(repo, remoteName);
             await gitClient.Push(repo, repo.Head.TrackedBranch.UpstreamBranchCanonicalName, remote.Name);
             return Observable.Return(Unit.Default);
         }
     }));
 }
예제 #6
0
        public IObservable <Unit> Checkout(ILocalRepositoryModel repository, IPullRequestModel pullRequest, string localBranchName)
        {
            return(Observable.Defer(async() =>
            {
                var repo = gitService.GetRepository(repository.LocalPath);
                var existing = repo.Branches[localBranchName];

                if (existing != null)
                {
                    await gitClient.Checkout(repo, localBranchName);
                }
                else if (repository.CloneUrl.ToRepositoryUrl() == pullRequest.Head.RepositoryCloneUrl.ToRepositoryUrl())
                {
                    var remote = await gitClient.GetHttpRemote(repo, "origin");
                    await gitClient.Fetch(repo, remote.Name);
                    await gitClient.Checkout(repo, localBranchName);
                }
                else
                {
                    var refSpec = $"{pullRequest.Head.Ref}:{localBranchName}";
                    var prConfigKey = $"branch.{localBranchName}.{SettingGHfVSPullRequest}";
                    var remoteName = await CreateRemote(repo, pullRequest.Head.RepositoryCloneUrl);

                    await gitClient.Fetch(repo, remoteName);
                    await gitClient.Fetch(repo, remoteName, new[] { refSpec });
                    await gitClient.Checkout(repo, localBranchName);
                    await gitClient.SetTrackingBranch(repo, localBranchName, $"refs/remotes/{remoteName}/{pullRequest.Head.Ref}");
                    await gitClient.SetConfig(repo, prConfigKey, pullRequest.Number.ToString());
                }

                return Observable.Return(Unit.Default);
            }));
        }
    static LibGit2Sharp.IRepository SetupLocalRepoMock(IGitClient gitClient, IGitService gitService, string remote, string head, bool isTracking)
    {
        var l2remote = Substitute.For<LibGit2Sharp.Remote>();
        l2remote.Name.Returns(remote);
        gitClient.GetHttpRemote(Args.LibGit2Repo, Args.String).Returns(Task.FromResult(l2remote));

        var l2repo = Substitute.For<LibGit2Sharp.IRepository>();
        var l2branchcol = Substitute.For<LibGit2Sharp.BranchCollection>();
        var l2branch = Substitute.For<LibGit2Sharp.Branch>();
        l2branch.FriendlyName.Returns(head);
        l2branch.IsTracking.Returns(isTracking);
        l2branchcol[Args.String].Returns(l2branch);
        l2repo.Branches.Returns(l2branchcol);
        l2repo.Head.Returns(l2branch);
        gitService.GetRepository(Args.String).Returns(l2repo);
        return l2repo;
    }
    static LibGit2Sharp.IRepository SetupLocalRepoMock(IGitClient gitClient, IGitService gitService, string remote, string head, bool isTracking)
    {
        var l2remote = Substitute.For <LibGit2Sharp.Remote>();

        l2remote.Name.Returns(remote);
        gitClient.GetHttpRemote(Args.LibGit2Repo, Args.String).Returns(Task.FromResult(l2remote));

        var l2repo      = Substitute.For <LibGit2Sharp.IRepository>();
        var l2branchcol = Substitute.For <LibGit2Sharp.BranchCollection>();
        var l2branch    = Substitute.For <LibGit2Sharp.Branch>();

        l2branch.FriendlyName.Returns(head);
        l2branch.IsTracking.Returns(isTracking);
        l2branchcol[Args.String].Returns(l2branch);
        l2repo.Branches.Returns(l2branchcol);
        l2repo.Head.Returns(l2branch);
        gitService.GetRepository(Args.String).Returns(l2repo);
        return(l2repo);
    }