Skip to content

Commit 661334a

Browse files
committed
feat(git-node): add limited support for cross-repo PRs
Node.js security patches are prepared on a separate repo, it can be useful to be able to run `git node land` without needing to touch the local config.
1 parent 5034b4f commit 661334a

File tree

2 files changed

+33
-9
lines changed

2 files changed

+33
-9
lines changed

lib/landing_session.js

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,28 @@ export default class LandingSession extends Session {
8282
}
8383

8484
async downloadAndPatch() {
85-
const { cli, upstream, prid, expectedCommitShas } = this;
85+
const { cli, upstream, prid, expectedCommitShas, crossRepoPR } = this;
86+
87+
if (crossRepoPR) {
88+
const { owner, repo } = this;
89+
let response;
90+
do {
91+
cli.warn(`The configured remote "${upstream}" does not point to the ` +
92+
'Pull Request repository.');
93+
cli.warn('We cannot fetch the commit(s) automatically, the user needs to fetch manually.');
94+
95+
cli.info('Run the following command to fetch the commit(s):');
96+
cli.info(`git fetch git@github.com:${owner}/${repo}.git refs/pull/${prid}/merge`);
97+
response = await cli.prompt('Ready to continue?', { defaultAnswer: false });
98+
} while (!response);
99+
cli.startSpinner('Parse fetched merge commit');
100+
} else {
101+
cli.startSpinner(`Downloading patch for ${prid}`);
102+
await runAsync('git', [
103+
'fetch', upstream,
104+
`refs/pull/${prid}/merge`]);
105+
}
86106

87-
cli.startSpinner(`Downloading patch for ${prid}`);
88-
await runAsync('git', [
89-
'fetch', upstream,
90-
`refs/pull/${prid}/merge`]);
91107
// We fetched the commit that would result if we used `git merge`.
92108
// ^1 and ^2 refer to the PR base and the PR head, respectively.
93109
const [base, head] = await runAsync('git',
@@ -472,7 +488,7 @@ export default class LandingSession extends Session {
472488
}
473489

474490
cli.separator();
475-
cli.log('The following commits are ready to be pushed to ' +
491+
cli.log('The following commits are landable on ' +
476492
`${upstream}/${branch}`);
477493
cli.log(`- ${strayVerbose.join('\n- ')}`);
478494
cli.separator();
@@ -483,8 +499,15 @@ export default class LandingSession extends Session {
483499
willBeLanded = `${head}...${willBeLanded}`;
484500
}
485501

502+
cli.startSpinner('Removing temporary files');
486503
this.cleanFiles();
487-
cli.log('Temporary files removed.');
504+
cli.stopSpinner('Temporary files removed.');
505+
if (this.crossRepoPR) {
506+
cli.warn(`The configured remote "${upstream}" does not point to the ` +
507+
'Pull Request repository.');
508+
cli.info(`${willBeLanded} should likely not be pushed to "${upstream}"`);
509+
return;
510+
}
488511
cli.log('To finish landing:');
489512
cli.log('1. Run: ');
490513
cli.log(` git push ${upstream} ${branch}`);

lib/session.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,11 @@ export default class Session {
3333
const upstreamHref = runSync('git', [
3434
'config', '--get',
3535
`remote.${upstream}.url`]).trim();
36-
if (!new RegExp(`${owner}/${repo}(?:.git)?$`).test(upstreamHref)) {
36+
if (!upstreamHref.endsWith(`${owner}/${repo}.git`) &&
37+
!upstreamHref.endsWith(`${owner}/${repo}`)) {
3738
cli.warn('Remote repository URL does not point to the expected ' +
3839
`repository ${owner}/${repo}`);
39-
cli.setExitCode(1);
40+
this.crossRepoPR = true;
4041
}
4142
}
4243
}

0 commit comments

Comments
 (0)