-
-
Save squibobblepants/4995065 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################################################################## | |
# | |
# Copyright (c) 2012 Zope Foundation and Contributors. | |
# All Rights Reserved. | |
# | |
# This software is subject to the provisions of the Zope Public License, | |
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. | |
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED | |
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS | |
# FOR A PARTICULAR PURPOSE. | |
# | |
############################################################################## | |
"""%prog [options] subversion_url | |
svn to git conversion helper | |
Based loosely on the svn2git ruby tool. | |
You must have git and the svn git plugin installed. | |
A repository directory will be created with a name derived from the | |
subversion URL. | |
The subversion URL must point to a subversion project with a standard | |
layout, with trunk, branches, and tags. | |
""" | |
import optparse | |
parser = optparse.OptionParser(__doc__) | |
githelp=""" | |
Create a github repository. The argument is a string of the form | |
DEST/token. where DEST is either 'users/USERNAME' or 'orgs/ORGNAME' and | |
token is a github OAuth token: | |
https://help.github.com/articles/creating-an-oauth-token-for-command-line-use | |
curl must be installed if you use this. | |
""" | |
bitbuckethelp=""" | |
Create a bitbucket repository. The argument is a string of the form | |
user/password | |
Where user is either your username or the organisation user name. | |
curl must be installed if you use this. | |
""" | |
parser.add_option('--github', '-g', help=githelp) | |
parser.add_option('--bitbucket', '-b', help=bitbuckethelp) | |
parser.add_option('--private', '-p', action='store_true', | |
help="Create a private repository (bitbucket only currently)") | |
parser.add_option('--restart', '-r', action='store_true', | |
help="Restart after fetch times out") | |
parser.add_option( | |
'--authors', '-a', | |
help = 'Path to authors.txt file (required)') | |
import os | |
import sys | |
import xml.etree.ElementTree | |
def s(command): | |
print 'Running command:', command | |
if os.system(command): | |
raise SystemError | |
def r(command): | |
f = os.popen(command) | |
result = f.read() | |
f.close() | |
return result | |
def main(args=None): | |
if args is None: | |
args = sys.argv[1:] | |
options, args = parser.parse_args(args) | |
url, = args | |
if url.endswith('/'): | |
url = url[:-1] | |
name = url.rsplit('/', 1)[1] | |
if options.private and options.github: | |
raise NotImplementedError( | |
"Currently only --bitbucket supports --private") | |
if not options.restart: | |
os.mkdir(name) | |
os.chdir(name) | |
if not options.restart: | |
s('git svn init --no-metadata -s %s' % url) | |
assert options.authors | |
s('git config svn.authorsfile %s' % options.authors) | |
s('git svn fetch') | |
for tag in r('svn ls %s/tags' % url).strip().split(): | |
if tag[-1] == '/': | |
tag = tag[:-1] | |
f = os.popen('svn log --xml -l1 %s/tags/%s' % (url, tag)) | |
date = xml.etree.ElementTree.ElementTree( | |
file=f).find('logentry').find('date').text | |
f.close() | |
s("GIT_COMMITTER_DATE=%r git tag %r 'tags/%s'" % ( | |
date.replace('T', ' ').replace('Z', ' +0000'), | |
tag, tag, | |
)) | |
for branch in r('svn ls %s/branches' % url).strip().split(): | |
if branch[-1] == '/': | |
branch = branch[:-1] | |
s('git checkout %s' % branch) | |
s('git checkout -b %s' % branch) | |
# Not sure if this is necessary, or sufficient. The Ruby | |
# version ran into trouble when git left files around between | |
# branche checkouts. I haven't had the problem, with this | |
# script, which unlike the Ruby version, doesn't process | |
# deleted branches. | |
s('git reset --hard HEAD') | |
s('git checkout trunk') | |
s('git branch -D master') | |
s('git checkout -f -b master') | |
s('git branch -d -r trunk') | |
s('git gc') | |
if options.github: | |
github_dest, github_token = options.github.rsplit('/', 1) | |
if github_dest.startswith('users/'): | |
github_user = github_dest[6:] | |
github_dest = 'user' | |
else: | |
assert github_dest.startswith('orgs/') | |
github_user = github_dest.split('/')[1] | |
s('curl -v -XPOST -H "Authorization: token %s"' | |
' https://api.github.com/%s/repos -d ' | |
"""'{"name": "'"%s"'"}'""" | |
% (github_token, github_dest, name)) | |
s('git remote add origin ssh://[email protected]/%s/%s.git' | |
% (github_user, name)) | |
s("git push -u origin '*' --tags") | |
if options.bitbucket: | |
bitbucket_user, bitbucket_password = options.bitbucket.split('/', 1) | |
is_private = 0 | |
if options.private: | |
is_private = 1 | |
s('curl -k -X POST --user "%s:%s" ' | |
'"https://api.bitbucket.org/1.0/repositories" -d "name=%s" ' | |
'-d "is_private=%d" -d "scm=git"' | |
% (bitbucket_user, bitbucket_password, name, is_private)) | |
s('git remote add origin ssh://[email protected]/%s/%s.git' | |
% (bitbucket_user, name)) | |
s("git push -u origin '*' --tags") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment