Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save kellyselden/48e5798e48009d8431d6a898b8d7c923 to your computer and use it in GitHub Desktop.
Save kellyselden/48e5798e48009d8431d6a898b8d7c923 to your computer and use it in GitHub Desktop.
node delete-remote-tags-missing-from-local origin
'use strict';
const fs = require('fs').promises;
const { spawn } = require('child_process');
async function waitForEnd(process) {
let stderr = '';
process.stderr.on('data', data => {
stderr += data.toString();
});
await new Promise(resolve => {
process.on('exit', resolve);
});
if (process.exitCode) {
throw new Error(stderr);
}
}
async function getRemoteTags({
remote,
cwd,
}) {
let process = spawn('git', ['ls-remote', '--tags', remote], {
cwd,
});
let stdout = '';
process.stdout.on('data', data => {
stdout += data.toString();
});
await waitForEnd(process);
let lines = stdout.split(/\r?\n/);
let tags = lines.reduce((tags, line) => {
let match = line.match(/\w{40}\trefs\/tags\/(.+)\^\{\}*/);
if (match) {
tags.push(match[1]);
}
return tags;
}, []);
return tags;
}
function difference(setA, setB) {
let _difference = new Set(setA);
for (let elem of setB) {
_difference.delete(elem);
}
return [..._difference];
}
async function getLocalTags({
cwd,
}) {
let process = spawn('git', ['tag'], {
cwd,
});
let stdout = '';
process.stdout.on('data', data => {
stdout += data.toString();
});
await waitForEnd(process);
let tags = stdout.split(/\r?\n/);
return tags;
}
async function run({
remote,
cwd = process.cwd(),
} = {}) {
let localTagsPromise = getLocalTags({
cwd,
});
let remoteTagsPromise = getRemoteTags({
remote,
cwd,
});
let [
localTags,
remoteTags,
] = await Promise.all([
localTagsPromise,
remoteTagsPromise,
]);
let remoteTagsToRemove = difference(remoteTags, localTags);
if (!remoteTagsToRemove.length) {
console.log('nothing to do');
return;
}
let deleteProcess = spawn('git', ['push', remote, '-d', ...remoteTagsToRemove], {
cwd,
});
deleteProcess.stdout.pipe(process.stdout);
deleteProcess.stderr.pipe(process.stderr);
await waitForEnd(deleteProcess);
}
(async () => {
await run({
remote: process.argv[2],
});
})();
// https://medium.com/@dtinth/making-unhandled-promise-rejections-crash-the-node-js-process-ffc27cfcc9dd
process.on('unhandledRejection', (up) => {
throw up;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment