# HG changeset patch # User Joerg Sonnenberger # Date 1588460479 -7200 # Node ID 2570d2d4a268ece829b1b8a11bedfd1665d63b11 # Parent 9e2f2557c42ea2041e57ffeea2734adf0262ce51 caches: preserve permissions of top-level .hg When using hg on a shared filesystem on UNIX, cache files normally inherit the permissions of the .hg directory. This is most commonly used to ensure everything is writable by all users. The sqlite3 cache files don't have a way to directly set the permission, so check if a special mode is necessary and try to apply them to newly created database files. diff -r 9e2f2557c42e -r 2570d2d4a268 hgext3rd/evolve/obsdiscovery.py --- a/hgext3rd/evolve/obsdiscovery.py Sat May 02 23:31:31 2020 +0800 +++ b/hgext3rd/evolve/obsdiscovery.py Sun May 03 01:01:19 2020 +0200 @@ -17,6 +17,7 @@ import hashlib import heapq +import os import sqlite3 import struct import weakref @@ -30,6 +31,7 @@ node, obsolete, scmutil, + store, util, ) from mercurial.i18n import _ @@ -343,6 +345,7 @@ # cache status self._ondiskcachekey = None self._data = {} + self._createmode = store._calcmode(self._vfs) def clear(self, reset=False): super(_obshashcache, self).clear(reset=reset) @@ -490,12 +493,19 @@ def _db(self): try: - util.makedirs(self._vfs.dirname(self._path)) + util.makedirs(self._vfs.dirname(self._path), self._createmode) except OSError: return None + if self._createmode is not None: + pre_existed = os.access(self._path, os.R_OK) con = sqlite3.connect(encoding.strfromlocal(self._path), timeout=30, isolation_level=r"IMMEDIATE") con.text_factory = bytes + if self._createmode is not None and not pre_existed: + try: + os.chmod(self._path, self._createmode & 0o666) + except OSError: + pass return con @util.propertycache @@ -599,6 +609,7 @@ self._new.clear() self._valid = True self._ondiskcachekey = self._cachekey + @eh.wrapfunction(obsolete.obsstore, '_addmarkers') def _addmarkers(orig, obsstore, *args, **kwargs): obsstore.rangeobshashcache.clear() diff -r 9e2f2557c42e -r 2570d2d4a268 hgext3rd/evolve/stablerangecache.py --- a/hgext3rd/evolve/stablerangecache.py Sat May 02 23:31:31 2020 +0800 +++ b/hgext3rd/evolve/stablerangecache.py Sun May 03 01:01:19 2020 +0200 @@ -9,6 +9,7 @@ import abc import heapq +import os import random import sqlite3 import time @@ -19,6 +20,7 @@ error, localrepo, node as nodemod, + store, util, ) @@ -185,6 +187,7 @@ self._ondisktiprev = None self._ondisktipnode = None self._unsavedsubranges = {} + self._createmode = store._calcmode(self._vfs) def contains(self, repo, revs): con = self._con @@ -240,12 +243,19 @@ def _db(self): try: - util.makedirs(self._vfs.dirname(self._path)) + util.makedirs(self._vfs.dirname(self._path), self._createmode) except OSError: return None + if self._createmode is not None: + pre_existed = os.access(self._path, os.R_OK) con = sqlite3.connect(encoding.strfromlocal(self._path), timeout=30, isolation_level=r"IMMEDIATE") con.text_factory = bytes + if self._createmode is not None and not pre_existed: + try: + os.chmod(self._path, self._createmode & 0o666) + except OSError: + pass return con @util.propertycache diff -r 9e2f2557c42e -r 2570d2d4a268 tests/test-sqlite3-permissions.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-sqlite3-permissions.t Sun May 03 01:01:19 2020 +0200 @@ -0,0 +1,30 @@ +#require unix-permissions + +Test that sqlite3 cache files inherit the permissions of the .hg +directory like other cache files. + + $ . $TESTDIR/testlib/common.sh + + $ cat << EOF >> $HGRCPATH + > [extensions] + > evolve = + > EOF + $ hg init test + $ cd test + $ chmod 700 .hg + $ hg debugupdatecache + $ ls -l .hg/cache/evoext_*.sqlite + -rw------- * .hg/cache/evoext_obshashrange_v2.sqlite (glob) + -rw------- * .hg/cache/evoext_stablerange_v2.sqlite (glob) + $ rm -r .hg/cache + $ chmod 770 .hg + $ hg debugupdatecache + $ ls -l .hg/cache/evoext_*.sqlite + -rw-rw---- * .hg/cache/evoext_obshashrange_v2.sqlite (glob) + -rw-rw---- * .hg/cache/evoext_stablerange_v2.sqlite (glob) + $ rm -r .hg/cache + $ chmod 774 .hg + $ hg debugupdatecache + $ ls -l .hg/cache/evoext_*.sqlite + -rw-rw-r-- * .hg/cache/evoext_obshashrange_v2.sqlite (glob) + -rw-rw-r-- * .hg/cache/evoext_stablerange_v2.sqlite (glob)