mercurial/archival.py
author Pulkit Goyal <7895pulkit@gmail.com>
Wed, 23 Nov 2016 00:03:11 +0530
changeset 30519 20a42325fdef
parent 30479 798bcb1274dd
child 31099 b44ab288358e
permissions -rw-r--r--
py3: use pycompat.getcwd() instead of os.getcwd() We have pycompat.getcwd() which returns bytes path on Python 3. This patch changes most of the occurences of the os.getcwd() with pycompat one.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 _
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    19
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    20
from . import (
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    21
    cmdutil,
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    22
    encoding,
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    23
    error,
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    24
    match as matchmod,
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    25
    scmutil,
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    26
    util,
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    27
)
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28017
diff changeset
    28
stringio = util.stringio
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    29
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
    30
# from unzip source code:
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
    31
_UNX_IFREG = 0x8000
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
    32
_UNX_IFLNK = 0xa000
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
    33
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
    34
def tidyprefix(dest, kind, prefix):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    35
    '''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
    36
    safe for consumers.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    37
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    38
    if prefix:
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 4951
diff changeset
    39
        prefix = util.normpath(prefix)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    40
    else:
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    41
        if not isinstance(dest, str):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    42
            raise ValueError('dest must be string if no prefix')
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    43
        prefix = os.path.basename(dest)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    44
        lower = prefix.lower()
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
    45
        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
    46
            if lower.endswith(sfx):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    47
                prefix = prefix[:-len(sfx)]
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    48
                break
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    49
    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
    50
    prefix = util.pconvert(lpfx)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    51
    if not prefix.endswith('/'):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    52
        prefix += '/'
24953
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
    53
    # 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
    54
    # zip files (issue4634)
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
    55
    if prefix.startswith('./'):
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
    56
        prefix = prefix[2:]
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    57
    if prefix.startswith('../') or os.path.isabs(lpfx) or '/../' in prefix:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26198
diff changeset
    58
        raise error.Abort(_('archive prefix contains illegal components'))
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    59
    return prefix
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    60
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    61
exts = {
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    62
    'tar': ['.tar'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    63
    'tbz2': ['.tbz2', '.tar.bz2'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    64
    'tgz': ['.tgz', '.tar.gz'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    65
    'zip': ['.zip'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    66
    }
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    67
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    68
def guesskind(dest):
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    69
    for kind, extensions in exts.iteritems():
25149
3f0744eeaeaf cleanup: use __builtins__.any instead of util.any
Augie Fackler <augie@google.com>
parents: 24953
diff changeset
    70
        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
    71
            return kind
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    72
    return None
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    73
24681
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
    74
def _rootctx(repo):
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
    75
    # 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
    76
    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
    77
        return repo[rev]
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
    78
    return repo['null']
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
    79
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    80
def buildmetadata(ctx):
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    81
    '''build content of .hg_archival.txt'''
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    82
    repo = ctx.repo()
25615
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    83
    hex = ctx.hex()
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    84
    if ctx.rev() is None:
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    85
        hex = ctx.p1().hex()
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    86
        if ctx.dirty():
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    87
            hex += '+'
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    88
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    89
    base = 'repo: %s\nnode: %s\nbranch: %s\n' % (
25615
dc707fb35550 archive: report the node as "{p1node}+" when archiving a dirty wdir()
Matt Harbison <matt_harbison@yahoo.com>
parents: 25601
diff changeset
    90
        _rootctx(repo).hex(), hex, encoding.fromlocal(ctx.branch()))
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    91
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    92
    tags = ''.join('tag: %s\n' % t for t in ctx.tags()
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    93
                   if repo.tagtype(t) == 'global')
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    94
    if not tags:
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    95
        repo.ui.pushbuffer()
25725
f5f43178bdde archive: use {changessincelatesttag} to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 25695
diff changeset
    96
        opts = {'template': '{latesttag}\n{latesttagdistance}\n'
f5f43178bdde archive: use {changessincelatesttag} to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 25695
diff changeset
    97
                            '{changessincelatesttag}',
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    98
                'style': '', 'patch': None, 'git': None}
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    99
        cmdutil.show_changeset(repo.ui, repo, opts).show(ctx)
25725
f5f43178bdde archive: use {changessincelatesttag} to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 25695
diff changeset
   100
        ltags, dist, changessince = repo.ui.popbuffer().split('\n')
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   101
        ltags = ltags.split(':')
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   102
        tags = ''.join('latesttag: %s\n' % t for t in ltags)
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   103
        tags += 'latesttagdistance: %s\n' % dist
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   104
        tags += 'changessincelatesttag: %s\n' % changessince
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   105
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   106
    return base + tags
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   107
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   108
class tarit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   109
    '''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
   110
    or compress with gzip or bzip2.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   111
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   112
    class GzipFileWithTime(gzip.GzipFile):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   113
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   114
        def __init__(self, *args, **kw):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   115
            timestamp = None
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   116
            if 'timestamp' in kw:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   117
                timestamp = kw.pop('timestamp')
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8312
diff changeset
   118
            if timestamp is None:
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   119
                self.timestamp = time.time()
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   120
            else:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   121
                self.timestamp = timestamp
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   122
            gzip.GzipFile.__init__(self, *args, **kw)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   123
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   124
        def _write_gzip_header(self):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   125
            self.fileobj.write('\037\213')             # magic header
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   126
            self.fileobj.write('\010')                 # compression method
26198
1a781a986611 archival: drop self.filename - deprecated in py2.6
timeless@mozdev.org
parents: 25916
diff changeset
   127
            fname = self.name
13102
2956945c3bee archival: don't set gzip filename header when there's no filename
Brodie Rao <brodie@bitheap.org>
parents: 12323
diff changeset
   128
            if fname and fname.endswith('.gz'):
2956945c3bee archival: don't set gzip filename header when there's no filename
Brodie Rao <brodie@bitheap.org>
parents: 12323
diff changeset
   129
                fname = fname[:-3]
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   130
            flags = 0
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   131
            if fname:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   132
                flags = gzip.FNAME
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   133
            self.fileobj.write(chr(flags))
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   134
            gzip.write32u(self.fileobj, long(self.timestamp))
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   135
            self.fileobj.write('\002')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   136
            self.fileobj.write('\377')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   137
            if fname:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   138
                self.fileobj.write(fname + '\000')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   139
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   140
    def __init__(self, dest, mtime, kind=''):
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   141
        self.mtime = mtime
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   142
        self.fileobj = None
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   143
30479
798bcb1274dd archival: simplify code and drop message about Python 2.5
Augie Fackler <augie@google.com>
parents: 29890
diff changeset
   144
        def taropen(mode, name='', fileobj=None):
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   145
            if kind == 'gz':
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   146
                mode = mode[0]
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   147
                if not fileobj:
4731
1d5a2ee683b0 Fix tgz archival on Windows.
csaba.henk@creo.hu
parents: 4685
diff changeset
   148
                    fileobj = open(name, mode + 'b')
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   149
                gzfileobj = self.GzipFileWithTime(name, mode + 'b',
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   150
                                                  zlib.Z_BEST_COMPRESSION,
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   151
                                                  fileobj, timestamp=mtime)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   152
                self.fileobj = gzfileobj
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   153
                return tarfile.TarFile.taropen(name, mode, gzfileobj)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   154
            else:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   155
                return tarfile.open(name, mode + kind, fileobj)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   156
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   157
        if isinstance(dest, str):
30479
798bcb1274dd archival: simplify code and drop message about Python 2.5
Augie Fackler <augie@google.com>
parents: 29890
diff changeset
   158
            self.z = taropen('w:', name=dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   159
        else:
30479
798bcb1274dd archival: simplify code and drop message about Python 2.5
Augie Fackler <augie@google.com>
parents: 29890
diff changeset
   160
            self.z = taropen('w|', fileobj=dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   161
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   162
    def addfile(self, name, mode, islink, data):
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   163
        i = tarfile.TarInfo(name)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   164
        i.mtime = self.mtime
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   165
        i.size = len(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   166
        if islink:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   167
            i.type = tarfile.SYMTYPE
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   168
            i.mode = 0o777
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   169
            i.linkname = data
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   170
            data = None
7770
fd3e5ff53a31 fix disappearing symlinks [issue1509]
Peter van Dijk <mercurial-bugs@selenic.com>
parents: 6913
diff changeset
   171
            i.size = 0
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   172
        else:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   173
            i.mode = mode
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28017
diff changeset
   174
            data = stringio(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   175
        self.z.addfile(i, data)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   176
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   177
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   178
        self.z.close()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   179
        if self.fileobj:
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   180
            self.fileobj.close()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   181
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   182
class tellable(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   183
    '''provide tell method for zipfile.ZipFile when writing to http
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   184
    response file object.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   185
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   186
    def __init__(self, fp):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   187
        self.fp = fp
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   188
        self.offset = 0
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   189
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   190
    def __getattr__(self, key):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   191
        return getattr(self.fp, key)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   192
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   193
    def write(self, s):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   194
        self.fp.write(s)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   195
        self.offset += len(s)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   196
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   197
    def tell(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   198
        return self.offset
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   199
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   200
class zipit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   201
    '''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
   202
    or compressed with deflate.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   203
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   204
    def __init__(self, dest, mtime, compress=True):
2168
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   205
        if not isinstance(dest, str):
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   206
            try:
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   207
                dest.tell()
2169
4564794b6f55 Combine catching exceptions added in dd4ec4576cc8 in one except statement.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2168
diff changeset
   208
            except (AttributeError, IOError):
2168
dd4ec4576cc8 Proper check to see if zip dest needs to be wrapped in tellable
Colin McMillen <mcmillen@cs.cmu.edu>
parents: 2112
diff changeset
   209
                dest = tellable(dest)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   210
        self.z = zipfile.ZipFile(dest, 'w',
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   211
                                 compress and zipfile.ZIP_DEFLATED or
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   212
                                 zipfile.ZIP_STORED)
12319
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   213
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   214
        # 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
   215
        # to store files with a date before 1980.
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   216
        epoch = 315532800 # calendar.timegm((1980, 1, 1, 0, 0, 0, 1, 1, 0))
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   217
        if mtime < epoch:
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   218
            mtime = epoch
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   219
17628
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
   220
        self.mtime = mtime
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   221
        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
   222
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   223
    def addfile(self, name, mode, islink, data):
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   224
        i = zipfile.ZipInfo(name, self.date_time)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   225
        i.compress_type = self.z.compression
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   226
        # 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
   227
        # set to unix (id 3).
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   228
        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
   229
        ftype = _UNX_IFREG
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   230
        if islink:
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   231
            mode = 0o777
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
   232
            ftype = _UNX_IFLNK
29890
31a6d5e14508 py3: remove use of *L syntax
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28861
diff changeset
   233
        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
   234
        # 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
   235
        # 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
   236
        # if TZ is not configured as GMT
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
   237
        i.extra += struct.pack('<hhBl',
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
   238
                               0x5455,     # block type: "extended-timestamp"
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
   239
                               1 + 4,      # size of this block
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
   240
                               1,          # "modification time is present"
18301
49ad7030ecc4 archival: pass integer to struct.pack int field instead of float
Mads Kiilerich <madski@unity3d.com>
parents: 17629
diff changeset
   241
                               int(self.mtime)) # last modification (UTC)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   242
        self.z.writestr(i, data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   243
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   244
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   245
        self.z.close()
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   246
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   247
class fileit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   248
    '''write archive as files in directory.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   249
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   250
    def __init__(self, name, mtime):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   251
        self.basedir = name
13970
d13913355390 move opener from util to scmutil
Adrian Buehlmann <adrian@cadifra.com>
parents: 13668
diff changeset
   252
        self.opener = scmutil.opener(self.basedir)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   253
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   254
    def addfile(self, name, mode, islink, data):
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   255
        if islink:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   256
            self.opener.symlink(data, name)
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   257
            return
4830
74f36b1027f4 archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4731
diff changeset
   258
        f = self.opener(name, "w", atomictemp=True)
74f36b1027f4 archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4731
diff changeset
   259
        f.write(data)
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 13970
diff changeset
   260
        f.close()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   261
        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
   262
        os.chmod(destfile, mode)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   263
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   264
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   265
        pass
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   266
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   267
archivers = {
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   268
    'files': fileit,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   269
    'tar': tarit,
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   270
    'tbz2': lambda name, mtime: tarit(name, mtime, 'bz2'),
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   271
    'tgz': lambda name, mtime: tarit(name, mtime, 'gz'),
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   272
    'uzip': lambda name, mtime: zipit(name, mtime, False),
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   273
    'zip': zipit,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   274
    }
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   275
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   276
def archive(repo, dest, node, kind, decode=True, matchfn=None,
24172
e0f06228bb66 archive: change the default prefix to '' from None
Matt Harbison <matt_harbison@yahoo.com>
parents: 23645
diff changeset
   277
            prefix='', mtime=None, subrepos=False):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   278
    '''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
   279
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   280
    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
   281
    object to write archive to.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   282
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   283
    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
   284
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   285
    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
   286
    hgrc.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   287
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   288
    matchfn is function to filter names of files to write to archive.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   289
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   290
    prefix is name of path to put before every archive member.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   291
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   292
    if kind == 'files':
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   293
        if prefix:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26198
diff changeset
   294
            raise error.Abort(_('cannot give prefix when archiving to files'))
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   295
    else:
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   296
        prefix = tidyprefix(dest, kind, prefix)
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   297
4951
667290b6c95e archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4831
diff changeset
   298
    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
   299
        data = getdata()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   300
        if decode:
4005
656e06eebda7 replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents: 3968
diff changeset
   301
            data = repo.wwritedata(name, data)
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   302
        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
   303
6019
b70a530bdb93 cleanly abort on unknown archive type (issue966)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 4951
diff changeset
   304
    if kind not in archivers:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26198
diff changeset
   305
        raise error.Abort(_("unknown archive type '%s'") % kind)
6749
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
   306
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
   307
    ctx = repo[node]
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   308
    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
   309
6183
0750e4ba9d3d Add config option to disable putting .hg_archival.txt inside archives.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6020
diff changeset
   310
    if repo.ui.configbool("ui", "archivemeta", True):
16919
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   311
        name = '.hg_archival.txt'
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   312
        if not matchfn or matchfn(name):
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   313
            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
   314
16919
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   315
    if matchfn:
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   316
        files = [f for f in ctx.manifest().keys() if matchfn(f)]
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   317
    else:
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   318
        files = ctx.manifest().keys()
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   319
    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
   320
    if total:
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   321
        files.sort()
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   322
        repo.ui.progress(_('archiving'), 0, unit=_('files'), total=total)
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   323
        for i, f in enumerate(files):
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   324
            ff = ctx.flags(f)
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   325
            write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, ctx[f].data)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   326
            repo.ui.progress(_('archiving'), i + 1, item=f,
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   327
                             unit=_('files'), total=total)
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   328
        repo.ui.progress(_('archiving'), None)
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
   329
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
   330
    if subrepos:
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18344
diff changeset
   331
        for subpath in sorted(ctx.substate):
25601
3ec8351fa6ed archive: support 'wdir()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 25149
diff changeset
   332
            sub = ctx.workingsub(subpath)
28017
d3f1b7ee5e70 match: rename "narrowmatcher" to "subdirmatcher" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 26587
diff changeset
   333
            submatch = matchmod.subdirmatcher(subpath, matchfn)
23575
a2f139d25845 subrepo: drop the 'ui' parameter to archive()
Matt Harbison <matt_harbison@yahoo.com>
parents: 18967
diff changeset
   334
            total += sub.archive(archiver, prefix, submatch)
18967
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   335
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   336
    if total == 0:
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   337
        raise error.Abort(_('no files match the archive pattern'))
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
   338
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   339
    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
   340
    return total