mercurial/obsolete.py
changeset 17831 70b08df24fef
parent 17828 9495be4126ef
child 18001 e02feadd15ea
equal deleted inserted replaced
17830:1cb51d65453d 17831:70b08df24fef
    99 _fmversion = 0
    99 _fmversion = 0
   100 _fmfixed   = '>BIB20s'
   100 _fmfixed   = '>BIB20s'
   101 _fmnode = '20s'
   101 _fmnode = '20s'
   102 _fmfsize = struct.calcsize(_fmfixed)
   102 _fmfsize = struct.calcsize(_fmfixed)
   103 _fnodesize = struct.calcsize(_fmnode)
   103 _fnodesize = struct.calcsize(_fmnode)
       
   104 
       
   105 ### obsolescence marker flag
       
   106 
       
   107 ## bumpedfix flag
       
   108 #
       
   109 # When a changeset A' succeed to a changeset A which became public, we call A'
       
   110 # "bumped" because it's a successors of a public changesets
       
   111 #
       
   112 # o    A' (bumped)
       
   113 # |`:
       
   114 # | o  A
       
   115 # |/
       
   116 # o    Z
       
   117 #
       
   118 # The way to solve this situation is to create a new changeset Ad as children
       
   119 # of A. This changeset have the same content than A'. So the diff from A to A'
       
   120 # is the same than the diff from A to Ad. Ad is marked as a successors of A'
       
   121 #
       
   122 # o   Ad
       
   123 # |`:
       
   124 # | x A'
       
   125 # |'|
       
   126 # o | A
       
   127 # |/
       
   128 # o Z
       
   129 #
       
   130 # But by transitivity Ad is also a successors of A. To avoid having Ad marked
       
   131 # as bumped too, we add the `bumpedfix` flag to the marker. <A', (Ad,)>.
       
   132 # This flag mean that the successors are an interdiff that fix the bumped
       
   133 # situation, breaking the transitivity of "bumped" here.
       
   134 bumpedfix = 1
   104 
   135 
   105 def _readmarkers(data):
   136 def _readmarkers(data):
   106     """Read and enumerate markers from raw data"""
   137     """Read and enumerate markers from raw data"""
   107     off = 0
   138     off = 0
   108     diskversion = _unpack('>B', data[off:off + 1])[0]
   139     diskversion = _unpack('>B', data[off:off + 1])[0]
   349 def successormarkers(ctx):
   380 def successormarkers(ctx):
   350     """obsolete marker making this changeset obsolete"""
   381     """obsolete marker making this changeset obsolete"""
   351     for data in ctx._repo.obsstore.successors.get(ctx.node(), ()):
   382     for data in ctx._repo.obsstore.successors.get(ctx.node(), ()):
   352         yield marker(ctx._repo, data)
   383         yield marker(ctx._repo, data)
   353 
   384 
   354 def allsuccessors(obsstore, nodes):
   385 def allsuccessors(obsstore, nodes, ignoreflags=0):
   355     """Yield node for every successor of <nodes>.
   386     """Yield node for every successor of <nodes>.
   356 
   387 
   357     Some successors may be unknown locally.
   388     Some successors may be unknown locally.
   358 
   389 
   359     This is a linear yield unsuited to detecting split changesets."""
   390     This is a linear yield unsuited to detecting split changesets."""
   361     seen = set(remaining)
   392     seen = set(remaining)
   362     while remaining:
   393     while remaining:
   363         current = remaining.pop()
   394         current = remaining.pop()
   364         yield current
   395         yield current
   365         for mark in obsstore.successors.get(current, ()):
   396         for mark in obsstore.successors.get(current, ()):
       
   397             # ignore marker flagged with with specified flag
       
   398             if mark[2] & ignoreflags:
       
   399                 continue
   366             for suc in mark[1]:
   400             for suc in mark[1]:
   367                 if suc not in seen:
   401                 if suc not in seen:
   368                     seen.add(suc)
   402                     seen.add(suc)
   369                     remaining.add(suc)
   403                     remaining.add(suc)
   370 
   404 
   447 def _computebumpedset(repo):
   481 def _computebumpedset(repo):
   448     """the set of revs trying to obsolete public revisions"""
   482     """the set of revs trying to obsolete public revisions"""
   449     # get all possible bumped changesets
   483     # get all possible bumped changesets
   450     tonode = repo.changelog.node
   484     tonode = repo.changelog.node
   451     publicnodes = (tonode(r) for r in repo.revs('public()'))
   485     publicnodes = (tonode(r) for r in repo.revs('public()'))
   452     successors = allsuccessors(repo.obsstore, publicnodes)
   486     successors = allsuccessors(repo.obsstore, publicnodes,
       
   487                                ignoreflags=bumpedfix)
   453     # revision public or already obsolete don't count as bumped
   488     # revision public or already obsolete don't count as bumped
   454     query = '%ld - obsolete() - public()'
   489     query = '%ld - obsolete() - public()'
   455     return set(repo.revs(query, _knownrevs(repo, successors)))
   490     return set(repo.revs(query, _knownrevs(repo, successors)))
   456 
   491 
   457 def createmarkers(repo, relations, flag=0, metadata=None):
   492 def createmarkers(repo, relations, flag=0, metadata=None):