[PATCH V2] largefiles: replace tempfile.NamedTemporaryFile with tempfile.mkstemp
Greg Ward
greg-hg at gerg.ca
Mon Oct 24 20:00:24 CDT 2011
On Mon, Oct 24, 2011 at 6:01 PM, Hao Lian <hao at fogcreek.com> wrote:
> # HG changeset patch
> # User Hao Lian <hao at fogcreek.com>
> # Date 1319145899 14400
> # Branch stable
> # Node ID c53a79531d3c5688cc31d13e0ba4c288c57e79ef
> # Parent 8b8dd13295dbd733cc03ebb3c2af2f33d24d5428
> largefiles: replace tempfile.NamedTemporaryFile with tempfile.mkstemp
>
> This is consistent with the rest of Mercurial's code, mirroring the
> try-finally-unlink structure elsewhere. Furthermore, it fixes the case where
> largefiles throws an IOError on Windows when the temporary file is opened a
> second time by copytocacheabsolute.
>
> This patch creates the temporary file in the repo's largefiles store rather than
> /tmp, which might be a different filesystem.
>
> diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py
> --- a/hgext/largefiles/lfutil.py
> +++ b/hgext/largefiles/lfutil.py
> @@ -13,6 +13,7 @@
> import platform
> import shutil
> import stat
> +import tempfile
>
> from mercurial import dirstate, httpconnection, match as match_, util, scmutil
> from mercurial.i18n import _
> @@ -442,6 +443,13 @@
> return ('largefiles' in repo.requirements and
> util.any(shortname + '/' in f[0] for f in repo.store.datafiles()))
>
> +def mkstemp(repo, prefix):
> + '''Returns a file object and a filename corresponding to a temporary file in
> + the repo's largefiles store.'''
That's not a file object, it's a file descriptor. I would just say
'''Return (fd, filename) for a temporary file in the repo's
largefile store.'''
> + path = repo.join(longname)
> + createdir(repo.join(path))
Should use mercurial.util.makedirs(). Can lfutil.createdir() disappear
entirely? don't see what value it adds.
> class storeprotonotcapable(Exception):
> def __init__(self, storetypes):
> self.storetypes = storetypes
> diff --git a/hgext/largefiles/proto.py b/hgext/largefiles/proto.py
> --- a/hgext/largefiles/proto.py
> +++ b/hgext/largefiles/proto.py
> @@ -4,7 +4,6 @@
> # GNU General Public License version 2 or any later version.
>
> import os
> -import tempfile
> import urllib2
>
> from mercurial import error, httprepo, util, wireproto
> @@ -19,23 +18,25 @@
> def putlfile(repo, proto, sha):
> '''Put a largefile into a repository's local store and into the
> user cache.'''
> - f = None
> proto.redirect()
> +
> + fd, tmpname = lfutil.mkstemp(repo, prefix='hg-putlfile')
> + tmpfp = os.fdopen(fd, 'wb+')
> try:
> try:
> - f = tempfile.NamedTemporaryFile(mode='wb+', prefix='hg-putlfile-')
> - proto.getfile(f)
> - f.seek(0)
> - if sha != lfutil.hexsha1(f):
> + proto.getfile(tmpfp)
> + tmpfp.seek(0)
> + if sha != lfutil.hexsha1(tmpfp):
> return wireproto.pushres(1)
> + tmpfp.close()
> lfutil.copytostoreabsolute(repo, f.name, sha)
> except IOError:
> - repo.ui.warn(
> - _('error: could not put received data into largefile store'))
> + repo.ui.warn(_('largefiles: failed to put %s (%s) into store') %
> + (sha, tmpname))
You're still not showing the actual error! Disk full? Permission
denied? Something else? I need to *know* -- don't make me guess!
Greg
More information about the Mercurial-devel
mailing list