# HG changeset patch # User Martin Geisler # Date 2012-02-23 12:37:10 # Node ID 1b2b42e866bec02325324749a87c5eb056b5986d # Parent 9b072a5f8f9284930a0441e0399e7cf2cf60e502 largefiles: respect store.createmode and avoid extra file copy Before, a tempfile was used to create a temp file was created with 600 permissions and the uploaded data was written into it. This file was then *copied* to .hg/largefiles/. We now simply use atomictempfile to write the data to a temp file with the right permissions and then rename that into place. diff --git a/hgext/largefiles/lfutil.py b/hgext/largefiles/lfutil.py --- a/hgext/largefiles/lfutil.py +++ b/hgext/largefiles/lfutil.py @@ -13,7 +13,6 @@ import errno import platform import shutil import stat -import tempfile from mercurial import dirstate, httpconnection, match as match_, util, scmutil from mercurial.i18n import _ @@ -439,13 +438,6 @@ def islfilesrepo(repo): 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 descriptor and a filename corresponding to a temporary - file in the repo's largefiles store.''' - path = repo.join(longname) - util.makedirs(path) - return tempfile.mkstemp(prefix=prefix, dir=path) - 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 @@ -20,23 +20,22 @@ def putlfile(repo, proto, sha): user cache.''' proto.redirect() - fd, tmpname = lfutil.mkstemp(repo, prefix='hg-putlfile') - tmpfp = os.fdopen(fd, 'wb+') + tmpfp = util.atomictempfile(lfutil.storepath(repo, sha), + createmode=repo.store.createmode) try: try: proto.getfile(tmpfp) - tmpfp.seek(0) - if sha != lfutil.hexsha1(tmpfp): + tmpfp._fp.seek(0) + if sha != lfutil.hexsha1(tmpfp._fp): raise IOError(0, _('largefile contents do not match hash')) tmpfp.close() - lfutil.copytostoreabsolute(repo, tmpname, sha) + lfutil.linktousercache(repo, sha) except IOError, e: repo.ui.warn(_('largefiles: failed to put %s into store: %s') % (sha, e.strerror)) return wireproto.pushres(1) finally: - tmpfp.close() - os.unlink(tmpname) + tmpfp.discard() return wireproto.pushres(0) diff --git a/tests/test-largefiles-cache.t b/tests/test-largefiles-cache.t --- a/tests/test-largefiles-cache.t +++ b/tests/test-largefiles-cache.t @@ -103,3 +103,19 @@ Test permission of with files in .hg/lar $ hg pull ../src --update -q $ ../ls-l.py .hg/largefiles/e151b474069de4ca6898f67ce2f2a7263adf8fea 640 + +Test permission of files created by push: + + $ hg serve -R ../src -d -p $HGPORT --pid-file hg.pid \ + > --config "web.allow_push=*" --config web.push_ssl=no + $ cat hg.pid >> $DAEMON_PIDS + + $ echo change >> large + $ hg commit -m change + + $ rm -r "$USERCACHE" + + $ hg push -q http://localhost:$HGPORT/ + + $ ../ls-l.py ../src/.hg/largefiles/b734e14a0971e370408ab9bce8d56d8485e368a9 + 640