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.""" |
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): |