diff options
Diffstat (limited to 'contrib/remote-helpers/git-remote-bzr')
-rwxr-xr-x | contrib/remote-helpers/git-remote-bzr | 172 |
1 files changed, 80 insertions, 92 deletions
diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 10300c63d1..054161ae21 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -13,8 +13,11 @@ # or # % git clone bzr::lp:myrepo # -# If you want to specify which branches you want track (per repo): -# git config remote-bzr.branches 'trunk, devel, test' +# If you want to specify which branches you want to track (per repo): +# % git config remote.origin.bzr-branches 'trunk, devel, test' +# +# Where 'origin' is the name of the repository you want to specify the +# branches. # import sys @@ -116,7 +119,10 @@ class Marks: self.last_mark = mark def get_tip(self, branch): - return self.tips.get(branch, None) + try: + return str(self.tips[branch]) + except KeyError: + return None def set_tip(self, branch, tip): self.tips[branch] = tip @@ -165,17 +171,16 @@ class Parser: if not m: return None _, name, email, date, tz = m.groups() + name = name.decode('utf-8') committer = '%s <%s>' % (name, email) tz = int(tz) tz = ((tz / 100) * 3600) + ((tz % 100) * 60) return (committer, int(date), tz) def rev_to_mark(rev): - global marks return marks.from_rev(rev) def mark_to_rev(mark): - global marks return marks.to_rev(mark) def fixup_user(user): @@ -230,8 +235,6 @@ def get_filechanges(cur, prev): return modified, removed def export_files(tree, files): - global marks, filenodes - final = [] for path, fid in files.iteritems(): kind = tree.kind(fid) @@ -273,12 +276,10 @@ def export_files(tree, files): return final def export_branch(repo, name): - global prefix - ref = '%s/heads/%s' % (prefix, name) tip = marks.get_tip(name) - branch = bzrlib.branch.Branch.open(branches[name]) + branch = get_remote_branch(name) repo = branch.repository branch.lock_read() @@ -375,16 +376,12 @@ def export_branch(repo, name): marks.set_tip(name, revid) def export_tag(repo, name): - global tags, prefix - ref = '%s/tags/%s' % (prefix, name) print "reset %s" % ref print "from :%u" % rev_to_mark(tags[name]) print def do_import(parser): - global dirname - repo = parser.repo path = os.path.join(dirname, 'marks-git') @@ -410,8 +407,6 @@ def do_import(parser): sys.stdout.flush() def parse_blob(parser): - global blob_marks - parser.next() mark = parser.get_mark() parser.next() @@ -422,8 +417,6 @@ def parse_blob(parser): class CustomTree(): def __init__(self, branch, revid, parents, files): - global files_cache - self.updates = {} self.branch = branch @@ -481,7 +474,7 @@ class CustomTree(): add_entry(fid, dirname, 'directory') return fid - def add_entry(fid, path, kind, mode = None): + def add_entry(fid, path, kind, mode=None): dirname, basename = os.path.split(path) parent_fid = get_parent(dirname, basename) @@ -502,7 +495,7 @@ class CustomTree(): self.files[path] = [change[0], None] changes.append(change) - def update_entry(fid, path, kind, mode = None): + def update_entry(fid, path, kind, mode=None): dirname, basename = os.path.split(path) parent_fid = get_parent(dirname, basename) @@ -580,9 +573,6 @@ def c_style_unescape(string): return string def parse_commit(parser): - global marks, blob_marks, parsed_refs - global mode - parents = [] ref = parser[1] @@ -590,7 +580,7 @@ def parse_commit(parser): if ref.startswith('refs/heads/'): name = ref[len('refs/heads/'):] - branch = bzrlib.branch.Branch.open(branches[name]) + branch = get_remote_branch(name) else: die('unknown ref') @@ -621,7 +611,7 @@ def parse_commit(parser): mark = int(mark_ref[1:]) f = { 'mode' : m, 'mark' : mark } elif parser.check('D'): - t, path = line.split(' ') + t, path = line.split(' ', 1) f = { 'deleted' : True } else: die('Unknown file command: %s' % line) @@ -654,8 +644,6 @@ def parse_commit(parser): marks.new_mark(revid, commit_mark) def parse_reset(parser): - global parsed_refs - ref = parser[1] parser.next() @@ -671,8 +659,6 @@ def parse_reset(parser): parsed_refs[ref] = mark_to_rev(from_mark) def do_export(parser): - global parsed_refs, dirname - parser.next() for line in parser.each_block('done'): @@ -692,11 +678,12 @@ def do_export(parser): for ref, revid in parsed_refs.iteritems(): if ref.startswith('refs/heads/'): name = ref[len('refs/heads/'):] - branch = bzrlib.branch.Branch.open(branches[name]) + branch = get_remote_branch(name) branch.generate_revision_history(revid, marks.get_tip(name)) if name in peers: - peer = bzrlib.branch.Branch.open(peers[name]) + peer = bzrlib.branch.Branch.open(peers[name], + possible_transports=transports) try: peer.bzrdir.push_branch(branch, revision_id=revid) except bzrlib.errors.DivergedBranches: @@ -721,8 +708,6 @@ def do_export(parser): print def do_capabilities(parser): - global dirname - print "import" print "export" print "refspec refs/heads/*:%s/heads/*" % prefix @@ -740,8 +725,6 @@ def ref_is_valid(name): return not True in [c in name for c in '~^: \\'] def do_list(parser): - global tags - master_branch = None for name in branches: @@ -749,7 +732,7 @@ def do_list(parser): master_branch = name print "? refs/heads/%s" % name - branch = bzrlib.branch.Branch.open(branches[master_branch]) + branch = get_remote_branch(master_branch) branch.lock_read() for tag, revid in branch.tags.get_tag_dict().items(): try: @@ -765,30 +748,40 @@ def do_list(parser): print "@refs/heads/%s HEAD" % master_branch print -def get_remote_branch(origin, remote_branch, name): - global dirname, peers +def clone(path, remote_branch): + try: + bdir = bzrlib.bzrdir.BzrDir.create(path, possible_transports=transports) + except bzrlib.errors.AlreadyControlDirError: + bdir = bzrlib.bzrdir.BzrDir.open(path, possible_transports=transports) + repo = bdir.find_repository() + repo.fetch(remote_branch.repository) + return remote_branch.sprout(bdir, repository=repo) + +def get_remote_branch(name): + remote_branch = bzrlib.branch.Branch.open(branches[name], + possible_transports=transports) + if isinstance(remote_branch.user_transport, bzrlib.transport.local.LocalTransport): + return remote_branch branch_path = os.path.join(dirname, 'clone', name) - if os.path.exists(branch_path): + + try: + branch = bzrlib.branch.Branch.open(branch_path, + possible_transports=transports) + except bzrlib.errors.NotBranchError: + # clone + branch = clone(branch_path, remote_branch) + else: # pull - d = bzrlib.bzrdir.BzrDir.open(branch_path) - branch = d.open_branch() try: - branch.pull(remote_branch, [], None, False) + branch.pull(remote_branch, overwrite=True) except bzrlib.errors.DivergedBranches: # use remote branch for now return remote_branch - else: - # clone - d = origin.sprout(branch_path, None, - hardlink=True, create_tree_if_local=False, - force_new_repo=False, - source_branch=remote_branch) - branch = d.open_branch() return branch -def find_branches(repo, wanted): +def find_branches(repo): transport = repo.bzrdir.root_transport for fn in transport.iter_files_recursive(): @@ -799,29 +792,26 @@ def find_branches(repo, wanted): name = name if name != '' else 'master' name = name.replace('/', '+') - if wanted and not name in wanted: - continue - try: cur = transport.clone(subdir) branch = bzrlib.branch.Branch.open_from_transport(cur) except bzrlib.errors.NotBranchError: continue else: - yield name, branch + yield name, branch.base def get_repo(url, alias): - global dirname, peer, branches - normal_url = bzrlib.urlutils.normalize_url(url) - origin = bzrlib.bzrdir.BzrDir.open(url) + origin = bzrlib.bzrdir.BzrDir.open(url, possible_transports=transports) is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport) shared_path = os.path.join(gitdir, 'bzr') try: - shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path) + shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path, + possible_transports=transports) except bzrlib.errors.NotBranchError: - shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path) + shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path, + possible_transports=transports) try: shared_repo = shared_dir.open_repository() except bzrlib.errors.NoRepositoryPresent: @@ -834,51 +824,47 @@ def get_repo(url, alias): else: # check and remove old organization try: - bdir = bzrlib.bzrdir.BzrDir.open(clone_path) + bdir = bzrlib.bzrdir.BzrDir.open(clone_path, + possible_transports=transports) bdir.destroy_repository() except bzrlib.errors.NotBranchError: pass except bzrlib.errors.NoRepositoryPresent: pass - try: - repo = origin.open_repository() - if not repo.user_transport.listable(): - # this repository is not usable for us - raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir) - except bzrlib.errors.NoRepositoryPresent: - # branch - - name = 'master' - remote_branch = origin.open_branch() - - if not is_local: - peers[name] = remote_branch.base - branch = get_remote_branch(origin, remote_branch, name) - else: - branch = remote_branch - - branches[name] = branch.base - - return branch.repository - else: - # repository - + wanted = get_config('remote.%s.bzr-branches' % alias).rstrip().split(', ') + # stupid python + wanted = [e for e in wanted if e] + if not wanted: wanted = get_config('remote-bzr.branches').rstrip().split(', ') # stupid python wanted = [e for e in wanted if e] - for name, remote_branch in find_branches(repo, wanted): - - if not is_local: - peers[name] = remote_branch.base - branch = get_remote_branch(origin, remote_branch, name) - else: - branch = remote_branch + if not wanted: + try: + repo = origin.open_repository() + if not repo.user_transport.listable(): + # this repository is not usable for us + raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir) + except bzrlib.errors.NoRepositoryPresent: + wanted = ['master'] + + if wanted: + def list_wanted(url, wanted): + for name in wanted: + subdir = name if name != 'master' else '' + yield name, bzrlib.urlutils.join(url, subdir) + + branch_list = list_wanted(url, wanted) + else: + branch_list = find_branches(repo) - branches[name] = branch.base + for name, url in branch_list: + if not is_local: + peers[name] = url + branches[name] = url - return repo + return origin def fix_path(alias, orig_url): url = urlparse.urlparse(orig_url, 'file') @@ -896,6 +882,7 @@ def main(args): global files_cache global is_tmp global branches, peers + global transports alias = args[1] url = args[2] @@ -908,6 +895,7 @@ def main(args): marks = None branches = {} peers = {} + transports = [] if alias[5:] == url: is_tmp = True |