447 def shortesthexnodeidprefix(repo, node, minlength=1): |
447 def shortesthexnodeidprefix(repo, node, minlength=1): |
448 """Find the shortest unambiguous prefix that matches hexnode.""" |
448 """Find the shortest unambiguous prefix that matches hexnode.""" |
449 # _partialmatch() of filtered changelog could take O(len(repo)) time, |
449 # _partialmatch() of filtered changelog could take O(len(repo)) time, |
450 # which would be unacceptably slow. so we look for hash collision in |
450 # which would be unacceptably slow. so we look for hash collision in |
451 # unfiltered space, which means some hashes may be slightly longer. |
451 # unfiltered space, which means some hashes may be slightly longer. |
|
452 cl = repo.unfiltered().changelog |
|
453 |
|
454 def isrev(prefix): |
|
455 try: |
|
456 i = int(prefix) |
|
457 # if we are a pure int, then starting with zero will not be |
|
458 # confused as a rev; or, obviously, if the int is larger |
|
459 # than the value of the tip rev |
|
460 if prefix[0] == '0' or i > len(cl): |
|
461 return False |
|
462 return True |
|
463 except ValueError: |
|
464 return False |
|
465 |
|
466 def disambiguate(prefix): |
|
467 """Disambiguate against revnums.""" |
|
468 hexnode = hex(node) |
|
469 for length in range(len(prefix), 41): |
|
470 prefix = hexnode[:length] |
|
471 if not isrev(prefix): |
|
472 return prefix |
|
473 |
452 try: |
474 try: |
453 return repo.unfiltered().changelog.shortest(node, minlength) |
475 return disambiguate(cl.shortest(node, minlength)) |
454 except error.LookupError: |
476 except error.LookupError: |
455 raise error.RepoLookupError() |
477 raise error.RepoLookupError() |
456 |
478 |
457 def isrevsymbol(repo, symbol): |
479 def isrevsymbol(repo, symbol): |
458 """Checks if a symbol exists in the repo. |
480 """Checks if a symbol exists in the repo. |