Usage question about bzrlib.builtins.cmd_diff

Martin (gzlist) gzlist at googlemail.com
Thu Mar 10 00:05:00 UTC 2011


On 09/03/2011, Matt Drew <matt.drew at steeprockinc.com> wrote:
> I can run this command from the command line:
> bzr diff filename -r1..2
> to generate a diff between file filename as it existed at revision 1 and
> revision 2.
>
> I want to do the same thing from python. I tried this:
> import bzrlib.builtins
> bzrlib.builtins.cmd_diff().run(file_list=['filename'])

It doesn't appear Command objects are designed to be reused like this,
though people seem to want to. The arguments to `run` are not just
strings but have been preprocessed, as can be seen from the class
attributes.


In this case, that means passing one or two RevisionSpec objects,
which, if you want to ignore the rest of this post, you can do like
so:

    from bzrlib.builtins import cmd_diff
    from bzrlib.option import _parse_revision_str
    revspecs = _parse_revision_str("1..2")
    cmd_diff().run(revision=revspecs)

However, that's a bad idea, it uses a private api that's likely to
move and skips a bunch of other things you'll need to do in practice.
Avoiding that function instead doing:

    from bzrlib.revisionspec import RevisionSpec
    revspecs = (RevisionSpec.from_string("1"), RevisionSpec.from_string("2"))

Is possible, but doesn't really help in the general case.


For the "I don't care, I just want it to work like the script" uses,
the closest to the right thing is:

    bzrlib.commands.run_bzr(["diff", "-r1..2", "filename"])

But that still leaves you a lot of annoying initialisation to do that
bzr-as-a-script normally handles. It's somewhere I think bzrlib and
the documentation could improve.


If you're actually interested in learning how to use bzrlib in detail,
it's possible to write a function that does the same as your example,
limited to between two (undotted) revisions from the same branch along
these lines:

    import sys
    from bzrlib.branch import Branch
    from bzrlib.diff import show_diff_trees


    def diff_branch_revs(branch_loc=None, rev_a=1, rev_b=2, *specific_files):
        """Prints the diff between two mainline revisions in branch"""
        branch = Branch.open(branch_loc)
        branch.lock_read()
        try:
            get_revtree = branch.repository.revision_tree
            revtree_a = get_revtree(branch.get_rev_id(rev_a))
            revtree_b = get_revtree(branch.get_rev_id(rev_b))
            show_diff_trees(revtree_a, revtree_b, sys.stdout, specific_files)
        finally:
            branch.unlock()

See the docstrings on those objects and methods for more. You can add
back in some of the elaborations like "-1" meaning last revision, and
comparing against the working tree, if you need those aspects.

Martin



More information about the bazaar mailing list