# HG changeset patch # User Alexis S. L. Carvalho # Date 1202589534 7200 # Node ID 3c3b126e561970e5d68ed6d3c9748d6a374782d8 # Parent de08788511d7039b39dc87e0116a802223ab3856 Make files in .hg inherit the permissions from .hg/store diff -r de08788511d7 -r 3c3b126e5619 mercurial/localrepo.py --- a/mercurial/localrepo.py Sat Feb 09 20:17:09 2008 +0100 +++ b/mercurial/localrepo.py Sat Feb 09 18:38:54 2008 -0200 @@ -68,8 +68,20 @@ self.encodefn = lambda x: x self.decodefn = lambda x: x self.spath = self.path - self.sopener = util.encodedopener(util.opener(self.spath), - self.encodefn) + + try: + # files in .hg/ will be created using this mode + mode = os.stat(self.spath).st_mode + # avoid some useless chmods + if (0777 & ~util._umask) == (0777 & mode): + mode = None + except OSError: + mode = None + + self.opener.createmode = mode + sopener = util.opener(self.spath) + sopener.createmode = mode + self.sopener = util.encodedopener(sopener, self.encodefn) self.ui = ui.ui(parentui=parentui) try: diff -r de08788511d7 -r 3c3b126e5619 mercurial/util.py --- a/mercurial/util.py Sat Feb 09 20:17:09 2008 +0100 +++ b/mercurial/util.py Sat Feb 09 18:38:54 2008 -0200 @@ -1298,7 +1298,7 @@ return openerfn(fn(path), *args, **kw) return o -def mktempcopy(name, emptyok=False): +def mktempcopy(name, emptyok=False, createmode=None): """Create a temporary file with the same contents from name The permission bits are copied from the original file. @@ -1319,7 +1319,10 @@ except OSError, inst: if inst.errno != errno.ENOENT: raise - st_mode = 0666 & ~_umask + st_mode = createmode + if st_mode is None: + st_mode = ~_umask + st_mode &= 0666 os.chmod(temp, st_mode) if emptyok: return temp @@ -1350,9 +1353,10 @@ file. When rename is called, the copy is renamed to the original name, making the changes visible. """ - def __init__(self, name, mode): + def __init__(self, name, mode, createmode): self.__name = name - self.temp = mktempcopy(name, emptyok=('w' in mode)) + self.temp = mktempcopy(name, emptyok=('w' in mode), + createmode=createmode) posixfile.__init__(self, self.temp, mode) def rename(self): @@ -1367,6 +1371,22 @@ except: pass posixfile.close(self) +def makedirs(name, mode=None): + """recursive directory creation with parent mode inheritance""" + try: + os.mkdir(name) + if mode is not None: + os.chmod(name, mode) + return + except OSError, err: + if err.errno == errno.EEXIST: + return + if err.errno != errno.ENOENT: + raise + parent = os.path.abspath(os.path.dirname(name)) + makedirs(parent, mode) + makedirs(name, mode) + class opener(object): """Open files relative to a base directory @@ -1379,6 +1399,7 @@ self.audit_path = path_auditor(base) else: self.audit_path = always + self.createmode = None def __getattr__(self, name): if name == '_can_symlink': @@ -1386,6 +1407,11 @@ return self._can_symlink raise AttributeError(name) + def _fixfilemode(self, name): + if self.createmode is None: + return + os.chmod(name, self.createmode & 0666) + def __call__(self, path, mode="r", text=False, atomictemp=False): self.audit_path(path) f = os.path.join(self.base, path) @@ -1393,6 +1419,7 @@ if not text and "b" not in mode: mode += "b" # for that other OS + nlink = -1 if mode[0] != "r": try: nlink = nlinks(f) @@ -1400,12 +1427,15 @@ nlink = 0 d = os.path.dirname(f) if not os.path.isdir(d): - os.makedirs(d) + makedirs(d, self.createmode) if atomictemp: - return atomictempfile(f, mode) + return atomictempfile(f, mode, self.createmode) if nlink > 1: rename(mktempcopy(f), f) - return posixfile(f, mode) + fp = posixfile(f, mode) + if nlink == 0: + self._fixfilemode(f) + return fp def symlink(self, src, dst): self.audit_path(dst) @@ -1417,7 +1447,7 @@ dirname = os.path.dirname(linkname) if not os.path.exists(dirname): - os.makedirs(dirname) + makedirs(dirname, self.createmode) if self._can_symlink: try: @@ -1429,6 +1459,7 @@ f = self(dst, "w") f.write(src) f.close() + self._fixfilemode(dst) class chunkbuffer(object): """Allow arbitrary sized chunks of data to be efficiently read from an