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() |