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 {localCanonicalName}" : $"Creating local branch {localCanonicalName} pointing at {repoTipId}"); repo.Refs.Add(localCanonicalName, repoTipId.Sha); } else { log.Info(isBranch ? $"Updating local branch {localCanonicalName} to point at {repoTip}" : $"Updating local branch {localCanonicalName} to match ref {currentBranch}"); var localRef = repo.Refs[localCanonicalName]; repo.Refs.UpdateTarget(localRef, repoTipId); } repo.Checkout(localCanonicalName); }
public void EnsureLocalBranchExistsForCurrentBranch(IRemote?remote, string?currentBranch) { remote.NotNull(); if (currentBranch.IsNullOrEmpty()) { 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 = this.repository.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 = this.repository.Branches[originCanonicalName]; if (originBranch != null) { repoTip = originBranch.Tip; } var repoTipId = repoTip?.Id; if (repoTipId != null) { var referenceName = ReferenceName.Parse(localCanonicalName); if (this.repository.Branches.All(b => !b.Name.Equals(referenceName))) { this.log.Info(isBranch ? $"Creating local branch {referenceName}" : $"Creating local branch {referenceName} pointing at {repoTipId}"); this.repository.Refs.Add(localCanonicalName, repoTipId.Sha); } else { this.log.Info(isBranch ? $"Updating local branch {referenceName} to point at {repoTipId}" : $"Updating local branch {referenceName} to match ref {currentBranch}"); var localRef = this.repository.Refs[localCanonicalName]; if (localRef != null) { this.retryAction.Execute(() => this.repository.Refs.UpdateTarget(localRef, repoTipId)); } } } Checkout(localCanonicalName); }
private void CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(string remoteName) { var prefix = $"refs/remotes/{remoteName}/"; var remoteHeadCanonicalName = $"{prefix}HEAD"; var headReferenceName = ReferenceName.Parse(remoteHeadCanonicalName); var remoteTrackingReferences = this.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 localReferenceName = ReferenceName.FromBranchName(branchName); // We do not want to touch our current branch if (this.repository.Head.Name.EquivalentTo(branchName)) { continue; } var localRef = this.repository.Refs[localReferenceName]; if (localRef != null) { if (localRef.TargetIdentifier == remoteTrackingReference.TargetIdentifier) { this.log.Info($"Skipping update of '{remoteTrackingReference.Name.Canonical}' as it already matches the remote ref."); continue; } var remoteRefTipId = remoteTrackingReference.ReferenceTargetId; if (remoteRefTipId != null) { this.log.Info($"Updating local ref '{localRef.Name.Canonical}' to point at {remoteRefTipId}."); this.retryAction.Execute(() => this.repository.Refs.UpdateTarget(localRef, remoteRefTipId)); } continue; } this.log.Info($"Creating local branch from remote tracking '{remoteTrackingReference.Name.Canonical}'."); this.repository.Refs.Add(localReferenceName.Canonical, remoteTrackingReference.TargetIdentifier, true); var branch = this.repository.Branches[branchName]; if (branch != null) { this.repository.Branches.UpdateTrackedBranch(branch, remoteTrackingReferenceName); } } }
public void CreateBranchForPullRequestBranch(AuthenticationInfo auth) => RepositoryExtensions.RunSafe(() => { this.log.Info("Fetching remote refs to see if there is a pull request ref"); // FIX ME: What to do when Tip is null? if (Head.Tip == null) { return; } var headTipSha = Head.Tip.Sha; var remote = RepositoryInstance.Network.Remotes.Single(); var reference = GetPullRequestReference(auth, remote, headTipSha); var canonicalName = reference.CanonicalName; var referenceName = ReferenceName.Parse(reference.CanonicalName); this.log.Info($"Found remote tip '{canonicalName}' pointing at the commit '{headTipSha}'."); if (referenceName.IsTag) { this.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/"); this.log.Info($"Creating fake local branch '{fakeBranchName}'."); Refs.Add(fakeBranchName, headTipSha); this.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); } });