Skip to content

Instantly share code, notes, and snippets.

@andreifecioru
Last active July 7, 2019 09:58
Show Gist options
  • Save andreifecioru/cf59a19899abbc1d72b0c49392f0789e to your computer and use it in GitHub Desktop.
Save andreifecioru/cf59a19899abbc1d72b0c49392f0789e to your computer and use it in GitHub Desktop.
Migrating git repos to GitHub
#!/usr/bin/env python
import sys
import sh
import json
import requests
from optparse import OptionParser
from contextlib import contextmanager
@contextmanager
def working_dir(path):
cwd = str(sh.pwd()).strip()
sh.cd(path)
yield path
sh.cd(cwd)
def migrate(migration, user, token):
def parse_repo(repo):
(host, name ) = repo.split(':')
(group, name) = name.split('/')
short_name = name.split('.git')[0]
return {
'host': host,
'group': group,
'name': name,
'short_name': short_name,
'full_name': repo
}
(src, dest) = [repo.strip() for repo in migration.split('>>')]
print('Migrating: \n from: {}\n to: {}'.format(src, dest))
try:
src = parse_repo(src)
dest = parse_repo(dest)
except Exception:
print('Error parsing repo file')
sys.exit(1)
print('Getting the code from GilLab')
sh.git('clone', '--mirror', src['full_name'])
with working_dir(src['name']):
print('Creating new repo on GitHub: {}'.format(dest['short_name']))
r = requests.post('https://api.github.com/user/repos',
auth=(user, token),
data=json.dumps({'name': dest['short_name'], 'private': True}))
if 200 <= r.status_code < 300:
print('Repo successfully created')
else:
print('Failed to create repo. ({})'.format(r.status_code))
print('Server says: {}'.format(r.text))
print('Uploading repo to GitHub')
sh.git('push', '--no-verify', '--mirror', dest['full_name'])
sh.rm('-rf', src['short_name'])
if __name__ == '__main__':
parser = OptionParser()
parser.add_option("-u", "--user", dest="user",
help="GitHub user name", metavar="USER")
parser.add_option("-t", "--token", dest="token",
help="GitHub API token", metavar="TOKEN")
parser.add_option("-f", "--file", dest="repo_file",
help="file with the list of repos", metavar="FILE")
(options, args) = parser.parse_args()
if not options.repo_file:
parser.error('Must provide a repo file')
if not options.user:
parser.error('Must provide a GitHub user')
if not options.token:
parser.error('Must provide a GitHub API token')
with open(options.repo_file) as f:
migrations = [line.strip() for line in f.readlines() if line]
[migrate(migration, options.user, options.token)
for migration in migrations]
git@gitlab.example.com:group/repo.git >> git@github.com:user/repo.git
git@gitlab.example.com:another-group/another-repo.git >> git@github.com:user/another-repo.git
./migrate_to_github.py -f repos.txt -u <github-user> -t <github-api-token>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment