# HG changeset patch # User Pierre-Yves David # Date 2013-04-16 13:16:33 # Node ID efef056b1ae9c9d71cad6b99da455595eb349b1d # Parent 31bcc5112191ecb72a964cb270363b9b68da2973 obsolete: extract foreground computation from bookmark.validdest This foreground logic will be reused by update logic. diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py --- a/mercurial/bookmarks.py +++ b/mercurial/bookmarks.py @@ -292,19 +292,7 @@ def validdest(repo, old, new): # (new != nullrev has been excluded by the previous check) return True elif repo.obsstore: - # We only need this complicated logic if there is obsolescence - # XXX will probably deserve an optimised revset. - nm = repo.changelog.nodemap - validdests = set([old]) - plen = -1 - # compute the whole set of successors or descendants - while len(validdests) != plen: - plen = len(validdests) - succs = set(c.node() for c in validdests) - mutable = [c.node() for c in validdests if c.mutable()] - succs.update(obsolete.allsuccessors(repo.obsstore, mutable)) - known = (n for n in succs if n in nm) - validdests = set(repo.set('%ln::', known)) - return new in validdests + return new.node() in obsolete.foreground(repo, [old.node()]) else: + # still an independant clause as it is lazyer (and therefore faster) return old.descendant(new) diff --git a/mercurial/obsolete.py b/mercurial/obsolete.py --- a/mercurial/obsolete.py +++ b/mercurial/obsolete.py @@ -405,6 +405,33 @@ def allsuccessors(obsstore, nodes, ignor seen.add(suc) remaining.add(suc) +def foreground(repo, nodes): + """return all nodes in the "foreground" of other node + + The foreground of a revision is anything reachable using parent -> children + or precursor -> sucessor relation. It is very similars to "descendant" but + augmented with obsolescence information. + + Beware that possible obsolescence cycle may result if complexe situation. + """ + repo = repo.unfiltered() + foreground = set(repo.set('%ln::', nodes)) + if repo.obsstore: + # We only need this complicated logic if there is obsolescence + # XXX will probably deserve an optimised revset. + nm = repo.changelog.nodemap + plen = -1 + # compute the whole set of successors or descendants + while len(foreground) != plen: + plen = len(foreground) + succs = set(c.node() for c in foreground) + mutable = [c.node() for c in foreground if c.mutable()] + succs.update(allsuccessors(repo.obsstore, mutable)) + known = (n for n in succs if n in nm) + foreground = set(repo.set('%ln::', known)) + return set(c.node() for c in foreground) + + def successorssets(repo, initialnode, cache=None): """Return all set of successors of initial nodes