# HG changeset patch # User Pierre-Yves David # Date 1536914877 -7200 # Node ID b3b861a7f6f750a3e02281005a462138899390e9 # Parent ef3c9ecb80991118ae2be66d3707aa76d726c70f# Parent d562316c548f7324b4287f05dde4905e89b2caea branching: merge stable into default diff -r ef3c9ecb8099 -r b3b861a7f6f7 CHANGELOG --- a/CHANGELOG Thu Sep 13 00:04:17 2018 +0800 +++ b/CHANGELOG Fri Sep 14 10:47:57 2018 +0200 @@ -1,7 +1,14 @@ Changelog ========= -8.1.2 -- 2018-09-03 +8.2.1 - in progress +------------------- + + * obshashrange: issue the "long stable cache" update message only once + * obshashrange: reduce impact of cache invalidation from many new obsmarkers + * caches: properly silence permission error related to caches + +8.2.0 -- 2018-09-03 ------------------- * prune: rename `--biject` flag to `--pair` (old flag is kept as an alias) diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/depthcache.py --- a/hgext3rd/evolve/depthcache.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/depthcache.py Fri Sep 14 10:47:57 2018 +0200 @@ -198,9 +198,14 @@ if self._cachekey is None or self._cachekey == self._ondiskkey: return - cachevfs = compat.getcachevfs(repo) - cachefile = cachevfs(self._filepath, 'w', atomictemp=True) - headerdata = self._serializecachekey() - cachefile.write(headerdata) - cachefile.write(self._data.tostring()) - cachefile.close() + try: + cachevfs = compat.getcachevfs(repo) + cachefile = cachevfs(self._filepath, 'w', atomictemp=True) + headerdata = self._serializecachekey() + cachefile.write(headerdata) + cachefile.write(self._data.tostring()) + cachefile.close() + self._ondiskkey = self._cachekey + except (IOError, OSError) as exc: + repo.ui.log('depthcache', 'could not write update %s\n' % exc) + repo.ui.debug('depthcache: could not write update %s\n' % exc) diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/evolvecmd.py Fri Sep 14 10:47:57 2018 +0200 @@ -355,7 +355,7 @@ # we don't handle split in content-divergence yet if len(others) > 1: othersstr = "[%s]" % (','.join([str(i) for i in others])) - msg = _("skipping %d:%s with a changeset that got split" + msg = _("skipping %s: %s with a changeset that got split" " into multiple ones:\n" "|[%s]\n" "| This is not handled by automatic evolution yet\n" diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/firstmergecache.py --- a/hgext3rd/evolve/firstmergecache.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/firstmergecache.py Fri Sep 14 10:47:57 2018 +0200 @@ -135,9 +135,14 @@ if self._cachekey is None or self._cachekey == self._ondiskkey: return - cachevfs = compat.getcachevfs(repo) - cachefile = cachevfs(self._filepath, 'w', atomictemp=True) - headerdata = self._serializecachekey() - cachefile.write(headerdata) - cachefile.write(self._data.tostring()) - cachefile.close() + try: + cachevfs = compat.getcachevfs(repo) + cachefile = cachevfs(self._filepath, 'w', atomictemp=True) + headerdata = self._serializecachekey() + cachefile.write(headerdata) + cachefile.write(self._data.tostring()) + cachefile.close() + self._ondiskkey = self._cachekey + except (IOError, OSError) as exc: + repo.ui.log('firstmergecache', 'could not write update %s\n' % exc) + repo.ui.debug('firstmergecache: could not write update %s\n' % exc) diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/obscache.py --- a/hgext3rd/evolve/obscache.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/obscache.py Fri Sep 14 10:47:57 2018 +0200 @@ -404,11 +404,16 @@ if self._cachekey is None or self._cachekey == self._ondiskkey: return - cachefile = self._vfs(self._filepath, 'w', atomictemp=True) - headerdata = struct.pack(self._headerformat, *self._cachekey) - cachefile.write(headerdata) - cachefile.write(self._data) - cachefile.close() + try: + cachefile = self._vfs(self._filepath, 'w', atomictemp=True) + headerdata = struct.pack(self._headerformat, *self._cachekey) + cachefile.write(headerdata) + cachefile.write(self._data) + cachefile.close() + self._ondiskkey = self._cachekey + except (IOError, OSError) as exc: + repo.ui.log('obscache', 'could not write update %s\n' % exc) + repo.ui.debug('obscache: could not write update %s\n' % exc) def load(self, repo): """load data from disk""" diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/obsdiscovery.py --- a/hgext3rd/evolve/obsdiscovery.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/obsdiscovery.py Fri Sep 14 10:47:57 2018 +0200 @@ -397,6 +397,9 @@ return affected_nodes +# if there is that many new obsmarkers, reset without analysing them +RESET_ABOVE = 10000 + class _obshashcache(obscache.dualsourcecache): _schemaversion = 3 @@ -470,23 +473,43 @@ con = self._con if con is not None: - max_stored = con.execute(_query_max_stored).fetchall()[0][0] - affected_nodes = _affectedby(repo, obsmarkers) + reset = False + affected = [] + if RESET_ABOVE < len(obsmarkers): + # lots of new obsmarkers, probably smarter to reset the cache + repo.ui.log('evoext-cache', 'obshashcache reset - ' + 'many new markers (%d)\n' + % len(obsmarkers)) + reset = True + elif obsmarkers: + max_stored = con.execute(_query_max_stored).fetchall()[0][0] + affected_nodes = _affectedby(repo, obsmarkers) - rev = repo.changelog.nodemap.get - affected = [rev(n) for n in affected_nodes] - affected = [r for r in affected - if r is not None and r <= max_stored] + rev = repo.changelog.nodemap.get + affected = [rev(n) for n in affected_nodes] + affected = [r for r in affected + if r is not None and r <= max_stored] - if affected: - repo.ui.log('evoext-cache', 'obshashcache clean - ' - 'new markers affect %d changeset and cached ranges\n' + if RESET_ABOVE < len(affected): + repo.ui.log('evoext-cache', 'obshashcache reset - ' + 'new markers affect many changeset (%d)\n' % len(affected)) + reset = True + + if affected or reset: + if not reset: + repo.ui.log('evoext-cache', 'obshashcache clean - ' + 'new markers affect %d changeset and cached ranges\n' + % len(affected)) if con is not None: # always reset for now, the code detecting affect is buggy # so we need to reset more broadly than we would like. try: if repo.stablerange._con is None: + repo.ui.log('evoext-cache', 'obshashcache reset - ' + 'underlying stablerange cache unavailable\n') + reset = True + if reset: con.execute(_reset) self._data.clear() else: @@ -589,7 +612,7 @@ return try: return self._trysave(repo) - except (sqlite3.DatabaseError, sqlite3.OperationalError, sqlite3.IntegrityError) as exc: + except (IOError, OSError, sqlite3.DatabaseError, sqlite3.OperationalError, sqlite3.IntegrityError) as exc: # Catch error that may arise under stress # # operational error catch read-only and locked database @@ -598,6 +621,7 @@ del self._con self._new.clear() repo.ui.log('evoext-cache', 'error while saving new data: %s' % exc) + repo.ui.debug('evoext-cache: error while saving new data: %s' % exc) def _trysave(self, repo): if self._con is None: diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/rewind.py --- a/hgext3rd/evolve/rewind.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/rewind.py Fri Sep 14 10:47:57 2018 +0200 @@ -27,49 +27,49 @@ @eh.command( '^rewind', - [('', 'to', [], _("rewind to these revision")), + [('', 'to', [], _("rewind to these revisions")), ('', 'as-divergence', None, _("preserve current latest successors")), ('', 'exact', None, _("only rewind explicitly selected revisions")), ('', 'from', [], _("rewind these revisions to their predecessors")), ], _('')) def rewind(ui, repo, **opts): - """rewind stacks of changeset to a previous content + """rewind a stack of changesets to a previous state This command can be used to restore stacks of changesets to an obsolete - state, creating identical identical copies. + state, creating identical copies. - There are two mains way to select the rewind target. Rewinding "from" - changesets will restore the direct precursors of theses changesets (and + There are two main ways to select the rewind target. Rewinding "from" + changesets will restore the direct predecessors of these changesets (and obsolete the changeset you rewind from). Rewinding "to" will restore the changeset you have selected (and obsolete their latest successors). By default, we rewind from the working copy parents, restoring its - precursor. + predecessor. When we rewind to an obsolete version, we also rewind to all its obsolete - ancestors. To only rewind to the explicitly selection changesets use the + ancestors. To only rewind to the explicitly selected changesets use the `--exact` flag. Using the `--exact` flag can restore some changesets as orphan. - The latest successors the obsolete changesets will be superseed by these - new copies. This behavior can be disabled using `--as-divergence`, the - current latest successors won't be affected and content-divergence will - appears between them and the restored version of the obsolete changesets. + The latest successors of the obsolete changesets will be superseded by + these new copies. This behavior can be disabled using `--as-divergence`, + the current latest successors won't be affected and content-divergence will + appear between them and the restored version of the obsolete changesets. - Current rought edges: + Current rough edges: * fold: rewinding to only some of the initially folded changesets will be problematic. The fold result is marked obsolete and the part not - rewinded too are "lost". Please use --as-divergence when you + rewinded to are "lost". Please use --as-divergence when you need to perform such operation. - * :hg:`rewind` might affect changeset outside the current stack. Without --exact, we - also restore ancestors of the rewind target, obsoleting their - latest successors (unless --as-divergent is provided). In some - case, these latest successors will be on branches unrelated to - the changeset you rewind from. - (We plan to automatically detect this cases in the future) + * :hg:`rewind` might affect changesets outside the current stack. Without + --exact, we also restore ancestors of the rewind target, + obsoleting their latest successors (unless --as-divergent is + provided). In some case, these latest successors will be on + branches unrelated to the changeset you rewind from. + (We plan to automatically detect this case in the future) """ unfi = repo.unfiltered() diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/stablerangecache.py --- a/hgext3rd/evolve/stablerangecache.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/stablerangecache.py Fri Sep 14 10:47:57 2018 +0200 @@ -94,6 +94,7 @@ progress_new = time.time() if not warned_long and LONG_WARNING_TIME < (progress_new - initial_time): repo.ui.warn(LONG_MESSAGE) + warned_long = True if (1 < progress_each) and (0.1 < progress_new - progress_last): progress_each /= 10 ui.progress(_("filling stablerange cache"), seen, @@ -265,7 +266,7 @@ return try: return self._trysave(repo) - except (sqlite3.DatabaseError, sqlite3.OperationalError, sqlite3.IntegrityError) as exc: + except (IOError, OSError, sqlite3.DatabaseError, sqlite3.OperationalError, sqlite3.IntegrityError) as exc: # Catch error that may arise under stress # # operational error catch read-only and locked database @@ -274,6 +275,7 @@ del self._con self._unsavedsubranges.clear() repo.ui.log('evoext-cache', 'error while saving new data: %s' % exc) + repo.ui.debug('evoext-cache: error while saving new data: %s' % exc) def _trysave(self, repo): repo = repo.unfiltered() diff -r ef3c9ecb8099 -r b3b861a7f6f7 hgext3rd/evolve/stablesort.py --- a/hgext3rd/evolve/stablesort.py Thu Sep 13 00:04:17 2018 +0800 +++ b/hgext3rd/evolve/stablesort.py Fri Sep 14 10:47:57 2018 +0200 @@ -634,21 +634,26 @@ """ if self._cachekey is None or self._cachekey == self._ondiskkey: return - cachevfs = compat.getcachevfs(repo) - cachefile = cachevfs(self._filepath, 'w', atomictemp=True) + try: + cachevfs = compat.getcachevfs(repo) + cachefile = cachevfs(self._filepath, 'w', atomictemp=True) + + # data to write + headerdata = self._serializecachekey() + indexdata = self._index.tostring() + data = self._data.tostring() + indexsize = S_INDEXSIZE.pack(len(indexdata)) - # data to write - headerdata = self._serializecachekey() - indexdata = self._index.tostring() - data = self._data.tostring() - indexsize = S_INDEXSIZE.pack(len(indexdata)) - - # writing - cachefile.write(headerdata) - cachefile.write(indexsize) - cachefile.write(indexdata) - cachefile.write(data) - cachefile.close() + # writing + cachefile.write(headerdata) + cachefile.write(indexsize) + cachefile.write(indexdata) + cachefile.write(data) + cachefile.close() + self._ondiskkey = self._cachekey + except (IOError, OSError) as exc: + repo.ui.log('stablesortcache', 'could not write update %s\n' % exc) + repo.ui.debug('stablesortcache: could not write update %s\n' % exc) @eh.reposetup def setupcache(ui, repo):