Skip to content

Instantly share code, notes, and snippets.

@juristr
Created June 16, 2023 17:12
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save juristr/9ba9dc4ae990382a62b4ddcfac36209e to your computer and use it in GitHub Desktop.
Save juristr/9ba9dc4ae990382a62b4ddcfac36209e to your computer and use it in GitHub Desktop.
...
[alias]
rb = !sh -c 'node ~/bin/recbranch.js'
...
/* don't look at code quality, AI generated */
const { exec } = require('child_process');
const readline = require('readline');
// ANSI escape sequences for text formatting
const ANSI = {
RESET: '\x1b[0m',
BOLD: '\x1b[1m',
REVERSE: '\x1b[7m',
};
function getGitBranches(callback) {
exec('git branch --sort=-committerdate --format="%(refname:short)" --list | head -n 10', (error, stdout) => {
if (error) {
console.error(`Error executing git command: ${error.message}`);
return;
}
const branches = stdout
.split('\n')
.filter((branch) => branch.trim() !== '')
.map((branch) => branch.trim());
callback(branches);
});
}
function chooseBranch(branches) {
return new Promise((resolve, reject) => {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: true,
});
let currentRow = 0;
const handleKeyPress = (line, key) => {
if (key.name === 'up') {
// Up arrow key
currentRow = Math.max(currentRow - 1, 0);
render();
} else if (key.name === 'down') {
// Down arrow key
currentRow = Math.min(currentRow + 1, branches.length - 1);
render();
} else if (key.name === 'return') {
// Enter key
clearConsole();
resolve(branches[currentRow]);
rl.close();
}
};
const render = () => {
clearConsole();
process.stdout.write('Select a branch (Use arrow keys to navigate, Enter to select):\n\n');
branches.forEach((branch, index) => {
const prefix = index === currentRow ? `=> ${ANSI.BOLD}${branch}${ANSI.RESET}` : ` ${branch}`;
const line = index === currentRow ? `${ANSI.REVERSE}${prefix}${ANSI.RESET}` : prefix;
process.stdout.write(`${line}\n`);
});
};
const clearConsole = () => {
readline.cursorTo(process.stdout, 0, 0);
readline.clearScreenDown(process.stdout);
};
process.stdin.setRawMode(true);
process.stdin.resume();
readline.emitKeypressEvents(process.stdin);
process.stdin.on('keypress', handleKeyPress);
rl.on('close', () => {
reject(new Error('Selection cancelled'));
});
render();
});
}
function checkoutBranch(branch) {
return new Promise((resolve, reject) => {
exec(`git checkout ${branch}`, (error, stdout, stderr) => {
console.log(stdout);
resolve();
});
});
}
function main() {
getGitBranches((branches) => {
if (branches.length === 0) {
console.log('No branches found!');
return;
}
chooseBranch(branches)
.then((chosenBranch) => checkoutBranch(chosenBranch))
.catch((error) => {
console.error(error.message);
})
.finally(() => {
process.stdin.pause();
});
});
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment