annotate hgext/inotify/server.py @ 13155:f02d7a562a21

subrepo: avoids empty commit when .hgsubstate is dirty (issue2403) This patch avoids empty commit when .hgsubstate is dirty. Empty commit was caused by .hgsubstate being updated back to the state of the working copy parent when committing, if a user had changed it manually and not made any changes in subrepositories. The subrepository state from the working copies parent is compared with the state calculated as a result of trying to commit the subrepositories. If the two states are the same, then return None otherwise the commit is just done. The line: "committing subrepository x" will be written if there is nothing committed, but .hgsubstate is dirty for x subrepository.
author Erik Zielke <ez@aragost.com>
date Mon, 29 Nov 2010 09:37:23 +0100
parents fed4bb2c8def
children 0d4f6e843b05
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
1 # server.py - common entry point for inotify status server
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2 #
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
3 # Copyright 2009 Nicolas Dumazet <nicdumz@gmail.com>
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 #
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8209
diff changeset
5 # This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9900
diff changeset
6 # GNU General Public License version 2 or any later version.
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
8 from mercurial.i18n import _
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
9 from mercurial import cmdutil, osutil, util
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
10 import common
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
11
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
12 import errno
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
13 import os
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
14 import socket
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
15 import stat
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
16 import struct
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
17 import sys
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
18 import tempfile
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
19
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
20 class AlreadyStartedException(Exception):
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
21 pass
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
22 class TimeoutException(Exception):
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
23 pass
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
24
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25 def join(a, b):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
26 if a:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
27 if a[-1] == '/':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
28 return a + b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
29 return a + '/' + b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
30 return b
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
31
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
32 def split(path):
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
33 c = path.rfind('/')
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
34 if c == -1:
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
35 return '', path
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
36 return path[:c], path[c + 1:]
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
37
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
38 walk_ignored_errors = (errno.ENOENT, errno.ENAMETOOLONG)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
39
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
40 def walk(dirstate, absroot, root):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
41 '''Like os.walk, but only yields regular files.'''
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
42
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
43 # This function is critical to performance during startup.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
44
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45 def walkit(root, reporoot):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
46 files, dirs = [], []
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
47
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 try:
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
49 fullpath = join(absroot, root)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50 for name, kind in osutil.listdir(fullpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 if kind == stat.S_IFDIR:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 if name == '.hg':
8325
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
53 if not reporoot:
8323
589a82fb02a2 inotify: inotify.server.walk*() cleanup
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8322
diff changeset
54 return
8325
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
55 else:
f2559645643a inotify: inotify.server.walk() simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8324
diff changeset
56 dirs.append(name)
8381
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
57 path = join(root, name)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
58 if dirstate._ignore(path):
8381
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
59 continue
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
60 for result in walkit(path, False):
f52fcc864df4 inotify: server.walk(): use yield instead of for
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8336
diff changeset
61 yield result
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
62 elif kind in (stat.S_IFREG, stat.S_IFLNK):
8334
0695288e8c37 inotify: inotify.server.walk() filetype is never used, do not yield it
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8325
diff changeset
63 files.append(name)
8324
b923d599c309 inotify: inotify.server.walk*() remove unnecessary var
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8323
diff changeset
64 yield fullpath, dirs, files
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
65
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
66 except OSError, err:
9116
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
67 if err.errno == errno.ENOTDIR:
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
68 # fullpath was a directory, but has since been replaced
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
69 # by a file.
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
70 yield fullpath, dirs, files
f90bbf1ea09f inotify: fix issue1375, add a test.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9115
diff changeset
71 elif err.errno not in walk_ignored_errors:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 raise
8320
a1305c1c8d8e inotify: inotify.server.walk() simplify algorithm
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8319
diff changeset
73
a1305c1c8d8e inotify: inotify.server.walk() simplify algorithm
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8319
diff changeset
74 return walkit(root, root == '')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
75
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
76 class directory(object):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
77 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
78 Representing a directory
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
79
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
80 * path is the relative path from repo root to this directory
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
81 * files is a dict listing the files in this directory
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
82 - keys are file names
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
83 - values are file status
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
84 * dirs is a dict listing the subdirectories
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
85 - key are subdirectories names
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
86 - values are directory objects
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
87 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
88 def __init__(self, relpath=''):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
89 self.path = relpath
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
90 self.files = {}
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
91 self.dirs = {}
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
92
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
93 def dir(self, relpath):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
94 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
95 Returns the directory contained at the relative path relpath.
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
96 Creates the intermediate directories if necessary.
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
97 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
98 if not relpath:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
99 return self
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
100 l = relpath.split('/')
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
101 ret = self
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
102 while l:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
103 next = l.pop(0)
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
104 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
105 ret = ret.dirs[next]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
106 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
107 d = directory(join(ret.path, next))
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
108 ret.dirs[next] = d
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
109 ret = d
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
110 return ret
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
111
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
112 def walk(self, states, visited=None):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
113 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
114 yield (filename, status) pairs for items in the trees
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
115 that have status in states.
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
116 filenames are relative to the repo root
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
117 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
118 for file, st in self.files.iteritems():
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
119 if st in states:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
120 yield join(self.path, file), st
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
121 for dir in self.dirs.itervalues():
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
122 if visited is not None:
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
123 visited.add(dir.path)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
124 for e in dir.walk(states):
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
125 yield e
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
126
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
127 def lookup(self, states, path, visited):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
128 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
129 yield root-relative filenames that match path, and whose
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
130 status are in states:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
131 * if path is a file, yield path
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
132 * if path is a directory, yield directory files
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
133 * if path is not tracked, yield nothing
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
134 """
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
135 if path[-1] == '/':
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
136 path = path[:-1]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
137
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
138 paths = path.split('/')
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
139
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
140 # we need to check separately for last node
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
141 last = paths.pop()
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
142
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
143 tree = self
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
144 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
145 for dir in paths:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
146 tree = tree.dirs[dir]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
147 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
148 # path is not tracked
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
149 visited.add(tree.path)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
150 return
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
151
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
152 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
153 # if path is a directory, walk it
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
154 target = tree.dirs[last]
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
155 visited.add(target.path)
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
156 for file, st in target.walk(states, visited):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
157 yield file
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
158 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
159 try:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
160 if tree.files[last] in states:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
161 # path is a file
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
162 visited.add(tree.path)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
163 yield path
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
164 except KeyError:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
165 # path is not tracked
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
166 pass
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
167
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
168 class repowatcher(object):
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
169 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
170 Watches inotify events
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
171 """
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
172 statuskeys = 'almr!?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
173
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
174 def __init__(self, ui, dirstate, root):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
175 self.ui = ui
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
176 self.dirstate = dirstate
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
177
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
178 self.wprefix = join(root, '')
9349
56fb15ad8fb1 inotify: server: use wprefix everywhere, introduce prefixlen
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9348
diff changeset
179 self.prefixlen = len(self.wprefix)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
180
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
181 self.tree = directory()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
182 self.statcache = {}
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
183 self.statustrees = dict([(s, directory()) for s in self.statuskeys])
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
184
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
185 self.ds_info = self.dirstate_info()
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
186
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
187 self.last_event = None
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
188
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
189
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
190 def handle_timeout(self):
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
191 pass
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
192
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
193 def dirstate_info(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
194 try:
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
195 st = os.lstat(self.wprefix + '.hg/dirstate')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
196 return st.st_mtime, st.st_ino
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
197 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
198 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
199 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
200 return 0, 0
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
201
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
202 def filestatus(self, fn, st):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
203 try:
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
204 type_, mode, size, time = self.dirstate._map[fn][:4]
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
205 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
206 type_ = '?'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
207 if type_ == 'n':
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
208 st_mode, st_size, st_mtime = st
7082
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
209 if size == -1:
be81b4788115 inotify: fix confusion on files in lookup state
Matt Mackall <mpm@selenic.com>
parents: 6998
diff changeset
210 return 'l'
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
211 if size and (size != st_size or (mode ^ st_mode) & 0100):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
212 return 'm'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
213 if time != int(st_mtime):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
214 return 'l'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
215 return 'n'
11545
db9d16233787 inotify: check all components of filenames against hgignore (issue884)
Renato Cunha <renatoc@gmail.com>
parents: 10494
diff changeset
216 if type_ == '?' and self.dirstate._dirignore(fn):
db9d16233787 inotify: check all components of filenames against hgignore (issue884)
Renato Cunha <renatoc@gmail.com>
parents: 10494
diff changeset
217 # we must check not only if the file is ignored, but if any part
db9d16233787 inotify: check all components of filenames against hgignore (issue884)
Renato Cunha <renatoc@gmail.com>
parents: 10494
diff changeset
218 # of its path match an ignore pattern
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
219 return 'i'
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
220 return type_
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
221
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
222 def updatefile(self, wfn, osstat):
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
223 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
224 update the file entry of an existing file.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
225
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
226 osstat: (mode, size, time) tuple, as returned by os.lstat(wfn)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
227 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
228
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
229 self._updatestatus(wfn, self.filestatus(wfn, osstat))
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
230
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
231 def deletefile(self, wfn, oldstatus):
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
232 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
233 update the entry of a file which has been deleted.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
234
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
235 oldstatus: char in statuskeys, status of the file before deletion
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
236 '''
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
237 if oldstatus == 'r':
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
238 newstatus = 'r'
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
239 elif oldstatus in 'almn':
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
240 newstatus = '!'
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
241 else:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
242 newstatus = None
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
243
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
244 self.statcache.pop(wfn, None)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
245 self._updatestatus(wfn, newstatus)
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
246
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
247 def _updatestatus(self, wfn, newstatus):
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
248 '''
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
249 Update the stored status of a file.
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
250
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
251 newstatus: - char in (statuskeys + 'ni'), new status to apply.
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
252 - or None, to stop tracking wfn
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
253 '''
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
254 root, fn = split(wfn)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
255 d = self.tree.dir(root)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
256
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
257 oldstatus = d.files.get(fn)
8599
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
258 # oldstatus can be either:
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
259 # - None : fn is new
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
260 # - a char in statuskeys: fn is a (tracked) file
1f706b1b62f3 inotify: server: refactor updatestatus()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8557
diff changeset
261
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
262 if self.ui.debugflag and oldstatus != newstatus:
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
263 self.ui.note(_('status: %r %s -> %s\n') %
8382
6f44b1adc948 inotify: RepoWatcher.updatestatus: document & use meaningful parameter names
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8381
diff changeset
264 (wfn, oldstatus, newstatus))
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
265
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
266 if oldstatus and oldstatus in self.statuskeys \
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
267 and oldstatus != newstatus:
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
268 del self.statustrees[oldstatus].dir(root).files[fn]
9348
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
269
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
270 if newstatus in (None, 'i'):
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
271 d.files.pop(fn, None)
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
272 elif oldstatus != newstatus:
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
273 d.files[fn] = newstatus
9348
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
274 if newstatus != 'n':
954f7a879495 inotify: server._updatestatus: simplify control flow
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9117
diff changeset
275 self.statustrees[newstatus].dir(root).files[fn] = newstatus
7892
67e59a9886d5 Fixing issue1542, adding a relevant test
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 7451
diff changeset
276
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
277 def check_deleted(self, key):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
278 # Files that had been deleted but were present in the dirstate
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
279 # may have vanished from the dirstate; we must clean them up.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
280 nuke = []
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
281 for wfn, ignore in self.statustrees[key].walk(key):
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
282 if wfn not in self.dirstate:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
283 nuke.append(wfn)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
284 for wfn in nuke:
8787
9aca76502280 inotify: server: move split() out of server
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8786
diff changeset
285 root, fn = split(wfn)
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
286 del self.statustrees[key].dir(root).files[fn]
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
287 del self.tree.dir(root).files[fn]
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
288
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
289 def update_hgignore(self):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
290 # An update of the ignore file can potentially change the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
291 # states of all unknown and ignored files.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
292
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
293 # XXX If the user has other ignore files outside the repo, or
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
294 # changes their list of ignore files at run time, we'll
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
295 # potentially never see changes to them. We could get the
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
296 # client to report to us what ignore data they're using.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
297 # But it's easier to do nothing than to open that can of
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
298 # worms.
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
299
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
300 if '_ignore' in self.dirstate.__dict__:
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
301 delattr(self.dirstate, '_ignore')
6961
12163fb21fce i18n: mark strings for translation in inotify extension
Martin Geisler <mg@daimi.au.dk>
parents: 6909
diff changeset
302 self.ui.note(_('rescanning due to .hgignore change\n'))
8604
578f2a0049cd inotify: do not recurse in handle_timeout(): call it explicitely, not in scan()
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8600
diff changeset
303 self.handle_timeout()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
304 self.scan()
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
305
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
306 def getstat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
307 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
308 return self.statcache[wpath]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
309 except KeyError:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
310 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311 return self.stat(wpath)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
312 except OSError, err:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
313 if err.errno != errno.ENOENT:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
314 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
315
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
316 def stat(self, wpath):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
317 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
318 st = os.lstat(join(self.wprefix, wpath))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
319 ret = st.st_mode, st.st_size, st.st_mtime
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
320 self.statcache[wpath] = ret
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
321 return ret
7280
810ca383da9c remove unused variables
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7220
diff changeset
322 except OSError:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
323 self.statcache.pop(wpath, None)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
324 raise
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
325
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
326 class socketlistener(object):
8610
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
327 """
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
328 Listens for client queries on unix socket inotify.sock
8ef1f63e554c inotify: server: use a common 'pollable' interface for server & repowatcher
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8609
diff changeset
329 """
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
330 def __init__(self, ui, root, repowatcher, timeout):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
331 self.ui = ui
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
332 self.repowatcher = repowatcher
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
333 self.sock = socket.socket(socket.AF_UNIX)
9350
b789ea382fc0 inotify: server: use dirstate instead of repo
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9349
diff changeset
334 self.sockpath = join(root, '.hg/inotify.sock')
12650
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
335
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
336 self.realsockpath = self.sockpath
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
337 if os.path.islink(self.sockpath):
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
338 if os.path.exists(self.sockpath):
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
339 self.realsockpath = os.readlink(self.sockpath)
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
340 else:
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
341 raise util.Abort('inotify-server: cannot start: '
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
342 '.hg/inotify.sock is a broken symlink')
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
343 try:
12650
fed4bb2c8def inotify: raise correct error if server is already started in a deep repository
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 11943
diff changeset
344 self.sock.bind(self.realsockpath)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
345 except socket.error, err:
11567
34cc8b84407f removed exception args indexing (not supported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11545
diff changeset
346 if err.args[0] == errno.EADDRINUSE:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
347 raise AlreadyStartedException(_('cannot start: socket is '
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10264
diff changeset
348 'already bound'))
11567
34cc8b84407f removed exception args indexing (not supported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11545
diff changeset
349 if err.args[0] == "AF_UNIX path too long":
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
350 tempdir = tempfile.mkdtemp(prefix="hg-inotify-")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
351 self.realsockpath = os.path.join(tempdir, "inotify.sock")
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
352 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
353 self.sock.bind(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
354 os.symlink(self.realsockpath, self.sockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
355 except (OSError, socket.error), inst:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
356 try:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
357 os.unlink(self.realsockpath)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
358 except:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
359 pass
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
360 os.rmdir(tempdir)
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
361 if inst.errno == errno.EEXIST:
9900
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
362 raise AlreadyStartedException(_('cannot start: tried '
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
363 'linking .hg/inotify.sock to a temporary socket but'
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
364 ' .hg/inotify.sock already exists'))
6997
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
365 raise
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
366 else:
9c4e488f105e inotify: workaround ENAMETOOLONG by using symlinks
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 6994
diff changeset
367 raise
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
368 self.sock.listen(5)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
369 self.fileno = self.sock.fileno
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
370
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
371 def answer_stat_query(self, cs):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
372 names = cs.read().split('\0')
6287
c86207d41512 Spacing cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 6239
diff changeset
373
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
374 states = names.pop()
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
375
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
376 self.ui.note(_('answering query for %r\n') % states)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
377
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
378 visited = set()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
379 if not names:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
380 def genresult(states, tree):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
381 for fn, state in tree.walk(states):
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
382 yield fn
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
383 else:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
384 def genresult(states, tree):
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
385 for fn in names:
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
386 for f in tree.lookup(states, fn, visited):
9115
b55d44719b47 inotify: server: new data structure to keep track of changes.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8953
diff changeset
387 yield f
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
388
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
389 return ['\0'.join(r) for r in [
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
390 genresult('l', self.repowatcher.statustrees['l']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
391 genresult('m', self.repowatcher.statustrees['m']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
392 genresult('a', self.repowatcher.statustrees['a']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
393 genresult('r', self.repowatcher.statustrees['r']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
394 genresult('!', self.repowatcher.statustrees['!']),
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
395 '?' in states
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
396 and genresult('?', self.repowatcher.statustrees['?'])
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
397 or [],
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
398 [],
8335
713ec3f9c9de inotify: Clarify the use of "watcher" name.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8334
diff changeset
399 'c' in states and genresult('n', self.repowatcher.tree) or [],
9854
95e1867f765b inotify: mark directories visited during lookup (issue1844)
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9514
diff changeset
400 visited
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
401 ]]
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
402
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
403 def answer_dbug_query(self):
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
404 return ['\0'.join(self.repowatcher.debug())]
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
405
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
406 def accept_connection(self):
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
407 sock, addr = self.sock.accept()
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
408
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
409 cs = common.recvcs(sock)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
410 version = ord(cs.read(1))
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
411
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
412 if version != common.version:
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
413 self.ui.warn(_('received query from incompatible client '
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
414 'version %d\n') % version)
8952
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
415 try:
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
416 # try to send back our version to the client
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
417 # this way, the client too is informed of the mismatch
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
418 sock.sendall(chr(common.version))
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
419 except:
7c7a672e9db7 inotify: return version to client even when not matching
Simon Heimberg <simohe@besonet.ch>
parents: 8794
diff changeset
420 pass
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
421 return
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
422
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
423 type = cs.read(4)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
424
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
425 if type == 'STAT':
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
426 results = self.answer_stat_query(cs)
8555
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
427 elif type == 'DBUG':
3e09bc5fee12 inotify: introduce debuginotify, which lists which paths are under watch
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8554
diff changeset
428 results = self.answer_dbug_query()
8554
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
429 else:
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
430 self.ui.warn(_('unrecognized query type: %s\n') % type)
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
431 return
47d7347484f5 inotify: put STAT-specific query answer generation part in its own method
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8553
diff changeset
432
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
433 try:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
434 try:
8386
4aad982111b6 inotify: Abstract the layer format and sizes to a inotify.common dictionary
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8385
diff changeset
435 v = chr(common.version)
4aad982111b6 inotify: Abstract the layer format and sizes to a inotify.common dictionary
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8385
diff changeset
436
8553
e387ecd7a6ed inotify: change protocol so that different query types can be supported.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8386
diff changeset
437 sock.sendall(v + type + struct.pack(common.resphdrfmts[type],
e387ecd7a6ed inotify: change protocol so that different query types can be supported.
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8386
diff changeset
438 *map(len, results)))
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
439 sock.sendall(''.join(results))
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
440 finally:
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
441 sock.shutdown(socket.SHUT_WR)
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
442 except socket.error, err:
11567
34cc8b84407f removed exception args indexing (not supported by py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11545
diff changeset
443 if err.args[0] != errno.EPIPE:
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
444 raise
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
445
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
446 if sys.platform == 'linux2':
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
447 import linuxserver as _server
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
448 else:
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
449 raise ImportError
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
450
9933
2e7902158af9 inotify: create a common, OS-independent server entry point
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9900
diff changeset
451 master = _server.master
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
452
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
453 def start(ui, dirstate, root, opts):
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
454 timeout = opts.get('idle_timeout')
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
455 if timeout:
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
456 timeout = float(timeout) * 60000
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
457 else:
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
458 timeout = None
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
459
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
460 class service(object):
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
461 def init(self):
7451
fca9947652ce inotify: close most file descriptors when autostarting
Brendan Cully <brendan@kublai.com>
parents: 7420
diff changeset
462 try:
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
463 self.master = master(ui, dirstate, root, timeout)
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
464 except AlreadyStartedException, inst:
9900
8939900073a8 inotify: improve error messages
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9897
diff changeset
465 raise util.Abort("inotify-server: %s" % inst)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
466
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
467 def run(self):
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
468 try:
10494
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
469 try:
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
470 self.master.run()
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
471 except TimeoutException:
08064db9f005 inotify/inserve: implement --timeout-idle option (issue885)
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10282
diff changeset
472 pass
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
473 finally:
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
474 self.master.shutdown()
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
475
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
476 if 'inserve' not in sys.argv:
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10090
diff changeset
477 runargs = util.hgcmd() + ['inserve', '-R', root]
9897
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
478 else:
10239
8e4be44a676f Find right hg command for detached process
Patrick Mezard <pmezard@gmail.com>
parents: 10090
diff changeset
479 runargs = util.hgcmd() + sys.argv[1:]
9897
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
480
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
481 pidfile = ui.config('inotify', 'pidfile')
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
482 if opts['daemon'] and pidfile is not None and 'pid-file' not in runargs:
97eda2133a9b inotify: add a inotify.pidfile configuration possibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9854
diff changeset
483 runargs.append("--pid-file=%s" % pidfile)
6239
39cfcef4f463 Add inotify extension
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
484
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
485 service = service()
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
486 logfile = ui.config('inotify', 'log')
10013
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
487
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
488 appendpid = ui.configbool('inotify', 'appendpid', False)
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
489
11943
2d3cbcace897 inotify: show the exact command used to start the server
Greg Ward <greg-hg@gerg.ca>
parents: 11567
diff changeset
490 ui.debug('starting inotify server: %s\n' % ' '.join(runargs))
9514
7c01599dd340 inotify: use cmdutil.service instead of local daemonizing code
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9351
diff changeset
491 cmdutil.service(opts, initfn=service.init, runfn=service.run,
10013
b2e87fde6806 run-tests: --inotify: use inotify.appendpid to append pids to $DAEMON_PIDS
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9933
diff changeset
492 logfile=logfile, runargs=runargs, appendpid=appendpid)