Signed-off-by: Felipe Contreras <felipe.contreras@xxxxxxxxx> --- contrib/remote-helpers/git-remote-bzr | 187 ++++++++++++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100755 contrib/remote-helpers/git-remote-bzr diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr new file mode 100755 index 0000000..76a609a --- /dev/null +++ b/contrib/remote-helpers/git-remote-bzr @@ -0,0 +1,187 @@ +#!/usr/bin/env python +# +# Copyright (c) 2012 Felipe Contreras +# + +# Just copy to your ~/bin, or anywhere in your $PATH. +# Then you can clone with: +# git clone bzr::/path/to/mercurial/repo/ +# +# You need to have bzr-fastimport installed: +# http://wiki.bazaar.canonical.com/BzrFastImport +# +# You might also need to find this line bzr-fastimport's +# code, and modify it: +# +# self._use_known_graph = False + +import sys + +import bzrlib +bzrlib.initialize() + +import bzrlib.plugin +bzrlib.plugin.load_plugins() + +import bzrlib.revisionspec + +from bzrlib.plugins.fastimport import exporter as bzr_exporter + +import sys +import os +import json + +def die(msg, *args): + sys.stderr.write('ERROR: %s\n' % (msg % args)) + sys.exit(1) + +def warn(msg, *args): + sys.stderr.write('WARNING: %s\n' % (msg % args)) + +class Marks: + + def __init__(self, path): + self.path = path + self.tips = {} + self.load() + + def load(self): + if not os.path.exists(self.path): + return + + tmp = json.load(open(self.path)) + self.tips = tmp['tips'] + + def dict(self): + return { 'tips': self.tips } + + def store(self): + json.dump(self.dict(), open(self.path, 'w')) + + def __str__(self): + return str(self.dict()) + + def get_tip(self, branch): + return self.tips.get(branch, '1') + + def set_tip(self, branch, tip): + self.tips[branch] = tip + +class Parser: + + def __init__(self, repo): + self.repo = repo + self.line = self.get_line() + + def get_line(self): + return sys.stdin.readline().strip() + + def __getitem__(self, i): + return self.line.split()[i] + + def check(self, word): + return self.line.startswith(word) + + def each_block(self, separator): + while self.line != separator: + yield self.line + self.line = self.get_line() + + def __iter__(self): + return self.each_block('') + + def next(self): + self.line = self.get_line() + if self.line == 'done': + self.line = None + +def export_branch(branch, name): + global prefix, dirname + + marks_path = os.path.join(dirname, 'marks-bzr') + ref = '%s/heads/%s' % (prefix, name) + tip = marks.get_tip(name) + start = "before:%s" % tip + rev1 = bzrlib.revisionspec.RevisionSpec.from_string(start) + rev2 = bzrlib.revisionspec.RevisionSpec.from_string(None) + + exporter = bzr_exporter.BzrFastExporter(branch, + outf=sys.stdout, ref=ref, + checkpoint=None, + import_marks_file=marks_path, + export_marks_file=marks_path, + revision=[rev1, rev2], + verbose=None, plain_format=True, + rewrite_tags=False) + exporter.run() + + marks.set_tip(name, branch.last_revision()) + +def do_import(parser): + global dirname + + branch = parser.repo + path = os.path.join(dirname, 'marks-git') + + print "feature done" + if os.path.exists(path): + print "feature import-marks=%s" % path + print "feature export-marks=%s" % path + sys.stdout.flush() + + while parser.check('import'): + ref = parser[1] + if ref.startswith('refs/heads/'): + name = ref[len('refs/heads/'):] + export_branch(branch, name) + parser.next() + + print 'done' + + sys.stdout.flush() + +def do_capabilities(parser): + print "import" + print "refspec refs/heads/*:%s/heads/*" % prefix + print + +def do_list(parser): + print "? refs/heads/%s" % 'master' + print "@refs/heads/%s HEAD" % 'master' + print + +def main(args): + global marks, prefix, dirname + + alias = args[1] + url = args[2] + + d = bzrlib.controldir.ControlDir.open(url) + repo = d.open_branch() + + prefix = 'refs/bzr/%s' % alias + + gitdir = os.environ['GIT_DIR'] + dirname = os.path.join(gitdir, 'bzr', alias) + + if not os.path.exists(dirname): + os.makedirs(dirname) + + marks_path = os.path.join(dirname, 'marks-int') + marks = Marks(marks_path) + + parser = Parser(repo) + for line in parser: + if parser.check('capabilities'): + do_capabilities(parser) + elif parser.check('list'): + do_list(parser) + elif parser.check('import'): + do_import(parser) + else: + die('unhandled command: %s' % line) + sys.stdout.flush() + + marks.store() + +sys.exit(main(sys.argv)) -- 1.8.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html