Mercurial > hg
annotate hgext/fsmonitor/__init__.py @ 28443:49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Keeping the codebase in sync with upstream:
Watchman 4.4 introduced an advanced settling feature that allows publishing
tools to notify subscribing tools of the boundaries for important filesystem
operations.
https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling
has more information about how this feature works.
This diff connects a signal that we're calling `hg.update` to the mercurial
update function so that mercurial can indirectly notify tools (such as IDEs or
build machinery) when it is changing the working copy. This will allow those
tools to pause their normal actions as the files are changing and defer them
until the end of the operation.
In addition to sending the enter/leave signals for the state, we are able to
publish useful metadata along the same channel. In this case we are passing
the following pieces of information:
1. destination revision hash
2. An estimate of the distance between the current state and the target state
3. A success indicator.
4. Whether it is a partial update
The distance is estimate may be useful to tools that wish to change their
strategy after the update has complete. For example, a large update may be
efficient to deal with by walking some internal state in the subscriber rather
than feeding every individual file notification through its normal (small)
delta mechanism.
We estimate the distance by comparing the repository revision number. In some
cases we cannot come up with a number so we report 0. This is ok; we're
offering this for informational purposes only and don't guarantee its accuracy.
The success indicator is only really meaningful when we generate the
state-leave notification; it indicates the overall success of the update.
author | Martijn Pieters <mjpieters@fb.com> |
---|---|
date | Thu, 10 Mar 2016 16:04:09 +0000 |
parents | 3b67f27bb908 |
children | a0939666b836 |
rev | line source |
---|---|
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 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
94 import os |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
95 import stat |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
96 import sys |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
97 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
98 from mercurial import ( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
99 context, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
100 extensions, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
101 localrepo, |
28443
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
102 merge, |
28433
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
103 pathutil, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
104 scmutil, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
105 util, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
106 ) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
107 from mercurial import match as matchmod |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
108 from mercurial.i18n import _ |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
109 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
110 from . import ( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
111 state, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
112 watchmanclient, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
113 ) |
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 # Note for extension authors: ONLY specify testedwith = 'internal' for |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
116 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
117 # 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
|
118 # leave the attribute unspecified. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
119 testedwith = 'internal' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
120 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
121 # This extension is incompatible with the following blacklisted extensions |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
122 # and will disable itself when encountering one of these: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
123 _blacklist = ['largefiles', 'eol'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
124 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
125 def _handleunavailable(ui, state, ex): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
126 """Exception handler for Watchman interaction exceptions""" |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
127 if isinstance(ex, watchmanclient.Unavailable): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
128 if ex.warn: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
129 ui.warn(str(ex) + '\n') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
130 if ex.invalidate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
131 state.invalidate() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
132 ui.log('fsmonitor', 'Watchman unavailable: %s\n', ex.msg) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
133 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
134 ui.log('fsmonitor', 'Watchman exception: %s\n', ex) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
135 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
136 def _hashignore(ignore): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
137 """Calculate hash for ignore patterns and filenames |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
138 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
139 If this information changes between Mercurial invocations, we can't |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
140 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
|
141 copy. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
142 |
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 sha1 = util.sha1() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
145 if util.safehasattr(ignore, 'includepat'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
146 sha1.update(ignore.includepat) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
147 sha1.update('\0\0') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
148 if util.safehasattr(ignore, 'excludepat'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
149 sha1.update(ignore.excludepat) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
150 sha1.update('\0\0') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
151 if util.safehasattr(ignore, 'patternspat'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
152 sha1.update(ignore.patternspat) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
153 sha1.update('\0\0') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
154 if util.safehasattr(ignore, '_files'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
155 for f in ignore._files: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
156 sha1.update(f) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
157 sha1.update('\0') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
158 return sha1.hexdigest() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
159 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
160 def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
161 '''Replacement for dirstate.walk, hooking into Watchman. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
162 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
163 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
|
164 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
|
165 subset of files.''' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
166 def bail(): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
167 return orig(match, subrepos, unknown, ignored, full=True) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
168 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
169 if full or ignored or not self._watchmanclient.available(): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
170 return bail() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
171 state = self._fsmonitorstate |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
172 clock, ignorehash, notefiles = state.get() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
173 if not clock: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
174 if state.walk_on_invalidate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
175 return bail() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
176 # Initial NULL clock value, see |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
177 # https://facebook.github.io/watchman/docs/clockspec.html |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
178 clock = 'c:0:0' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
179 notefiles = [] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
180 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
181 def fwarn(f, msg): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
182 self._ui.warn('%s: %s\n' % (self.pathto(f), msg)) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
183 return False |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
184 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
185 def badtype(mode): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
186 kind = _('unknown') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
187 if stat.S_ISCHR(mode): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
188 kind = _('character device') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
189 elif stat.S_ISBLK(mode): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
190 kind = _('block device') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
191 elif stat.S_ISFIFO(mode): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
192 kind = _('fifo') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
193 elif stat.S_ISSOCK(mode): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
194 kind = _('socket') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
195 elif stat.S_ISDIR(mode): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
196 kind = _('directory') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
197 return _('unsupported file type (type is %s)') % kind |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
198 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
199 ignore = self._ignore |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
200 dirignore = self._dirignore |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
201 if unknown: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
202 if _hashignore(ignore) != ignorehash and clock != 'c:0:0': |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
203 # ignore list changed -- can't rely on Watchman state any more |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
204 if state.walk_on_invalidate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
205 return bail() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
206 notefiles = [] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
207 clock = 'c:0:0' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
208 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
209 # always ignore |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
210 ignore = util.always |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
211 dirignore = util.always |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
212 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
213 matchfn = match.matchfn |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
214 matchalways = match.always() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
215 dmap = self._map |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
216 nonnormalset = getattr(self, '_nonnormalset', None) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
217 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
218 copymap = self._copymap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
219 getkind = stat.S_IFMT |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
220 dirkind = stat.S_IFDIR |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
221 regkind = stat.S_IFREG |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
222 lnkkind = stat.S_IFLNK |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
223 join = self._join |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
224 normcase = util.normcase |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
225 fresh_instance = False |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
226 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
227 exact = skipstep3 = False |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
228 if matchfn == match.exact: # match.exact |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
229 exact = True |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
230 dirignore = util.always # skip step 2 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
231 elif match.files() and not match.anypats(): # match.match, no patterns |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
232 skipstep3 = True |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
233 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
234 if not exact and self._checkcase: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
235 # 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
|
236 # 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
|
237 # normalize files if possible. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
238 normalize = self._normalizefile |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
239 skipstep3 = False |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
240 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
241 normalize = None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
242 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
243 # step 1: find all explicit files |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
244 results, work, dirsnotfound = self._walkexplicit(match, subrepos) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
245 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
246 skipstep3 = skipstep3 and not (work or dirsnotfound) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
247 work = [d for d in work if not dirignore(d[0])] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
248 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
249 if not work and (exact or skipstep3): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
250 for s in subrepos: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
251 del results[s] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
252 del results['.hg'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
253 return results |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
254 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
255 # step 2: query Watchman |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
256 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
257 # Use the user-configured timeout for the query. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
258 # 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
|
259 # overheads while transferring the data |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
260 self._watchmanclient.settimeout(state.timeout + 0.1) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
261 result = self._watchmanclient.command('query', { |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
262 'fields': ['mode', 'mtime', 'size', 'exists', 'name'], |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
263 'since': clock, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
264 'expression': [ |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
265 'not', [ |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
266 'anyof', ['dirname', '.hg'], |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
267 ['name', '.hg', 'wholename'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
268 ] |
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 'sync_timeout': int(state.timeout * 1000), |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
271 'empty_on_fresh_instance': state.walk_on_invalidate, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
272 }) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
273 except Exception as ex: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
274 _handleunavailable(self._ui, state, ex) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
275 self._watchmanclient.clearconnection() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
276 return bail() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
277 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
278 # 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
|
279 # can use it for our next query |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
280 state.setlastclock(result['clock']) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
281 if result['is_fresh_instance']: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
282 if state.walk_on_invalidate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
283 state.invalidate() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
284 return bail() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
285 fresh_instance = True |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
286 # Ignore any prior noteable files from the state info |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
287 notefiles = [] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
288 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
289 # for file paths which require normalization and we encounter a case |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
290 # collision, we store our own foldmap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
291 if normalize: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
292 foldmap = dict((normcase(k), k) for k in results) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
293 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
294 switch_slashes = os.sep == '\\' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
295 # The order of the results is, strictly speaking, undefined. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
296 # For case changes on a case insensitive filesystem we may receive |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
297 # two entries, one with exists=True and another with exists=False. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
298 # The exists=True entries in the same response should be interpreted |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
299 # 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
|
300 # Watchman tracks files. We use this property to reconcile deletes |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
301 # for name case changes. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
302 for entry in result['files']: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
303 fname = entry['name'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
304 if switch_slashes: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
305 fname = fname.replace('\\', '/') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
306 if normalize: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
307 normed = normcase(fname) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
308 fname = normalize(fname, True, True) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
309 foldmap[normed] = fname |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
310 fmode = entry['mode'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
311 fexists = entry['exists'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
312 kind = getkind(fmode) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
313 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
314 if not fexists: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
315 # 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
|
316 # record, mark it as deleted. If we already have an entry |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
317 # for fname then it was either part of walkexplicit or was |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
318 # an earlier result that was a case change |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
319 if fname not in results and fname in dmap and ( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
320 matchalways or matchfn(fname)): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
321 results[fname] = None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
322 elif kind == dirkind: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
323 if fname in dmap and (matchalways or matchfn(fname)): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
324 results[fname] = None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
325 elif kind == regkind or kind == lnkkind: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
326 if fname in dmap: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
327 if matchalways or matchfn(fname): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
328 results[fname] = entry |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
329 elif (matchalways or matchfn(fname)) and not ignore(fname): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
330 results[fname] = entry |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
331 elif fname in dmap and (matchalways or matchfn(fname)): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
332 results[fname] = None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
333 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
334 # step 3: query notable files we don't already know about |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
335 # XXX try not to iterate over the entire dmap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
336 if normalize: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
337 # any notable files that have changed case will already be handled |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
338 # above, so just check membership in the foldmap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
339 notefiles = set((normalize(f, True, True) for f in notefiles |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
340 if normcase(f) not in foldmap)) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
341 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
|
342 and (f in dmap or not ignore(f))))) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
343 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
344 if nonnormalset is not None and not fresh_instance: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
345 if matchalways: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
346 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
|
347 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
|
348 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
349 visit.update(f for f in nonnormalset |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
350 if f not in results and matchfn(f)) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
351 visit.update(f for f in copymap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
352 if f not in results and matchfn(f)) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
353 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
354 if matchalways: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
355 visit.update(f for f, st in dmap.iteritems() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
356 if (f not in results and |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
357 (st[2] < 0 or st[0] != 'n' or fresh_instance))) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
358 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
|
359 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
360 visit.update(f for f, st in dmap.iteritems() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
361 if (f not in results and |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
362 (st[2] < 0 or st[0] != 'n' or fresh_instance) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
363 and matchfn(f))) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
364 visit.update(f for f in copymap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
365 if f not in results and matchfn(f)) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
366 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
367 audit = pathutil.pathauditor(self._root).check |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
368 auditpass = [f for f in visit if audit(f)] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
369 auditpass.sort() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
370 auditfail = visit.difference(auditpass) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
371 for f in auditfail: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
372 results[f] = None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
373 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
374 nf = iter(auditpass).next |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
375 for st in util.statfiles([join(f) for f in auditpass]): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
376 f = nf() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
377 if st or f in dmap: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
378 results[f] = st |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
379 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
380 for s in subrepos: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
381 del results[s] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
382 del results['.hg'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
383 return results |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
384 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
385 def overridestatus( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
386 orig, self, node1='.', node2=None, match=None, ignored=False, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
387 clean=False, unknown=False, listsubrepos=False): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
388 listignored = ignored |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
389 listclean = clean |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
390 listunknown = unknown |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
391 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
392 def _cmpsets(l1, l2): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
393 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
394 if 'FSMONITOR_LOG_FILE' in os.environ: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
395 fn = os.environ['FSMONITOR_LOG_FILE'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
396 f = open(fn, 'wb') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
397 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
398 fn = 'fsmonitorfail.log' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
399 f = self.opener(fn, 'wb') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
400 except (IOError, OSError): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
401 self.ui.warn(_('warning: unable to write to %s\n') % fn) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
402 return |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
403 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
404 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
405 for i, (s1, s2) in enumerate(zip(l1, l2)): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
406 if set(s1) != set(s2): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
407 f.write('sets at position %d are unequal\n' % i) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
408 f.write('watchman returned: %s\n' % s1) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
409 f.write('stat returned: %s\n' % s2) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
410 finally: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
411 f.close() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
412 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
413 if isinstance(node1, context.changectx): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
414 ctx1 = node1 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
415 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
416 ctx1 = self[node1] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
417 if isinstance(node2, context.changectx): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
418 ctx2 = node2 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
419 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
420 ctx2 = self[node2] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
421 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
422 working = ctx2.rev() is None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
423 parentworking = working and ctx1 == self['.'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
424 match = match or matchmod.always(self.root, self.getcwd()) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
425 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
426 # Maybe we can use this opportunity to update Watchman's state. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
427 # Mercurial uses workingcommitctx and/or memctx to represent the part of |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
428 # 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
|
429 # that case. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
430 # 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
|
431 # 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
|
432 # case, or we risk forgetting about changes in the working copy. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
433 updatestate = (parentworking and match.always() and |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
434 not isinstance(ctx2, (context.workingcommitctx, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
435 context.memctx)) and |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
436 'HG_PENDING' not in os.environ) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
437 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
438 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
439 if self._fsmonitorstate.walk_on_invalidate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
440 # Use a short timeout to query the current clock. If that |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
441 # 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
|
442 # to answer our query. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
443 # walk_on_invalidate indicates that we prefer to walk the |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
444 # tree ourselves because we can ignore portions that Watchman |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
445 # 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
|
446 # cases. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
447 self._watchmanclient.settimeout(0.1) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
448 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
449 # Give Watchman more time to potentially complete its walk |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
450 # and return the initial clock. In this mode we assume that |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
451 # the filesystem will be slower than parsing a potentially |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
452 # very large Watchman result set. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
453 self._watchmanclient.settimeout( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
454 self._fsmonitorstate.timeout + 0.1) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
455 startclock = self._watchmanclient.getcurrentclock() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
456 except Exception as ex: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
457 self._watchmanclient.clearconnection() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
458 _handleunavailable(self.ui, self._fsmonitorstate, ex) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
459 # boo, Watchman failed. bail |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
460 return orig(node1, node2, match, listignored, listclean, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
461 listunknown, listsubrepos) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
462 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
463 if updatestate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
464 # 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
|
465 # first time, but whatever. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
466 stateunknown = True |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
467 else: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
468 stateunknown = listunknown |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
469 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
470 r = orig(node1, node2, match, listignored, listclean, stateunknown, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
471 listsubrepos) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
472 modified, added, removed, deleted, unknown, ignored, clean = r |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
473 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
474 if updatestate: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
475 notefiles = modified + added + removed + deleted + unknown |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
476 self._fsmonitorstate.set( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
477 self._fsmonitorstate.getlastclock() or startclock, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
478 _hashignore(self.dirstate._ignore), |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
479 notefiles) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
480 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
481 if not listunknown: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
482 unknown = [] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
483 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
484 # 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
|
485 full = listclean or match.traversedir is not None |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
486 if self._fsmonitorstate.mode == 'paranoid' and not full: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
487 # 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
|
488 self.dirstate._fsmonitordisable = True |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
489 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
490 # shut the UI up |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
491 quiet = self.ui.quiet |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
492 self.ui.quiet = True |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
493 fout, ferr = self.ui.fout, self.ui.ferr |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
494 self.ui.fout = self.ui.ferr = open(os.devnull, 'wb') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
495 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
496 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
497 rv2 = orig( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
498 node1, node2, match, listignored, listclean, listunknown, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
499 listsubrepos) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
500 finally: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
501 self.dirstate._fsmonitordisable = False |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
502 self.ui.quiet = quiet |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
503 self.ui.fout, self.ui.ferr = fout, ferr |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
504 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
505 # clean isn't tested since it's set to True above |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
506 _cmpsets([modified, added, removed, deleted, unknown, ignored, clean], |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
507 rv2) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
508 modified, added, removed, deleted, unknown, ignored, clean = rv2 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
509 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
510 return scmutil.status( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
511 modified, added, removed, deleted, unknown, ignored, clean) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
512 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
513 def makedirstate(cls): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
514 class fsmonitordirstate(cls): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
515 def _fsmonitorinit(self, fsmonitorstate, watchmanclient): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
516 # _fsmonitordisable is used in paranoid mode |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
517 self._fsmonitordisable = False |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
518 self._fsmonitorstate = fsmonitorstate |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
519 self._watchmanclient = watchmanclient |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
520 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
521 def walk(self, *args, **kwargs): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
522 orig = super(fsmonitordirstate, self).walk |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
523 if self._fsmonitordisable: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
524 return orig(*args, **kwargs) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
525 return overridewalk(orig, self, *args, **kwargs) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
526 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
527 def rebuild(self, *args, **kwargs): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
528 self._fsmonitorstate.invalidate() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
529 return super(fsmonitordirstate, self).rebuild(*args, **kwargs) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
530 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
531 def invalidate(self, *args, **kwargs): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
532 self._fsmonitorstate.invalidate() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
533 return super(fsmonitordirstate, self).invalidate(*args, **kwargs) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
534 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
535 return fsmonitordirstate |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
536 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
537 def wrapdirstate(orig, self): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
538 ds = orig(self) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
539 # only override the dirstate when Watchman is available for the repo |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
540 if util.safehasattr(self, '_fsmonitorstate'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
541 ds.__class__ = makedirstate(ds.__class__) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
542 ds._fsmonitorinit(self._fsmonitorstate, self._watchmanclient) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
543 return ds |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
544 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
545 def extsetup(ui): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
546 wrapfilecache(localrepo.localrepository, 'dirstate', wrapdirstate) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
547 if sys.platform == 'darwin': |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
548 # An assist for avoiding the dangling-symlink fsevents bug |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
549 extensions.wrapfunction(os, 'symlink', wrapsymlink) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
550 |
28443
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
551 extensions.wrapfunction(merge, 'update', wrapupdate) |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
552 |
28433
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
553 def wrapsymlink(orig, source, link_name): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
554 ''' if we create a dangling symlink, also touch the parent dir |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
555 to encourage fsevents notifications to work more correctly ''' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
556 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
557 return orig(source, link_name) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
558 finally: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
559 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
560 os.utime(os.path.dirname(link_name), None) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
561 except OSError: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
562 pass |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
563 |
28443
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
564 class state_update(object): |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
565 ''' 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
|
566 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
|
567 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
568 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
|
569 self.repo = repo |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
570 self.node = node |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
571 self.distance = distance |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
572 self.partial = partial |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
573 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
574 def __enter__(self): |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
575 self._state('state-enter') |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
576 return self |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
577 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
578 def __exit__(self, type_, value, tb): |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
579 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
|
580 self._state('state-leave', status=status) |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
581 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
582 def _state(self, cmd, status='ok'): |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
583 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
|
584 return |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
585 try: |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
586 commithash = self.repo[self.node].hex() |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
587 self.repo._watchmanclient.command(cmd, { |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
588 'name': 'hg.update', |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
589 'metadata': { |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
590 # the target revision |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
591 'rev': commithash, |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
592 # 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
|
593 'distance': self.distance, |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
594 # 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
|
595 'status': status, |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
596 # 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
|
597 'partial': self.partial, |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
598 }}) |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
599 except Exception as e: |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
600 # Swallow any errors; fire and forget |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
601 self.repo.ui.log( |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
602 '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
|
603 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
604 # 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
|
605 # 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
|
606 # settling during bulk file change scenarios |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
607 # 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
|
608 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
|
609 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
|
610 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
611 distance = 0 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
612 partial = True |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
613 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
|
614 partial = False |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
615 wc = repo[None] |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
616 parents = wc.parents() |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
617 if len(parents) == 2: |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
618 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
|
619 ancrev = repo[anc].rev() |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
620 distance = abs(repo[node].rev() - ancrev) |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
621 elif len(parents) == 1: |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
622 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
|
623 |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
624 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
|
625 return orig( |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
626 repo, node, branchmerge, force, ancestor, mergeancestor, |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
627 labels, matcher, *kwargs) |
49d65663d7e4
fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents:
28433
diff
changeset
|
628 |
28433
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
629 def reposetup(ui, repo): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
630 # We don't work with largefiles or inotify |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
631 exts = extensions.enabled() |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
632 for ext in _blacklist: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
633 if ext in exts: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
634 ui.warn(_('The fsmonitor extension is incompatible with the %s ' |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
635 'extension and has been disabled.\n') % ext) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
636 return |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
637 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
638 if util.safehasattr(repo, 'dirstate'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
639 # 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
|
640 # 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
|
641 # XXX This sucks. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
642 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
643 # 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
|
644 # slow. Instead, look for a file called hgsubstate, |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
645 if repo.wvfs.exists('.hgsubstate') or repo.wvfs.exists('.hgsub'): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
646 return |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
647 except AttributeError: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
648 return |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
649 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
650 fsmonitorstate = state.state(repo) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
651 if fsmonitorstate.mode == 'off': |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
652 return |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
653 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
654 try: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
655 client = watchmanclient.client(repo) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
656 except Exception as ex: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
657 _handleunavailable(ui, fsmonitorstate, ex) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
658 return |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
659 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
660 repo._fsmonitorstate = fsmonitorstate |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
661 repo._watchmanclient = client |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
662 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
663 # at this point since fsmonitorstate wasn't present, repo.dirstate is |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
664 # not a fsmonitordirstate |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
665 repo.dirstate.__class__ = makedirstate(repo.dirstate.__class__) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
666 # nuke the dirstate so that _fsmonitorinit and subsequent configuration |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
667 # changes take effect on it |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
668 del repo._filecache['dirstate'] |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
669 delattr(repo.unfiltered(), 'dirstate') |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
670 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
671 class fsmonitorrepo(repo.__class__): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
672 def status(self, *args, **kwargs): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
673 orig = super(fsmonitorrepo, self).status |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
674 return overridestatus(orig, self, *args, **kwargs) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
675 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
676 repo.__class__ = fsmonitorrepo |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
677 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
678 def wrapfilecache(cls, propname, wrapper): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
679 """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
|
680 wrapfunction. This should eventually go into upstream Mercurial. |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
681 """ |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
682 assert callable(wrapper) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
683 for currcls in cls.__mro__: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
684 if propname in currcls.__dict__: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
685 origfn = currcls.__dict__[propname].func |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
686 assert callable(origfn) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
687 def wrap(*args, **kwargs): |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
688 return wrapper(origfn, *args, **kwargs) |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
689 currcls.__dict__[propname].func = wrap |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
690 break |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
691 |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
692 if currcls is object: |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
693 raise AttributeError( |
3b67f27bb908
fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff
changeset
|
694 _("type '%s' has no property '%s'") % (cls, propname)) |