largefiles: respect store.createmode and avoid extra file copy stable
authorMartin Geisler <mg@aragost.com>
Thu, 23 Feb 2012 13:37:10 +0100
branchstable
changeset 16155 1b2b42e866be
parent 16154 9b072a5f8f92
child 16156 e7746fefd1ef
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/<hash>. We now simply use atomictempfile to write the data to a temp file with the right permissions and then rename that into place.
hgext/largefiles/lfutil.py
hgext/largefiles/proto.py
tests/test-largefiles-cache.t
--- a/hgext/largefiles/lfutil.py	Thu Feb 23 13:37:10 2012 +0100
+++ b/hgext/largefiles/lfutil.py	Thu Feb 23 13:37:10 2012 +0100
@@ -13,7 +13,6 @@
 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 @@
     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
--- a/hgext/largefiles/proto.py	Thu Feb 23 13:37:10 2012 +0100
+++ b/hgext/largefiles/proto.py	Thu Feb 23 13:37:10 2012 +0100
@@ -20,23 +20,22 @@
     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)
 
--- a/tests/test-largefiles-cache.t	Thu Feb 23 13:37:10 2012 +0100
+++ b/tests/test-largefiles-cache.t	Thu Feb 23 13:37:10 2012 +0100
@@ -103,3 +103,19 @@
   $ 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