Skip to content

Instantly share code, notes, and snippets.

@bvaughn
Last active January 4, 2021 20:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bvaughn/4223f511668a42c08ea60d6dfddeb1bb to your computer and use it in GitHub Desktop.
Save bvaughn/4223f511668a42c08ea60d6dfddeb1bb to your computer and use it in GitHub Desktop.
Utility to checkout a remote fork and branch from a GitHub PR
#!/usr/bin/env node
'use strict';
const { exec, execSync } = require('child_process');
const args = process.argv[0] === 'node'
? process.argv.slice(1)
: process.argv.slice(2);
const firstArg = args[0];
if (firstArg === '--help' || firstArg === '-h') {
console.log('Quickly checkout a Git branch from a fork.')
console.log("\x1b[2m", '\n # Short hand format; paste string from GitHub PR copy button:', "\x1b[0m");
console.log(' git-fork username:branch-name');
console.log("\x1b[2m", '\n # Long hand format; specify user, repo, and (optionally) branch name:', "\x1b[0m");
console.log(' git-fork username repo [optional-branch-name]');
process.exit(0);
}
let user, repo, branch;
if (firstArg.includes(':')) {
// Shorthand from clicking GitHub's copy button.
// e.g. "username:branch-name"
let result = firstArg.split(':');
user = result[0];
branch = result[1];
result = execSync('git config --get remote.origin.url').toString();
result = result.match(/\/(.+)\.git/);
repo = result[1];
} else {
// Long form.
// e.g. "git-fork user repo optional-branch"
user = args[0];
repo = args[1];
branch = args[2];
}
function noop() {}
async function logAndExec(command) {
console.log(command);
return new Promise((resolve, reject) =>
exec(command, error => {
if (!error) {
resolve();
} else {
reject(error);
}
})
);
}
async function main() {
try {
await logAndExec(`git remote add ${user} git@github.com:${user}/${repo}.git`);
} catch (error) {
if (!error.message.includes(`remote ${user} already exists`)) {
throw error;
}
}
await logAndExec(`git fetch ${user}`);
if (branch) {
try {
await logAndExec(`git checkout -b ${user}-${branch} ${user}/${branch}`);
} catch (error) {
if (error.message.includes(`branch named '${user}-${branch}' already exists`)) {
await logAndExec(`git checkout ${user}-${branch}`);
} else {
throw error;
}
}
await logAndExec(`git pull ${user} ${branch}`);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment