hgext/fsmonitor/__init__.py
author Gregory Szorc <gregory.szorc@gmail.com>
Thu, 14 Jul 2016 19:56:39 -0700
changeset 29557 53de8255ec4e
parent 29341 0d83ad967bf8
child 29841 d5883fd055c6
permissions -rw-r--r--
sslutil: update comment about create_default_context() While ssl.create_default_context() creates a SSLContext with reasonable default options, we can't use it because it conflicts with our CA loading controls. So replace the comment with reality. (FWIW the comment was written before the existing CA loading code was in place.)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     1
# __init__.py - fsmonitor initialization and overrides
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     2
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     3
# Copyright 2013-2016 Facebook, Inc.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     4
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms of the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     6
# GNU General Public License version 2 or any later version.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     7
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     8
'''Faster status operations with the Watchman file monitor (EXPERIMENTAL)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
     9
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    10
Integrates the file-watching program Watchman with Mercurial to produce faster
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    11
status results.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    12
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    13
On a particular Linux system, for a real-world repository with over 400,000
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    14
files hosted on ext4, vanilla `hg status` takes 1.3 seconds. On the same
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    15
system, with fsmonitor it takes about 0.3 seconds.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    16
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    17
fsmonitor requires no configuration -- it will tell Watchman about your
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    18
repository as necessary. You'll need to install Watchman from
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    19
https://facebook.github.io/watchman/ and make sure it is in your PATH.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    20
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    21
The following configuration options exist:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    22
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    23
::
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    24
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    25
    [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    26
    mode = {off, on, paranoid}
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    27
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    28
When `mode = off`, fsmonitor will disable itself (similar to not loading the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    29
extension at all). When `mode = on`, fsmonitor will be enabled (the default).
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    30
When `mode = paranoid`, fsmonitor will query both Watchman and the filesystem,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    31
and ensure that the results are consistent.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    32
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    33
::
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    34
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    35
    [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    36
    timeout = (float)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    37
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    38
A value, in seconds, that determines how long fsmonitor will wait for Watchman
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    39
to return results. Defaults to `2.0`.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    40
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    41
::
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    42
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    43
    [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    44
    blacklistusers = (list of userids)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    45
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    46
A list of usernames for which fsmonitor will disable itself altogether.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    47
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    48
::
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    49
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    50
    [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    51
    walk_on_invalidate = (boolean)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    52
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    53
Whether or not to walk the whole repo ourselves when our cached state has been
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    54
invalidated, for example when Watchman has been restarted or .hgignore rules
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    55
have been changed. Walking the repo in that case can result in competing for
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    56
I/O with Watchman. For large repos it is recommended to set this value to
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    57
false. You may wish to set this to true if you have a very fast filesystem
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    58
that can outpace the IPC overhead of getting the result data for the full repo
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    59
from Watchman. Defaults to false.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    60
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    61
fsmonitor is incompatible with the largefiles and eol extensions, and
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    62
will disable itself if any of those are active.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    63
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    64
'''
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    65
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    66
# Platforms Supported
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    67
# ===================
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    68
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    69
# **Linux:** *Stable*. Watchman and fsmonitor are both known to work reliably,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    70
#   even under severe loads.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    71
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    72
# **Mac OS X:** *Stable*. The Mercurial test suite passes with fsmonitor
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    73
#   turned on, on case-insensitive HFS+. There has been a reasonable amount of
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    74
#   user testing under normal loads.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    75
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    76
# **Solaris, BSD:** *Alpha*. watchman and fsmonitor are believed to work, but
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    77
#   very little testing has been done.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    78
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    79
# **Windows:** *Alpha*. Not in a release version of watchman or fsmonitor yet.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    80
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    81
# Known Issues
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    82
# ============
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    83
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    84
# * fsmonitor will disable itself if any of the following extensions are
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    85
#   enabled: largefiles, inotify, eol; or if the repository has subrepos.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    86
# * fsmonitor will produce incorrect results if nested repos that are not
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    87
#   subrepos exist. *Workaround*: add nested repo paths to your `.hgignore`.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    88
#
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    89
# The issues related to nested repos and subrepos are probably not fundamental
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    90
# ones. Patches to fix them are welcome.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    91
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    92
from __future__ import absolute_import
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    93
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29205
diff changeset
    94
import hashlib
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    95
import os
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    96
import stat
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    97
import sys
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
    98
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28443
diff changeset
    99
from mercurial.i18n import _
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   100
from mercurial import (
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   101
    context,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   102
    extensions,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   103
    localrepo,
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   104
    merge,
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   105
    pathutil,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   106
    scmutil,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   107
    util,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   108
)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   109
from mercurial import match as matchmod
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   110
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   111
from . import (
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   112
    state,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   113
    watchmanclient,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   114
)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   115
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   116
# Note for extension authors: ONLY specify testedwith = 'internal' for
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   117
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   118
# be specifying the version(s) of Mercurial they are tested with, or
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   119
# leave the attribute unspecified.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   120
testedwith = 'internal'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   121
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   122
# This extension is incompatible with the following blacklisted extensions
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   123
# and will disable itself when encountering one of these:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   124
_blacklist = ['largefiles', 'eol']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   125
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   126
def _handleunavailable(ui, state, ex):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   127
    """Exception handler for Watchman interaction exceptions"""
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   128
    if isinstance(ex, watchmanclient.Unavailable):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   129
        if ex.warn:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   130
            ui.warn(str(ex) + '\n')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   131
        if ex.invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   132
            state.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   133
        ui.log('fsmonitor', 'Watchman unavailable: %s\n', ex.msg)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   134
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   135
        ui.log('fsmonitor', 'Watchman exception: %s\n', ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   136
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   137
def _hashignore(ignore):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   138
    """Calculate hash for ignore patterns and filenames
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   139
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   140
    If this information changes between Mercurial invocations, we can't
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   141
    rely on Watchman information anymore and have to re-scan the working
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   142
    copy.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   143
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   144
    """
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29205
diff changeset
   145
    sha1 = hashlib.sha1()
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   146
    if util.safehasattr(ignore, 'includepat'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   147
        sha1.update(ignore.includepat)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   148
    sha1.update('\0\0')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   149
    if util.safehasattr(ignore, 'excludepat'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   150
        sha1.update(ignore.excludepat)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   151
    sha1.update('\0\0')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   152
    if util.safehasattr(ignore, 'patternspat'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   153
        sha1.update(ignore.patternspat)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   154
    sha1.update('\0\0')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   155
    if util.safehasattr(ignore, '_files'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   156
        for f in ignore._files:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   157
            sha1.update(f)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   158
    sha1.update('\0')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   159
    return sha1.hexdigest()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   160
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   161
def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   162
    '''Replacement for dirstate.walk, hooking into Watchman.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   163
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   164
    Whenever full is False, ignored is False, and the Watchman client is
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   165
    available, use Watchman combined with saved state to possibly return only a
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   166
    subset of files.'''
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   167
    def bail():
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   168
        return orig(match, subrepos, unknown, ignored, full=True)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   169
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   170
    if full or ignored or not self._watchmanclient.available():
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   171
        return bail()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   172
    state = self._fsmonitorstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   173
    clock, ignorehash, notefiles = state.get()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   174
    if not clock:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   175
        if state.walk_on_invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   176
            return bail()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   177
        # Initial NULL clock value, see
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   178
        # https://facebook.github.io/watchman/docs/clockspec.html
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   179
        clock = 'c:0:0'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   180
        notefiles = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   181
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   182
    def fwarn(f, msg):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   183
        self._ui.warn('%s: %s\n' % (self.pathto(f), msg))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   184
        return False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   185
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   186
    def badtype(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   187
        kind = _('unknown')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   188
        if stat.S_ISCHR(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   189
            kind = _('character device')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   190
        elif stat.S_ISBLK(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   191
            kind = _('block device')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   192
        elif stat.S_ISFIFO(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   193
            kind = _('fifo')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   194
        elif stat.S_ISSOCK(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   195
            kind = _('socket')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   196
        elif stat.S_ISDIR(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   197
            kind = _('directory')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   198
        return _('unsupported file type (type is %s)') % kind
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   199
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   200
    ignore = self._ignore
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   201
    dirignore = self._dirignore
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   202
    if unknown:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   203
        if _hashignore(ignore) != ignorehash and clock != 'c:0:0':
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   204
            # ignore list changed -- can't rely on Watchman state any more
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   205
            if state.walk_on_invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   206
                return bail()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   207
            notefiles = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   208
            clock = 'c:0:0'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   209
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   210
        # always ignore
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   211
        ignore = util.always
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   212
        dirignore = util.always
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   213
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   214
    matchfn = match.matchfn
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   215
    matchalways = match.always()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   216
    dmap = self._map
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   217
    nonnormalset = getattr(self, '_nonnormalset', None)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   218
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   219
    copymap = self._copymap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   220
    getkind = stat.S_IFMT
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   221
    dirkind = stat.S_IFDIR
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   222
    regkind = stat.S_IFREG
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   223
    lnkkind = stat.S_IFLNK
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   224
    join = self._join
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   225
    normcase = util.normcase
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   226
    fresh_instance = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   227
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   228
    exact = skipstep3 = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   229
    if matchfn == match.exact:  # match.exact
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   230
        exact = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   231
        dirignore = util.always  # skip step 2
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   232
    elif match.files() and not match.anypats():  # match.match, no patterns
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   233
        skipstep3 = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   234
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   235
    if not exact and self._checkcase:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   236
        # note that even though we could receive directory entries, we're only
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   237
        # interested in checking if a file with the same name exists. So only
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   238
        # normalize files if possible.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   239
        normalize = self._normalizefile
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   240
        skipstep3 = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   241
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   242
        normalize = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   243
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   244
    # step 1: find all explicit files
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   245
    results, work, dirsnotfound = self._walkexplicit(match, subrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   246
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   247
    skipstep3 = skipstep3 and not (work or dirsnotfound)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   248
    work = [d for d in work if not dirignore(d[0])]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   249
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   250
    if not work and (exact or skipstep3):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   251
        for s in subrepos:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   252
            del results[s]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   253
        del results['.hg']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   254
        return results
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   255
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   256
    # step 2: query Watchman
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   257
    try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   258
        # Use the user-configured timeout for the query.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   259
        # Add a little slack over the top of the user query to allow for
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   260
        # overheads while transferring the data
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   261
        self._watchmanclient.settimeout(state.timeout + 0.1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   262
        result = self._watchmanclient.command('query', {
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   263
            'fields': ['mode', 'mtime', 'size', 'exists', 'name'],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   264
            'since': clock,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   265
            'expression': [
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   266
                'not', [
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   267
                    'anyof', ['dirname', '.hg'],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   268
                    ['name', '.hg', 'wholename']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   269
                ]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   270
            ],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   271
            'sync_timeout': int(state.timeout * 1000),
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   272
            'empty_on_fresh_instance': state.walk_on_invalidate,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   273
        })
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   274
    except Exception as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   275
        _handleunavailable(self._ui, state, ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   276
        self._watchmanclient.clearconnection()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   277
        return bail()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   278
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   279
        # We need to propagate the last observed clock up so that we
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   280
        # can use it for our next query
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   281
        state.setlastclock(result['clock'])
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   282
        if result['is_fresh_instance']:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   283
            if state.walk_on_invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   284
                state.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   285
                return bail()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   286
            fresh_instance = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   287
            # Ignore any prior noteable files from the state info
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   288
            notefiles = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   289
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   290
    # for file paths which require normalization and we encounter a case
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   291
    # collision, we store our own foldmap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   292
    if normalize:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   293
        foldmap = dict((normcase(k), k) for k in results)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   294
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   295
    switch_slashes = os.sep == '\\'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   296
    # The order of the results is, strictly speaking, undefined.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   297
    # For case changes on a case insensitive filesystem we may receive
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   298
    # two entries, one with exists=True and another with exists=False.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   299
    # The exists=True entries in the same response should be interpreted
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   300
    # as being happens-after the exists=False entries due to the way that
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   301
    # Watchman tracks files.  We use this property to reconcile deletes
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   302
    # for name case changes.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   303
    for entry in result['files']:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   304
        fname = entry['name']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   305
        if switch_slashes:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   306
            fname = fname.replace('\\', '/')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   307
        if normalize:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   308
            normed = normcase(fname)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   309
            fname = normalize(fname, True, True)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   310
            foldmap[normed] = fname
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   311
        fmode = entry['mode']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   312
        fexists = entry['exists']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   313
        kind = getkind(fmode)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   314
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   315
        if not fexists:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   316
            # if marked as deleted and we don't already have a change
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   317
            # record, mark it as deleted.  If we already have an entry
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   318
            # for fname then it was either part of walkexplicit or was
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   319
            # an earlier result that was a case change
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   320
            if fname not in results and fname in dmap and (
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   321
                    matchalways or matchfn(fname)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   322
                results[fname] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   323
        elif kind == dirkind:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   324
            if fname in dmap and (matchalways or matchfn(fname)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   325
                results[fname] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   326
        elif kind == regkind or kind == lnkkind:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   327
            if fname in dmap:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   328
                if matchalways or matchfn(fname):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   329
                    results[fname] = entry
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   330
            elif (matchalways or matchfn(fname)) and not ignore(fname):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   331
                results[fname] = entry
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   332
        elif fname in dmap and (matchalways or matchfn(fname)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   333
            results[fname] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   334
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   335
    # step 3: query notable files we don't already know about
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   336
    # XXX try not to iterate over the entire dmap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   337
    if normalize:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   338
        # any notable files that have changed case will already be handled
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   339
        # above, so just check membership in the foldmap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   340
        notefiles = set((normalize(f, True, True) for f in notefiles
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   341
                         if normcase(f) not in foldmap))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   342
    visit = set((f for f in notefiles if (f not in results and matchfn(f)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   343
                                          and (f in dmap or not ignore(f)))))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   344
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   345
    if nonnormalset is not None and not fresh_instance:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   346
        if matchalways:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   347
            visit.update(f for f in nonnormalset if f not in results)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   348
            visit.update(f for f in copymap if f not in results)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   349
        else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   350
            visit.update(f for f in nonnormalset
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   351
                         if f not in results and matchfn(f))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   352
            visit.update(f for f in copymap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   353
                         if f not in results and matchfn(f))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   354
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   355
        if matchalways:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   356
            visit.update(f for f, st in dmap.iteritems()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   357
                         if (f not in results and
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   358
                             (st[2] < 0 or st[0] != 'n' or fresh_instance)))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   359
            visit.update(f for f in copymap if f not in results)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   360
        else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   361
            visit.update(f for f, st in dmap.iteritems()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   362
                         if (f not in results and
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   363
                             (st[2] < 0 or st[0] != 'n' or fresh_instance)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   364
                             and matchfn(f)))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   365
            visit.update(f for f in copymap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   366
                         if f not in results and matchfn(f))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   367
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   368
    audit = pathutil.pathauditor(self._root).check
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   369
    auditpass = [f for f in visit if audit(f)]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   370
    auditpass.sort()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   371
    auditfail = visit.difference(auditpass)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   372
    for f in auditfail:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   373
        results[f] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   374
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   375
    nf = iter(auditpass).next
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   376
    for st in util.statfiles([join(f) for f in auditpass]):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   377
        f = nf()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   378
        if st or f in dmap:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   379
            results[f] = st
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   380
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   381
    for s in subrepos:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   382
        del results[s]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   383
    del results['.hg']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   384
    return results
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   385
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   386
def overridestatus(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   387
        orig, self, node1='.', node2=None, match=None, ignored=False,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   388
        clean=False, unknown=False, listsubrepos=False):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   389
    listignored = ignored
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   390
    listclean = clean
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   391
    listunknown = unknown
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   392
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   393
    def _cmpsets(l1, l2):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   394
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   395
            if 'FSMONITOR_LOG_FILE' in os.environ:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   396
                fn = os.environ['FSMONITOR_LOG_FILE']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   397
                f = open(fn, 'wb')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   398
            else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   399
                fn = 'fsmonitorfail.log'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   400
                f = self.opener(fn, 'wb')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   401
        except (IOError, OSError):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   402
            self.ui.warn(_('warning: unable to write to %s\n') % fn)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   403
            return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   404
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   405
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   406
            for i, (s1, s2) in enumerate(zip(l1, l2)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   407
                if set(s1) != set(s2):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   408
                    f.write('sets at position %d are unequal\n' % i)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   409
                    f.write('watchman returned: %s\n' % s1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   410
                    f.write('stat returned: %s\n' % s2)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   411
        finally:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   412
            f.close()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   413
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   414
    if isinstance(node1, context.changectx):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   415
        ctx1 = node1
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   416
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   417
        ctx1 = self[node1]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   418
    if isinstance(node2, context.changectx):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   419
        ctx2 = node2
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   420
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   421
        ctx2 = self[node2]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   422
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   423
    working = ctx2.rev() is None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   424
    parentworking = working and ctx1 == self['.']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   425
    match = match or matchmod.always(self.root, self.getcwd())
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   426
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   427
    # Maybe we can use this opportunity to update Watchman's state.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   428
    # Mercurial uses workingcommitctx and/or memctx to represent the part of
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   429
    # the workingctx that is to be committed. So don't update the state in
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   430
    # that case.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   431
    # HG_PENDING is set in the environment when the dirstate is being updated
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   432
    # in the middle of a transaction; we must not update our state in that
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   433
    # case, or we risk forgetting about changes in the working copy.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   434
    updatestate = (parentworking and match.always() and
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   435
                   not isinstance(ctx2, (context.workingcommitctx,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   436
                                         context.memctx)) and
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   437
                   'HG_PENDING' not in os.environ)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   438
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   439
    try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   440
        if self._fsmonitorstate.walk_on_invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   441
            # Use a short timeout to query the current clock.  If that
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   442
            # takes too long then we assume that the service will be slow
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   443
            # to answer our query.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   444
            # walk_on_invalidate indicates that we prefer to walk the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   445
            # tree ourselves because we can ignore portions that Watchman
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   446
            # cannot and we tend to be faster in the warmer buffer cache
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   447
            # cases.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   448
            self._watchmanclient.settimeout(0.1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   449
        else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   450
            # Give Watchman more time to potentially complete its walk
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   451
            # and return the initial clock.  In this mode we assume that
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   452
            # the filesystem will be slower than parsing a potentially
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   453
            # very large Watchman result set.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   454
            self._watchmanclient.settimeout(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   455
                self._fsmonitorstate.timeout + 0.1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   456
        startclock = self._watchmanclient.getcurrentclock()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   457
    except Exception as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   458
        self._watchmanclient.clearconnection()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   459
        _handleunavailable(self.ui, self._fsmonitorstate, ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   460
        # boo, Watchman failed. bail
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   461
        return orig(node1, node2, match, listignored, listclean,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   462
                    listunknown, listsubrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   463
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   464
    if updatestate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   465
        # We need info about unknown files. This may make things slower the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   466
        # first time, but whatever.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   467
        stateunknown = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   468
    else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   469
        stateunknown = listunknown
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   470
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   471
    r = orig(node1, node2, match, listignored, listclean, stateunknown,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   472
             listsubrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   473
    modified, added, removed, deleted, unknown, ignored, clean = r
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   474
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   475
    if updatestate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   476
        notefiles = modified + added + removed + deleted + unknown
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   477
        self._fsmonitorstate.set(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   478
            self._fsmonitorstate.getlastclock() or startclock,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   479
            _hashignore(self.dirstate._ignore),
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   480
            notefiles)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   481
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   482
    if not listunknown:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   483
        unknown = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   484
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   485
    # don't do paranoid checks if we're not going to query Watchman anyway
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   486
    full = listclean or match.traversedir is not None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   487
    if self._fsmonitorstate.mode == 'paranoid' and not full:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   488
        # run status again and fall back to the old walk this time
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   489
        self.dirstate._fsmonitordisable = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   490
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   491
        # shut the UI up
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   492
        quiet = self.ui.quiet
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   493
        self.ui.quiet = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   494
        fout, ferr = self.ui.fout, self.ui.ferr
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   495
        self.ui.fout = self.ui.ferr = open(os.devnull, 'wb')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   496
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   497
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   498
            rv2 = orig(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   499
                node1, node2, match, listignored, listclean, listunknown,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   500
                listsubrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   501
        finally:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   502
            self.dirstate._fsmonitordisable = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   503
            self.ui.quiet = quiet
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   504
            self.ui.fout, self.ui.ferr = fout, ferr
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   505
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   506
        # clean isn't tested since it's set to True above
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   507
        _cmpsets([modified, added, removed, deleted, unknown, ignored, clean],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   508
                 rv2)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   509
        modified, added, removed, deleted, unknown, ignored, clean = rv2
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   510
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   511
    return scmutil.status(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   512
        modified, added, removed, deleted, unknown, ignored, clean)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   513
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   514
def makedirstate(cls):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   515
    class fsmonitordirstate(cls):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   516
        def _fsmonitorinit(self, fsmonitorstate, watchmanclient):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   517
            # _fsmonitordisable is used in paranoid mode
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   518
            self._fsmonitordisable = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   519
            self._fsmonitorstate = fsmonitorstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   520
            self._watchmanclient = watchmanclient
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   521
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   522
        def walk(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   523
            orig = super(fsmonitordirstate, self).walk
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   524
            if self._fsmonitordisable:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   525
                return orig(*args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   526
            return overridewalk(orig, self, *args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   527
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   528
        def rebuild(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   529
            self._fsmonitorstate.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   530
            return super(fsmonitordirstate, self).rebuild(*args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   531
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   532
        def invalidate(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   533
            self._fsmonitorstate.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   534
            return super(fsmonitordirstate, self).invalidate(*args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   535
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   536
    return fsmonitordirstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   537
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   538
def wrapdirstate(orig, self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   539
    ds = orig(self)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   540
    # only override the dirstate when Watchman is available for the repo
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   541
    if util.safehasattr(self, '_fsmonitorstate'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   542
        ds.__class__ = makedirstate(ds.__class__)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   543
        ds._fsmonitorinit(self._fsmonitorstate, self._watchmanclient)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   544
    return ds
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   545
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   546
def extsetup(ui):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   547
    wrapfilecache(localrepo.localrepository, 'dirstate', wrapdirstate)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   548
    if sys.platform == 'darwin':
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   549
        # An assist for avoiding the dangling-symlink fsevents bug
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   550
        extensions.wrapfunction(os, 'symlink', wrapsymlink)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   551
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   552
    extensions.wrapfunction(merge, 'update', wrapupdate)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   553
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   554
def wrapsymlink(orig, source, link_name):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   555
    ''' if we create a dangling symlink, also touch the parent dir
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   556
    to encourage fsevents notifications to work more correctly '''
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   557
    try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   558
        return orig(source, link_name)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   559
    finally:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   560
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   561
            os.utime(os.path.dirname(link_name), None)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   562
        except OSError:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   563
            pass
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   564
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   565
class state_update(object):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   566
    ''' This context mananger is responsible for dispatching the state-enter
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   567
        and state-leave signals to the watchman service '''
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   568
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   569
    def __init__(self, repo, node, distance, partial):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   570
        self.repo = repo
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   571
        self.node = node
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   572
        self.distance = distance
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   573
        self.partial = partial
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   574
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   575
    def __enter__(self):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   576
        self._state('state-enter')
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   577
        return self
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   578
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   579
    def __exit__(self, type_, value, tb):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   580
        status = 'ok' if type_ is None else 'failed'
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   581
        self._state('state-leave', status=status)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   582
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   583
    def _state(self, cmd, status='ok'):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   584
        if not util.safehasattr(self.repo, '_watchmanclient'):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   585
            return
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   586
        try:
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   587
            commithash = self.repo[self.node].hex()
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   588
            self.repo._watchmanclient.command(cmd, {
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   589
                'name': 'hg.update',
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   590
                'metadata': {
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   591
                    # the target revision
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   592
                    'rev': commithash,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   593
                    # approximate number of commits between current and target
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   594
                    'distance': self.distance,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   595
                    # success/failure (only really meaningful for state-leave)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   596
                    'status': status,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   597
                    # whether the working copy parent is changing
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   598
                    'partial': self.partial,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   599
            }})
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   600
        except Exception as e:
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   601
            # Swallow any errors; fire and forget
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   602
            self.repo.ui.log(
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   603
                'watchman', 'Exception %s while running %s\n', e, cmd)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   604
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   605
# Bracket working copy updates with calls to the watchman state-enter
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   606
# and state-leave commands.  This allows clients to perform more intelligent
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   607
# settling during bulk file change scenarios
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   608
# https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   609
def wrapupdate(orig, repo, node, branchmerge, force, ancestor=None,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   610
               mergeancestor=False, labels=None, matcher=None, **kwargs):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   611
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   612
    distance = 0
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   613
    partial = True
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   614
    if matcher is None or matcher.always():
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   615
        partial = False
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   616
        wc = repo[None]
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   617
        parents = wc.parents()
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   618
        if len(parents) == 2:
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   619
            anc = repo.changelog.ancestor(parents[0].node(), parents[1].node())
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   620
            ancrev = repo[anc].rev()
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   621
            distance = abs(repo[node].rev() - ancrev)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   622
        elif len(parents) == 1:
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   623
            distance = abs(repo[node].rev() - parents[0].rev())
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   624
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   625
    with state_update(repo, node, distance, partial):
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   626
        return orig(
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   627
            repo, node, branchmerge, force, ancestor, mergeancestor,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   628
            labels, matcher, *kwargs)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
   629
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   630
def reposetup(ui, repo):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   631
    # We don't work with largefiles or inotify
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   632
    exts = extensions.enabled()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   633
    for ext in _blacklist:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   634
        if ext in exts:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   635
            ui.warn(_('The fsmonitor extension is incompatible with the %s '
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   636
                      'extension and has been disabled.\n') % ext)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   637
            return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   638
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   639
    if util.safehasattr(repo, 'dirstate'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   640
        # We don't work with subrepos either. Note that we can get passed in
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   641
        # e.g. a statichttprepo, which throws on trying to access the substate.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   642
        # XXX This sucks.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   643
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   644
            # if repo[None].substate can cause a dirstate parse, which is too
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   645
            # slow. Instead, look for a file called hgsubstate,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   646
            if repo.wvfs.exists('.hgsubstate') or repo.wvfs.exists('.hgsub'):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   647
                return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   648
        except AttributeError:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   649
            return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   650
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   651
        fsmonitorstate = state.state(repo)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   652
        if fsmonitorstate.mode == 'off':
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   653
            return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   654
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   655
        try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   656
            client = watchmanclient.client(repo)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   657
        except Exception as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   658
            _handleunavailable(ui, fsmonitorstate, ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   659
            return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   660
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   661
        repo._fsmonitorstate = fsmonitorstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   662
        repo._watchmanclient = client
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   663
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   664
        # at this point since fsmonitorstate wasn't present, repo.dirstate is
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   665
        # not a fsmonitordirstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   666
        repo.dirstate.__class__ = makedirstate(repo.dirstate.__class__)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   667
        # nuke the dirstate so that _fsmonitorinit and subsequent configuration
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   668
        # changes take effect on it
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   669
        del repo._filecache['dirstate']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   670
        delattr(repo.unfiltered(), 'dirstate')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   671
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   672
        class fsmonitorrepo(repo.__class__):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   673
            def status(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   674
                orig = super(fsmonitorrepo, self).status
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   675
                return overridestatus(orig, self, *args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   676
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   677
        repo.__class__ = fsmonitorrepo
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   678
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   679
def wrapfilecache(cls, propname, wrapper):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   680
    """Wraps a filecache property. These can't be wrapped using the normal
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   681
    wrapfunction. This should eventually go into upstream Mercurial.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   682
    """
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   683
    assert callable(wrapper)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   684
    for currcls in cls.__mro__:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   685
        if propname in currcls.__dict__:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   686
            origfn = currcls.__dict__[propname].func
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   687
            assert callable(origfn)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   688
            def wrap(*args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   689
                return wrapper(origfn, *args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   690
            currcls.__dict__[propname].func = wrap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   691
            break
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   692
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   693
    if currcls is object:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   694
        raise AttributeError(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
   695
            _("type '%s' has no property '%s'") % (cls, propname))