mercurial/archival.py
author Augie Fackler <augie@google.com>
Mon, 29 Oct 2018 16:23:42 -0400
branchstable
changeset 40426 588f1e9a4d16
parent 40247 844deb408a5b
child 40407 3d76a8e627a6
permissions -rw-r--r--
http: work around custom http client classes that refuse extra attrs I have no idea what is going on with our custom http client code at Google, but it chokes on these extra attributes we're tucking on http clients. Since it feels more than a little wrong to just stuff extra data on a client, let's degrade gracefully when the client class refuses the attributes.
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 _
39894
d739f423bf06 repo: look up nullrev context by revnum, not symbolic name
Martin von Zweigbergk <martinvonz@google.com>
parents: 38381
diff changeset
    19
from .node import (
d739f423bf06 repo: look up nullrev context by revnum, not symbolic name
Martin von Zweigbergk <martinvonz@google.com>
parents: 38381
diff changeset
    20
    nullrev,
d739f423bf06 repo: look up nullrev context by revnum, not symbolic name
Martin von Zweigbergk <martinvonz@google.com>
parents: 38381
diff changeset
    21
)
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    22
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    23
from . import (
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    24
    error,
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
    25
    formatter,
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    26
    match as matchmod,
36707
bfe23afea361 archival: fsdecode paths before passing to tar or zip objects
Augie Fackler <augie@google.com>
parents: 36447
diff changeset
    27
    pycompat,
36139
b72c6ff4e4c0 archive: migrate to the fileprefetch callback mechanism
Matt Harbison <matt_harbison@yahoo.com>
parents: 36036
diff changeset
    28
    scmutil,
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
diff changeset
    29
    util,
31235
7feab0e7702d vfs: use 'vfs' module directly in 'mercurial.archival'
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 31216
diff changeset
    30
    vfs as vfsmod,
25916
c1777ece502a archival: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25725
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
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
    36
_UNX_IFLNK = 0xa000
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
    37
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
    38
def tidyprefix(dest, kind, prefix):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    39
    '''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
    40
    safe for consumers.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    41
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    42
    if prefix:
5842
111ed8c871bf Use util.normpath() instead of direct path string operation.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 4951
diff changeset
    43
        prefix = util.normpath(prefix)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    44
    else:
36437
745b0df08514 py3: use bytes instead of str in isinstance
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36139
diff changeset
    45
        if not isinstance(dest, bytes):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    46
            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
    47
        prefix = os.path.basename(dest)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    48
        lower = prefix.lower()
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
    49
        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
    50
            if lower.endswith(sfx):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    51
                prefix = prefix[:-len(sfx)]
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    52
                break
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    53
    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
    54
    prefix = util.pconvert(lpfx)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    55
    if not prefix.endswith('/'):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    56
        prefix += '/'
24953
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
    57
    # 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
    58
    # zip files (issue4634)
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
    59
    if prefix.startswith('./'):
5115d03440f4 archive: drop the leading '.' path component from the prefix (issue4634)
Matt Harbison <matt_harbison@yahoo.com>
parents: 24681
diff changeset
    60
        prefix = prefix[2:]
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    61
    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
    62
        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
    63
    return prefix
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
    64
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    65
exts = {
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    66
    'tar': ['.tar'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    67
    'tbz2': ['.tbz2', '.tar.bz2'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    68
    'tgz': ['.tgz', '.tar.gz'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    69
    'zip': ['.zip'],
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    70
    }
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    71
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    72
def guesskind(dest):
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    73
    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
    74
        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
    75
            return kind
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    76
    return None
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
    77
24681
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
    78
def _rootctx(repo):
33ab99a6ad9b archive: look for first visible revision to build repo identity (issue4591)
Yuya Nishihara <yuya@tcha.org>
parents: 24678
diff changeset
    79
    # 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
    80
    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
    81
        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
    82
    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
    83
35905
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    84
# {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
    85
# 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
    86
# 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
    87
_defaultmetatemplate = br'''
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    88
repo: {root}
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    89
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
    90
branch: {branch|utf8}
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    91
{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
    92
      separate("\n",
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    93
               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
    94
               "latesttagdistance: {latesttagdistance}",
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    95
               "changessincelatesttag: {changessincelatesttag}"))}
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    96
'''[1:]  # drop leading '\n'
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
    97
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    98
def buildmetadata(ctx):
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
    99
    '''build content of .hg_archival.txt'''
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   100
    repo = ctx.repo()
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   101
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   102
    opts = {
33545
8074e2d006c0 archive: add an experimental config to control the metadata file template
Matt Harbison <matt_harbison@yahoo.com>
parents: 33544
diff changeset
   103
        'template': repo.ui.config('experimental', 'archivemetatemplate',
35905
887bbce7f491 archive: rewrite default metadata template as a multi-line bytes literal
Yuya Nishihara <yuya@tcha.org>
parents: 35349
diff changeset
   104
                                   _defaultmetatemplate)
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   105
    }
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   106
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   107
    out = util.stringio()
24678
fbcace19534f archive: extract metadata() closure to module-level function
Yuya Nishihara <yuya@tcha.org>
parents: 24677
diff changeset
   108
33544
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   109
    fm = formatter.formatter(repo.ui, out, 'archive', opts)
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   110
    fm.startitem()
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   111
    fm.context(ctx=ctx)
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   112
    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
   113
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   114
    if ctx.rev() is None:
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   115
        dirty = ''
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   116
        if ctx.dirty(missing=True):
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   117
            dirty = '+'
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   118
        fm.data(dirty=dirty)
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   119
    fm.end()
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   120
4c4e95cae33a archive: use a templater to build the metadata file
Matt Harbison <matt_harbison@yahoo.com>
parents: 33499
diff changeset
   121
    return out.getvalue()
11557
57bdc2239535 archival: move commands.archive.guess_type to archival.guesskind
Martin Geisler <mg@lazybytes.net>
parents: 10282
diff changeset
   122
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   123
class tarit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   124
    '''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
   125
    or compress with gzip or bzip2.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   126
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   127
    class GzipFileWithTime(gzip.GzipFile):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   128
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   129
        def __init__(self, *args, **kw):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   130
            timestamp = None
36726
009da8c28e4d archival: fix a missing r'' on a kwargs check
Augie Fackler <augie@google.com>
parents: 36709
diff changeset
   131
            if r'timestamp' in kw:
35349
a274c4b698f2 py3: handle keyword arguments correctly in archival.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35202
diff changeset
   132
                timestamp = kw.pop(r'timestamp')
8527
f9a80054dd3c use 'x is None' instead of 'x == None'
Martin Geisler <mg@lazybytes.net>
parents: 8312
diff changeset
   133
            if timestamp is None:
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   134
                self.timestamp = time.time()
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   135
            else:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   136
                self.timestamp = timestamp
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   137
            gzip.GzipFile.__init__(self, *args, **kw)
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   138
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   139
        def _write_gzip_header(self):
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   140
            self.fileobj.write('\037\213')             # magic header
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   141
            self.fileobj.write('\010')                 # compression method
26198
1a781a986611 archival: drop self.filename - deprecated in py2.6
timeless@mozdev.org
parents: 25916
diff changeset
   142
            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
   143
            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
   144
                fname = fname[:-3]
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   145
            flags = 0
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   146
            if fname:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   147
                flags = gzip.FNAME
36728
f14ba6eb2b5a archival: use py3 friendly replacements for chr() and long()
Augie Fackler <augie@google.com>
parents: 36727
diff changeset
   148
            self.fileobj.write(pycompat.bytechr(flags))
f14ba6eb2b5a archival: use py3 friendly replacements for chr() and long()
Augie Fackler <augie@google.com>
parents: 36727
diff changeset
   149
            gzip.write32u(self.fileobj, int(self.timestamp))
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   150
            self.fileobj.write('\002')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   151
            self.fileobj.write('\377')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   152
            if fname:
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   153
                self.fileobj.write(fname + '\000')
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   154
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   155
    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
   156
        self.mtime = mtime
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   157
        self.fileobj = None
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   158
30479
798bcb1274dd archival: simplify code and drop message about Python 2.5
Augie Fackler <augie@google.com>
parents: 29890
diff changeset
   159
        def taropen(mode, name='', fileobj=None):
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   160
            if kind == 'gz':
36447
588048a6a8d3 py3: slice over bytes or use .startswith() to prevent getting ascii values
Pulkit Goyal <7895pulkit@gmail.com>
parents: 36437
diff changeset
   161
                mode = mode[0:1]
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   162
                if not fileobj:
4731
1d5a2ee683b0 Fix tgz archival on Windows.
csaba.henk@creo.hu
parents: 4685
diff changeset
   163
                    fileobj = open(name, mode + 'b')
36727
d3c231f8d27d archival: ensure file mode for gzipfile is sysstr
Augie Fackler <augie@google.com>
parents: 36726
diff changeset
   164
                gzfileobj = self.GzipFileWithTime(name,
d3c231f8d27d archival: ensure file mode for gzipfile is sysstr
Augie Fackler <augie@google.com>
parents: 36726
diff changeset
   165
                                                  pycompat.sysstr(mode + 'b'),
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   166
                                                  zlib.Z_BEST_COMPRESSION,
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   167
                                                  fileobj, timestamp=mtime)
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   168
                self.fileobj = gzfileobj
36708
abf252a1c938 archival: tar file modes need to be sysstrs
Augie Fackler <augie@google.com>
parents: 36707
diff changeset
   169
                return tarfile.TarFile.taropen(
abf252a1c938 archival: tar file modes need to be sysstrs
Augie Fackler <augie@google.com>
parents: 36707
diff changeset
   170
                    name, pycompat.sysstr(mode), gzfileobj)
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   171
            else:
36708
abf252a1c938 archival: tar file modes need to be sysstrs
Augie Fackler <augie@google.com>
parents: 36707
diff changeset
   172
                return tarfile.open(
abf252a1c938 archival: tar file modes need to be sysstrs
Augie Fackler <augie@google.com>
parents: 36707
diff changeset
   173
                    name, pycompat.sysstr(mode + kind), fileobj)
4652
06de65673ec2 timestamp of gzip archives taken from changeset context
csaba.henk@creo.hu
parents: 4370
diff changeset
   174
36709
7f9a6f5f7612 archival: our filenames are bytes, not strs
Augie Fackler <augie@google.com>
parents: 36708
diff changeset
   175
        if isinstance(dest, bytes):
30479
798bcb1274dd archival: simplify code and drop message about Python 2.5
Augie Fackler <augie@google.com>
parents: 29890
diff changeset
   176
            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
   177
        else:
30479
798bcb1274dd archival: simplify code and drop message about Python 2.5
Augie Fackler <augie@google.com>
parents: 29890
diff changeset
   178
            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
   179
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   180
    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
   181
        name = pycompat.fsdecode(name)
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   182
        i = tarfile.TarInfo(name)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   183
        i.mtime = self.mtime
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   184
        i.size = len(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   185
        if islink:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   186
            i.type = tarfile.SYMTYPE
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   187
            i.mode = 0o777
36707
bfe23afea361 archival: fsdecode paths before passing to tar or zip objects
Augie Fackler <augie@google.com>
parents: 36447
diff changeset
   188
            i.linkname = pycompat.fsdecode(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   189
            data = None
7770
fd3e5ff53a31 fix disappearing symlinks [issue1509]
Peter van Dijk <mercurial-bugs@selenic.com>
parents: 6913
diff changeset
   190
            i.size = 0
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   191
        else:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   192
            i.mode = mode
28861
86db5cb55d46 pycompat: switch to util.stringio for py3 compat
timeless <timeless@mozdev.org>
parents: 28017
diff changeset
   193
            data = stringio(data)
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   194
        self.z.addfile(i, data)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   195
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   196
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   197
        self.z.close()
13400
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   198
        if self.fileobj:
14f3795a5ed7 explicitly close files
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 13144
diff changeset
   199
            self.fileobj.close()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   200
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   201
class zipit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   202
    '''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
   203
    or compressed with deflate.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   204
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   205
    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
   206
        if isinstance(dest, bytes):
844deb408a5b archival: don't try and fsdecode non-{bytes,str} objects
Augie Fackler <augie@google.com>
parents: 39894
diff changeset
   207
            dest = pycompat.fsdecode(dest)
844deb408a5b archival: don't try and fsdecode non-{bytes,str} objects
Augie Fackler <augie@google.com>
parents: 39894
diff changeset
   208
        self.z = zipfile.ZipFile(dest, r'w',
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   209
                                 compress and zipfile.ZIP_DEFLATED or
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   210
                                 zipfile.ZIP_STORED)
12319
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   211
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   212
        # 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
   213
        # 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
   214
        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
   215
        if mtime < epoch:
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   216
            mtime = epoch
381f131220ad archive: set date to 1980 for very old zip files
Martin Geisler <mg@aragost.com>
parents: 10282
diff changeset
   217
17628
133d13e44544 archival: add "extended-timestamp" extra block for zip archives (issue3600)
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 17108
diff changeset
   218
        self.mtime = mtime
2477
857591c586e0 use commit time as mtime for file archives.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2353
diff changeset
   219
        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
   220
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   221
    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
   222
        i = zipfile.ZipInfo(pycompat.fsdecode(name), self.date_time)
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   223
        i.compress_type = self.z.compression
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   224
        # 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
   225
        # set to unix (id 3).
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   226
        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
   227
        ftype = _UNX_IFREG
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   228
        if islink:
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   229
            mode = 0o777
17429
72fa4ef2245f declare local constants instead of using magic values and comments
Mads Kiilerich <mads@kiilerich.com>
parents: 17108
diff changeset
   230
            ftype = _UNX_IFLNK
29890
31a6d5e14508 py3: remove use of *L syntax
Pulkit Goyal <7895pulkit@gmail.com>
parents: 28861
diff changeset
   231
        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
   232
        # 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
   233
        # 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
   234
        # 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
   235
        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
   236
                               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
   237
                               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
   238
                               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
   239
                               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
   240
        self.z.writestr(i, data)
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   241
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   242
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   243
        self.z.close()
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   244
8778
c5f36402daad use new style classes
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 8527
diff changeset
   245
class fileit(object):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   246
    '''write archive as files in directory.'''
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   247
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   248
    def __init__(self, name, mtime):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   249
        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
   250
        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
   251
        self.mtime = mtime
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   252
4831
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   253
    def addfile(self, name, mode, islink, data):
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   254
        if islink:
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   255
            self.opener.symlink(data, name)
6f08bc1bd00b archive: add symlink support
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4830
diff changeset
   256
            return
36767
a148c67d8b09 archival: fileit should not use atomictemp, causes performance regression
Vincent Parrett <vincent@finalbuilder.com>
parents: 36728
diff changeset
   257
        f = self.opener(name, "w", atomictemp=False)
4830
74f36b1027f4 archive: use util.opener when archiving files.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4731
diff changeset
   258
        f.write(data)
15057
774da7121fc9 atomictempfile: make close() consistent with other file-like objects.
Greg Ward <greg@gerg.ca>
parents: 13970
diff changeset
   259
        f.close()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   260
        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
   261
        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
   262
        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
   263
            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
   264
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   265
    def done(self):
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   266
        pass
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   267
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   268
archivers = {
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   269
    'files': fileit,
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   270
    'tar': tarit,
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   271
    'tbz2': lambda name, mtime: tarit(name, mtime, 'bz2'),
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   272
    'tgz': lambda name, mtime: tarit(name, mtime, 'gz'),
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   273
    '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
   274
    'zip': zipit,
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
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   277
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
   278
            prefix='', mtime=None, subrepos=False):
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   279
    '''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
   280
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   281
    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
   282
    object to write archive to.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   283
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   284
    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
   285
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   286
    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
   287
    hgrc.
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   288
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   289
    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
   290
35202
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
   291
    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
   292
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
   293
    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
   294
760fef6aca74 archive: pass thru mtime for directory archives, like other archive types do
James May <james.may@draeger.com>
parents: 33545
diff changeset
   295
    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
   296
    '''
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   297
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   298
    if kind == 'files':
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   299
        if prefix:
26587
56b2bcea2529 error: get Abort from 'error' instead of 'util'
Pierre-Yves David <pierre-yves.david@fb.com>
parents: 26198
diff changeset
   300
            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
   301
    else:
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   302
        prefix = tidyprefix(dest, kind, prefix)
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   303
4951
667290b6c95e archive: delay extraction of file revisions
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4831
diff changeset
   304
    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
   305
        data = getdata()
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   306
        if decode:
4005
656e06eebda7 replace filehandle version of wwrite with wwritedata
Matt Mackall <mpm@selenic.com>
parents: 3968
diff changeset
   307
            data = repo.wwritedata(name, data)
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   308
        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
   309
6019
b70a530bdb93 cleanly abort on unknown archive type (issue966)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 4951
diff changeset
   310
    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
   311
        raise error.Abort(_("unknown archive type '%s'") % kind)
6749
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
   312
51b0e799352f manifest: remove execf/linkf methods
Matt Mackall <mpm@selenic.com>
parents: 6747
diff changeset
   313
    ctx = repo[node]
11558
d8f6458434ec archival: remove prefix argument from archivers
Martin Geisler <mg@lazybytes.net>
parents: 11557
diff changeset
   314
    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
   315
33499
0407a51b9d8c codemod: register core configitems using a script
Jun Wu <quark@fb.com>
parents: 33363
diff changeset
   316
    if repo.ui.configbool("ui", "archivemeta"):
16919
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   317
        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
   318
        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
   319
            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
   320
16919
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   321
    if matchfn:
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   322
        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
   323
    else:
51932c835b74 archive: make progress only show files that are actually archived
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15057
diff changeset
   324
        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
   325
    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
   326
    if total:
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   327
        files.sort()
37762
7269b87f817c scmutil: teach the file prefetch hook to handle multiple commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 36875
diff changeset
   328
        scmutil.prefetchfiles(repo, [ctx.rev()],
7269b87f817c scmutil: teach the file prefetch hook to handle multiple commits
Matt Harbison <matt_harbison@yahoo.com>
parents: 36875
diff changeset
   329
                              scmutil.matchfiles(repo, files))
38381
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
   330
        progress = scmutil.progress(repo.ui, _('archiving'), unit=_('files'),
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
   331
                                    total=total)
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
   332
        progress.update(0)
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
   333
        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
   334
            ff = ctx.flags(f)
25658
e93036747902 global: mass rewrite to use modern octal syntax
Gregory Szorc <gregory.szorc@gmail.com>
parents: 25615
diff changeset
   335
            write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, ctx[f].data)
38381
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
   336
            progress.increment(item=f)
1a2ff11e8a88 archival: use progress helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 37762
diff changeset
   337
        progress.complete()
12323
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
   338
f00953d9533c subrepo: add support for 'hg archive'
Martin Geisler <mg@aragost.com>
parents: 12321
diff changeset
   339
    if subrepos:
18364
6252b4f1c4b4 subrepos: process subrepos in sorted order
Mads Kiilerich <mads@kiilerich.com>
parents: 18344
diff changeset
   340
        for subpath in sorted(ctx.substate):
25601
3ec8351fa6ed archive: support 'wdir()'
Matt Harbison <matt_harbison@yahoo.com>
parents: 25149
diff changeset
   341
            sub = ctx.workingsub(subpath)
28017
d3f1b7ee5e70 match: rename "narrowmatcher" to "subdirmatcher" (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 26587
diff changeset
   342
            submatch = matchmod.subdirmatcher(subpath, matchfn)
31099
b44ab288358e subrepo: run the repo decoders when archiving
Matt Harbison <matt_harbison@yahoo.com>
parents: 30479
diff changeset
   343
            total += sub.archive(archiver, prefix, 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
   344
88d1b59f6906 archive: raise error.Abort if the file pattern matches no files
Angel Ezquerra <angel.ezquerra@gmail.com>
parents: 18364
diff changeset
   345
    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
   346
        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
   347
2112
2b03c6733efa add "archive" command, like "cvs export" only better.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
diff changeset
   348
    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
   349
    return total