diff --git a/mercurial/archival.py b/mercurial/archival.py --- a/mercurial/archival.py +++ b/mercurial/archival.py @@ -86,12 +86,19 @@ class tarit: # 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 @@ class zipit: 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 @@ class fileit: 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 @@ def archive(repo, dest, node, kind, deco 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()