annotate hgext/fsmonitor/__init__.py @ 29804:7b9157aa752f

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