# HG changeset patch # User Augie Fackler # Date 2016-11-17 04:29:28 # Node ID 854190becacb8abecddddbf5c18a777b02bbc045 # Parent c27614f2dec1405db606d1ef871dfabf72cc0737 # Parent e0ff47999b1384e42bdc99f5026c7e2ed5405047 merge with stable diff --git a/mercurial/hgweb/webcommands.py b/mercurial/hgweb/webcommands.py --- a/mercurial/hgweb/webcommands.py +++ b/mercurial/hgweb/webcommands.py @@ -861,12 +861,24 @@ def annotate(web, req, tmpl): f = fctx.path() parity = paritygen(web.stripecount) + # parents() is called once per line and several lines likely belong to + # same revision. So it is worth caching. + # TODO there are still redundant operations within basefilectx.parents() + # and from the fctx.annotate() call itself that could be cached. + parentscache = {} def parents(f): - for p in f.parents(): - yield { - "node": p.hex(), - "rev": p.rev(), - } + rev = f.rev() + if rev not in parentscache: + parentscache[rev] = [] + for p in f.parents(): + entry = { + 'node': p.hex(), + 'rev': p.rev(), + } + parentscache[rev].append(entry) + + for p in parentscache[rev]: + yield p def annotate(**map): if util.binary(fctx.data()): diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -392,8 +392,7 @@ class abstractvfs(object): newstat = util.filestat(dstpath) if newstat.isambig(oldstat): # stat of renamed file is ambiguous to original one - advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff - os.utime(dstpath, (advanced, advanced)) + newstat.avoidambig(dstpath, oldstat) return ret return util.rename(self.join(src), dstpath) @@ -1460,8 +1459,7 @@ class checkambigatclosing(closewrapbase) newstat = util.filestat(self._origfh.name) if newstat.isambig(oldstat): # stat of changed file is ambiguous to original one - advanced = (oldstat.stat.st_mtime + 1) & 0x7fffffff - os.utime(self._origfh.name, (advanced, advanced)) + newstat.avoidambig(self._origfh.name, oldstat) def __exit__(self, exc_type, exc_value, exc_tb): self._origfh.__exit__(exc_type, exc_value, exc_tb) diff --git a/mercurial/util.py b/mercurial/util.py --- a/mercurial/util.py +++ b/mercurial/util.py @@ -1499,6 +1499,24 @@ class filestat(object): except AttributeError: return False + def avoidambig(self, path, old): + """Change file stat of specified path to avoid ambiguity + + 'old' should be previous filestat of 'path'. + + This skips avoiding ambiguity, if a process doesn't have + appropriate privileges for 'path'. + """ + advanced = (old.stat.st_mtime + 1) & 0x7fffffff + try: + os.utime(path, (advanced, advanced)) + except OSError as inst: + if inst.errno == errno.EPERM: + # utime() on the file created by another user causes EPERM, + # if a process doesn't have appropriate privileges + return + raise + def __ne__(self, other): return not self == other