Mercurial > hg
changeset 4831:6f08bc1bd00b
archive: add symlink support
author | Alexis S. L. Carvalho <alexis@cecm.usp.br> |
---|---|
date | Wed, 11 Jul 2007 17:40:41 -0300 |
parents | 74f36b1027f4 |
children | 0875082d5471 |
files | mercurial/archival.py tests/test-archive-symlinks tests/test-archive-symlinks.out |
diffstat | 3 files changed, 67 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/archival.py Wed Jul 11 17:40:41 2007 -0300 +++ b/mercurial/archival.py Wed Jul 11 17:40:41 2007 -0300 @@ -86,12 +86,19 @@ # Python 2.5-2.5.1 have a regression that requires a name arg self.z = taropen(name='', mode='w|', fileobj=dest) - def addfile(self, name, mode, data): + def addfile(self, name, mode, islink, data): i = tarfile.TarInfo(self.prefix + name) i.mtime = self.mtime i.size = len(data) - i.mode = mode - self.z.addfile(i, cStringIO.StringIO(data)) + if islink: + i.type = tarfile.SYMTYPE + i.mode = 0777 + i.linkname = data + data = None + else: + i.mode = mode + data = cStringIO.StringIO(data) + self.z.addfile(i, data) def done(self): self.z.close() @@ -130,13 +137,17 @@ zipfile.ZIP_STORED) self.date_time = time.gmtime(mtime)[:6] - def addfile(self, name, mode, data): + def addfile(self, name, mode, islink, data): i = zipfile.ZipInfo(self.prefix + name, self.date_time) i.compress_type = self.z.compression # unzip will not honor unix file modes unless file creator is # set to unix (id 3). i.create_system = 3 - i.external_attr = (mode | stat.S_IFREG) << 16L + ftype = stat.S_IFREG + if islink: + mode = 0777 + ftype = stat.S_IFLNK + i.external_attr = (mode | ftype) << 16L self.z.writestr(i, data) def done(self): @@ -151,7 +162,10 @@ self.basedir = name self.opener = util.opener(self.basedir) - def addfile(self, name, mode, data): + def addfile(self, name, mode, islink, data): + if islink: + self.opener.symlink(data, name) + return f = self.opener(name, "w", atomictemp=True) f.write(data) f.rename() @@ -186,20 +200,20 @@ prefix is name of path to put before every archive member.''' - def write(name, mode, data): + def write(name, mode, islink, data): if matchfn and not matchfn(name): return if decode: data = repo.wwritedata(name, data) - archiver.addfile(name, mode, data) + archiver.addfile(name, mode, islink, data) ctx = repo.changectx(node) archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0]) m = ctx.manifest() items = m.items() items.sort() - write('.hg_archival.txt', 0644, + write('.hg_archival.txt', 0644, False, 'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node))) for filename, filenode in items: - write(filename, m.execf(filename) and 0755 or 0644, + write(filename, m.execf(filename) and 0755 or 0644, m.linkf(filename), repo.file(filename).read(filenode)) archiver.done()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-archive-symlinks Wed Jul 11 17:40:41 2007 -0300 @@ -0,0 +1,37 @@ +#!/bin/sh + +origdir=`pwd` + +cat >> readlink.py <<EOF +import os +import sys + +for f in sys.argv[1:]: + print f, '->', os.readlink(f) +EOF + +hg init repo +cd repo +ln -s nothing dangling +hg ci -qAm 'add symlink' + +hg archive -t files ../archive +hg archive -t tar -p tar ../archive.tar +hg archive -t zip -p zip ../archive.zip + +echo '% files' +cd "$origdir" +cd archive +python ../readlink.py dangling + +echo '% tar' +cd "$origdir" +tar xf archive.tar +cd tar +python ../readlink.py dangling + +echo '% zip' +cd "$origdir" +unzip archive.zip > /dev/null +cd zip +python ../readlink.py dangling