hgext/largefiles/lfcommands.py
author Greg Ward <greg@gerg.ca>
Tue, 11 Oct 2011 21:07:08 -0400
changeset 15228 ee625de3541e
parent 15227 a7686abf73a6
child 15230 697289c5d415
permissions -rw-r--r--
largefiles: allow minimum size to be a float Some old-fashioned people (e.g. me) think that incompressible binary files >100 kB count as "large".
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     1
# Copyright 2009-2010 Gregory P. Ward
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     2
# Copyright 2009-2010 Intelerad Medical Systems Incorporated
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     3
# Copyright 2010-2011 Fog Creek Software
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     4
# Copyright 2010-2011 Unity Technologies
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     5
#
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     6
# This software may be used and distributed according to the terms of the
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     7
# GNU General Public License version 2 or any later version.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     8
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
     9
'''High-level command functions: lfadd() et. al, plus the cmdtable.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    10
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    11
import os
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    12
import shutil
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    13
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    14
from mercurial import util, match as match_, hg, node, context, error
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    15
from mercurial.i18n import _
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    16
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    17
import lfutil
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    18
import basestore
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    19
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    20
# -- Commands ----------------------------------------------------------
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    21
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    22
def lfconvert(ui, src, dest, *pats, **opts):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    23
    '''Convert a normal repository to a largefiles repository
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    24
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    25
    Convert source repository creating an identical repository, except that all
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    26
    files that match the patterns given, or are over the given size will be
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    27
    added as largefiles. The size used to determine whether or not to track a
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    28
    file as a largefile is the size of the first version of the file. After
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    29
    running this command you will need to make sure that largefiles is enabled
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    30
    anywhere you intend to push the new repository.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    31
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    32
    if opts['tonormal']:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    33
        tolfile = False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    34
    else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    35
        tolfile = True
15227
a7686abf73a6 largefiles: factor out lfutil.getminsize()
Greg Ward <greg@gerg.ca>
parents: 15224
diff changeset
    36
        size = lfutil.getminsize(ui, True, opts.get('size'), default=None)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    37
    try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    38
        rsrc = hg.repository(ui, src)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    39
        if not rsrc.local():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    40
            raise util.Abort(_('%s is not a local Mercurial repo') % src)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    41
    except error.RepoError, err:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    42
        ui.traceback()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    43
        raise util.Abort(err.args[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    44
    if os.path.exists(dest):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    45
        if not os.path.isdir(dest):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    46
            raise util.Abort(_('destination %s already exists') % dest)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    47
        elif os.listdir(dest):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    48
            raise util.Abort(_('destination %s is not empty') % dest)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    49
    try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    50
        ui.status(_('initializing destination %s\n') % dest)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    51
        rdst = hg.repository(ui, dest, create=True)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    52
        if not rdst.local():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    53
            raise util.Abort(_('%s is not a local Mercurial repo') % dest)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    54
    except error.RepoError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    55
        ui.traceback()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    56
        raise util.Abort(_('%s is not a repo') % dest)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    57
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
    58
    success = False
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    59
    try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    60
        # Lock destination to prevent modification while it is converted to.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    61
        # Don't need to lock src because we are just reading from its history
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    62
        # which can't change.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    63
        dst_lock = rdst.lock()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    64
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    65
        # Get a list of all changesets in the source.  The easy way to do this
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    66
        # is to simply walk the changelog, using changelog.nodesbewteen().
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    67
        # Take a look at mercurial/revlog.py:639 for more details.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    68
        # Use a generator instead of a list to decrease memory usage
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    69
        ctxs = (rsrc[ctx] for ctx in rsrc.changelog.nodesbetween(None,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    70
            rsrc.heads())[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    71
        revmap = {node.nullid: node.nullid}
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    72
        if tolfile:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    73
            lfiles = set()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    74
            normalfiles = set()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    75
            if not pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    76
                pats = ui.config(lfutil.longname, 'patterns', default=())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    77
                if pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    78
                    pats = pats.split(' ')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    79
            if pats:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    80
                matcher = match_.match(rsrc.root, '', list(pats))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    81
            else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    82
                matcher = None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    83
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    84
            lfiletohash = {}
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    85
            for ctx in ctxs:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    86
                ui.progress(_('converting revisions'), ctx.rev(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    87
                    unit=_('revision'), total=rsrc['tip'].rev())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    88
                _lfconvert_addchangeset(rsrc, rdst, ctx, revmap,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    89
                    lfiles, normalfiles, matcher, size, lfiletohash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    90
            ui.progress(_('converting revisions'), None)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    91
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    92
            if os.path.exists(rdst.wjoin(lfutil.shortname)):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    93
                shutil.rmtree(rdst.wjoin(lfutil.shortname))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    94
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    95
            for f in lfiletohash.keys():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    96
                if os.path.isfile(rdst.wjoin(f)):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    97
                    os.unlink(rdst.wjoin(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    98
                try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    99
                    os.removedirs(os.path.dirname(rdst.wjoin(f)))
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
   100
                except OSError:
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   101
                    pass
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   102
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   103
        else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   104
            for ctx in ctxs:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   105
                ui.progress(_('converting revisions'), ctx.rev(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   106
                    unit=_('revision'), total=rsrc['tip'].rev())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   107
                _addchangeset(ui, rsrc, rdst, ctx, revmap)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   108
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   109
            ui.progress(_('converting revisions'), None)
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
   110
        success = True
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   111
    finally:
15171
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
   112
        if not success:
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
   113
            # we failed, remove the new directory
547da6115d1d largefiles: eliminate naked exceptions
Matt Mackall <mpm@selenic.com>
parents: 15170
diff changeset
   114
            shutil.rmtree(rdst.root)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   115
        dst_lock.release()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   116
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   117
def _addchangeset(ui, rsrc, rdst, ctx, revmap):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   118
 # Convert src parents to dst parents
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   119
    parents = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   120
    for p in ctx.parents():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   121
        parents.append(revmap[p.node()])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   122
    while len(parents) < 2:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   123
        parents.append(node.nullid)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   124
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   125
    # Generate list of changed files
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   126
    files = set(ctx.files())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   127
    if node.nullid not in parents:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   128
        mc = ctx.manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   129
        mp1 = ctx.parents()[0].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   130
        mp2 = ctx.parents()[1].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   131
        files |= (set(mp1) | set(mp2)) - set(mc)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   132
        for f in mc:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   133
            if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   134
                files.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   135
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   136
    def getfilectx(repo, memctx, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   137
        if lfutil.standin(f) in files:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   138
            # if the file isn't in the manifest then it was removed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   139
            # or renamed, raise IOError to indicate this
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   140
            try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   141
                fctx = ctx.filectx(lfutil.standin(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   142
            except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   143
                raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   144
            renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   145
            if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   146
                renamed = lfutil.splitstandin(renamed[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   147
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   148
            hash = fctx.data().strip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   149
            path = lfutil.findfile(rsrc, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   150
            ### TODO: What if the file is not cached?
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   151
            data = ''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   152
            fd = None
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   153
            try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   154
                fd = open(path, 'rb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   155
                data = fd.read()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   156
            finally:
15172
fb1dcd2aae2a largefiles: fix multistatement line
Matt Mackall <mpm@selenic.com>
parents: 15171
diff changeset
   157
                if fd:
fb1dcd2aae2a largefiles: fix multistatement line
Matt Mackall <mpm@selenic.com>
parents: 15171
diff changeset
   158
                    fd.close()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   159
            return context.memfilectx(f, data, 'l' in fctx.flags(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   160
                                      'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   161
        else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   162
            try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   163
                fctx = ctx.filectx(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   164
            except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   165
                raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   166
            renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   167
            if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   168
                renamed = renamed[0]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   169
            data = fctx.data()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   170
            if f == '.hgtags':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   171
                newdata = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   172
                for line in data.splitlines():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   173
                    id, name = line.split(' ', 1)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   174
                    newdata.append('%s %s\n' % (node.hex(revmap[node.bin(id)]),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   175
                        name))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   176
                data = ''.join(newdata)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   177
            return context.memfilectx(f, data, 'l' in fctx.flags(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   178
                                      'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   179
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   180
    dstfiles = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   181
    for file in files:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   182
        if lfutil.isstandin(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   183
            dstfiles.append(lfutil.splitstandin(file))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   184
        else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   185
            dstfiles.append(file)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   186
    # Commit
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   187
    mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   188
                          getfilectx, ctx.user(), ctx.date(), ctx.extra())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   189
    ret = rdst.commitctx(mctx)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   190
    rdst.dirstate.setparents(ret)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   191
    revmap[ctx.node()] = rdst.changelog.tip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   192
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   193
def _lfconvert_addchangeset(rsrc, rdst, ctx, revmap, lfiles, normalfiles,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   194
        matcher, size, lfiletohash):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   195
    # Convert src parents to dst parents
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   196
    parents = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   197
    for p in ctx.parents():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   198
        parents.append(revmap[p.node()])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   199
    while len(parents) < 2:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   200
        parents.append(node.nullid)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   201
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   202
    # Generate list of changed files
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   203
    files = set(ctx.files())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   204
    if node.nullid not in parents:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   205
        mc = ctx.manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   206
        mp1 = ctx.parents()[0].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   207
        mp2 = ctx.parents()[1].manifest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   208
        files |= (set(mp1) | set(mp2)) - set(mc)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   209
        for f in mc:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   210
            if mc[f] != mp1.get(f, None) or mc[f] != mp2.get(f, None):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   211
                files.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   212
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   213
    dstfiles = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   214
    for f in files:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   215
        if f not in lfiles and f not in normalfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   216
            islfile = _islfile(f, ctx, matcher, size)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   217
            # If this file was renamed or copied then copy
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   218
            # the lfileness of its predecessor
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   219
            if f in ctx.manifest():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   220
                fctx = ctx.filectx(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   221
                renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   222
                renamedlfile = renamed and renamed[0] in lfiles
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   223
                islfile |= renamedlfile
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   224
                if 'l' in fctx.flags():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   225
                    if renamedlfile:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   226
                        raise util.Abort(
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   227
                            _('Renamed/copied largefile %s becomes symlink')
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   228
                            % f)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   229
                    islfile = False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   230
            if islfile:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   231
                lfiles.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   232
            else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   233
                normalfiles.add(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   234
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   235
        if f in lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   236
            dstfiles.append(lfutil.standin(f))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   237
            # lfile in manifest if it has not been removed/renamed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   238
            if f in ctx.manifest():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   239
                if 'l' in ctx.filectx(f).flags():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   240
                    if renamed and renamed[0] in lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   241
                        raise util.Abort(_('largefile %s becomes symlink') % f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   242
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   243
                # lfile was modified, update standins
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   244
                fullpath = rdst.wjoin(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   245
                lfutil.createdir(os.path.dirname(fullpath))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   246
                m = util.sha1('')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   247
                m.update(ctx[f].data())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   248
                hash = m.hexdigest()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   249
                if f not in lfiletohash or lfiletohash[f] != hash:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   250
                    try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   251
                        fd = open(fullpath, 'wb')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   252
                        fd.write(ctx[f].data())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   253
                    finally:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   254
                        if fd:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   255
                            fd.close()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   256
                    executable = 'x' in ctx[f].flags()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   257
                    os.chmod(fullpath, lfutil.getmode(executable))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   258
                    lfutil.writestandin(rdst, lfutil.standin(f), hash,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   259
                        executable)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   260
                    lfiletohash[f] = hash
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   261
        else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   262
            # normal file
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   263
            dstfiles.append(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   264
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   265
    def getfilectx(repo, memctx, f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   266
        if lfutil.isstandin(f):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   267
            # if the file isn't in the manifest then it was removed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   268
            # or renamed, raise IOError to indicate this
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   269
            srcfname = lfutil.splitstandin(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   270
            try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   271
                fctx = ctx.filectx(srcfname)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   272
            except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   273
                raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   274
            renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   275
            if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   276
                # standin is always a lfile because lfileness
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   277
                # doesn't change after rename or copy
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   278
                renamed = lfutil.standin(renamed[0])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   279
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   280
            return context.memfilectx(f, lfiletohash[srcfname], 'l' in
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   281
                fctx.flags(), 'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   282
        else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   283
            try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   284
                fctx = ctx.filectx(f)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   285
            except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   286
                raise IOError()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   287
            renamed = fctx.renamed()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   288
            if renamed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   289
                renamed = renamed[0]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   290
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   291
            data = fctx.data()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   292
            if f == '.hgtags':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   293
                newdata = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   294
                for line in data.splitlines():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   295
                    id, name = line.split(' ', 1)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   296
                    newdata.append('%s %s\n' % (node.hex(revmap[node.bin(id)]),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   297
                        name))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   298
                data = ''.join(newdata)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   299
            return context.memfilectx(f, data, 'l' in fctx.flags(),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   300
                                      'x' in fctx.flags(), renamed)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   301
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   302
    # Commit
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   303
    mctx = context.memctx(rdst, parents, ctx.description(), dstfiles,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   304
                          getfilectx, ctx.user(), ctx.date(), ctx.extra())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   305
    ret = rdst.commitctx(mctx)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   306
    rdst.dirstate.setparents(ret)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   307
    revmap[ctx.node()] = rdst.changelog.tip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   308
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   309
def _islfile(file, ctx, matcher, size):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   310
    '''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   311
    A file is a lfile if it matches a pattern or is over
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   312
    the given size.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   313
    '''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   314
    # Never store hgtags or hgignore as lfiles
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   315
    if file == '.hgtags' or file == '.hgignore' or file == '.hgsigs':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   316
        return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   317
    if matcher and matcher(file):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   318
        return True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   319
    try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   320
        return ctx.filectx(file).size() >= size * 1024 * 1024
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   321
    except error.LookupError:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   322
        return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   323
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   324
def uploadlfiles(ui, rsrc, rdst, files):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   325
    '''upload largefiles to the central store'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   326
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   327
    # Don't upload locally. All largefiles are in the system wide cache
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   328
    # so the other repo can just get them from there.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   329
    if not files or rdst.local():
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   330
        return
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   331
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   332
    store = basestore._openstore(rsrc, rdst, put=True)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   333
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   334
    at = 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   335
    files = filter(lambda h: not store.exists(h), files)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   336
    for hash in files:
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   337
        ui.progress(_('uploading largefiles'), at, unit='largefile',
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   338
                    total=len(files))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   339
        source = lfutil.findfile(rsrc, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   340
        if not source:
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   341
            raise util.Abort(_('Missing largefile %s needs to be uploaded')
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   342
                             % hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   343
        # XXX check for errors here
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   344
        store.put(source, hash)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   345
        at += 1
15173
3d27a8ff895f largefiles: mark a string for translation
Matt Mackall <mpm@selenic.com>
parents: 15172
diff changeset
   346
    ui.progress(_('uploading largefiles'), None)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   347
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   348
def verifylfiles(ui, repo, all=False, contents=False):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   349
    '''Verify that every big file revision in the current changeset
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   350
    exists in the central store.  With --contents, also verify that
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   351
    the contents of each big file revision are correct (SHA-1 hash
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   352
    matches the revision ID).  With --all, check every changeset in
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   353
    this repository.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   354
    if all:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   355
        # Pass a list to the function rather than an iterator because we know a
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   356
        # list will work.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   357
        revs = range(len(repo))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   358
    else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   359
        revs = ['.']
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   360
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   361
    store = basestore._openstore(repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   362
    return store.verify(revs, contents=contents)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   363
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   364
def cachelfiles(ui, repo, node):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   365
    '''cachelfiles ensures that all largefiles needed by the specified revision
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   366
    are present in the repository's largefile cache.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   367
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   368
    returns a tuple (cached, missing).  cached is the list of files downloaded
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   369
    by this operation; missing is the list of files that were needed but could
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   370
    not be found.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   371
    lfiles = lfutil.listlfiles(repo, node)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   372
    toget = []
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   373
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   374
    for lfile in lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   375
        expectedhash = repo[node][lfutil.standin(lfile)].data().strip()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   376
        # if it exists and its hash matches, it might have been locally
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   377
        # modified before updating and the user chose 'local'.  in this case,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   378
        # it will not be in any store, so don't look for it.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   379
        if (not os.path.exists(repo.wjoin(lfile)) \
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   380
                or expectedhash != lfutil.hashfile(repo.wjoin(lfile))) and \
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   381
                not lfutil.findfile(repo, expectedhash):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   382
            toget.append((lfile, expectedhash))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   383
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   384
    if toget:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   385
        store = basestore._openstore(repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   386
        ret = store.get(toget)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   387
        return ret
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   388
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   389
    return ([], [])
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   390
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   391
def updatelfiles(ui, repo, filelist=None, printmessage=True):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   392
    wlock = repo.wlock()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   393
    try:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   394
        lfdirstate = lfutil.openlfdirstate(ui, repo)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   395
        lfiles = set(lfutil.listlfiles(repo)) | set(lfdirstate)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   396
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   397
        if filelist is not None:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   398
            lfiles = [f for f in lfiles if f in filelist]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   399
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   400
        printed = False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   401
        if printmessage and lfiles:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   402
            ui.status(_('getting changed largefiles\n'))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   403
            printed = True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   404
            cachelfiles(ui, repo, '.')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   405
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   406
        updated, removed = 0, 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   407
        for i in map(lambda f: _updatelfile(repo, lfdirstate, f), lfiles):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   408
            # increment the appropriate counter according to _updatelfile's
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   409
            # return value
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   410
            updated += i > 0 and i or 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   411
            removed -= i < 0 and i or 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   412
            if printmessage and (removed or updated) and not printed:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   413
                ui.status(_('getting changed largefiles\n'))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   414
                printed = True
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   415
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   416
        lfdirstate.write()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   417
        if printed and printmessage:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   418
            ui.status(_('%d largefiles updated, %d removed\n') % (updated,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   419
                removed))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   420
    finally:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   421
        wlock.release()
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   422
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   423
def _updatelfile(repo, lfdirstate, lfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   424
    '''updates a single largefile and copies the state of its standin from
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   425
    the repository's dirstate to its state in the lfdirstate.
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   426
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   427
    returns 1 if the file was modified, -1 if the file was removed, 0 if the
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   428
    file was unchanged, and None if the needed largefile was missing from the
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   429
    cache.'''
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   430
    ret = 0
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   431
    abslfile = repo.wjoin(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   432
    absstandin = repo.wjoin(lfutil.standin(lfile))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   433
    if os.path.exists(absstandin):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   434
        if os.path.exists(absstandin+'.orig'):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   435
            shutil.copyfile(abslfile, abslfile+'.orig')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   436
        expecthash = lfutil.readstandin(repo, lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   437
        if expecthash != '' and \
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   438
                (not os.path.exists(abslfile) or \
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   439
                expecthash != lfutil.hashfile(abslfile)):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   440
            if not lfutil.copyfromcache(repo, expecthash, lfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   441
                return None # don't try to set the mode or update the dirstate
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   442
            ret = 1
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   443
        mode = os.stat(absstandin).st_mode
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   444
        if mode != os.stat(abslfile).st_mode:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   445
            os.chmod(abslfile, mode)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   446
            ret = 1
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   447
    else:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   448
        if os.path.exists(abslfile):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   449
            os.unlink(abslfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   450
            ret = -1
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   451
    state = repo.dirstate[lfutil.standin(lfile)]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   452
    if state == 'n':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   453
        lfdirstate.normal(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   454
    elif state == 'r':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   455
        lfdirstate.remove(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   456
    elif state == 'a':
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   457
        lfdirstate.add(lfile)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   458
    elif state == '?':
15224
7c604d8c7e83 largefiles: remove pre-1.9 code from extension first bundled with 1.9
Na'Tosha Bard <natosha@unity3d.com>
parents: 15173
diff changeset
   459
        lfdirstate.drop(lfile)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   460
    return ret
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   461
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   462
# -- hg commands declarations ------------------------------------------------
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   463
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   464
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   465
cmdtable = {
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   466
    'lfconvert': (lfconvert,
15228
ee625de3541e largefiles: allow minimum size to be a float
Greg Ward <greg@gerg.ca>
parents: 15227
diff changeset
   467
                  [('s', 'size', '', 'All files over this size (in megabytes) '
15170
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   468
                  'will be considered largefiles. This can also be specified '
c1a4a3220711 largefiles: fix over-long lines
Matt Mackall <mpm@selenic.com>
parents: 15168
diff changeset
   469
                  'in your hgrc as [largefiles].size.'),
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   470
                  ('','tonormal',False,
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   471
                      'Convert from a largefiles repo to a normal repo')],
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   472
                  _('hg lfconvert SOURCE DEST [FILE ...]')),
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
   473
    }