hgext/largefiles/localstore.py
author Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
Fri, 13 Jul 2012 21:47:06 +0200
changeset 17192 1ac628cd7113
parent 17191 5884812686f7
child 17411 a02e36568e88
child 17424 e7cfe3587ea4
permissions -rw-r--r--
peer: introduce real peer classes This change separates peer implementations from the repository implementation. localpeer currently is a simple pass-through to localrepository, except for legacy calls, which have already been removed from localpeer. This ensures that the local client code only uses the most modern peer API when talking to local repos. Peers have a .local() method which returns either None or the underlying localrepository (or descendant thereof). Repos have a .peer() method to return a freshly constructed localpeer. The latter is used by hg.peer(), and also to allow folks to pass either a peer or a repo to some generic helper methods. We might want to get rid of .peer() eventually. The only user of locallegacypeer is debugdiscovery, which uses it to pose as a pre-setdiscovery client. But we decided to leave the old API defined in locallegacypeer for clarity and maybe for other uses in the future. It might be nice to actually define the peer API directly in peer.py as stub methods. One problem there is, however, that localpeer implements lock/addchangegroup, whereas the true remote peers implement unbundle. It might be desireable to get rid of this distinction eventually.
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
15252
6e809bb4f969 largefiles: improve comments, internal docstrings
Greg Ward <greg@gerg.ca>
parents: 15168
diff changeset
     9
'''store class for local filesystem'''
15168
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
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    13
from mercurial import util
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    14
from mercurial.i18n import _
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    15
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    16
import lfutil
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    17
import basestore
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    18
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    19
class localstore(basestore.basestore):
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    20
    '''localstore first attempts to grab files out of the store in the remote
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    21
    Mercurial repository.  Failling that, it attempts to grab the files from
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    22
    the user cache.'''
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    23
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    24
    def __init__(self, ui, repo, remote):
17191
5884812686f7 peer: introduce peer methods to prepare for peer classes
Sune Foldager <cryo@cyanite.org>
parents: 16928
diff changeset
    25
        url = os.path.join(remote.local().path, '.hg', lfutil.longname)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    26
        super(localstore, self).__init__(ui, repo, util.expandpath(url))
17191
5884812686f7 peer: introduce peer methods to prepare for peer classes
Sune Foldager <cryo@cyanite.org>
parents: 16928
diff changeset
    27
        self.remote = remote.local()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    28
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    29
    def put(self, source, hash):
15371
f26ed4ea46d8 largefiles: remove lfutil.createdir, replace calls with util.makedirs
Hao Lian <hao@fogcreek.com>
parents: 15317
diff changeset
    30
        util.makedirs(os.path.dirname(lfutil.storepath(self.remote, hash)))
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    31
        if lfutil.instore(self.remote, hash):
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    32
            return
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    33
        lfutil.link(lfutil.storepath(self.repo, hash),
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    34
                lfutil.storepath(self.remote, hash))
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    35
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    36
    def exists(self, hash):
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    37
        return lfutil.instore(self.remote, hash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    38
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    39
    def _getfile(self, tmpfile, filename, hash):
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    40
        if lfutil.instore(self.remote, hash):
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    41
            path = lfutil.storepath(self.remote, hash)
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    42
        elif lfutil.inusercache(self.ui, hash):
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    43
            path = lfutil.usercachepath(self.ui, hash)
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    44
        else:
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    45
            raise basestore.StoreError(filename, hash, '',
16928
73b9286e667c largefiles: lowercase messages
Martin Geisler <mg@aragost.com>
parents: 15371
diff changeset
    46
                _("can't get file locally"))
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    47
        fd = open(path, 'rb')
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    48
        try:
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    49
            return lfutil.copyandhash(fd, tmpfile)
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    50
        finally:
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    51
            fd.close()
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    52
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    53
    def _verifyfile(self, cctx, cset, contents, standin, verified):
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    54
        filename = lfutil.splitstandin(standin)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    55
        if not filename:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    56
            return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    57
        fctx = cctx[standin]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    58
        key = (filename, fctx.filenode())
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    59
        if key in verified:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    60
            return False
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    61
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    62
        expecthash = fctx.data()[0:40]
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    63
        verified.add(key)
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    64
        if not lfutil.instore(self.remote, expecthash):
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    65
            self.ui.warn(
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    66
                _('changeset %s: %s missing\n'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    67
                  '  (looked for hash %s)\n')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    68
                % (cset, filename, expecthash))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    69
            return True                 # failed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    70
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    71
        if contents:
15317
41f371150ccb largefiles: make the store primary, and the user cache secondary
Benjamin Pollack <benjamin@bitquabit.com>
parents: 15316
diff changeset
    72
            storepath = lfutil.storepath(self.remote, expecthash)
15168
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    73
            actualhash = lfutil.hashfile(storepath)
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    74
            if actualhash != expecthash:
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    75
                self.ui.warn(
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    76
                    _('changeset %s: %s: contents differ\n'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    77
                      '  (%s:\n'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    78
                      '  expected hash %s,\n'
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    79
                      '  but got %s)\n')
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    80
                    % (cset, filename, storepath, expecthash, actualhash))
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    81
                return True             # failed
cfccd3bee7b3 hgext: add largefiles extension
various
parents:
diff changeset
    82
        return False