Ignoring (certain) symlinks

Greg Ward greg-hg at gerg.ca
Mon Jul 6 14:34:34 CDT 2009


On Mon, Jul 6, 2009 at 2:54 PM, I wrote:
> So, just to see how hard it is in principle, I hacked the inner guts
> of dirstate.walk() (please hold your noses, this stinks):
[...]
> Can anyone think of a non-evil way to do this?  My extension idea was
> to wrap ignore.ignore() to return a function that checks for *.java
> symlinks before passing control to the original ignore func.

Figured it out: I wrote an extension that wraps osutil.listdir().  The
only interesting part was that I only want different behaviour from
listdir() while in dirstate.walk().  Here's how I did it, if anyone is
interested:

"""
import stat

from mercurial import extensions, localrepo, osutil

def wraplistdir(orig, path, **kwargs):
    # XXX should readlink() and ensure the target matches "../*/*.java"
    return [(fn, kind, st)
            for (fn, kind, st) in orig(path, **kwargs)
            if not (kind == stat.S_IFLNK and fn.endswith(".java"))]

def reposetup(ui, repo):
    if not isinstance(repo, localrepo.localrepository):
        return

    def dirstate_walk(origwalk, *args):
        ui.debug("wrapping osutil.listdir\n")
        try:
            origlistdir = extensions.wrapfunction(osutil, 'listdir',
wraplistdir)
            return origwalk(*args)
        finally:
            ui.debug("unwrapping osutil.listdir\n")
            osutil.listdir = origlistdir

    extensions.wrapfunction(repo.dirstate, 'walk', dirstate_walk)
"""

Greg



More information about the Mercurial mailing list