Show More
@@ -99,6 +99,7 b' from mercurial import (' | |||||
99 | context, |
|
99 | context, | |
100 | extensions, |
|
100 | extensions, | |
101 | localrepo, |
|
101 | localrepo, | |
|
102 | merge, | |||
102 | pathutil, |
|
103 | pathutil, | |
103 | scmutil, |
|
104 | scmutil, | |
104 | util, |
|
105 | util, | |
@@ -547,6 +548,8 b' def extsetup(ui):' | |||||
547 | # An assist for avoiding the dangling-symlink fsevents bug |
|
548 | # An assist for avoiding the dangling-symlink fsevents bug | |
548 | extensions.wrapfunction(os, 'symlink', wrapsymlink) |
|
549 | extensions.wrapfunction(os, 'symlink', wrapsymlink) | |
549 |
|
550 | |||
|
551 | extensions.wrapfunction(merge, 'update', wrapupdate) | |||
|
552 | ||||
550 | def wrapsymlink(orig, source, link_name): |
|
553 | def wrapsymlink(orig, source, link_name): | |
551 | ''' if we create a dangling symlink, also touch the parent dir |
|
554 | ''' if we create a dangling symlink, also touch the parent dir | |
552 | to encourage fsevents notifications to work more correctly ''' |
|
555 | to encourage fsevents notifications to work more correctly ''' | |
@@ -558,6 +561,71 b' def wrapsymlink(orig, source, link_name)' | |||||
558 | except OSError: |
|
561 | except OSError: | |
559 | pass |
|
562 | pass | |
560 |
|
563 | |||
|
564 | class state_update(object): | |||
|
565 | ''' This context mananger is responsible for dispatching the state-enter | |||
|
566 | and state-leave signals to the watchman service ''' | |||
|
567 | ||||
|
568 | def __init__(self, repo, node, distance, partial): | |||
|
569 | self.repo = repo | |||
|
570 | self.node = node | |||
|
571 | self.distance = distance | |||
|
572 | self.partial = partial | |||
|
573 | ||||
|
574 | def __enter__(self): | |||
|
575 | self._state('state-enter') | |||
|
576 | return self | |||
|
577 | ||||
|
578 | def __exit__(self, type_, value, tb): | |||
|
579 | status = 'ok' if type_ is None else 'failed' | |||
|
580 | self._state('state-leave', status=status) | |||
|
581 | ||||
|
582 | def _state(self, cmd, status='ok'): | |||
|
583 | if not util.safehasattr(self.repo, '_watchmanclient'): | |||
|
584 | return | |||
|
585 | try: | |||
|
586 | commithash = self.repo[self.node].hex() | |||
|
587 | self.repo._watchmanclient.command(cmd, { | |||
|
588 | 'name': 'hg.update', | |||
|
589 | 'metadata': { | |||
|
590 | # the target revision | |||
|
591 | 'rev': commithash, | |||
|
592 | # approximate number of commits between current and target | |||
|
593 | 'distance': self.distance, | |||
|
594 | # success/failure (only really meaningful for state-leave) | |||
|
595 | 'status': status, | |||
|
596 | # whether the working copy parent is changing | |||
|
597 | 'partial': self.partial, | |||
|
598 | }}) | |||
|
599 | except Exception as e: | |||
|
600 | # Swallow any errors; fire and forget | |||
|
601 | self.repo.ui.log( | |||
|
602 | 'watchman', 'Exception %s while running %s\n', e, cmd) | |||
|
603 | ||||
|
604 | # Bracket working copy updates with calls to the watchman state-enter | |||
|
605 | # and state-leave commands. This allows clients to perform more intelligent | |||
|
606 | # settling during bulk file change scenarios | |||
|
607 | # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling | |||
|
608 | def wrapupdate(orig, repo, node, branchmerge, force, ancestor=None, | |||
|
609 | mergeancestor=False, labels=None, matcher=None, **kwargs): | |||
|
610 | ||||
|
611 | distance = 0 | |||
|
612 | partial = True | |||
|
613 | if matcher is None or matcher.always(): | |||
|
614 | partial = False | |||
|
615 | wc = repo[None] | |||
|
616 | parents = wc.parents() | |||
|
617 | if len(parents) == 2: | |||
|
618 | anc = repo.changelog.ancestor(parents[0].node(), parents[1].node()) | |||
|
619 | ancrev = repo[anc].rev() | |||
|
620 | distance = abs(repo[node].rev() - ancrev) | |||
|
621 | elif len(parents) == 1: | |||
|
622 | distance = abs(repo[node].rev() - parents[0].rev()) | |||
|
623 | ||||
|
624 | with state_update(repo, node, distance, partial): | |||
|
625 | return orig( | |||
|
626 | repo, node, branchmerge, force, ancestor, mergeancestor, | |||
|
627 | labels, matcher, *kwargs) | |||
|
628 | ||||
561 | def reposetup(ui, repo): |
|
629 | def reposetup(ui, repo): | |
562 | # We don't work with largefiles or inotify |
|
630 | # We don't work with largefiles or inotify | |
563 | exts = extensions.enabled() |
|
631 | exts = extensions.enabled() |
General Comments 0
You need to be logged in to leave comments.
Login now