diff options
Diffstat (limited to 'contrib/remote-helpers/git-remote-bzr')
-rwxr-xr-x | contrib/remote-helpers/git-remote-bzr | 148 |
1 files changed, 86 insertions, 62 deletions
diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index 3e452af1dc..1e0044b69f 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -31,6 +31,7 @@ import bzrlib.transport import bzrlib.errors import bzrlib.ui import bzrlib.urlutils +import bzrlib.branch import sys import os @@ -115,7 +116,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 @@ -277,7 +281,7 @@ def export_branch(repo, name): 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() @@ -589,7 +593,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') @@ -620,7 +624,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) @@ -670,7 +674,7 @@ def parse_reset(parser): parsed_refs[ref] = mark_to_rev(from_mark) def do_export(parser): - global parsed_refs, dirname + global parsed_refs, dirname, transports parser.next() @@ -691,11 +695,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: @@ -748,7 +753,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: @@ -764,31 +769,44 @@ 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): + global transports + 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): + global dirname, branches, transports + + 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): - transport = repo.user_transport +def find_branches(repo): + transport = repo.bzrdir.root_transport for fn in transport.iter_files_recursive(): if not fn.endswith('.bzr/branch-format'): @@ -798,29 +816,28 @@ 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 + global dirname, peer, branches, transports 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: @@ -830,42 +847,46 @@ def get_repo(url, alias): clone_path = os.path.join(dirname, 'clone') if not os.path.exists(clone_path): os.mkdir(clone_path) - - try: - repo = origin.open_repository() - 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 + # check and remove old organization + try: + bdir = bzrlib.bzrdir.BzrDir.open(clone_path, + possible_transports=transports) + bdir.destroy_repository() + except bzrlib.errors.NotBranchError: + pass + except bzrlib.errors.NoRepositoryPresent: + pass - branches[name] = branch.base + wanted = get_config('remote-bzr.branches').rstrip().split(', ') + # stupid python + wanted = [e for e in wanted if e] - return branch.repository + 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: - # repository - - 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): + branch_list = find_branches(repo) - 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 + 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') @@ -883,6 +904,7 @@ def main(args): global files_cache global is_tmp global branches, peers + global transports alias = args[1] url = args[2] @@ -895,6 +917,7 @@ def main(args): marks = None branches = {} peers = {} + transports = [] if alias[5:] == url: is_tmp = True @@ -912,7 +935,8 @@ def main(args): if not os.path.exists(dirname): os.makedirs(dirname) - bzrlib.ui.ui_factory.be_quiet(True) + if hasattr(bzrlib.ui.ui_factory, 'be_quiet'): + bzrlib.ui.ui_factory.be_quiet(True) repo = get_repo(url, alias) |