annotate hgext/fsmonitor/__init__.py @ 35146:0b5716ec8500

fsmonitor: issue debug messages when we fall back to core status Having more information about when and why fsmonitor bails out help when looking into status performance.
author Boris Feld <boris.feld@octobus.net>
date Tue, 28 Nov 2017 11:00:54 -0500
parents ae7ad53d3c8d
children 73abb81ccb28
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
34885
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
21 fsmonitor is incompatible with the largefiles and eol extensions, and
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
22 will disable itself if any of those are active.
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
23
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
24 The following configuration options exist:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
25
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
26 ::
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 [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
29 mode = {off, on, paranoid}
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
30
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
31 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
32 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
33 When `mode = paranoid`, fsmonitor will query both Watchman and the filesystem,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
34 and ensure that the results are consistent.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
35
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
36 ::
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 [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
39 timeout = (float)
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 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
42 to return results. Defaults to `2.0`.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
43
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
44 ::
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 [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
47 blacklistusers = (list of userids)
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 A list of usernames for which fsmonitor will disable itself altogether.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
50
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
51 ::
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 [fsmonitor]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
54 walk_on_invalidate = (boolean)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
55
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
56 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
57 invalidated, for example when Watchman has been restarted or .hgignore rules
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
58 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
59 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
60 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
61 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
62 from Watchman. Defaults to false.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
63
34885
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
64 ::
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
65
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
66 [fsmonitor]
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
67 warn_when_unused = (boolean)
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
68
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
69 Whether to print a warning during certain operations when fsmonitor would be
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
70 beneficial to performance but isn't enabled.
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
71
34885
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
72 ::
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
73
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
74 [fsmonitor]
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
75 warn_update_file_count = (integer)
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
76
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
77 If ``warn_when_unused`` is set and fsmonitor isn't enabled, a warning will
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
78 be printed during working directory updates if this many files will be
df2ff314e36f fsmonitor: warn when fsmonitor could be used
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34647
diff changeset
79 created.
28433
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
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
82 # Platforms Supported
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 #
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
85 # **Linux:** *Stable*. Watchman and fsmonitor are both known to work reliably,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
86 # even under severe loads.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
87 #
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
88 # **Mac OS X:** *Stable*. The Mercurial test suite passes with fsmonitor
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
89 # 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
90 # user testing under normal loads.
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 # **Solaris, BSD:** *Alpha*. watchman and fsmonitor are believed to work, but
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
93 # very little testing has been done.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
94 #
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
95 # **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
96 #
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
97 # Known Issues
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
98 # ============
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
99 #
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
100 # * fsmonitor will disable itself if any of the following extensions are
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
101 # enabled: largefiles, inotify, eol; or if the repository has subrepos.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
102 # * fsmonitor will produce incorrect results if nested repos that are not
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
103 # subrepos exist. *Workaround*: add nested repo paths to your `.hgignore`.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
104 #
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
105 # 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
106 # ones. Patches to fix them are welcome.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
107
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
108 from __future__ import absolute_import
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
109
31846
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
110 import codecs
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29205
diff changeset
111 import hashlib
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
112 import os
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
113 import stat
31846
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
114 import sys
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
115 import weakref
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
116
29205
a0939666b836 py3: move up symbol imports to enforce import-checker rules
Yuya Nishihara <yuya@tcha.org>
parents: 28443
diff changeset
117 from mercurial.i18n import _
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
118 from mercurial.node import (
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
119 hex,
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
120 nullid,
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
121 )
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
122
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
123 from mercurial import (
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
124 context,
30666
6ada1658fc6b py3: use python 3 compatible variables in hgext/fsmontor/__init__.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
125 encoding,
31846
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
126 error,
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
127 extensions,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
128 localrepo,
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
129 merge,
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
130 pathutil,
30666
6ada1658fc6b py3: use python 3 compatible variables in hgext/fsmontor/__init__.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
131 pycompat,
34463
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
132 registrar,
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
133 scmutil,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
134 util,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
135 )
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
136 from mercurial import match as matchmod
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
137
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
138 from . import (
31846
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
139 pywatchman,
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
140 state,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
141 watchmanclient,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
142 )
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
143
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29341
diff changeset
144 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
145 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
146 # 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
147 # leave the attribute unspecified.
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 29341
diff changeset
148 testedwith = 'ships-with-hg-core'
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
149
34463
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
150 configtable = {}
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
151 configitem = registrar.configitem(configtable)
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
152
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
153 configitem('fsmonitor', 'mode',
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
154 default='on',
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
155 )
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
156 configitem('fsmonitor', 'walk_on_invalidate',
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
157 default=False,
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
158 )
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
159 configitem('fsmonitor', 'timeout',
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
160 default='2',
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
161 )
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
162 configitem('fsmonitor', 'blacklistusers',
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
163 default=list,
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
164 )
34886
dbb542326582 fsmonitor: declare missing config options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34885
diff changeset
165 configitem('experimental', 'fsmonitor.transaction_notify',
dbb542326582 fsmonitor: declare missing config options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34885
diff changeset
166 default=False,
dbb542326582 fsmonitor: declare missing config options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34885
diff changeset
167 )
dbb542326582 fsmonitor: declare missing config options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34885
diff changeset
168 configitem('experimental', 'fsmonitor.wc_change_notify',
dbb542326582 fsmonitor: declare missing config options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34885
diff changeset
169 default=False,
dbb542326582 fsmonitor: declare missing config options
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34885
diff changeset
170 )
34463
718f7acd6d5e fsmonitor: use configitem
Gregory Szorc <gregory.szorc@gmail.com>
parents: 34462
diff changeset
171
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
172 # This extension is incompatible with the following blacklisted extensions
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
173 # and will disable itself when encountering one of these:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
174 _blacklist = ['largefiles', 'eol']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
175
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
176 def _handleunavailable(ui, state, ex):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
177 """Exception handler for Watchman interaction exceptions"""
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
178 if isinstance(ex, watchmanclient.Unavailable):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
179 if ex.warn:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
180 ui.warn(str(ex) + '\n')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
181 if ex.invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
182 state.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
183 ui.log('fsmonitor', 'Watchman unavailable: %s\n', ex.msg)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
184 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
185 ui.log('fsmonitor', 'Watchman exception: %s\n', ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
186
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
187 def _hashignore(ignore):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
188 """Calculate hash for ignore patterns and filenames
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
189
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
190 If this information changes between Mercurial invocations, we can't
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
191 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
192 copy.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
193
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
194 """
29341
0d83ad967bf8 cleanup: replace uses of util.(md5|sha1|sha256|sha512) with hashlib.\1
Augie Fackler <raf@durin42.com>
parents: 29205
diff changeset
195 sha1 = hashlib.sha1()
32406
952017471f93 match: implement __repr__() and update users (API)
Martin von Zweigbergk <martinvonz@google.com>
parents: 32405
diff changeset
196 sha1.update(repr(ignore))
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
197 return sha1.hexdigest()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
198
31846
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
199 _watchmanencoding = pywatchman.encoding.get_local_encoding()
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
200 _fsencoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
201 _fixencoding = codecs.lookup(_watchmanencoding) != codecs.lookup(_fsencoding)
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
202
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
203 def _watchmantofsencoding(path):
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
204 """Fix path to match watchman and local filesystem encoding
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
205
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
206 watchman's paths encoding can differ from filesystem encoding. For example,
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
207 on Windows, it's always utf-8.
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
208 """
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
209 try:
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
210 decoded = path.decode(_watchmanencoding)
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
211 except UnicodeDecodeError as e:
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
212 raise error.Abort(str(e), hint='watchman encoding error')
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
213
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
214 try:
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
215 encoded = decoded.encode(_fsencoding, 'strict')
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
216 except UnicodeEncodeError as e:
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
217 raise error.Abort(str(e))
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
218
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
219 return encoded
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
220
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
221 def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
222 '''Replacement for dirstate.walk, hooking into Watchman.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
223
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
224 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
225 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
226 subset of files.'''
35146
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
227 def bail(reason):
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
228 self._ui.debug('fsmonitor: fallback to core status, %s\n' % reason)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
229 return orig(match, subrepos, unknown, ignored, full=True)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
230
35146
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
231 if full:
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
232 return bail('full rewalk requested')
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
233 if ignored:
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
234 return bail('listing ignored files')
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
235 if not self._watchmanclient.available():
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
236 return bail('client unavailable')
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
237 state = self._fsmonitorstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
238 clock, ignorehash, notefiles = state.get()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
239 if not clock:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
240 if state.walk_on_invalidate:
35146
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
241 return bail('no clock')
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
242 # Initial NULL clock value, see
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
243 # https://facebook.github.io/watchman/docs/clockspec.html
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
244 clock = 'c:0:0'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
245 notefiles = []
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 def fwarn(f, msg):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
248 self._ui.warn('%s: %s\n' % (self.pathto(f), msg))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
249 return False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
250
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
251 def badtype(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
252 kind = _('unknown')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
253 if stat.S_ISCHR(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
254 kind = _('character device')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
255 elif stat.S_ISBLK(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
256 kind = _('block device')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
257 elif stat.S_ISFIFO(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
258 kind = _('fifo')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
259 elif stat.S_ISSOCK(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
260 kind = _('socket')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
261 elif stat.S_ISDIR(mode):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
262 kind = _('directory')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
263 return _('unsupported file type (type is %s)') % kind
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
264
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
265 ignore = self._ignore
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
266 dirignore = self._dirignore
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
267 if unknown:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
268 if _hashignore(ignore) != ignorehash and clock != 'c:0:0':
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
269 # ignore list changed -- can't rely on Watchman state any more
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
270 if state.walk_on_invalidate:
35146
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
271 return bail('ignore rules changed')
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
272 notefiles = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
273 clock = 'c:0:0'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
274 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
275 # always ignore
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
276 ignore = util.always
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
277 dirignore = util.always
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
278
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
279 matchfn = match.matchfn
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
280 matchalways = match.always()
35085
ae7ad53d3c8d fsmonitor: only access inner dirstate map if it is available
Mark Thomas <mbthomas@fb.com>
parents: 34897
diff changeset
281 dmap = self._map
ae7ad53d3c8d fsmonitor: only access inner dirstate map if it is available
Mark Thomas <mbthomas@fb.com>
parents: 34897
diff changeset
282 if util.safehasattr(dmap, '_map'):
ae7ad53d3c8d fsmonitor: only access inner dirstate map if it is available
Mark Thomas <mbthomas@fb.com>
parents: 34897
diff changeset
283 # for better performance, directly access the inner dirstate map if the
ae7ad53d3c8d fsmonitor: only access inner dirstate map if it is available
Mark Thomas <mbthomas@fb.com>
parents: 34897
diff changeset
284 # standard dirstate implementation is in use.
ae7ad53d3c8d fsmonitor: only access inner dirstate map if it is available
Mark Thomas <mbthomas@fb.com>
parents: 34897
diff changeset
285 dmap = dmap._map
34897
2e350d2a0eca fsmonitor: use nonnormalset from dirstatemap
Jun Wu <quark@fb.com>
parents: 34886
diff changeset
286 nonnormalset = self._map.nonnormalset
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
287
34462
8337f7772aa2 fsmonitor: access copymap in new location
Gregory Szorc <gregory.szorc@gmail.com>
parents: 33649
diff changeset
288 copymap = self._map.copymap
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
289 getkind = stat.S_IFMT
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
290 dirkind = stat.S_IFDIR
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
291 regkind = stat.S_IFREG
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
292 lnkkind = stat.S_IFLNK
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
293 join = self._join
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
294 normcase = util.normcase
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
295 fresh_instance = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
296
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
297 exact = skipstep3 = False
32321
7df259077d4b fsmonitor: use modern match API
Martin von Zweigbergk <martinvonz@google.com>
parents: 32226
diff changeset
298 if match.isexact(): # match.exact
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
299 exact = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
300 dirignore = util.always # skip step 2
32321
7df259077d4b fsmonitor: use modern match API
Martin von Zweigbergk <martinvonz@google.com>
parents: 32226
diff changeset
301 elif match.prefix(): # match.match, no patterns
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
302 skipstep3 = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
303
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
304 if not exact and self._checkcase:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
305 # 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
306 # 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
307 # normalize files if possible.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
308 normalize = self._normalizefile
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
309 skipstep3 = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
310 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
311 normalize = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
312
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
313 # step 1: find all explicit files
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
314 results, work, dirsnotfound = self._walkexplicit(match, subrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
315
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
316 skipstep3 = skipstep3 and not (work or dirsnotfound)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
317 work = [d for d in work if not dirignore(d[0])]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
318
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
319 if not work and (exact or skipstep3):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
320 for s in subrepos:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
321 del results[s]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
322 del results['.hg']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
323 return results
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
324
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
325 # step 2: query Watchman
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
326 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
327 # Use the user-configured timeout for the query.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
328 # 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
329 # overheads while transferring the data
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
330 self._watchmanclient.settimeout(state.timeout + 0.1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
331 result = self._watchmanclient.command('query', {
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
332 'fields': ['mode', 'mtime', 'size', 'exists', 'name'],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
333 'since': clock,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
334 'expression': [
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
335 'not', [
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
336 'anyof', ['dirname', '.hg'],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
337 ['name', '.hg', 'wholename']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
338 ]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
339 ],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
340 'sync_timeout': int(state.timeout * 1000),
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
341 'empty_on_fresh_instance': state.walk_on_invalidate,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
342 })
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
343 except Exception as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
344 _handleunavailable(self._ui, state, ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
345 self._watchmanclient.clearconnection()
35146
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
346 return bail('exception during run')
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
347 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
348 # 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
349 # can use it for our next query
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
350 state.setlastclock(result['clock'])
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
351 if result['is_fresh_instance']:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
352 if state.walk_on_invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
353 state.invalidate()
35146
0b5716ec8500 fsmonitor: issue debug messages when we fall back to core status
Boris Feld <boris.feld@octobus.net>
parents: 35085
diff changeset
354 return bail('fresh instance')
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
355 fresh_instance = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
356 # Ignore any prior noteable files from the state info
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
357 notefiles = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
358
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
359 # for file paths which require normalization and we encounter a case
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
360 # collision, we store our own foldmap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
361 if normalize:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
362 foldmap = dict((normcase(k), k) for k in results)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
363
30666
6ada1658fc6b py3: use python 3 compatible variables in hgext/fsmontor/__init__.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
364 switch_slashes = pycompat.ossep == '\\'
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
365 # The order of the results is, strictly speaking, undefined.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
366 # For case changes on a case insensitive filesystem we may receive
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
367 # two entries, one with exists=True and another with exists=False.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
368 # The exists=True entries in the same response should be interpreted
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
369 # 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
370 # Watchman tracks files. We use this property to reconcile deletes
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
371 # for name case changes.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
372 for entry in result['files']:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
373 fname = entry['name']
31846
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
374 if _fixencoding:
1064a296a2a7 fsmonitor: match watchman and filesystem encoding
Olivier Trempe <oliviertrempe@gmail.com>
parents: 30666
diff changeset
375 fname = _watchmantofsencoding(fname)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
376 if switch_slashes:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
377 fname = fname.replace('\\', '/')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
378 if normalize:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
379 normed = normcase(fname)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
380 fname = normalize(fname, True, True)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
381 foldmap[normed] = fname
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
382 fmode = entry['mode']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
383 fexists = entry['exists']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
384 kind = getkind(fmode)
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 if not fexists:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
387 # 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
388 # record, mark it as deleted. If we already have an entry
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
389 # for fname then it was either part of walkexplicit or was
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
390 # an earlier result that was a case change
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
391 if fname not in results and fname in dmap and (
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
392 matchalways or matchfn(fname)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
393 results[fname] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
394 elif kind == dirkind:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
395 if fname in dmap and (matchalways or matchfn(fname)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
396 results[fname] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
397 elif kind == regkind or kind == lnkkind:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
398 if fname in dmap:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
399 if matchalways or matchfn(fname):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
400 results[fname] = entry
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
401 elif (matchalways or matchfn(fname)) and not ignore(fname):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
402 results[fname] = entry
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
403 elif fname in dmap and (matchalways or matchfn(fname)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
404 results[fname] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
405
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
406 # step 3: query notable files we don't already know about
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
407 # XXX try not to iterate over the entire dmap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
408 if normalize:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
409 # any notable files that have changed case will already be handled
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
410 # above, so just check membership in the foldmap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
411 notefiles = set((normalize(f, True, True) for f in notefiles
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
412 if normcase(f) not in foldmap))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
413 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
414 and (f in dmap or not ignore(f)))))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
415
34897
2e350d2a0eca fsmonitor: use nonnormalset from dirstatemap
Jun Wu <quark@fb.com>
parents: 34886
diff changeset
416 if not fresh_instance:
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
417 if matchalways:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
418 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
419 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
420 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
421 visit.update(f for f in nonnormalset
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
422 if f not in results and matchfn(f))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
423 visit.update(f for f in copymap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
424 if f not in results and matchfn(f))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
425 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
426 if matchalways:
34897
2e350d2a0eca fsmonitor: use nonnormalset from dirstatemap
Jun Wu <quark@fb.com>
parents: 34886
diff changeset
427 visit.update(f for f, st in dmap.iteritems() if f not in results)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
428 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
429 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
430 visit.update(f for f, st in dmap.iteritems()
34897
2e350d2a0eca fsmonitor: use nonnormalset from dirstatemap
Jun Wu <quark@fb.com>
parents: 34886
diff changeset
431 if f not in results and matchfn(f))
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
432 visit.update(f for f in copymap
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
433 if f not in results and matchfn(f))
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
434
33649
377e8ddaebef pathauditor: disable cache of audited paths by default (issue5628)
Yuya Nishihara <yuya@tcha.org>
parents: 33387
diff changeset
435 audit = pathutil.pathauditor(self._root, cached=True).check
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
436 auditpass = [f for f in visit if audit(f)]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
437 auditpass.sort()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
438 auditfail = visit.difference(auditpass)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
439 for f in auditfail:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
440 results[f] = None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
441
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
442 nf = iter(auditpass).next
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
443 for st in util.statfiles([join(f) for f in auditpass]):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
444 f = nf()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
445 if st or f in dmap:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
446 results[f] = st
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
447
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
448 for s in subrepos:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
449 del results[s]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
450 del results['.hg']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
451 return results
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
452
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
453 def overridestatus(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
454 orig, self, node1='.', node2=None, match=None, ignored=False,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
455 clean=False, unknown=False, listsubrepos=False):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
456 listignored = ignored
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
457 listclean = clean
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
458 listunknown = unknown
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
459
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
460 def _cmpsets(l1, l2):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
461 try:
30666
6ada1658fc6b py3: use python 3 compatible variables in hgext/fsmontor/__init__.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
462 if 'FSMONITOR_LOG_FILE' in encoding.environ:
6ada1658fc6b py3: use python 3 compatible variables in hgext/fsmontor/__init__.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
463 fn = encoding.environ['FSMONITOR_LOG_FILE']
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
464 f = open(fn, 'wb')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
465 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
466 fn = 'fsmonitorfail.log'
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
467 f = self.opener(fn, 'wb')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
468 except (IOError, OSError):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
469 self.ui.warn(_('warning: unable to write to %s\n') % fn)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
470 return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
471
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
472 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
473 for i, (s1, s2) in enumerate(zip(l1, l2)):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
474 if set(s1) != set(s2):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
475 f.write('sets at position %d are unequal\n' % i)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
476 f.write('watchman returned: %s\n' % s1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
477 f.write('stat returned: %s\n' % s2)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
478 finally:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
479 f.close()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
480
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
481 if isinstance(node1, context.changectx):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
482 ctx1 = node1
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
483 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
484 ctx1 = self[node1]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
485 if isinstance(node2, context.changectx):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
486 ctx2 = node2
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
487 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
488 ctx2 = self[node2]
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
489
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
490 working = ctx2.rev() is None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
491 parentworking = working and ctx1 == self['.']
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
492 match = match or matchmod.always(self.root, self.getcwd())
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
493
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
494 # Maybe we can use this opportunity to update Watchman's state.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
495 # Mercurial uses workingcommitctx and/or memctx to represent the part of
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
496 # 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
497 # that case.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
498 # 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
499 # 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
500 # case, or we risk forgetting about changes in the working copy.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
501 updatestate = (parentworking and match.always() and
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
502 not isinstance(ctx2, (context.workingcommitctx,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
503 context.memctx)) and
30666
6ada1658fc6b py3: use python 3 compatible variables in hgext/fsmontor/__init__.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 30332
diff changeset
504 'HG_PENDING' not in encoding.environ)
28433
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 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
507 if self._fsmonitorstate.walk_on_invalidate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
508 # Use a short timeout to query the current clock. If that
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
509 # 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
510 # to answer our query.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
511 # walk_on_invalidate indicates that we prefer to walk the
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
512 # tree ourselves because we can ignore portions that Watchman
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
513 # 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
514 # cases.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
515 self._watchmanclient.settimeout(0.1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
516 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
517 # Give Watchman more time to potentially complete its walk
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
518 # and return the initial clock. In this mode we assume that
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
519 # the filesystem will be slower than parsing a potentially
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
520 # very large Watchman result set.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
521 self._watchmanclient.settimeout(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
522 self._fsmonitorstate.timeout + 0.1)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
523 startclock = self._watchmanclient.getcurrentclock()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
524 except Exception as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
525 self._watchmanclient.clearconnection()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
526 _handleunavailable(self.ui, self._fsmonitorstate, ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
527 # boo, Watchman failed. bail
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
528 return orig(node1, node2, match, listignored, listclean,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
529 listunknown, listsubrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
530
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
531 if updatestate:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
532 # 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
533 # first time, but whatever.
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
534 stateunknown = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
535 else:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
536 stateunknown = listunknown
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
537
32815
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
538 if updatestate:
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
539 ps = poststatus(startclock)
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
540 self.addpostdsstatus(ps)
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
541
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
542 r = orig(node1, node2, match, listignored, listclean, stateunknown,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
543 listsubrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
544 modified, added, removed, deleted, unknown, ignored, clean = r
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 if not listunknown:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
547 unknown = []
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
548
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
549 # 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
550 full = listclean or match.traversedir is not None
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
551 if self._fsmonitorstate.mode == 'paranoid' and not full:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
552 # 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
553 self.dirstate._fsmonitordisable = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
554
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
555 # shut the UI up
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
556 quiet = self.ui.quiet
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
557 self.ui.quiet = True
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
558 fout, ferr = self.ui.fout, self.ui.ferr
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
559 self.ui.fout = self.ui.ferr = open(os.devnull, 'wb')
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
560
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
561 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
562 rv2 = orig(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
563 node1, node2, match, listignored, listclean, listunknown,
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
564 listsubrepos)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
565 finally:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
566 self.dirstate._fsmonitordisable = False
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
567 self.ui.quiet = quiet
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
568 self.ui.fout, self.ui.ferr = fout, ferr
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
569
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
570 # clean isn't tested since it's set to True above
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
571 _cmpsets([modified, added, removed, deleted, unknown, ignored, clean],
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
572 rv2)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
573 modified, added, removed, deleted, unknown, ignored, clean = rv2
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
574
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
575 return scmutil.status(
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
576 modified, added, removed, deleted, unknown, ignored, clean)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
577
32815
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
578 class poststatus(object):
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
579 def __init__(self, startclock):
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
580 self._startclock = startclock
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
581
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
582 def __call__(self, wctx, status):
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
583 clock = wctx.repo()._fsmonitorstate.getlastclock() or self._startclock
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
584 hashignore = _hashignore(wctx.repo().dirstate._ignore)
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
585 notefiles = (status.modified + status.added + status.removed +
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
586 status.deleted + status.unknown)
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
587 wctx.repo()._fsmonitorstate.set(clock, hashignore, notefiles)
15e85dded933 fsmonitor: write state with wlock held and dirstate unchanged (issue5581)
Siddharth Agarwal <sid0@fb.com>
parents: 32722
diff changeset
588
33386
5a9b4370bb3b fsmonitor: centralize setup procedures for dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33385
diff changeset
589 def makedirstate(repo, dirstate):
5a9b4370bb3b fsmonitor: centralize setup procedures for dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33385
diff changeset
590 class fsmonitordirstate(dirstate.__class__):
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
591 def _fsmonitorinit(self, repo):
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
592 # _fsmonitordisable is used in paranoid mode
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
593 self._fsmonitordisable = False
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
594 self._fsmonitorstate = repo._fsmonitorstate
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
595 self._watchmanclient = repo._watchmanclient
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
596 self._repo = weakref.proxy(repo)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
597
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
598 def walk(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
599 orig = super(fsmonitordirstate, self).walk
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
600 if self._fsmonitordisable:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
601 return orig(*args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
602 return overridewalk(orig, self, *args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
603
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
604 def rebuild(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
605 self._fsmonitorstate.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
606 return super(fsmonitordirstate, self).rebuild(*args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
607
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
608 def invalidate(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
609 self._fsmonitorstate.invalidate()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
610 return super(fsmonitordirstate, self).invalidate(*args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
611
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
612 if dirstate._ui.configbool(
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
613 "experimental", "fsmonitor.wc_change_notify"):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
614 def setparents(self, p1, p2=nullid):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
615 with state_update(self._repo, name="hg.wc_change",
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
616 oldnode=self._pl[0], newnode=p1,
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
617 partial=False):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
618 return super(fsmonitordirstate, self).setparents(p1, p2)
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
619
33386
5a9b4370bb3b fsmonitor: centralize setup procedures for dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33385
diff changeset
620 dirstate.__class__ = fsmonitordirstate
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
621 dirstate._fsmonitorinit(repo)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
622
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
623 def wrapdirstate(orig, self):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
624 ds = orig(self)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
625 # only override the dirstate when Watchman is available for the repo
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
626 if util.safehasattr(self, '_fsmonitorstate'):
33386
5a9b4370bb3b fsmonitor: centralize setup procedures for dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33385
diff changeset
627 makedirstate(self, ds)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
628 return ds
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
629
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
630 def extsetup(ui):
32722
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32406
diff changeset
631 extensions.wrapfilecache(
de09138bf0f5 extensions: move wrapfilecache function from fsmonitor
Augie Fackler <augie@google.com>
parents: 32406
diff changeset
632 localrepo.localrepository, 'dirstate', wrapdirstate)
34647
dacfcdd8b94e codemod: use pycompat.isdarwin
Jun Wu <quark@fb.com>
parents: 34580
diff changeset
633 if pycompat.isdarwin:
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
634 # An assist for avoiding the dangling-symlink fsevents bug
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
635 extensions.wrapfunction(os, 'symlink', wrapsymlink)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
636
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
637 extensions.wrapfunction(merge, 'update', wrapupdate)
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
638
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
639 def wrapsymlink(orig, source, link_name):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
640 ''' if we create a dangling symlink, also touch the parent dir
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
641 to encourage fsevents notifications to work more correctly '''
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
642 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
643 return orig(source, link_name)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
644 finally:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
645 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
646 os.utime(os.path.dirname(link_name), None)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
647 except OSError:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
648 pass
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
649
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
650 class state_update(object):
30332
318a24b52eeb spelling: fixes of non-dictionary words
Mads Kiilerich <madski@unity3d.com>
parents: 29841
diff changeset
651 ''' This context manager is responsible for dispatching the state-enter
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
652 and state-leave signals to the watchman service. The enter and leave
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
653 methods can be invoked manually (for scenarios where context manager
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
654 semantics are not possible). If parameters oldnode and newnode are None,
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
655 they will be populated based on current working copy in enter and
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
656 leave, respectively. Similarly, if the distance is none, it will be
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
657 calculated based on the oldnode and newnode in the leave method.'''
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
658
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
659 def __init__(self, repo, name, oldnode=None, newnode=None, distance=None,
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
660 partial=False):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
661 self.repo = repo.unfiltered()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
662 self.name = name
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
663 self.oldnode = oldnode
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
664 self.newnode = newnode
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
665 self.distance = distance
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
666 self.partial = partial
32334
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
667 self._lock = None
32335
354329178dee fsmonitor: don't attempt state-leave if we didn't state-enter
Wez Furlong <wez@fb.com>
parents: 32334
diff changeset
668 self.need_leave = False
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
669
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
670 def __enter__(self):
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
671 self.enter()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
672
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
673 def enter(self):
32334
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
674 # We explicitly need to take a lock here, before we proceed to update
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
675 # watchman about the update operation, so that we don't race with
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
676 # some other actor. merge.update is going to take the wlock almost
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
677 # immediately anyway, so this is effectively extending the lock
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
678 # around a couple of short sanity checks.
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
679 if self.oldnode is None:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
680 self.oldnode = self.repo['.'].node()
32334
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
681 self._lock = self.repo.wlock()
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
682 self.need_leave = self._state(
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
683 'state-enter',
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
684 hex(self.oldnode))
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
685 return self
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
686
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
687 def __exit__(self, type_, value, tb):
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
688 abort = True if type_ else False
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
689 self.exit(abort=abort)
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
690
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
691 def exit(self, abort=False):
32334
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
692 try:
32335
354329178dee fsmonitor: don't attempt state-leave if we didn't state-enter
Wez Furlong <wez@fb.com>
parents: 32334
diff changeset
693 if self.need_leave:
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
694 status = 'failed' if abort else 'ok'
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
695 if self.newnode is None:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
696 self.newnode = self.repo['.'].node()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
697 if self.distance is None:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
698 self.distance = calcdistance(
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
699 self.repo, self.oldnode, self.newnode)
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
700 self._state(
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
701 'state-leave',
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
702 hex(self.newnode),
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
703 status=status)
32334
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
704 finally:
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
705 self.need_leave = False
32334
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
706 if self._lock:
6e0d1043e8fc fsmonitor: acquire localrepo.wlock prior to emitting hg.update state
Wez Furlong <wez@fb.com>
parents: 32321
diff changeset
707 self._lock.release()
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
708
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
709 def _state(self, cmd, commithash, status='ok'):
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
710 if not util.safehasattr(self.repo, '_watchmanclient'):
32335
354329178dee fsmonitor: don't attempt state-leave if we didn't state-enter
Wez Furlong <wez@fb.com>
parents: 32334
diff changeset
711 return False
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
712 try:
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
713 self.repo._watchmanclient.command(cmd, {
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
714 'name': self.name,
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
715 'metadata': {
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
716 # the target revision
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
717 'rev': commithash,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
718 # approximate number of commits between current and target
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
719 'distance': self.distance if self.distance else 0,
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
720 # 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
721 'status': status,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
722 # 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
723 'partial': self.partial,
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
724 }})
32335
354329178dee fsmonitor: don't attempt state-leave if we didn't state-enter
Wez Furlong <wez@fb.com>
parents: 32334
diff changeset
725 return True
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
726 except Exception as e:
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
727 # Swallow any errors; fire and forget
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
728 self.repo.ui.log(
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
729 'watchman', 'Exception %s while running %s\n', e, cmd)
32335
354329178dee fsmonitor: don't attempt state-leave if we didn't state-enter
Wez Furlong <wez@fb.com>
parents: 32334
diff changeset
730 return False
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
731
34564
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
732 # Estimate the distance between two nodes
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
733 def calcdistance(repo, oldnode, newnode):
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
734 anc = repo.changelog.ancestor(oldnode, newnode)
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
735 ancrev = repo[anc].rev()
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
736 distance = (abs(repo[oldnode].rev() - ancrev)
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
737 + abs(repo[newnode].rev() - ancrev))
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
738 return distance
b79f59425964 fsmonitor: change the distance calculation
Eamonn Kent <ekent@fb.com>
parents: 34463
diff changeset
739
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
740 # 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
741 # 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
742 # settling during bulk file change scenarios
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
743 # 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
744 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
745 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
746
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
747 distance = 0
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
748 partial = True
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
749 oldnode = repo['.'].node()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
750 newnode = repo[node].node()
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
751 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
752 partial = False
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
753 distance = calcdistance(repo.unfiltered(), oldnode, newnode)
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
754
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
755 with state_update(repo, name="hg.update", oldnode=oldnode, newnode=newnode,
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
756 distance=distance, partial=partial):
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
757 return orig(
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
758 repo, node, branchmerge, force, ancestor, mergeancestor,
32405
bdc4861ffe59 fsmonitor: fix silly "*kwargs" bug in merge.update() override
Martin von Zweigbergk <martinvonz@google.com>
parents: 32335
diff changeset
759 labels, matcher, **kwargs)
28443
49d65663d7e4 fsmonitor: hook up state-enter, state-leave signals
Martijn Pieters <mjpieters@fb.com>
parents: 28433
diff changeset
760
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
761 def reposetup(ui, repo):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
762 # We don't work with largefiles or inotify
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
763 exts = extensions.enabled()
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
764 for ext in _blacklist:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
765 if ext in exts:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
766 ui.warn(_('The fsmonitor extension is incompatible with the %s '
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
767 'extension and has been disabled.\n') % ext)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
768 return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
769
33385
8bb4c69c4000 fsmonitor: avoid needless instantiation of dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32815
diff changeset
770 if repo.local():
8bb4c69c4000 fsmonitor: avoid needless instantiation of dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32815
diff changeset
771 # We don't work with subrepos either.
8bb4c69c4000 fsmonitor: avoid needless instantiation of dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32815
diff changeset
772 #
8bb4c69c4000 fsmonitor: avoid needless instantiation of dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32815
diff changeset
773 # if repo[None].substate can cause a dirstate parse, which is too
8bb4c69c4000 fsmonitor: avoid needless instantiation of dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32815
diff changeset
774 # slow. Instead, look for a file called hgsubstate,
8bb4c69c4000 fsmonitor: avoid needless instantiation of dirstate
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 32815
diff changeset
775 if repo.wvfs.exists('.hgsubstate') or repo.wvfs.exists('.hgsub'):
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
776 return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
777
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
778 fsmonitorstate = state.state(repo)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
779 if fsmonitorstate.mode == 'off':
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
780 return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
781
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
782 try:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
783 client = watchmanclient.client(repo)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
784 except Exception as ex:
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
785 _handleunavailable(ui, fsmonitorstate, ex)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
786 return
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
787
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
788 repo._fsmonitorstate = fsmonitorstate
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
789 repo._watchmanclient = client
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
790
33387
68e9762a357b fsmonitor: execute setup procedures only if dirstate is already instantiated
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33386
diff changeset
791 dirstate, cached = localrepo.isfilecached(repo, 'dirstate')
68e9762a357b fsmonitor: execute setup procedures only if dirstate is already instantiated
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33386
diff changeset
792 if cached:
68e9762a357b fsmonitor: execute setup procedures only if dirstate is already instantiated
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33386
diff changeset
793 # at this point since fsmonitorstate wasn't present,
68e9762a357b fsmonitor: execute setup procedures only if dirstate is already instantiated
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33386
diff changeset
794 # repo.dirstate is not a fsmonitordirstate
68e9762a357b fsmonitor: execute setup procedures only if dirstate is already instantiated
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 33386
diff changeset
795 makedirstate(repo, dirstate)
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
796
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
797 class fsmonitorrepo(repo.__class__):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
798 def status(self, *args, **kwargs):
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
799 orig = super(fsmonitorrepo, self).status
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
800 return overridestatus(orig, self, *args, **kwargs)
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
801
34565
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
802 if ui.configbool("experimental", "fsmonitor.transaction_notify"):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
803 def transaction(self, *args, **kwargs):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
804 tr = super(fsmonitorrepo, self).transaction(
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
805 *args, **kwargs)
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
806 if tr.count != 1:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
807 return tr
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
808 stateupdate = state_update(self, name="hg.transaction")
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
809 stateupdate.enter()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
810
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
811 class fsmonitortrans(tr.__class__):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
812 def _abort(self):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
813 try:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
814 result = super(fsmonitortrans, self)._abort()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
815 finally:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
816 stateupdate.exit(abort=True)
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
817 return result
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
818
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
819 def close(self):
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
820 try:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
821 result = super(fsmonitortrans, self).close()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
822 finally:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
823 if self.count == 0:
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
824 stateupdate.exit()
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
825 return result
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
826
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
827 tr.__class__ = fsmonitortrans
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
828 return tr
4aa57627692a fsmonitor: add new watchman notifications to fsmonitor extension
Eamonn Kent <ekent@fb.com>
parents: 34564
diff changeset
829
28433
3b67f27bb908 fsmonitor: new experimental extension
Martijn Pieters <mjpieters@fb.com>
parents:
diff changeset
830 repo.__class__ = fsmonitorrepo