Skip to content

Instantly share code, notes, and snippets.

@mistic100
Last active August 29, 2015 14:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mistic100/017a848ff619f0624dde to your computer and use it in GitHub Desktop.
Save mistic100/017a848ff619f0624dde to your computer and use it in GitHub Desktop.
[Node] Batch conversion of SVN directories to Git repositories

Requirements

  • node
  • npm
  • svn
  • git
  • git-svn

Usage

  1. npm install
  2. Create empty repositories on Github
  3. Fill the repositories and credentials objects
  4. Run node piwigo-svn2github.js
  5. Update authors.txt file
  6. Run node piwigo-svn2github.js again
{
"name": "piwigo-svn2github",
"version": "0.0.1",
"author": "Damien \"Mistic\" Sorel <contact@git.strangeplanet.fr>",
"main": "piwigo-svn2github",
"dependencies": {
"underscore": "latest"
}
}
var _ = require('underscore'),
fs = require('fs'),
EventEmitter = require('events').EventEmitter,
spawn = require('child_process').spawn;
var credentials = {
username: 'USERNAME',
password: 'PASSWORD'
};
// WARNING : password will be printed in the console output
// set ghRoot to 'https://' + credentials.username + '@github.com/' to avoid it
// but you will be asked for your password for each push
var ghRoot = 'https://' + credentials.username + ':' + credentials.password + '@github.com/',
svnRoot = 'http://piwigo.org/svn/extensions/';
var repositories = {
'BatchDownloader': [svnRoot + 'BatchDownloader', ghRoot + 'mistic100/Piwigo-BatchDownloader'],
'User Collections': [svnRoot + 'UserCollections', ghRoot + 'mistic100/Piwigo-User-Collections']
};
var known_authors = {
'TranslationTeam': 'Piwigo-TranslationTeam <translate-github@piwigo.org>',
'plg': 'plegall <plg@piwigo.org>',
'mistic100': 'mistic100 <mistic@piwigo.org>'
};
var sequentialExec = new function() {
this.processes = [];
this.add = function(msg, func, attrs) {
this.processes.push({
msg: msg,
func: func,
attrs: attrs
})
};
this.run = function() {
var process = this.processes.shift();
if (process === undefined) {
return;
}
if (process.msg !== null) {
console.log('\n== ' + process.msg + ' ==');
}
var proc = process.func.apply(null, process.attrs);
proc.on('exit', this.run.bind(this));
};
};
if (!fs.existsSync('authors.txt')) {
console.log('== About to create authors file ==');
var authors = {};
_.each(repositories, function(url, id) {
sequentialExec.add('Read ' + id + ' log', function(url, id) {
var proc = spawn('svn', ['log', '--quiet', url[0]]);
proc.stdout.on('data', function(data) {
_.each(data.toString().trim().split('\n'), function(line) {
if (/^r/.test(line)) {
var author = line.split(' | ')[1].trim();
authors[author] = true;
}
});
});
return proc;
}, [url, id]);
});
sequentialExec.add('Create authors.txt', function() {
console.log(authors);
var authors_file = '';
_.each(authors, function(yes, author) {
if (known_authors[author]) {
authors_file+= author + ' = ' + known_authors[author] + '\n';
}
else {
authors_file+= author + ' = ' + author + ' <' + author + '@piwigo.org>\n';
}
});
var proc = new EventEmitter();
fs.writeFile('authors.txt', authors_file, function() {
console.log('-- authors.txt created. Update it and re-run the script.');
proc.emit('exit');
});
return proc;
}, []);
}
else {
console.log('== Begin conversion ==');
_.each(repositories, function(url, id) {
sequentialExec.add('Clone ' + id, function(url, id) {
return spawn('git', ['svn', 'clone', '--authors-file=authors.txt', url[0], id], { stdio: 'inherit' });
}, [url, id]);
sequentialExec.add(null, function(url, id) {
return spawn('git', ['--git-dir=' + id + '/.git', '--work-tree=' + id + '', 'remote', 'add', 'origin', url[1]], { stdio: 'inherit' });
}, [url, id]);
sequentialExec.add('Push ' + id, function(url, id) {
return spawn('git', ['--git-dir=' + id + '/.git', '--work-tree=' + id + '', 'push', '-u', 'origin', '--all'], { stdio: 'inherit' });
}, [url, id]);
});
}
sequentialExec.run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment