annotate mercurial/archival.py @ 45092:e699cebc3ae9 stable

convert: use bytes for value in extra dict The keys and values of the extra dict are expected to be bytes. Before this fix, there was a crash in mercurial.changelog.encodeextra().
author Manuel Jacob <me@manueljacob.de>
date Tue, 14 Jul 2020 10:25:41 +0200
parents 2c0043977b6d
children 3a6ec080b521
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
1 # archival.py - revision archival for mercurial
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
2 #
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7770
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9614
diff changeset
6 # GNU General Public License version 2 or any later version.
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
7
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
8 from __future__ import absolute_import
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
9
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
10 import gzip
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
11 import os
17628
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
12 import struct
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
13 import tarfile
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
14 import time
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
15 import zipfile
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
16 import zlib
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
17
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
18 from .i18n import _
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
19 from .node import nullrev
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
20 from .pycompat import open
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
21
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
22 from . import (
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
23 error,
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
24 formatter,
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
25 match as matchmod,
36707
bfe23afea361 archival: fsdecode paths before passing to tar or zip objects
Augie Fackler <augie@google.com>
parents: 36447
diff changeset
26 pycompat,
36139
b72c6ff4e4c0 archive: migrate to the fileprefetch callback mechanism
Matt Harbison <matt_harbison@yahoo.com>
parents: 36036
diff changeset
27 scmutil,
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
28 util,
31235
7feab0e7702d vfs: use 'vfs' module directly in 'mercurial.archival'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31216
diff changeset
29 vfs as vfsmod,
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
30 )
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
31
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28017
diff changeset
32 stringio = util.stringio
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
33
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
34 # from unzip source code:
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
35 _UNX_IFREG = 0x8000
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
36 _UNX_IFLNK = 0xA000
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
37
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
38
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
39 def tidyprefix(dest, kind, prefix):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
40 '''choose prefix to use for names in archive. make sure prefix is
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
41 safe for consumers.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
42
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
43 if prefix:
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 4951
diff changeset
44 prefix = util.normpath(prefix)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
45 else:
36437
745b0df08514 py3: use bytes instead of str in isinstance
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36139
diff changeset
46 if not isinstance(dest, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
47 raise ValueError(b'dest must be string if no prefix')
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
48 prefix = os.path.basename(dest)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
49 lower = prefix.lower()
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
50 for sfx in exts.get(kind, []):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
51 if lower.endswith(sfx):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
52 prefix = prefix[: -len(sfx)]
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
53 break
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
54 lpfx = os.path.normpath(util.localpath(prefix))
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
55 prefix = util.pconvert(lpfx)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
56 if not prefix.endswith(b'/'):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
57 prefix += b'/'
24953
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
58 # Drop the leading '.' path component if present, so Windows can read the
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
59 # zip files (issue4634)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
60 if prefix.startswith(b'./'):
24953
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
61 prefix = prefix[2:]
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
62 if prefix.startswith(b'../') or os.path.isabs(lpfx) or b'/../' in prefix:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
63 raise error.Abort(_(b'archive prefix contains illegal components'))
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
64 return prefix
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
65
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
66
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
67 exts = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
68 b'tar': [b'.tar'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
69 b'tbz2': [b'.tbz2', b'.tar.bz2'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
70 b'tgz': [b'.tgz', b'.tar.gz'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
71 b'zip': [b'.zip'],
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
72 b'txz': [b'.txz', b'.tar.xz'],
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
73 }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
74
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
75
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
76 def guesskind(dest):
43106
d783f945a701 py3: finish porting iteritems() to pycompat and remove source transformer
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43085
diff changeset
77 for kind, extensions in pycompat.iteritems(exts):
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24953
diff changeset
78 if any(dest.endswith(ext) for ext in extensions):
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
79 return kind
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
80 return None
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
81
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
82
24681
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
83 def _rootctx(repo):
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
84 # repo[0] may be hidden
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
85 for rev in repo:
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
86 return repo[rev]
39894
d739f423bf06 repo: look up nullrev context by revnum, not symbolic name
Martin von Zweigbergk <martinvonz@google.com>
parents: 38381
diff changeset
87 return repo[nullrev]
24681
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
88
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
89
35905
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
90 # {tags} on ctx includes local tags and 'tip', with no current way to limit
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
91 # that to global tags. Therefore, use {latesttag} as a substitute when
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
92 # the distance is 0, since that will be the list of global tags on ctx.
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
93 _defaultmetatemplate = br'''
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
94 repo: {root}
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
95 node: {ifcontains(rev, revset("wdir()"), "{p1node}{dirty}", "{node}")}
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
96 branch: {branch|utf8}
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
97 {ifeq(latesttagdistance, 0, join(latesttag % "tag: {tag}", "\n"),
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
98 separate("\n",
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
99 join(latesttag % "latesttag: {tag}", "\n"),
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
100 "latesttagdistance: {latesttagdistance}",
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
101 "changessincelatesttag: {changessincelatesttag}"))}
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
102 '''[
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
103 1:
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
104 ] # drop leading '\n'
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
105
35905
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
106
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
107 def buildmetadata(ctx):
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
108 '''build content of .hg_archival.txt'''
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
109 repo = ctx.repo()
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
110
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
111 opts = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
112 b'template': repo.ui.config(
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
113 b'experimental', b'archivemetatemplate', _defaultmetatemplate
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
114 )
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
115 }
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
116
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
117 out = util.stringio()
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
118
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
119 fm = formatter.formatter(repo.ui, out, b'archive', opts)
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
120 fm.startitem()
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
121 fm.context(ctx=ctx)
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
122 fm.data(root=_rootctx(repo).hex())
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
123
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
124 if ctx.rev() is None:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
125 dirty = b''
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
126 if ctx.dirty(missing=True):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
127 dirty = b'+'
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
128 fm.data(dirty=dirty)
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
129 fm.end()
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
130
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
131 return out.getvalue()
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
132
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
133
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
134 class tarit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
135 '''write archive to tar file or stream. can write uncompressed,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
136 or compress with gzip or bzip2.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
137
44475
b7ca03dff14c gzip: use the stdlib version with python 3 (issue6284)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44474
diff changeset
138 if pycompat.ispy3:
b7ca03dff14c gzip: use the stdlib version with python 3 (issue6284)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44474
diff changeset
139 GzipFileWithTime = gzip.GzipFile # camelcase-required
b7ca03dff14c gzip: use the stdlib version with python 3 (issue6284)
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44474
diff changeset
140 else:
44474
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
141
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
142 class GzipFileWithTime(gzip.GzipFile):
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
143 def __init__(self, *args, **kw):
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
144 timestamp = None
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
145 if 'mtime' in kw:
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
146 timestamp = kw.pop('mtime')
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
147 if timestamp is None:
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
148 self.timestamp = time.time()
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
149 else:
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
150 self.timestamp = timestamp
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
151 gzip.GzipFile.__init__(self, *args, **kw)
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
152
44474
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
153 def _write_gzip_header(self):
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
154 self.fileobj.write(b'\037\213') # magic header
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
155 self.fileobj.write(b'\010') # compression method
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
156 fname = self.name
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
157 if fname and fname.endswith(b'.gz'):
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
158 fname = fname[:-3]
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
159 flags = 0
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
160 if fname:
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
161 flags = gzip.FNAME # pytype: disable=module-attr
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
162 self.fileobj.write(pycompat.bytechr(flags))
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
163 gzip.write32u( # pytype: disable=module-attr
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
164 self.fileobj, int(self.timestamp)
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
165 )
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
166 self.fileobj.write(b'\002')
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
167 self.fileobj.write(b'\377')
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
168 if fname:
a23b859ad17d gzip: indent the custom Gzip code
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 44473
diff changeset
169 self.fileobj.write(fname + b'\000')
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
170
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
171 def __init__(self, dest, mtime, kind=b''):
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
172 self.mtime = mtime
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
173 self.fileobj = None
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
174
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
175 def taropen(mode, name=b'', fileobj=None):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
176 if kind == b'gz':
36447
588048a6a8d3 py3: slice over bytes or use .startswith() to prevent getting ascii values
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36437
diff changeset
177 mode = mode[0:1]
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
178 if not fileobj:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
179 fileobj = open(name, mode + b'b')
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
180 gzfileobj = self.GzipFileWithTime(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
181 name,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
182 pycompat.sysstr(mode + b'b'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
183 zlib.Z_BEST_COMPRESSION,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
184 fileobj,
44473
6c36a521572e gzip: rename the argument to `mtime` to match upstream python
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 43506
diff changeset
185 mtime=mtime,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
186 )
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
187 self.fileobj = gzfileobj
43487
d5bef33ab83c archival: suppress some incorrect pytype failures
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
188 return tarfile.TarFile.taropen( # pytype: disable=attribute-error
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
189 name, pycompat.sysstr(mode), gzfileobj
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
190 )
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
191 else:
45048
2c0043977b6d archival: abort if compression method is unavailable
Manuel Jacob <me@manueljacob.de>
parents: 44577
diff changeset
192 try:
2c0043977b6d archival: abort if compression method is unavailable
Manuel Jacob <me@manueljacob.de>
parents: 44577
diff changeset
193 return tarfile.open(
2c0043977b6d archival: abort if compression method is unavailable
Manuel Jacob <me@manueljacob.de>
parents: 44577
diff changeset
194 name, pycompat.sysstr(mode + kind), fileobj
2c0043977b6d archival: abort if compression method is unavailable
Manuel Jacob <me@manueljacob.de>
parents: 44577
diff changeset
195 )
2c0043977b6d archival: abort if compression method is unavailable
Manuel Jacob <me@manueljacob.de>
parents: 44577
diff changeset
196 except tarfile.CompressionError as e:
2c0043977b6d archival: abort if compression method is unavailable
Manuel Jacob <me@manueljacob.de>
parents: 44577
diff changeset
197 raise error.Abort(pycompat.bytestr(e))
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
198
36709
7f9a6f5f7612 archival: our filenames are bytes, not strs
Augie Fackler <augie@google.com>
parents: 36708
diff changeset
199 if isinstance(dest, bytes):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
200 self.z = taropen(b'w:', name=dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
201 else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
202 self.z = taropen(b'w|', fileobj=dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
203
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
204 def addfile(self, name, mode, islink, data):
36707
bfe23afea361 archival: fsdecode paths before passing to tar or zip objects
Augie Fackler <augie@google.com>
parents: 36447
diff changeset
205 name = pycompat.fsdecode(name)
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
206 i = tarfile.TarInfo(name)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
207 i.mtime = self.mtime
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
208 i.size = len(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
209 if islink:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
210 i.type = tarfile.SYMTYPE
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
211 i.mode = 0o777
36707
bfe23afea361 archival: fsdecode paths before passing to tar or zip objects
Augie Fackler <augie@google.com>
parents: 36447
diff changeset
212 i.linkname = pycompat.fsdecode(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
213 data = None
7770
fd3e5ff53a31 fix disappearing symlinks [issue1509]
Peter van Dijk <mercurial-bugs@selenic.com>
parents: 6913
diff changeset
214 i.size = 0
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
215 else:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
216 i.mode = mode
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28017
diff changeset
217 data = stringio(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
218 self.z.addfile(i, data)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
219
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
220 def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
221 self.z.close()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
222 if self.fileobj:
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
223 self.fileobj.close()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
224
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
225
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
226 class zipit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
227 '''write archive to zip file or stream. can write uncompressed,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
228 or compressed with deflate.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
229
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
230 def __init__(self, dest, mtime, compress=True):
40247
844deb408a5b archival: don't try and fsdecode non-{bytes,str} objects
Augie Fackler <augie@google.com>
parents: 39894
diff changeset
231 if isinstance(dest, bytes):
844deb408a5b archival: don't try and fsdecode non-{bytes,str} objects
Augie Fackler <augie@google.com>
parents: 39894
diff changeset
232 dest = pycompat.fsdecode(dest)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
233 self.z = zipfile.ZipFile(
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43487
diff changeset
234 dest, 'w', compress and zipfile.ZIP_DEFLATED or zipfile.ZIP_STORED
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
235 )
12319
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
236
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
237 # Python's zipfile module emits deprecation warnings if we try
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
238 # to store files with a date before 1980.
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
239 epoch = 315532800 # calendar.timegm((1980, 1, 1, 0, 0, 0, 1, 1, 0))
12319
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
240 if mtime < epoch:
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
241 mtime = epoch
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
242
17628
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
243 self.mtime = mtime
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
244 self.date_time = time.gmtime(mtime)[:6]
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
245
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
246 def addfile(self, name, mode, islink, data):
36707
bfe23afea361 archival: fsdecode paths before passing to tar or zip objects
Augie Fackler <augie@google.com>
parents: 36447
diff changeset
247 i = zipfile.ZipInfo(pycompat.fsdecode(name), self.date_time)
43487
d5bef33ab83c archival: suppress some incorrect pytype failures
Augie Fackler <augie@google.com>
parents: 43106
diff changeset
248 i.compress_type = self.z.compression # pytype: disable=attribute-error
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
249 # unzip will not honor unix file modes unless file creator is
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
250 # set to unix (id 3).
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
251 i.create_system = 3
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
252 ftype = _UNX_IFREG
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
253 if islink:
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
254 mode = 0o777
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
255 ftype = _UNX_IFLNK
29890
31a6d5e14508 py3: remove use of *L syntax
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28861
diff changeset
256 i.external_attr = (mode | ftype) << 16
17628
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
257 # add "extended-timestamp" extra block, because zip archives
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
258 # without this will be extracted with unexpected timestamp,
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
259 # if TZ is not configured as GMT
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
260 i.extra += struct.pack(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
261 b'<hhBl',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
262 0x5455, # block type: "extended-timestamp"
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
263 1 + 4, # size of this block
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
264 1, # "modification time is present"
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
265 int(self.mtime),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
266 ) # last modification (UTC)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
267 self.z.writestr(i, data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
268
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
269 def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
270 self.z.close()
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
271
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
272
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
273 class fileit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
274 '''write archive as files in directory.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
275
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
276 def __init__(self, name, mtime):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
277 self.basedir = name
31235
7feab0e7702d vfs: use 'vfs' module directly in 'mercurial.archival'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31216
diff changeset
278 self.opener = vfsmod.vfs(self.basedir)
35202
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
279 self.mtime = mtime
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
280
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
281 def addfile(self, name, mode, islink, data):
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
282 if islink:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
283 self.opener.symlink(data, name)
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
284 return
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
285 f = self.opener(name, b"w", atomictemp=False)
4830
74f36b1027f4 archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4731
diff changeset
286 f.write(data)
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 13970
diff changeset
287 f.close()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
288 destfile = os.path.join(self.basedir, name)
4830
74f36b1027f4 archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4731
diff changeset
289 os.chmod(destfile, mode)
35202
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
290 if self.mtime is not None:
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
291 os.utime(destfile, (self.mtime, self.mtime))
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
292
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
293 def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
294 pass
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
295
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
296
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
297 archivers = {
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
298 b'files': fileit,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
299 b'tar': tarit,
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
300 b'tbz2': lambda name, mtime: tarit(name, mtime, b'bz2'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
301 b'tgz': lambda name, mtime: tarit(name, mtime, b'gz'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
302 b'txz': lambda name, mtime: tarit(name, mtime, b'xz'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
303 b'uzip': lambda name, mtime: zipit(name, mtime, False),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
304 b'zip': zipit,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
305 }
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
306
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
307
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
308 def archive(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
309 repo,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
310 dest,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
311 node,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
312 kind,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
313 decode=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
314 match=None,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
315 prefix=b'',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
316 mtime=None,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
317 subrepos=False,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
318 ):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
319 '''create archive of repo as it was at node.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
320
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
321 dest can be name of directory, name of archive file, or file
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
322 object to write archive to.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
323
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
324 kind is type of archive to create.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
325
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
326 decode tells whether to put files through decode filters from
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
327 hgrc.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
328
40407
3d76a8e627a6 archive: change "matcnfn" argument to a real matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 40247
diff changeset
329 match is a matcher to filter names of files to write to archive.
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
330
35202
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
331 prefix is name of path to put before every archive member.
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
332
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
333 mtime is the modified time, in seconds, or None to use the changeset time.
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
334
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
335 subrepos tells whether to include subrepos.
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
336 '''
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
337
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
338 if kind == b'txz' and not pycompat.ispy3:
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
339 raise error.Abort(_(b'xz compression is only available in Python 3'))
42940
c04e0836f039 archive: add XZ support if built with Python 3
David Demelier <markand@malikania.fr>
parents: 41631
diff changeset
340
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
341 if kind == b'files':
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
342 if prefix:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
343 raise error.Abort(_(b'cannot give prefix when archiving to files'))
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
344 else:
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
345 prefix = tidyprefix(dest, kind, prefix)
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
346
4951
667290b6c95e archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4831
diff changeset
347 def write(name, mode, islink, getdata):
667290b6c95e archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4831
diff changeset
348 data = getdata()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
349 if decode:
4005
656e06eebda7 replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents: 3968
diff changeset
350 data = repo.wwritedata(name, data)
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
351 archiver.addfile(prefix + name, mode, islink, data)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
352
6019
b70a530bdb93 cleanly abort on unknown archive type (issue966)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 4951
diff changeset
353 if kind not in archivers:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
354 raise error.Abort(_(b"unknown archive type '%s'") % kind)
6749
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
355
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
356 ctx = repo[node]
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
357 archiver = archivers[kind](dest, mtime or ctx.date()[0])
6749
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
358
40408
997997eb8367 archive: create alwaysmatcher when no matcher provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 40407
diff changeset
359 if not match:
997997eb8367 archive: create alwaysmatcher when no matcher provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 40407
diff changeset
360 match = scmutil.matchall(repo)
997997eb8367 archive: create alwaysmatcher when no matcher provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 40407
diff changeset
361
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
362 if repo.ui.configbool(b"ui", b"archivemeta"):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
363 name = b'.hg_archival.txt'
40408
997997eb8367 archive: create alwaysmatcher when no matcher provided
Martin von Zweigbergk <martinvonz@google.com>
parents: 40407
diff changeset
364 if match(name):
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
365 write(name, 0o644, False, lambda: buildmetadata(ctx))
9614
58edd448da4f archive: add branch and tag informations to the .hg_archival.txt file
Gilles Moris <gilles.moris@free.fr>
parents: 8778
diff changeset
366
44284
e786d69c665d archival: use walk() instead of matches() on manifest
Augie Fackler <augie@google.com>
parents: 43506
diff changeset
367 files = list(ctx.manifest().walk(match))
16919
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
368 total = len(files)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
369 if total:
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
370 files.sort()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
371 scmutil.prefetchfiles(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
372 repo, [ctx.rev()], scmutil.matchfiles(repo, files)
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
373 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
374 progress = repo.ui.makeprogress(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
375 _(b'archiving'), unit=_(b'files'), total=total
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 42940
diff changeset
376 )
38381
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
377 progress.update(0)
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
378 for f in files:
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
379 ff = ctx.flags(f)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
380 write(f, b'x' in ff and 0o755 or 0o644, b'l' in ff, ctx[f].data)
38381
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
381 progress.increment(item=f)
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
382 progress.complete()
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
383
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
384 if subrepos:
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18344
diff changeset
385 for subpath in sorted(ctx.substate):
25601
3ec8351fa6ed archive: support 'wdir()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 25149
diff changeset
386 sub = ctx.workingsub(subpath)
40407
3d76a8e627a6 archive: change "matcnfn" argument to a real matcher
Martin von Zweigbergk <martinvonz@google.com>
parents: 40247
diff changeset
387 submatch = matchmod.subdirmatcher(subpath, match)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
388 subprefix = prefix + subpath + b'/'
41631
3d9d5e612e67 subrepo: adjust subrepo prefix before calling subrepo.archive() (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 41208
diff changeset
389 total += sub.archive(archiver, subprefix, submatch, decode)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
390
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
391 if total == 0:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
392 raise error.Abort(_(b'no files match the archive pattern'))
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
393
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
394 archiver.done()
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
395 return total