diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -2105,6 +2105,13 @@ def diff(repo, node1=None, node2=None, m ctx1 = repo[node1] ctx2 = repo[node2] + relfiltered = False + if relroot != '' and match.always(): + # as a special case, create a new matcher with just the relroot + pats = [relroot] + match = scmutil.match(ctx2, pats, default='path') + relfiltered = True + if not changes: changes = repo.status(ctx1, ctx2, match=match) modified, added, removed = changes[:3] @@ -2123,14 +2130,16 @@ def diff(repo, node1=None, node2=None, m copy = copies.pathcopies(ctx1, ctx2) if relroot is not None: - # XXX this would ideally be done in the matcher, but that is generally - # meant to 'or' patterns, not 'and' them. In this case we need to 'and' - # all the patterns from the matcher with relroot. - def filterrel(l): - return [f for f in l if f.startswith(relroot)] - modified = filterrel(modified) - added = filterrel(added) - removed = filterrel(removed) + if not relfiltered: + # XXX this would ideally be done in the matcher, but that is + # generally meant to 'or' patterns, not 'and' them. In this case we + # need to 'and' all the patterns from the matcher with relroot. + def filterrel(l): + return [f for f in l if f.startswith(relroot)] + modified = filterrel(modified) + added = filterrel(added) + removed = filterrel(removed) + relfiltered = True # filter out copies where either side isn't inside the relative root copy = dict(((dst, src) for (dst, src) in copy.iteritems() if dst.startswith(relroot)