# HG changeset patch # User Alexis S. L. Carvalho # Date 1184186441 10800 # Node ID 6f08bc1bd00bc5df390e36cd7671ef4c9a58f152 # Parent 74f36b1027f49df5bd1aa731bfccbdc810922853 archive: add symlink support diff -r 74f36b1027f4 -r 6f08bc1bd00b mercurial/archival.py --- 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() diff -r 74f36b1027f4 -r 6f08bc1bd00b tests/test-archive-symlinks --- /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 <', 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 diff -r 74f36b1027f4 -r 6f08bc1bd00b tests/test-archive-symlinks.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-archive-symlinks.out Wed Jul 11 17:40:41 2007 -0300 @@ -0,0 +1,6 @@ +% files +dangling -> nothing +% tar +dangling -> nothing +% zip +dangling -> nothing