Comment 5 for bug 197597

Revision history for this message
John A Meinel (jameinel) wrote : Re: [Bug 197597] Re: branches command slow

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Gareth White wrote:
> I should add that the server machine was on the same LAN as the client
> machines so the network latency would have been minimal.
>

bzr branches is pretty 'stupid'. It does a listdir and then tries to
open a bzr branch for each entry it sees. I believe it even
screen-scrapes Apache index files and tries to do the same thing. This
is especially bad if you have working trees.

Also, all of the work is done on the client.

I wrote a script which implements a 'local_branches' operation, which is
significantly faster in practice. (Though where I'm using it also has
working trees, so it is extra significant.)

As for not needing to probe underneath .bzr. There are several
'colocated-branches' designs that use something like '.bzr/branches/*'
to hold extra branch definitions. So it isn't entirely true that we
don't need to probe underneath .bzr. We *could* stop probing underneath
.bzr/{checkout,branch,repository}

Note that my custom function does skip all of .bzr because I know I'm
not using anything fancy. It also *only* probes directories that have a
'.bzr' directory. Which means that it would give incorrect results if
you were using "bzr-svn" or "bzr-git" etc. (IIRC 'bzr branches' will
return svn and git branches if you have those plugins installed.)

John
=:->

def find_local_bzr_branches(repo):
    """Walk the filesystem, and find bzr branches.

    This skips over the 'repo.find_branches()' api, because that is sort
of a
    worst-case implementation. (It tries to open every object as a Branch,
    files, dirs, etc.)
    """
    all_branches = []
    root_path = repo.bzrdir.root_transport.local_abspath('.')
    for dir_info, files_info in osutils._walkdirs_utf8(root_path):
        utf8_relpath, dirpath = dir_info
        bzr_index = None
        for idx, (_, utf8_name, kind, _, _) in enumerate(files_info):
            if utf8_name == '.bzr' and kind == 'directory':
                bzr_index = idx
                break
        # For now, we don't recurse into .bzr directories. Note that this
        # behavior has to change based on how 'colocated' branches end up
        # getting implemented
        if bzr_index is not None:
            del files_info[bzr_index]
            try:
                b = branch.Branch.open(dirpath)
            except errors.NotBranchError:
                continue
            all_branches.append(b)
    return all_branches
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAktMl0sACgkQJdeBCYSNAAOkwwCfVxPYdcUpJFcKdO5mb4SK8EQ9
nOIAn2yec/iec3DJwMiPWdf+W3b7JBI5
=RH40
-----END PGP SIGNATURE-----