view hgext/largefiles/localstore.py @ 22287:f3ac9677fa2b

largefiles: move "updatestandin" invocation to "hg.updaterepo" wrapper Code paths below expect "hg.updaterepo" (or "hg.update" using it) to execute linear merging: - "update" in commands - "postincoming" in commands, used for: - "hg pull --update" - "hg unbundle --update" - "hgsubrepo.get" in subrepo For linear merging with largefiles, standins should be updated according to (possibly dirty) largefiles before "merge.update" invocation to detect conflicts correctly. Before this patch, only the "update" command can execute linear merging correctly, because largefiles extension takes care of only it. This patch moves "updatestandin" invocation from "overrideupdate" ("hg update" wrapper) to "_hgupdaterepo" ("hg.updaterepo" wrapper) to execute linear merging in "hg.updaterepo" correctly. This is also a preparation to centralize the logic of updating largefiles in the working directory into the function wrapping "merge.update" in the subsequent patch.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Sun, 24 Aug 2014 23:47:26 +0900
parents 266b5fb72f26
children c082a4756ed7
line wrap: on
line source

# Copyright 2009-2010 Gregory P. Ward
# Copyright 2009-2010 Intelerad Medical Systems Incorporated
# Copyright 2010-2011 Fog Creek Software
# Copyright 2010-2011 Unity Technologies
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.

'''store class for local filesystem'''

from mercurial.i18n import _

import lfutil
import basestore

class localstore(basestore.basestore):
    '''localstore first attempts to grab files out of the store in the remote
    Mercurial repository.  Failing that, it attempts to grab the files from
    the user cache.'''

    def __init__(self, ui, repo, remote):
        self.remote = remote.local()
        super(localstore, self).__init__(ui, repo, self.remote.url())

    def put(self, source, hash):
        if lfutil.instore(self.remote, hash):
            return
        lfutil.link(source, lfutil.storepath(self.remote, hash))

    def exists(self, hashes):
        retval = {}
        for hash in hashes:
            retval[hash] = lfutil.instore(self.remote, hash)
        return retval


    def _getfile(self, tmpfile, filename, hash):
        path = lfutil.findfile(self.remote, hash)
        if not path:
            raise basestore.StoreError(filename, hash, self.url,
                _("can't get file locally"))
        fd = open(path, 'rb')
        try:
            return lfutil.copyandhash(fd, tmpfile)
        finally:
            fd.close()

    def _verifyfile(self, cctx, cset, contents, standin, verified):
        filename = lfutil.splitstandin(standin)
        if not filename:
            return False
        fctx = cctx[standin]
        key = (filename, fctx.filenode())
        if key in verified:
            return False

        expecthash = fctx.data()[0:40]
        storepath = lfutil.storepath(self.remote, expecthash)
        verified.add(key)
        if not lfutil.instore(self.remote, expecthash):
            self.ui.warn(
                _('changeset %s: %s references missing %s\n')
                % (cset, filename, storepath))
            return True                 # failed

        if contents:
            actualhash = lfutil.hashfile(storepath)
            if actualhash != expecthash:
                self.ui.warn(
                    _('changeset %s: %s references corrupted %s\n')
                    % (cset, filename, storepath))
                return True             # failed
        return False