Mercurial > hg
changeset 22271:8c69262df82d
obsstore: add relevantmarkers method
We add a ``relevantmarkers`` method to fetch all markers that seem relevant to a
set of nodes. See function documentation about how this set is computed. This
will let us exchange only the markers that seem "relevant" to the set of
changesets related to a push or a pull.
The approach used to define "relevant" has been successfully tested in evolve
for 6 months.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Tue, 19 Aug 2014 17:03:10 -0700 |
parents | e5adb6935239 |
children | 406181ee335f |
files | mercurial/obsolete.py |
diffstat | 1 files changed, 28 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/obsolete.py Tue Aug 19 16:53:53 2014 -0700 +++ b/mercurial/obsolete.py Tue Aug 19 17:03:10 2014 -0700 @@ -385,6 +385,34 @@ if node.nullid in self.precursors: raise util.Abort(_('bad obsolescence marker detected: ' 'invalid successors nullid')) + def relevantmarkers(self, nodes): + """return a set of all obsolescence markers relevant to a set of nodes. + + "relevant" to a set of nodes mean: + + - marker that use this changeset as successor + - prune marker of direct children on this changeset + - recursive application of the two rules on precursors of these markers + + It is a set so you cannot rely on order.""" + + pendingnodes = set(nodes) + seenmarkers = set() + seennodes = set(pendingnodes) + precursorsmarkers = self.precursors + children = self.children + while pendingnodes: + direct = set() + for current in pendingnodes: + direct.update(precursorsmarkers.get(current, ())) + pruned = [m for m in children.get(current, ()) if not m[1]] + direct.update(pruned) + direct -= seenmarkers + pendingnodes = set([m[0] for m in direct]) + seenmarkers |= direct + pendingnodes -= seennodes + seennodes |= pendingnodes + return seenmarkers def _encodemarkers(markers, addheader=False): # Kept separate from flushmarkers(), it will be reused for