mercurial/obsolete.py
changeset 33760 0c3112f17610
parent 33759 d5acd967f95a
child 33761 e6d8ee3c9ec3
equal deleted inserted replaced
33759:d5acd967f95a 33760:0c3112f17610
    18 building new tools to reconcile conflicting rewrite actions. To
    18 building new tools to reconcile conflicting rewrite actions. To
    19 facilitate conflict resolution, markers include various annotations
    19 facilitate conflict resolution, markers include various annotations
    20 besides old and news changeset identifiers, such as creation date or
    20 besides old and news changeset identifiers, such as creation date or
    21 author name.
    21 author name.
    22 
    22 
    23 The old obsoleted changeset is called a "precursor" and possible
    23 The old obsoleted changeset is called a "predecessor" and possible
    24 replacements are called "successors". Markers that used changeset X as
    24 replacements are called "successors". Markers that used changeset X as
    25 a precursor are called "successor markers of X" because they hold
    25 a predecessor are called "successor markers of X" because they hold
    26 information about the successors of X. Markers that use changeset Y as
    26 information about the successors of X. Markers that use changeset Y as
    27 a successors are call "precursor markers of Y" because they hold
    27 a successors are call "predecessor markers of Y" because they hold
    28 information about the precursors of Y.
    28 information about the predecessors of Y.
    29 
    29 
    30 Examples:
    30 Examples:
    31 
    31 
    32 - When changeset A is replaced by changeset A', one marker is stored:
    32 - When changeset A is replaced by changeset A', one marker is stored:
    33 
    33 
   292 #     2: two parents stored,
   292 #     2: two parents stored,
   293 #     3: no parent data stored
   293 #     3: no parent data stored
   294 #
   294 #
   295 # - uint8: number of metadata entries M
   295 # - uint8: number of metadata entries M
   296 #
   296 #
   297 # - 20 or 32 bytes: precursor changeset identifier.
   297 # - 20 or 32 bytes: predecessor changeset identifier.
   298 #
   298 #
   299 # - N*(20 or 32) bytes: successors changesets identifiers.
   299 # - N*(20 or 32) bytes: successors changesets identifiers.
   300 #
   300 #
   301 # - P*(20 or 32) bytes: parents of the precursors changesets.
   301 # - P*(20 or 32) bytes: parents of the predecessors changesets.
   302 #
   302 #
   303 # - M*(uint8, uint8): size of all metadata entries (key and value)
   303 # - M*(uint8, uint8): size of all metadata entries (key and value)
   304 #
   304 #
   305 # - remaining bytes: the metadata, each (key, value) pair after the other.
   305 # - remaining bytes: the metadata, each (key, value) pair after the other.
   306 _fm1version = 1
   306 _fm1version = 1
   504 
   504 
   505 class obsstore(object):
   505 class obsstore(object):
   506     """Store obsolete markers
   506     """Store obsolete markers
   507 
   507 
   508     Markers can be accessed with two mappings:
   508     Markers can be accessed with two mappings:
   509     - precursors[x] -> set(markers on precursors edges of x)
   509     - predecessors[x] -> set(markers on predecessors edges of x)
   510     - successors[x] -> set(markers on successors edges of x)
   510     - successors[x] -> set(markers on successors edges of x)
   511     - children[x]   -> set(markers on precursors edges of children(x)
   511     - children[x]   -> set(markers on predecessors edges of children(x)
   512     """
   512     """
   513 
   513 
   514     fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
   514     fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents')
   515     # prec:    nodeid, precursor changesets
   515     # prec:    nodeid, predecessors changesets
   516     # succs:   tuple of nodeid, successor changesets (0-N length)
   516     # succs:   tuple of nodeid, successor changesets (0-N length)
   517     # flag:    integer, flag field carrying modifier for the markers (see doc)
   517     # flag:    integer, flag field carrying modifier for the markers (see doc)
   518     # meta:    binary blob, encoded metadata dictionary
   518     # meta:    binary blob, encoded metadata dictionary
   519     # date:    (float, int) tuple, date of marker creation
   519     # date:    (float, int) tuple, date of marker creation
   520     # parents: (tuple of nodeid) or None, parents of precursors
   520     # parents: (tuple of nodeid) or None, parents of predecessors
   521     #          None is used when no data has been recorded
   521     #          None is used when no data has been recorded
   522 
   522 
   523     def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
   523     def __init__(self, svfs, defaultformat=_fm1version, readonly=False):
   524         # caches for various obsolescence related cache
   524         # caches for various obsolescence related cache
   525         self.caches = {}
   525         self.caches = {}
   705 
   705 
   706         "relevant" to a set of nodes mean:
   706         "relevant" to a set of nodes mean:
   707 
   707 
   708         - marker that use this changeset as successor
   708         - marker that use this changeset as successor
   709         - prune marker of direct children on this changeset
   709         - prune marker of direct children on this changeset
   710         - recursive application of the two rules on precursors of these markers
   710         - recursive application of the two rules on predecessors of these
       
   711           markers
   711 
   712 
   712         It is a set so you cannot rely on order."""
   713         It is a set so you cannot rely on order."""
   713 
   714 
   714         pendingnodes = set(nodes)
   715         pendingnodes = set(nodes)
   715         seenmarkers = set()
   716         seenmarkers = set()
   945     torev = cl.nodemap.get
   946     torev = cl.nodemap.get
   946     for ctx in repo.set('(not public()) and (not obsolete())'):
   947     for ctx in repo.set('(not public()) and (not obsolete())'):
   947         rev = ctx.rev()
   948         rev = ctx.rev()
   948         # We only evaluate mutable, non-obsolete revision
   949         # We only evaluate mutable, non-obsolete revision
   949         node = ctx.node()
   950         node = ctx.node()
   950         # (future) A cache of precursors may worth if split is very common
   951         # (future) A cache of predecessors may worth if split is very common
   951         for pnode in obsutil.allprecursors(repo.obsstore, [node],
   952         for pnode in obsutil.allprecursors(repo.obsstore, [node],
   952                                    ignoreflags=bumpedfix):
   953                                    ignoreflags=bumpedfix):
   953             prev = torev(pnode) # unfiltered! but so is phasecache
   954             prev = torev(pnode) # unfiltered! but so is phasecache
   954             if (prev is not None) and (phase(repo, prev) <= public):
   955             if (prev is not None) and (phase(repo, prev) <= public):
   955                 # we have a public precursor
   956                 # we have a public predecessor
   956                 bumped.add(rev)
   957                 bumped.add(rev)
   957                 break # Next draft!
   958                 break # Next draft!
   958     return bumped
   959     return bumped
   959 
   960 
   960 @cachefor('divergent')
   961 @cachefor('divergent')