Package: bzrtools Version: 0.18.0-1 Severity: wishlist Tags: patch Hi,
multi-pull is relatively slow because it opens a connection for each branch (especially ssh connections are slow). I'm attaching a patch to reuse the connection for all branches with the same URL base. I hope it's not so ugly that you poke yourself an eye out. The old behavior isn't available anymore with the patch, but perhaps this is a problem for some transports? I have no idea. Bye, -- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.22-1-686 (SMP w/2 CPU cores) Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages bzrtools depends on: ii bzr 0.18-1 Bazaar, the next-generation distri ii patch 2.5.9-4 Apply a diff file to an original ii python 2.4.4-6 An interactive high-level object-o ii python-central 0.5.14 register and build utility for Pyt Versions of packages bzrtools recommends: ii graphviz 2.12-3 rich set of graph drawing tools ii rsync 2.6.9-3 fast remote file copy program (lik -- no debconf information -- Loïc Minier
--- bzrtools-0.18.0/debian/changelog +++ bzrtools-0.18.0/debian/changelog @@ -1,3 +1,11 @@ +bzrtools (0.18.0-1.1) UNRELEASED; urgency=low + + * Non-maintainer upload. + * Group branches by URL base and reuse one transport per URL base to avoid + reopening a connection for each pull in multi-pull. + + -- Loic Minier <[EMAIL PROTECTED]> Mon, 30 Jul 2007 12:06:43 +0200 + bzrtools (0.18.0-1) unstable; urgency=low [ Arnaud Fontaine ] --- bzrtools-0.18.0.orig/__init__.py +++ bzrtools-0.18.0/__init__.py @@ -503,27 +503,72 @@ if not t.listable(): print "Can't list this type of location." return 3 - for branch, wt in iter_branch_tree(t): - if wt is None: - pullable = branch - else: - pullable = wt - parent = branch.get_parent() - if parent is None: - continue - if wt is not None: - base = wt.basedir - else: - base = branch.base - if base.startswith(t.base): - relpath = base[len(t.base):].rstrip('/') - else: - relpath = base - print "Pulling %s from %s" % (relpath, parent) - try: - pullable.pull(Branch.open(parent)) - except Exception, e: - print e + print "Grouping branches by URL" + by_urlbase = pullable_infos_by_urlbase(t) + for urlbase in by_urlbase: + print "Processing branches for %s/" % urlbase + urlbase_transport = get_transport(urlbase) + for pi in by_urlbase[urlbase]: + pullable = pi.get_pullable() + relpath = get_relpath(t.base, pi.get_base()) + parent = pi.get_parent() + from bzrtools import bzrdir_from_transport + pull_transport = urlbase_transport.clone(get_relpath(urlbase, parent)) + bzrdir = bzrdir_from_transport(pull_transport) + pull_branch = bzrdir.open_branch() + print "Pulling %s from %s" % (relpath, parent) + try: + pullable.pull(pull_branch) + except Exception, e: + print e + + +def get_relpath(base, path): + if path.startswith(base): + return path[len(base):].rstrip('/') + else: + return path + + +class PullableInfo: + def __init__(self, branch, wt): + self.branch = branch + self.wt = wt + + def get_pullable(self): + if self.wt is None: + return self.branch + return self.wt + + def get_parent(self): + return self.branch.get_parent() + + def get_base(self): + if self.wt is not None: + return self.wt.basedir + return self.branch.base + + def get_urlbase(self): + import re + # always matches at least the empty string + urlbase_pattern = re.compile("^(([^:]*://)?([^/]*))") + return urlbase_pattern.match(self.get_parent()).groups()[0] + + +def pullable_infos_by_urlbase(t): + pullables_by_urlbase = {} + from bzrtools import iter_branch_tree + for branch, wt in iter_branch_tree(t): + parent = branch.get_parent() + if parent is None: + continue + pullable_info = PullableInfo(branch, wt) + urlbase = pullable_info.get_urlbase() + try: + pullables_by_urlbase[urlbase] += (pullable_info, ) + except KeyError: + pullables_by_urlbase[urlbase] = (pullable_info, ) + return pullables_by_urlbase class cmd_branch_mark(bzrlib.commands.Command):