Пример #1
0
        public void CreateBranchForPullRequestBranch(AuthenticationInfo auth)
        {
            RepositoryExtensions.RunSafe(() =>
            {
                var network = repositoryInstance.Network;
                var remote  = network.Remotes.Single();

                log.Info("Fetching remote refs to see if there is a pull request ref");
                var credentialsProvider = GetCredentialsProvider(auth);
                var remoteTips          = (credentialsProvider != null
                        ? network.ListReferences(remote, credentialsProvider)
                        : network.ListReferences(remote))
                                          .Select(r => r.ResolveToDirectReference()).ToList();

                log.Info($"Remote Refs:{System.Environment.NewLine}" + string.Join(System.Environment.NewLine, remoteTips.Select(r => r.CanonicalName)));

                var headTipSha = Head.Tip?.Sha;

                var refs = remoteTips.Where(r => r.TargetIdentifier == headTipSha).ToList();

                if (refs.Count == 0)
                {
                    var message = $"Couldn't find any remote tips from remote '{remote.Url}' pointing at the commit '{headTipSha}'.";
                    throw new WarningException(message);
                }

                if (refs.Count > 1)
                {
                    var names   = string.Join(", ", refs.Select(r => r.CanonicalName));
                    var message = $"Found more than one remote tip from remote '{remote.Url}' pointing at the commit '{headTipSha}'. Unable to determine which one to use ({names}).";
                    throw new WarningException(message);
                }

                var reference     = refs.First();
                var canonicalName = reference.CanonicalName;
                var referenceName = ReferenceName.Parse(reference.CanonicalName);
                log.Info($"Found remote tip '{canonicalName}' pointing at the commit '{headTipSha}'.");

                if (referenceName.IsTag)
                {
                    log.Info($"Checking out tag '{canonicalName}'");
                    Checkout(reference.Target.Sha);
                }
                else if (referenceName.IsPullRequest)
                {
                    var fakeBranchName = canonicalName.Replace("refs/pull/", "refs/heads/pull/").Replace("refs/pull-requests/", "refs/heads/pull-requests/");

                    log.Info($"Creating fake local branch '{fakeBranchName}'.");
                    Refs.Add(fakeBranchName, headTipSha);

                    log.Info($"Checking local branch '{fakeBranchName}' out.");
                    Checkout(fakeBranchName);
                }
                else
                {
                    var message = $"Remote tip '{canonicalName}' from remote '{remote.Url}' doesn't look like a valid pull request.";
                    throw new WarningException(message);
                }
            });
        }
Пример #2
0
        private static void EnsureLocalBranchExistsForCurrentBranch(IGitRepository repo, ILog log, IRemote remote, string currentBranch)
        {
            if (log is null)
            {
                throw new ArgumentNullException(nameof(log));
            }

            if (remote is null)
            {
                throw new ArgumentNullException(nameof(remote));
            }

            if (string.IsNullOrEmpty(currentBranch))
            {
                return;
            }

            var isRef              = currentBranch.Contains("refs");
            var isBranch           = currentBranch.Contains("refs/heads");
            var localCanonicalName = !isRef
                ? "refs/heads/" + currentBranch
                : isBranch
                    ? currentBranch
                    : currentBranch.Replace("refs/", "refs/heads/");

            var repoTip = repo.Head.Tip;

            // We currently have the rep.Head of the *default* branch, now we need to look up the right one
            var originCanonicalName = $"{remote.Name}/{currentBranch}";
            var originBranch        = repo.Branches[originCanonicalName];

            if (originBranch != null)
            {
                repoTip = originBranch.Tip;
            }

            var repoTipId = repoTip.Id;

            var referenceName = ReferenceName.Parse(localCanonicalName);

            if (repo.Branches.All(b => !b.Name.Equals(referenceName)))
            {
                log.Info(isBranch ? $"Creating local branch {referenceName}"
                    : $"Creating local branch {referenceName} pointing at {repoTipId}");
                repo.Refs.Add(localCanonicalName, repoTipId.Sha);
            }
            else
            {
                log.Info(isBranch ? $"Updating local branch {referenceName} to point at {repoTip}"
                    : $"Updating local branch {referenceName} to match ref {currentBranch}");
                var localRef = repo.Refs[localCanonicalName];
                repo.Refs.UpdateTarget(localRef, repoTipId);
            }

            repo.Checkout(localCanonicalName);
        }
Пример #3
0
        private static void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(IGitRepository repo, ILog log, string remoteName)
        {
            var prefix = $"refs/remotes/{remoteName}/";
            var remoteHeadCanonicalName  = $"{prefix}HEAD";
            var headReferenceName        = ReferenceName.Parse(remoteHeadCanonicalName);
            var remoteTrackingReferences = repo.Refs
                                           .FromGlob(prefix + "*")
                                           .Where(r => !r.Name.Equals(headReferenceName));

            foreach (var remoteTrackingReference in remoteTrackingReferences)
            {
                var remoteTrackingReferenceName = remoteTrackingReference.Name.Canonical;
                var branchName         = remoteTrackingReferenceName.Substring(prefix.Length);
                var localCanonicalName = "refs/heads/" + branchName;

                var referenceName = ReferenceName.Parse(localCanonicalName);
                // We do not want to touch our current branch
                if (repo.Head.Name.EquivalentTo(branchName))
                {
                    continue;
                }

                if (repo.Refs.Any(x => x.Name.Equals(referenceName)))
                {
                    var localRef = repo.Refs[localCanonicalName];
                    if (localRef.DirectReferenceTargetIdentifier == remoteTrackingReference.DirectReferenceTargetIdentifier)
                    {
                        log.Info($"Skipping update of '{remoteTrackingReference.Name.Canonical}' as it already matches the remote ref.");
                        continue;
                    }
                    var remoteRefTipId = remoteTrackingReference.DirectReferenceTargetId;
                    log.Info($"Updating local ref '{localRef.Name.Canonical}' to point at {remoteRefTipId}.");
                    repo.Refs.UpdateTarget(localRef, remoteRefTipId);
                    continue;
                }

                log.Info($"Creating local branch from remote tracking '{remoteTrackingReference.Name.Canonical}'.");
                repo.Refs.Add(localCanonicalName, remoteTrackingReference.DirectReferenceTargetIdentifier, true);

                var branch = repo.Branches[branchName];
                repo.Branches.UpdateTrackedBranch(branch, remoteTrackingReferenceName);
            }
        }
Пример #4
0
        private void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(string remoteName)
        {
            var prefix = $"refs/remotes/{remoteName}/";
            var remoteHeadCanonicalName  = $"{prefix}HEAD";
            var headReferenceName        = ReferenceName.Parse(remoteHeadCanonicalName);
            var remoteTrackingReferences = repository.Refs
                                           .FromGlob(prefix + "*")
                                           .Where(r => !r.Name.Equals(headReferenceName));

            foreach (var remoteTrackingReference in remoteTrackingReferences)
            {
                var remoteTrackingReferenceName = remoteTrackingReference.Name.Canonical;
                var branchName         = remoteTrackingReferenceName.Substring(prefix.Length);
                var localCanonicalName = "refs/heads/" + branchName;

                var referenceName = ReferenceName.Parse(localCanonicalName);
                // We do not want to touch our current branch
                if (repository.Head.Name.EquivalentTo(branchName))
                {
                    continue;
                }

                if (repository.Refs.Any(x => x.Name.Equals(referenceName)))
                {
                    var localRef = repository.Refs[localCanonicalName];
                    if (localRef.TargetIdentifier == remoteTrackingReference.TargetIdentifier)
                    {
                        log.Info($"Skipping update of '{remoteTrackingReference.Name.Canonical}' as it already matches the remote ref.");
                        continue;
                    }
                    var remoteRefTipId = remoteTrackingReference.ReferenceTargetId;
                    log.Info($"Updating local ref '{localRef.Name.Canonical}' to point at {remoteRefTipId}.");
                    new OperationWithExponentialBackoff <LockedFileException>(new ThreadSleep(), log, () => repository.Refs.UpdateTarget(localRef, remoteRefTipId)).ExecuteAsync().Wait();
                    continue;
                }

                log.Info($"Creating local branch from remote tracking '{remoteTrackingReference.Name.Canonical}'.");
                repository.Refs.Add(localCanonicalName, remoteTrackingReference.TargetIdentifier, true);

                var branch = repository.Branches[branchName];
                repository.Branches.UpdateTrackedBranch(branch, remoteTrackingReferenceName);
            }
        }