mirror of
https://github.com/facebook/sapling.git
synced 2025-01-06 04:43:19 +03:00
lfs: move abstract local blobstore to core mercurial
Summary: It will be used by snapshot extension too. Reviewed By: markbt Differential Revision: D17132134 fbshipit-source-id: 6c9fc285e0f1eb445bfa0abe0b6f4de4a1bd1db0
This commit is contained in:
parent
4576ab19c2
commit
bead18e577
@ -7,11 +7,11 @@
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
|
||||
from edenscm.mercurial import (
|
||||
blobstore,
|
||||
error,
|
||||
pathutil,
|
||||
perftrace,
|
||||
@ -58,7 +58,7 @@ class filewithprogress(object):
|
||||
self._fp = None
|
||||
|
||||
|
||||
class local(object):
|
||||
class local(blobstore.localblobstore):
|
||||
"""Local blobstore for large file contents.
|
||||
|
||||
This blobstore is used both as a cache and as a staging area for large blobs
|
||||
@ -67,38 +67,12 @@ class local(object):
|
||||
|
||||
def __init__(self, repo):
|
||||
fullpath = repo.svfs.join("lfs/objects")
|
||||
self.vfs = vfsmod.blobvfs(fullpath)
|
||||
vfs = vfsmod.blobvfs(fullpath)
|
||||
cachevfs = None
|
||||
usercachepath = repo.ui.config("lfs", "usercache")
|
||||
if usercachepath:
|
||||
self.cachevfs = vfsmod.blobvfs(usercachepath)
|
||||
else:
|
||||
self.cachevfs = None
|
||||
|
||||
def write(self, oid, data):
|
||||
"""Write blob to local blobstore."""
|
||||
contentsha256 = hashlib.sha256(data).hexdigest()
|
||||
if contentsha256 != oid:
|
||||
raise error.Abort(
|
||||
_("lfs: sha256 mismatch (oid: %s, content: %s)") % (oid, contentsha256)
|
||||
)
|
||||
with self.vfs(oid, "wb", atomictemp=True) as fp:
|
||||
fp.write(data)
|
||||
|
||||
# XXX: should we verify the content of the cache, and hardlink back to
|
||||
# the local store on success, but truncate, write and link on failure?
|
||||
if self.cachevfs and not self.cachevfs.exists(oid):
|
||||
self.vfs.linktovfs(oid, self.cachevfs)
|
||||
|
||||
def read(self, oid):
|
||||
"""Read blob from local blobstore."""
|
||||
if self.cachevfs and not self.vfs.exists(oid):
|
||||
self.cachevfs.linktovfs(oid, self.vfs)
|
||||
return self.vfs.read(oid)
|
||||
|
||||
def has(self, oid):
|
||||
"""Returns True if the local blobstore contains the requested blob,
|
||||
False otherwise."""
|
||||
return (self.cachevfs and self.cachevfs.exists(oid)) or self.vfs.exists(oid)
|
||||
cachevfs = vfsmod.blobvfs(usercachepath)
|
||||
super(local, self).__init__(vfs, cachevfs)
|
||||
|
||||
|
||||
class memlocal(object):
|
||||
|
52
edenscm/mercurial/blobstore.py
Normal file
52
edenscm/mercurial/blobstore.py
Normal file
@ -0,0 +1,52 @@
|
||||
# blobstore.py - local blob storage
|
||||
#
|
||||
# Copyright 2017 Facebook, Inc.
|
||||
#
|
||||
# This software may be used and distributed according to the terms of the
|
||||
# GNU General Public License version 2 or any later version.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import hashlib
|
||||
|
||||
from . import error
|
||||
from .i18n import _
|
||||
|
||||
|
||||
class localblobstore(object):
|
||||
"""A local blobstore.
|
||||
|
||||
This blobstore is used both as a cache and as a staging area for large blobs
|
||||
to be uploaded to the remote blobstore.
|
||||
"""
|
||||
|
||||
def __init__(self, vfs, cachevfs):
|
||||
self.vfs = vfs
|
||||
self.cachevfs = cachevfs
|
||||
|
||||
def write(self, oid, data):
|
||||
"""Write blob to local blobstore."""
|
||||
contentsha256 = hashlib.sha256(data).hexdigest()
|
||||
if contentsha256 != oid:
|
||||
raise error.Abort(
|
||||
_("blobstore: sha256 mismatch (oid: %s, content: %s)")
|
||||
% (oid, contentsha256)
|
||||
)
|
||||
with self.vfs(oid, "wb", atomictemp=True) as fp:
|
||||
fp.write(data)
|
||||
|
||||
# XXX: should we verify the content of the cache, and hardlink back to
|
||||
# the local store on success, but truncate, write and link on failure?
|
||||
if self.cachevfs and not self.cachevfs.exists(oid):
|
||||
self.vfs.linktovfs(oid, self.cachevfs)
|
||||
|
||||
def read(self, oid):
|
||||
"""Read blob from local blobstore."""
|
||||
if self.cachevfs and not self.vfs.exists(oid):
|
||||
self.cachevfs.linktovfs(oid, self.vfs)
|
||||
return self.vfs.read(oid)
|
||||
|
||||
def has(self, oid):
|
||||
"""Returns True if the local blobstore contains the requested blob,
|
||||
False otherwise."""
|
||||
return (self.cachevfs and self.cachevfs.exists(oid)) or self.vfs.exists(oid)
|
@ -30,7 +30,7 @@ Download it again in a fresh new repo - should fail
|
||||
$ echo remotefilelog >> .hg/requires
|
||||
$ hg pull ../source -q
|
||||
$ hg update tip -q
|
||||
abort: lfs: sha256 mismatch (oid: 2f7548e627a92d9ce3f912eb71226f692ec83deed2e72298270b198540d7c70b, content: 3dff7d61038895144c0eca9d06ac8d067919785a5ba2604db7aef154899a494d)
|
||||
abort: blobstore: sha256 mismatch (oid: 2f7548e627a92d9ce3f912eb71226f692ec83deed2e72298270b198540d7c70b, content: 3dff7d61038895144c0eca9d06ac8d067919785a5ba2604db7aef154899a494d)
|
||||
[255]
|
||||
|
||||
$ [ -f A ]
|
||||
|
Loading…
Reference in New Issue
Block a user