hg clone fails on non-GNU systems

Stephen Darnell sdarnell at esmertec.com
Thu Jul 14 10:07:33 UTC 2005


> Replace non-portable (dependent on GNU fileutils) invocation
> of cp with Python standard library calls to implement
> recursive hardlink creation.

Using system("cp -al ...") is bound to be a compatability thorn,
but the proposed patch uses os.link() which appears to only be
supported on platforms that support hard links.

I believe the correct solution is to:
a. add a utility function to util.py that does the copy,
   rather than polluting commands.py
b. essentially take a copy of the Python2.4 shutil.copytree()
   'example' code and if the target supports os.link()
   use that to copy the file instead of copy2()

See below:

def copytree(src, dst, symlinks=False):
    """Recursively copy a directory tree using hard links if possible.

    The destination directory must not already exist.
    If exception(s) occur, an Error is raised with a list of reasons.

    If the optional symlinks flag is true, symbolic links in the
    source tree result in symbolic links in the destination tree; if
    it is false, the contents of the files pointed to by symbolic
    links are copied.
    """
    names = os.listdir(src)
    os.mkdir(dst)
    errors = []
    for name in names:
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                copytree(srcname, dstname, symlinks)
            elif hasattr(os, 'link'):
            	os.link(srcname, dstname)
            else:
                shutil.copy2(srcname, dstname)
            # XXX What about devices, sockets etc.?
        except (IOError, os.error), why:
            errors.append((srcname, dstname, why))
    if errors:
        raise Error, errors

Regards,
  Stephen




More information about the Mercurial mailing list