Skip to content

Instantly share code, notes, and snippets.

@jhmaster2000
Last active November 15, 2022 08:39
Show Gist options
  • Save jhmaster2000/9627b15d1c5b4234258ee1b1cd0afe32 to your computer and use it in GitHub Desktop.
Save jhmaster2000/9627b15d1c5b4234258ee1b1cd0afe32 to your computer and use it in GitHub Desktop.
GitCommitExtractor - Extracts every commit of a Git repository into folders of the repository at that commit's stage
// Usage:
// node --no-warnings --loader ts-node/esm gitcex.ts <REPOSITORY_GIT_URL>
// pass 'local' on <REPOSITORY_GIT_URL> to use an already fetched repository on ./repository folder.
//
//! WARNING: Very disk-intensive and disk space consuming for large repositories.
import fs from 'fs';
import { execSync as exec } from 'child_process';
const argv = process.argv.slice(2);
if (fs.existsSync('commits')) fs.rmSync('commits', { recursive: true });
fs.mkdirSync('commits');
const USE_LOCAL_REPO = argv[0] === 'local';
if (!USE_LOCAL_REPO) {
const REPOSITORY_URL = argv[0];
if (fs.existsSync('repository')) fs.rmSync('repository', { recursive: true });
exec(`git clone ${REPOSITORY_URL} repository`);
}
const gitlog = exec('git --no-pager log --no-merges --oneline', {
cwd: './repository'
}).toString('utf8').split('\n').slice(0, -1).map(commit => {
const [hash, ...msg] = commit.split(' ');
return [hash, msg.join(' ')];
});
for (const [hash, msg] of gitlog) {
console.log(`Extracting commit ${hash}: ${msg}`);
fs.cpSync(`./repository`, `./commits/${hash}`, { recursive: true });
exec(`git checkout ${hash}`, { cwd: `./commits/${hash}` });
const fullhash = exec(`git rev-parse ${hash}`, { cwd: `./repository` }).toString('utf8').trim();
fs.writeFileSync(`./commits/${hash}/commit.txt`, `${fullhash}\n${msg}\n`);
}
console.log(`${gitlog.length} commits extracted.`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment