MCPcopy Create free account
hub / github.com/angular/dev-infra / checkOutPullRequestLocally

Function checkOutPullRequestLocally

ng-dev/pr/common/checkout-pr.ts:65–139  ·  view source on GitHub ↗
(
  prNumber: number,
  opts: PullRequestCheckoutOptions = {},
)

Source from the content-addressed store, hash-verified

63 * to modify a pull request. Skipped if `allowIfMaintainerCannotModify` is set.
64 */
65export async function checkOutPullRequestLocally(
66 prNumber: number,
67 opts: PullRequestCheckoutOptions = {},
68) {
69 /** The singleton instance of the authenticated git client. */
70 const git = await AuthenticatedGitClient.get();
71
72 // In order to preserve local changes, checkouts cannot occur if local changes are present in the
73 // git environment. Checked before retrieving the PR to fail fast.
74 if (git.hasUncommittedChanges()) {
75 throw new UnexpectedLocalChangesError('Unable to checkout PR due to uncommitted changes.');
76 }
77
78 /**
79 * The branch or revision originally checked out before this method performed
80 * any Git operations that may change the working branch.
81 */
82 const previousBranchOrRevision = git.getCurrentBranchOrRevision();
83 /** The PR information from Github. */
84 const pr = await getPr(PR_SCHEMA, prNumber, git);
85
86 if (pr === null) {
87 throw new PullRequestNotFoundError(`Pull request #${prNumber} could not be found.`);
88 }
89
90 /** The branch name of the PR from the repository the PR came from. */
91 const headRefName = pr.headRef.name;
92 /** The full URL path of the repository the PR came from with github token as authentication. */
93 const headRefUrl = addTokenToGitHttpsUrl(pr.headRef.repository.url, git.githubToken);
94 // Note: Since we use a detached head for rebasing the PR and therefore do not have
95 // remote-tracking branches configured, we need to set our expected ref and SHA. This
96 // allows us to use `--force-with-lease` for the detached head while ensuring that we
97 // never accidentally override upstream changes that have been pushed in the meanwhile.
98 // See:
99 // https://git-scm.com/docs/git-push#Documentation/git-push.txt---force-with-leaseltrefnamegtltexpectgt
100 /** Flag for a force push with lease back to upstream. */
101 const forceWithLeaseFlag = `--force-with-lease=${headRefName}:${pr.headRefOid}`;
102 const escapedHeadRefName = `'${headRefName.replace(/'/g, "'\\''")}'`;
103 const escapedForceWithLeaseFlag = `--force-with-lease=${escapedHeadRefName}:${pr.headRefOid}`;
104
105 // If the PR does not allow maintainers to modify it, exit as the rebased PR cannot
106 // be pushed up.
107 if (!pr.maintainerCanModify && !pr.viewerDidAuthor && !opts.allowIfMaintainerCannotModify) {
108 throw new MaintainerModifyAccessError('PR is not set to allow maintainers to modify the PR');
109 }
110
111 try {
112 // Fetch the branch at the commit of the PR, and check it out in a detached state.
113 git.run(['fetch', '-q', headRefUrl, '--', headRefName]);
114 git.run(['checkout', '--detach', 'FETCH_HEAD']);
115 } catch (e) {
116 git.checkout(previousBranchOrRevision, true);
117 throw e;
118 }
119
120 return {
121 /**
122 * Pushes the current local branch to the PR on the upstream repository.

Callers 1

checkoutPullRequestFunction · 0.85

Calls 8

getPrFunction · 0.85
addTokenToGitHttpsUrlFunction · 0.85
upstreamUrlToPushFunction · 0.85
hasUncommittedChangesMethod · 0.80
checkoutMethod · 0.80
getMethod · 0.45
runMethod · 0.45

Tested by

no test coverage detected