Skip to content

Instantly share code, notes, and snippets.

@endquote
Last active March 2, 2017 15:29
Show Gist options
  • Select an option

  • Save endquote/ead21f78b83901563ff3 to your computer and use it in GitHub Desktop.

Select an option

Save endquote/ead21f78b83901563ff3 to your computer and use it in GitHub Desktop.
Migrate private repositories from your GitHub organization to your Bitbucket team.
/*
To use:
* save this script as migrate.js
* fill in the user/pass variables at the top
* save the block of json below as package.json right next to it
* install node.js from nodejs.org
* run 'npm install' from the directory where you saved the files
* run 'node migrate.js'
* profit
{
"dependencies": {
"async": "^0.9.0",
"fs.extra": "^1.3.2",
"github": "^0.2.4",
"request": "^2.55.0",
"underscore": "^1.8.3"
}
}
*/
var GitHubApi = require('github');
var request = require('request');
var child_process = require('child_process');
var async = require('async');
var fs = require('fs.extra');
var path = require('path');
var _ = require('underscore');
// fill in this stuff
var githubUser = '';
var githubPass = '';
var githubOrg = '';
var bitbucketUser = '';
var bitbucketPass = '';
var bitbucketTeam = '';
var checkoutDir = 'git';
var threads = 10;
var github = new GitHubApi({
version: '3.0.0'
});
async.waterfall([
// Wipe out previous checkouts
function(callback) {
fs.rmrf(checkoutDir, callback);
},
// Make a directory to check out to
function(callback) {
fs.mkdir(checkoutDir, 0777, callback);
},
// Auth to GitHub
function(callback) {
github.authenticate({
type: 'basic',
username: githubUser,
password: githubPass
});
callback();
},
// Get the list of repositories
function(callback) {
github.repos.getFromOrg({
org: githubOrg,
type: 'all',
per_page: 100
}, callback);
},
], function(error, data) {
// Ignore public repos, they can stay on GitHub.
var repos = _.filter(data, function(repo) {
return repo.private;
});
console.log(repos.length + ' repositories found.');
async.eachLimit(repos, threads, function(item, callback) {
var index = repos.indexOf(item) + 1;
var prompt = index + '/' + repos.length + ' - ' + item.name + ' - ';
async.waterfall([
// Clone the repo from GitHub
function(callback) {
console.info(prompt + 'cloning from GitHub');
child_process.exec('git clone --mirror ' + item.clone_url, {
cwd: path.join(__dirname, checkoutDir)
}, function(error, stdout, stderr) {
callback(error);
});
},
// Set the new remote
function(callback) {
console.info(prompt + 'setting remote ');
var remote = 'https://' + bitbucketUser + '@bitbucket.org/' + bitbucketTeam + '/' + item.name + '.git';
child_process.exec('git remote set-url --push origin ' + remote, {
cwd: path.join(__dirname, checkoutDir, item.name + '.git')
}, function(error, stdout, stderr) {
callback(error);
});
},
// Delete the Bitbucket repo if it exists.
function(callback) {
console.info(prompt + 'deleting Bitbucket repo');
request
.del('https://bitbucket.org/api/2.0/repositories/' + bitbucketTeam + '/' + item.name.toLowerCase(), function(error, response, body) {
callback();
})
.auth(bitbucketUser, bitbucketPass);
},
// Create the new Bitbucket repo.
function(callback) {
console.info(prompt + 'creating Bitbucket repo');
request
.post('https://bitbucket.org/api/2.0/repositories/' + bitbucketTeam + '/' + item.name.toLowerCase(), function(error, response, body) {
body = JSON.parse(body);
error = body.error;
callback(error);
})
.form({
name: item.name,
description: item.description,
is_private: true,
scm: 'git',
has_issues: false,
has_wiki: false
})
.auth(bitbucketUser, bitbucketPass);
},
// Push the repo to Bitbucket
function(callback) {
console.info(prompt + 'pushing to Bitbucket');
child_process.exec('git push --mirror', {
cwd: path.join(__dirname, checkoutDir, item.name + '.git')
}, function(error, stdout, stderr) {
callback(error);
});
},
// Delete the checkout
function(callback) {
console.info(prompt + 'deleting clone');
fs.rmrf(path.join(__dirname, checkoutDir, item.name + '.git'), function(error) {
callback(error)
});
}
], function(error, result) {
// Go on to the next one
if (error) {
console.error(prompt + error);
} else {
callback();
}
});
});
});
@fro
Copy link
Copy Markdown

fro commented Apr 30, 2015

Great job, useful stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment