Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/obsutil.py @ 33274:68f3e819d41d
obsolete: closest divergent support
Add a closest argument to successorssets changing the definition of latest
successors.
With "closest=false" (current behavior), latest successors are "leafs" on the
obsmarker graph. They don't have any successor and are known locally.
With "closest=true", latest successors are the closest locally-known
changesets that are visible in the repository or repoview. Closest successors
can be then obsolete, orphan.
This will be used in a later patch to show the closest successor of
changesets with the successorssets template.
author | Boris Feld <boris.feld@octobus.net> |
---|---|
date | Fri, 30 Jun 2017 15:27:19 +0200 |
parents | df90f4d6c609 |
children | 888f24810ea2 |
comparison
equal
deleted
inserted
replaced
33273:5724aaa99dd6 | 33274:68f3e819d41d |
---|---|
309 continue | 309 continue |
310 if set(succsmarkers(node)).issubset(addedmarkers): | 310 if set(succsmarkers(node)).issubset(addedmarkers): |
311 obsoleted.add(rev) | 311 obsoleted.add(rev) |
312 return obsoleted | 312 return obsoleted |
313 | 313 |
314 def successorssets(repo, initialnode, cache=None): | 314 def successorssets(repo, initialnode, closest=False, cache=None): |
315 """Return set of all latest successors of initial nodes | 315 """Return set of all latest successors of initial nodes |
316 | 316 |
317 The successors set of a changeset A are the group of revisions that succeed | 317 The successors set of a changeset A are the group of revisions that succeed |
318 A. It succeeds A as a consistent whole, each revision being only a partial | 318 A. It succeeds A as a consistent whole, each revision being only a partial |
319 replacement. The successors set contains non-obsolete changesets only. | 319 replacement. By default, the successors set contains non-obsolete |
320 changesets only, walking the obsolescence graph until reaching a leaf. If | |
321 'closest' is set to True, closest successors-sets are return (the | |
322 obsolescence walk stops on known changesets). | |
320 | 323 |
321 This function returns the full list of successor sets which is why it | 324 This function returns the full list of successor sets which is why it |
322 returns a list of tuples and not just a single tuple. Each tuple is a valid | 325 returns a list of tuples and not just a single tuple. Each tuple is a valid |
323 successors set. Note that (A,) may be a valid successors set for changeset A | 326 successors set. Note that (A,) may be a valid successors set for changeset A |
324 (see below). | 327 (see below). |
339 set will contain itself only, i.e. [(A,)]. | 342 set will contain itself only, i.e. [(A,)]. |
340 | 343 |
341 Finally, final successors unknown locally are considered to be pruned | 344 Finally, final successors unknown locally are considered to be pruned |
342 (pruned: obsoleted without any successors). (Final: successors not affected | 345 (pruned: obsoleted without any successors). (Final: successors not affected |
343 by markers). | 346 by markers). |
347 | |
348 The 'closest' mode respect the repoview filtering. For example, without | |
349 filter it will stop at the first locally known changeset, with 'visible' | |
350 filter it will stop on visible changesets). | |
344 | 351 |
345 The optional `cache` parameter is a dictionary that may contains | 352 The optional `cache` parameter is a dictionary that may contains |
346 precomputed successors sets. It is meant to reuse the computation of a | 353 precomputed successors sets. It is meant to reuse the computation of a |
347 previous call to `successorssets` when multiple calls are made at the same | 354 previous call to `successorssets` when multiple calls are made at the same |
348 time. The cache dictionary is updated in place. The caller is responsible | 355 time. The cache dictionary is updated in place. The caller is responsible |
349 for its life span. Code that makes multiple calls to `successorssets` | 356 for its life span. Code that makes multiple calls to `successorssets` |
350 *should* use this cache mechanism or risk a performance hit. | 357 *should* use this cache mechanism or risk a performance hit. |
358 | |
359 Since results are different depending of the 'closest' most, the same cache | |
360 cannot be reused for both mode. | |
351 """ | 361 """ |
352 | 362 |
353 succmarkers = repo.obsstore.successors | 363 succmarkers = repo.obsstore.successors |
354 | 364 |
355 # Stack of nodes we search successors sets for | 365 # Stack of nodes we search successors sets for |
392 # | 402 # |
393 # There are four possible outcomes: | 403 # There are four possible outcomes: |
394 # | 404 # |
395 # 1) We already know the successors sets of CURRENT: | 405 # 1) We already know the successors sets of CURRENT: |
396 # -> mission accomplished, pop it from the stack. | 406 # -> mission accomplished, pop it from the stack. |
397 # 2) Node is not obsolete: | 407 # 2) Stop the walk: |
398 # -> the node is its own successors sets. Add it to the cache. | 408 # default case: Node is not obsolete |
409 # closest case: Node is known at this repo filter level | |
410 # -> the node is its own successors sets. Add it to the cache. | |
399 # 3) We do not know successors set of direct successors of CURRENT: | 411 # 3) We do not know successors set of direct successors of CURRENT: |
400 # -> We add those successors to the stack. | 412 # -> We add those successors to the stack. |
401 # 4) We know successors sets of all direct successors of CURRENT: | 413 # 4) We know successors sets of all direct successors of CURRENT: |
402 # -> We can compute CURRENT successors set and add it to the | 414 # -> We can compute CURRENT successors set and add it to the |
403 # cache. | 415 # cache. |
404 # | 416 # |
405 current = toproceed[-1] | 417 current = toproceed[-1] |
418 | |
419 # case 2 condition is a bit hairy because of closest, | |
420 # we compute it on its own | |
421 case2condition = ((current not in succmarkers) | |
422 or (closest and current != initialnode | |
423 and current in repo)) | |
424 | |
406 if current in cache: | 425 if current in cache: |
407 # case (1): We already know the successors sets | 426 # case (1): We already know the successors sets |
408 stackedset.remove(toproceed.pop()) | 427 stackedset.remove(toproceed.pop()) |
409 elif current not in succmarkers: | 428 elif case2condition: |
410 # case (2): The node is not obsolete. | 429 # case (2): end of walk. |
411 if current in repo: | 430 if current in repo: |
412 # We have a valid last successors. | 431 # We have a valid successors. |
413 cache[current] = [(current,)] | 432 cache[current] = [(current,)] |
414 else: | 433 else: |
415 # Final obsolete version is unknown locally. | 434 # Final obsolete version is unknown locally. |
416 # Do not count that as a valid successors | 435 # Do not count that as a valid successors |
417 cache[current] = [] | 436 cache[current] = [] |