def difftree(ui, repo, node1=None, node2=None, *files, **opts):
    """diff trees from two commits"""
    def __difftree(repo, node1, node2, files=[]):
        assert node2 is not None
        mmap = repo[node1].manifest()
        mmap2 = repo[node2].manifest()
        m = cmdutil.match(repo, files)
        modified, added, removed  = repo.status(node1, node2, m)[:3]
        empty = short(nullid)

        for f in modified:
            # TODO get file permissions
            ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
                     (short(mmap[f]), short(mmap2[f]), f, f))
        for f in added:
            ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
                     (empty, short(mmap2[f]), f, f))
        for f in removed:
            ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
                     (short(mmap[f]), empty, f, f))
    ##

    while True:
        if opts['stdin']:
            try:
                line = raw_input().split(' ')
                node1 = line[0]
                if len(line) > 1:
                    node2 = line[1]
                else:
                    node2 = None
            except EOFError:
                break
        node1 = repo.lookup(node1)
        if node2:
            node2 = repo.lookup(node2)
        else:
            node2 = node1
            node1 = repo.changelog.parents(node1)[0]
        if opts['patch']:
            if opts['pretty']:
                catcommit(ui, repo, node2, "")
            m = cmdutil.match(repo, files)
            chunks = patch.diff(repo, node1, node2, match=m,
                                opts=patch.diffopts(ui, {'git': True}))
            for chunk in chunks:
                ui.write(chunk)
        else:
            __difftree(repo, node1, node2, files=files)
        if not opts['stdin']:
            break