comparison mercurial/archival.py @ 4862: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 667290b6c95e
comparison
equal deleted inserted replaced
4861:74f36b1027f4 4862:6f08bc1bd00b
84 self.z = taropen(dest, mode='w:') 84 self.z = taropen(dest, mode='w:')
85 else: 85 else:
86 # Python 2.5-2.5.1 have a regression that requires a name arg 86 # Python 2.5-2.5.1 have a regression that requires a name arg
87 self.z = taropen(name='', mode='w|', fileobj=dest) 87 self.z = taropen(name='', mode='w|', fileobj=dest)
88 88
89 def addfile(self, name, mode, data): 89 def addfile(self, name, mode, islink, data):
90 i = tarfile.TarInfo(self.prefix + name) 90 i = tarfile.TarInfo(self.prefix + name)
91 i.mtime = self.mtime 91 i.mtime = self.mtime
92 i.size = len(data) 92 i.size = len(data)
93 i.mode = mode 93 if islink:
94 self.z.addfile(i, cStringIO.StringIO(data)) 94 i.type = tarfile.SYMTYPE
95 i.mode = 0777
96 i.linkname = data
97 data = None
98 else:
99 i.mode = mode
100 data = cStringIO.StringIO(data)
101 self.z.addfile(i, data)
95 102
96 def done(self): 103 def done(self):
97 self.z.close() 104 self.z.close()
98 105
99 class tellable: 106 class tellable:
128 self.z = zipfile.ZipFile(dest, 'w', 135 self.z = zipfile.ZipFile(dest, 'w',
129 compress and zipfile.ZIP_DEFLATED or 136 compress and zipfile.ZIP_DEFLATED or
130 zipfile.ZIP_STORED) 137 zipfile.ZIP_STORED)
131 self.date_time = time.gmtime(mtime)[:6] 138 self.date_time = time.gmtime(mtime)[:6]
132 139
133 def addfile(self, name, mode, data): 140 def addfile(self, name, mode, islink, data):
134 i = zipfile.ZipInfo(self.prefix + name, self.date_time) 141 i = zipfile.ZipInfo(self.prefix + name, self.date_time)
135 i.compress_type = self.z.compression 142 i.compress_type = self.z.compression
136 # unzip will not honor unix file modes unless file creator is 143 # unzip will not honor unix file modes unless file creator is
137 # set to unix (id 3). 144 # set to unix (id 3).
138 i.create_system = 3 145 i.create_system = 3
139 i.external_attr = (mode | stat.S_IFREG) << 16L 146 ftype = stat.S_IFREG
147 if islink:
148 mode = 0777
149 ftype = stat.S_IFLNK
150 i.external_attr = (mode | ftype) << 16L
140 self.z.writestr(i, data) 151 self.z.writestr(i, data)
141 152
142 def done(self): 153 def done(self):
143 self.z.close() 154 self.z.close()
144 155
149 if prefix: 160 if prefix:
150 raise util.Abort(_('cannot give prefix when archiving to files')) 161 raise util.Abort(_('cannot give prefix when archiving to files'))
151 self.basedir = name 162 self.basedir = name
152 self.opener = util.opener(self.basedir) 163 self.opener = util.opener(self.basedir)
153 164
154 def addfile(self, name, mode, data): 165 def addfile(self, name, mode, islink, data):
166 if islink:
167 self.opener.symlink(data, name)
168 return
155 f = self.opener(name, "w", atomictemp=True) 169 f = self.opener(name, "w", atomictemp=True)
156 f.write(data) 170 f.write(data)
157 f.rename() 171 f.rename()
158 destfile = os.path.join(self.basedir, name) 172 destfile = os.path.join(self.basedir, name)
159 os.chmod(destfile, mode) 173 os.chmod(destfile, mode)
184 198
185 matchfn is function to filter names of files to write to archive. 199 matchfn is function to filter names of files to write to archive.
186 200
187 prefix is name of path to put before every archive member.''' 201 prefix is name of path to put before every archive member.'''
188 202
189 def write(name, mode, data): 203 def write(name, mode, islink, data):
190 if matchfn and not matchfn(name): return 204 if matchfn and not matchfn(name): return
191 if decode: 205 if decode:
192 data = repo.wwritedata(name, data) 206 data = repo.wwritedata(name, data)
193 archiver.addfile(name, mode, data) 207 archiver.addfile(name, mode, islink, data)
194 208
195 ctx = repo.changectx(node) 209 ctx = repo.changectx(node)
196 archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0]) 210 archiver = archivers[kind](dest, prefix, mtime or ctx.date()[0])
197 m = ctx.manifest() 211 m = ctx.manifest()
198 items = m.items() 212 items = m.items()
199 items.sort() 213 items.sort()
200 write('.hg_archival.txt', 0644, 214 write('.hg_archival.txt', 0644, False,
201 'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node))) 215 'repo: %s\nnode: %s\n' % (hex(repo.changelog.node(0)), hex(node)))
202 for filename, filenode in items: 216 for filename, filenode in items:
203 write(filename, m.execf(filename) and 0755 or 0644, 217 write(filename, m.execf(filename) and 0755 or 0644, m.linkf(filename),
204 repo.file(filename).read(filenode)) 218 repo.file(filename).read(filenode))
205 archiver.done() 219 archiver.done()