Mercurial > hg
comparison hgext/fsmonitor/__init__.py @ 32335:354329178dee
fsmonitor: don't attempt state-leave if we didn't state-enter
The state-enter command may not have been successful; for example, the watchman
client session may have timed out if the user was busy/idle for a long period
during a merge conflict resolution earlier in processing a rebase for a stack
of diffs.
It's cleaner (from the perspective of the watchman logs) to avoid issuing the
state-leave command in these cases.
Test Plan:
ran
`hg rebase --tool :merge -r '(draft() & date(-14)) - master::' -d master`
and didn't observe any errors in the watchman logs or in the output from
`watchman -p -j <<<'["subscribe", "/data/users/wez/fbsource", "wez", {"expression": ["name", ".hg/updatestate"]}]'`
author | Wez Furlong <wez@fb.com> |
---|---|
date | Thu, 18 May 2017 12:49:10 -0700 |
parents | 6e0d1043e8fc |
children | bdc4861ffe59 |
comparison
equal
deleted
inserted
replaced
32334:6e0d1043e8fc | 32335:354329178dee |
---|---|
599 self.repo = repo | 599 self.repo = repo |
600 self.node = node | 600 self.node = node |
601 self.distance = distance | 601 self.distance = distance |
602 self.partial = partial | 602 self.partial = partial |
603 self._lock = None | 603 self._lock = None |
604 self.need_leave = False | |
604 | 605 |
605 def __enter__(self): | 606 def __enter__(self): |
606 # We explicitly need to take a lock here, before we proceed to update | 607 # We explicitly need to take a lock here, before we proceed to update |
607 # watchman about the update operation, so that we don't race with | 608 # watchman about the update operation, so that we don't race with |
608 # some other actor. merge.update is going to take the wlock almost | 609 # some other actor. merge.update is going to take the wlock almost |
609 # immediately anyway, so this is effectively extending the lock | 610 # immediately anyway, so this is effectively extending the lock |
610 # around a couple of short sanity checks. | 611 # around a couple of short sanity checks. |
611 self._lock = self.repo.wlock() | 612 self._lock = self.repo.wlock() |
612 self._state('state-enter') | 613 self.need_leave = self._state('state-enter') |
613 return self | 614 return self |
614 | 615 |
615 def __exit__(self, type_, value, tb): | 616 def __exit__(self, type_, value, tb): |
616 try: | 617 try: |
617 status = 'ok' if type_ is None else 'failed' | 618 if self.need_leave: |
618 self._state('state-leave', status=status) | 619 status = 'ok' if type_ is None else 'failed' |
620 self._state('state-leave', status=status) | |
619 finally: | 621 finally: |
620 if self._lock: | 622 if self._lock: |
621 self._lock.release() | 623 self._lock.release() |
622 | 624 |
623 def _state(self, cmd, status='ok'): | 625 def _state(self, cmd, status='ok'): |
624 if not util.safehasattr(self.repo, '_watchmanclient'): | 626 if not util.safehasattr(self.repo, '_watchmanclient'): |
625 return | 627 return False |
626 try: | 628 try: |
627 commithash = self.repo[self.node].hex() | 629 commithash = self.repo[self.node].hex() |
628 self.repo._watchmanclient.command(cmd, { | 630 self.repo._watchmanclient.command(cmd, { |
629 'name': 'hg.update', | 631 'name': 'hg.update', |
630 'metadata': { | 632 'metadata': { |
635 # success/failure (only really meaningful for state-leave) | 637 # success/failure (only really meaningful for state-leave) |
636 'status': status, | 638 'status': status, |
637 # whether the working copy parent is changing | 639 # whether the working copy parent is changing |
638 'partial': self.partial, | 640 'partial': self.partial, |
639 }}) | 641 }}) |
642 return True | |
640 except Exception as e: | 643 except Exception as e: |
641 # Swallow any errors; fire and forget | 644 # Swallow any errors; fire and forget |
642 self.repo.ui.log( | 645 self.repo.ui.log( |
643 'watchman', 'Exception %s while running %s\n', e, cmd) | 646 'watchman', 'Exception %s while running %s\n', e, cmd) |
647 return False | |
644 | 648 |
645 # Bracket working copy updates with calls to the watchman state-enter | 649 # Bracket working copy updates with calls to the watchman state-enter |
646 # and state-leave commands. This allows clients to perform more intelligent | 650 # and state-leave commands. This allows clients to perform more intelligent |
647 # settling during bulk file change scenarios | 651 # settling during bulk file change scenarios |
648 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling | 652 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling |