##// END OF EJS Templates
cmdserver: invalidate the dirstate when running commands (issue3271)...
Idan Kamara -
r16114:acfca07a stable
parent child Browse files
Show More
@@ -1,237 +1,238 b''
1 # commandserver.py - communicate with Mercurial's API over a pipe
1 # commandserver.py - communicate with Mercurial's API over a pipe
2 #
2 #
3 # Copyright Matt Mackall <mpm@selenic.com>
3 # Copyright Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 from i18n import _
8 from i18n import _
9 import struct
9 import struct
10 import sys, os
10 import sys, os
11 import dispatch, encoding, util
11 import dispatch, encoding, util
12
12
13 logfile = None
13 logfile = None
14
14
15 def log(*args):
15 def log(*args):
16 if not logfile:
16 if not logfile:
17 return
17 return
18
18
19 for a in args:
19 for a in args:
20 logfile.write(str(a))
20 logfile.write(str(a))
21
21
22 logfile.flush()
22 logfile.flush()
23
23
24 class channeledoutput(object):
24 class channeledoutput(object):
25 """
25 """
26 Write data from in_ to out in the following format:
26 Write data from in_ to out in the following format:
27
27
28 data length (unsigned int),
28 data length (unsigned int),
29 data
29 data
30 """
30 """
31 def __init__(self, in_, out, channel):
31 def __init__(self, in_, out, channel):
32 self.in_ = in_
32 self.in_ = in_
33 self.out = out
33 self.out = out
34 self.channel = channel
34 self.channel = channel
35
35
36 def write(self, data):
36 def write(self, data):
37 if not data:
37 if not data:
38 return
38 return
39 self.out.write(struct.pack('>cI', self.channel, len(data)))
39 self.out.write(struct.pack('>cI', self.channel, len(data)))
40 self.out.write(data)
40 self.out.write(data)
41 self.out.flush()
41 self.out.flush()
42
42
43 def __getattr__(self, attr):
43 def __getattr__(self, attr):
44 if attr in ('isatty', 'fileno'):
44 if attr in ('isatty', 'fileno'):
45 raise AttributeError, attr
45 raise AttributeError, attr
46 return getattr(self.in_, attr)
46 return getattr(self.in_, attr)
47
47
48 class channeledinput(object):
48 class channeledinput(object):
49 """
49 """
50 Read data from in_.
50 Read data from in_.
51
51
52 Requests for input are written to out in the following format:
52 Requests for input are written to out in the following format:
53 channel identifier - 'I' for plain input, 'L' line based (1 byte)
53 channel identifier - 'I' for plain input, 'L' line based (1 byte)
54 how many bytes to send at most (unsigned int),
54 how many bytes to send at most (unsigned int),
55
55
56 The client replies with:
56 The client replies with:
57 data length (unsigned int), 0 meaning EOF
57 data length (unsigned int), 0 meaning EOF
58 data
58 data
59 """
59 """
60
60
61 maxchunksize = 4 * 1024
61 maxchunksize = 4 * 1024
62
62
63 def __init__(self, in_, out, channel):
63 def __init__(self, in_, out, channel):
64 self.in_ = in_
64 self.in_ = in_
65 self.out = out
65 self.out = out
66 self.channel = channel
66 self.channel = channel
67
67
68 def read(self, size=-1):
68 def read(self, size=-1):
69 if size < 0:
69 if size < 0:
70 # if we need to consume all the clients input, ask for 4k chunks
70 # if we need to consume all the clients input, ask for 4k chunks
71 # so the pipe doesn't fill up risking a deadlock
71 # so the pipe doesn't fill up risking a deadlock
72 size = self.maxchunksize
72 size = self.maxchunksize
73 s = self._read(size, self.channel)
73 s = self._read(size, self.channel)
74 buf = s
74 buf = s
75 while s:
75 while s:
76 s = self._read(size, self.channel)
76 s = self._read(size, self.channel)
77 buf += s
77 buf += s
78
78
79 return buf
79 return buf
80 else:
80 else:
81 return self._read(size, self.channel)
81 return self._read(size, self.channel)
82
82
83 def _read(self, size, channel):
83 def _read(self, size, channel):
84 if not size:
84 if not size:
85 return ''
85 return ''
86 assert size > 0
86 assert size > 0
87
87
88 # tell the client we need at most size bytes
88 # tell the client we need at most size bytes
89 self.out.write(struct.pack('>cI', channel, size))
89 self.out.write(struct.pack('>cI', channel, size))
90 self.out.flush()
90 self.out.flush()
91
91
92 length = self.in_.read(4)
92 length = self.in_.read(4)
93 length = struct.unpack('>I', length)[0]
93 length = struct.unpack('>I', length)[0]
94 if not length:
94 if not length:
95 return ''
95 return ''
96 else:
96 else:
97 return self.in_.read(length)
97 return self.in_.read(length)
98
98
99 def readline(self, size=-1):
99 def readline(self, size=-1):
100 if size < 0:
100 if size < 0:
101 size = self.maxchunksize
101 size = self.maxchunksize
102 s = self._read(size, 'L')
102 s = self._read(size, 'L')
103 buf = s
103 buf = s
104 # keep asking for more until there's either no more or
104 # keep asking for more until there's either no more or
105 # we got a full line
105 # we got a full line
106 while s and s[-1] != '\n':
106 while s and s[-1] != '\n':
107 s = self._read(size, 'L')
107 s = self._read(size, 'L')
108 buf += s
108 buf += s
109
109
110 return buf
110 return buf
111 else:
111 else:
112 return self._read(size, 'L')
112 return self._read(size, 'L')
113
113
114 def __iter__(self):
114 def __iter__(self):
115 return self
115 return self
116
116
117 def next(self):
117 def next(self):
118 l = self.readline()
118 l = self.readline()
119 if not l:
119 if not l:
120 raise StopIteration
120 raise StopIteration
121 return l
121 return l
122
122
123 def __getattr__(self, attr):
123 def __getattr__(self, attr):
124 if attr in ('isatty', 'fileno'):
124 if attr in ('isatty', 'fileno'):
125 raise AttributeError, attr
125 raise AttributeError, attr
126 return getattr(self.in_, attr)
126 return getattr(self.in_, attr)
127
127
128 class server(object):
128 class server(object):
129 """
129 """
130 Listens for commands on stdin, runs them and writes the output on a channel
130 Listens for commands on stdin, runs them and writes the output on a channel
131 based stream to stdout.
131 based stream to stdout.
132 """
132 """
133 def __init__(self, ui, repo, mode):
133 def __init__(self, ui, repo, mode):
134 self.cwd = os.getcwd()
134 self.cwd = os.getcwd()
135
135
136 logpath = ui.config("cmdserver", "log", None)
136 logpath = ui.config("cmdserver", "log", None)
137 if logpath:
137 if logpath:
138 global logfile
138 global logfile
139 if logpath == '-':
139 if logpath == '-':
140 # write log on a special 'd'ebug channel
140 # write log on a special 'd'ebug channel
141 logfile = channeledoutput(sys.stdout, sys.stdout, 'd')
141 logfile = channeledoutput(sys.stdout, sys.stdout, 'd')
142 else:
142 else:
143 logfile = open(logpath, 'a')
143 logfile = open(logpath, 'a')
144
144
145 # the ui here is really the repo ui so take its baseui so we don't end up
145 # the ui here is really the repo ui so take its baseui so we don't end up
146 # with its local configuration
146 # with its local configuration
147 self.ui = repo.baseui
147 self.ui = repo.baseui
148 self.repo = repo
148 self.repo = repo
149 self.repoui = repo.ui
149 self.repoui = repo.ui
150
150
151 if mode == 'pipe':
151 if mode == 'pipe':
152 self.cerr = channeledoutput(sys.stderr, sys.stdout, 'e')
152 self.cerr = channeledoutput(sys.stderr, sys.stdout, 'e')
153 self.cout = channeledoutput(sys.stdout, sys.stdout, 'o')
153 self.cout = channeledoutput(sys.stdout, sys.stdout, 'o')
154 self.cin = channeledinput(sys.stdin, sys.stdout, 'I')
154 self.cin = channeledinput(sys.stdin, sys.stdout, 'I')
155 self.cresult = channeledoutput(sys.stdout, sys.stdout, 'r')
155 self.cresult = channeledoutput(sys.stdout, sys.stdout, 'r')
156
156
157 self.client = sys.stdin
157 self.client = sys.stdin
158 else:
158 else:
159 raise util.Abort(_('unknown mode %s') % mode)
159 raise util.Abort(_('unknown mode %s') % mode)
160
160
161 def _read(self, size):
161 def _read(self, size):
162 if not size:
162 if not size:
163 return ''
163 return ''
164
164
165 data = self.client.read(size)
165 data = self.client.read(size)
166
166
167 # is the other end closed?
167 # is the other end closed?
168 if not data:
168 if not data:
169 raise EOFError()
169 raise EOFError()
170
170
171 return data
171 return data
172
172
173 def runcommand(self):
173 def runcommand(self):
174 """ reads a list of \0 terminated arguments, executes
174 """ reads a list of \0 terminated arguments, executes
175 and writes the return code to the result channel """
175 and writes the return code to the result channel """
176
176
177 length = struct.unpack('>I', self._read(4))[0]
177 length = struct.unpack('>I', self._read(4))[0]
178 if not length:
178 if not length:
179 args = []
179 args = []
180 else:
180 else:
181 args = self._read(length).split('\0')
181 args = self._read(length).split('\0')
182
182
183 # copy the uis so changes (e.g. --config or --verbose) don't
183 # copy the uis so changes (e.g. --config or --verbose) don't
184 # persist between requests
184 # persist between requests
185 copiedui = self.ui.copy()
185 copiedui = self.ui.copy()
186 self.repo.baseui = copiedui
186 self.repo.baseui = copiedui
187 self.repo.ui = self.repo.dirstate._ui = self.repoui.copy()
187 self.repo.ui = self.repo.dirstate._ui = self.repoui.copy()
188 self.repo.invalidate()
188 self.repo.invalidate()
189 self.repo.invalidatedirstate()
189
190
190 req = dispatch.request(args[:], copiedui, self.repo, self.cin,
191 req = dispatch.request(args[:], copiedui, self.repo, self.cin,
191 self.cout, self.cerr)
192 self.cout, self.cerr)
192
193
193 ret = dispatch.dispatch(req) or 0 # might return None
194 ret = dispatch.dispatch(req) or 0 # might return None
194
195
195 # restore old cwd
196 # restore old cwd
196 if '--cwd' in args:
197 if '--cwd' in args:
197 os.chdir(self.cwd)
198 os.chdir(self.cwd)
198
199
199 self.cresult.write(struct.pack('>i', int(ret)))
200 self.cresult.write(struct.pack('>i', int(ret)))
200
201
201 def getencoding(self):
202 def getencoding(self):
202 """ writes the current encoding to the result channel """
203 """ writes the current encoding to the result channel """
203 self.cresult.write(encoding.encoding)
204 self.cresult.write(encoding.encoding)
204
205
205 def serveone(self):
206 def serveone(self):
206 cmd = self.client.readline()[:-1]
207 cmd = self.client.readline()[:-1]
207 if cmd:
208 if cmd:
208 handler = self.capabilities.get(cmd)
209 handler = self.capabilities.get(cmd)
209 if handler:
210 if handler:
210 handler(self)
211 handler(self)
211 else:
212 else:
212 # clients are expected to check what commands are supported by
213 # clients are expected to check what commands are supported by
213 # looking at the servers capabilities
214 # looking at the servers capabilities
214 raise util.Abort(_('unknown command %s') % cmd)
215 raise util.Abort(_('unknown command %s') % cmd)
215
216
216 return cmd != ''
217 return cmd != ''
217
218
218 capabilities = {'runcommand' : runcommand,
219 capabilities = {'runcommand' : runcommand,
219 'getencoding' : getencoding}
220 'getencoding' : getencoding}
220
221
221 def serve(self):
222 def serve(self):
222 hellomsg = 'capabilities: ' + ' '.join(self.capabilities.keys())
223 hellomsg = 'capabilities: ' + ' '.join(self.capabilities.keys())
223 hellomsg += '\n'
224 hellomsg += '\n'
224 hellomsg += 'encoding: ' + encoding.encoding
225 hellomsg += 'encoding: ' + encoding.encoding
225
226
226 # write the hello msg in -one- chunk
227 # write the hello msg in -one- chunk
227 self.cout.write(hellomsg)
228 self.cout.write(hellomsg)
228
229
229 try:
230 try:
230 while self.serveone():
231 while self.serveone():
231 pass
232 pass
232 except EOFError:
233 except EOFError:
233 # we'll get here if the client disconnected while we were reading
234 # we'll get here if the client disconnected while we were reading
234 # its request
235 # its request
235 return 1
236 return 1
236
237
237 return 0
238 return 0
@@ -1,212 +1,214 b''
1 import sys, os, struct, subprocess, cStringIO, re, shutil
1 import sys, os, struct, subprocess, cStringIO, re, shutil
2
2
3 def connect(path=None):
3 def connect(path=None):
4 cmdline = ['hg', 'serve', '--cmdserver', 'pipe']
4 cmdline = ['hg', 'serve', '--cmdserver', 'pipe']
5 if path:
5 if path:
6 cmdline += ['-R', path]
6 cmdline += ['-R', path]
7
7
8 server = subprocess.Popen(cmdline, stdin=subprocess.PIPE,
8 server = subprocess.Popen(cmdline, stdin=subprocess.PIPE,
9 stdout=subprocess.PIPE)
9 stdout=subprocess.PIPE)
10
10
11 return server
11 return server
12
12
13 def writeblock(server, data):
13 def writeblock(server, data):
14 server.stdin.write(struct.pack('>I', len(data)))
14 server.stdin.write(struct.pack('>I', len(data)))
15 server.stdin.write(data)
15 server.stdin.write(data)
16 server.stdin.flush()
16 server.stdin.flush()
17
17
18 def readchannel(server):
18 def readchannel(server):
19 data = server.stdout.read(5)
19 data = server.stdout.read(5)
20 if not data:
20 if not data:
21 raise EOFError()
21 raise EOFError()
22 channel, length = struct.unpack('>cI', data)
22 channel, length = struct.unpack('>cI', data)
23 if channel in 'IL':
23 if channel in 'IL':
24 return channel, length
24 return channel, length
25 else:
25 else:
26 return channel, server.stdout.read(length)
26 return channel, server.stdout.read(length)
27
27
28 def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None):
28 def runcommand(server, args, output=sys.stdout, error=sys.stderr, input=None):
29 print ' runcommand', ' '.join(args)
29 print ' runcommand', ' '.join(args)
30 server.stdin.write('runcommand\n')
30 server.stdin.write('runcommand\n')
31 writeblock(server, '\0'.join(args))
31 writeblock(server, '\0'.join(args))
32
32
33 if not input:
33 if not input:
34 input = cStringIO.StringIO()
34 input = cStringIO.StringIO()
35
35
36 while True:
36 while True:
37 ch, data = readchannel(server)
37 ch, data = readchannel(server)
38 if ch == 'o':
38 if ch == 'o':
39 output.write(data)
39 output.write(data)
40 output.flush()
40 output.flush()
41 elif ch == 'e':
41 elif ch == 'e':
42 error.write(data)
42 error.write(data)
43 error.flush()
43 error.flush()
44 elif ch == 'I':
44 elif ch == 'I':
45 writeblock(server, input.read(data))
45 writeblock(server, input.read(data))
46 elif ch == 'L':
46 elif ch == 'L':
47 writeblock(server, input.readline(data))
47 writeblock(server, input.readline(data))
48 elif ch == 'r':
48 elif ch == 'r':
49 return struct.unpack('>i', data)[0]
49 return struct.unpack('>i', data)[0]
50 else:
50 else:
51 print "unexpected channel %c: %r" % (ch, data)
51 print "unexpected channel %c: %r" % (ch, data)
52 if ch.isupper():
52 if ch.isupper():
53 return
53 return
54
54
55 def check(func, repopath=None):
55 def check(func, repopath=None):
56 print
56 print
57 print 'testing %s:' % func.__name__
57 print 'testing %s:' % func.__name__
58 print
58 print
59 server = connect(repopath)
59 server = connect(repopath)
60 try:
60 try:
61 return func(server)
61 return func(server)
62 finally:
62 finally:
63 server.stdin.close()
63 server.stdin.close()
64 server.wait()
64 server.wait()
65
65
66 def unknowncommand(server):
66 def unknowncommand(server):
67 server.stdin.write('unknowncommand\n')
67 server.stdin.write('unknowncommand\n')
68
68
69 def hellomessage(server):
69 def hellomessage(server):
70 ch, data = readchannel(server)
70 ch, data = readchannel(server)
71 # escaping python tests output not supported
71 # escaping python tests output not supported
72 print '%c, %r' % (ch, re.sub('encoding: [a-zA-Z0-9-]+', 'encoding: ***', data))
72 print '%c, %r' % (ch, re.sub('encoding: [a-zA-Z0-9-]+', 'encoding: ***', data))
73
73
74 # run an arbitrary command to make sure the next thing the server sends
74 # run an arbitrary command to make sure the next thing the server sends
75 # isn't part of the hello message
75 # isn't part of the hello message
76 runcommand(server, ['id'])
76 runcommand(server, ['id'])
77
77
78 def checkruncommand(server):
78 def checkruncommand(server):
79 # hello block
79 # hello block
80 readchannel(server)
80 readchannel(server)
81
81
82 # no args
82 # no args
83 runcommand(server, [])
83 runcommand(server, [])
84
84
85 # global options
85 # global options
86 runcommand(server, ['id', '--quiet'])
86 runcommand(server, ['id', '--quiet'])
87
87
88 # make sure global options don't stick through requests
88 # make sure global options don't stick through requests
89 runcommand(server, ['id'])
89 runcommand(server, ['id'])
90
90
91 # --config
91 # --config
92 runcommand(server, ['id', '--config', 'ui.quiet=True'])
92 runcommand(server, ['id', '--config', 'ui.quiet=True'])
93
93
94 # make sure --config doesn't stick
94 # make sure --config doesn't stick
95 runcommand(server, ['id'])
95 runcommand(server, ['id'])
96
96
97 def inputeof(server):
97 def inputeof(server):
98 readchannel(server)
98 readchannel(server)
99 server.stdin.write('runcommand\n')
99 server.stdin.write('runcommand\n')
100 # close stdin while server is waiting for input
100 # close stdin while server is waiting for input
101 server.stdin.close()
101 server.stdin.close()
102
102
103 # server exits with 1 if the pipe closed while reading the command
103 # server exits with 1 if the pipe closed while reading the command
104 print 'server exit code =', server.wait()
104 print 'server exit code =', server.wait()
105
105
106 def serverinput(server):
106 def serverinput(server):
107 readchannel(server)
107 readchannel(server)
108
108
109 patch = """
109 patch = """
110 # HG changeset patch
110 # HG changeset patch
111 # User test
111 # User test
112 # Date 0 0
112 # Date 0 0
113 # Node ID c103a3dec114d882c98382d684d8af798d09d857
113 # Node ID c103a3dec114d882c98382d684d8af798d09d857
114 # Parent 0000000000000000000000000000000000000000
114 # Parent 0000000000000000000000000000000000000000
115 1
115 1
116
116
117 diff -r 000000000000 -r c103a3dec114 a
117 diff -r 000000000000 -r c103a3dec114 a
118 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
119 +++ b/a Thu Jan 01 00:00:00 1970 +0000
119 +++ b/a Thu Jan 01 00:00:00 1970 +0000
120 @@ -0,0 +1,1 @@
120 @@ -0,0 +1,1 @@
121 +1
121 +1
122 """
122 """
123
123
124 runcommand(server, ['import', '-'], input=cStringIO.StringIO(patch))
124 runcommand(server, ['import', '-'], input=cStringIO.StringIO(patch))
125 runcommand(server, ['log'])
125 runcommand(server, ['log'])
126
126
127 def cwd(server):
127 def cwd(server):
128 """ check that --cwd doesn't persist between requests """
128 """ check that --cwd doesn't persist between requests """
129 readchannel(server)
129 readchannel(server)
130 os.mkdir('foo')
130 os.mkdir('foo')
131 f = open('foo/bar', 'wb')
131 f = open('foo/bar', 'wb')
132 f.write('a')
132 f.write('a')
133 f.close()
133 f.close()
134 runcommand(server, ['--cwd', 'foo', 'st', 'bar'])
134 runcommand(server, ['--cwd', 'foo', 'st', 'bar'])
135 runcommand(server, ['st', 'foo/bar'])
135 runcommand(server, ['st', 'foo/bar'])
136 os.remove('foo/bar')
136 os.remove('foo/bar')
137
137
138 def localhgrc(server):
138 def localhgrc(server):
139 """ check that local configs for the cached repo aren't inherited when -R
139 """ check that local configs for the cached repo aren't inherited when -R
140 is used """
140 is used """
141 readchannel(server)
141 readchannel(server)
142
142
143 # the cached repo local hgrc contains ui.foo=bar, so showconfig should show it
143 # the cached repo local hgrc contains ui.foo=bar, so showconfig should show it
144 runcommand(server, ['showconfig'])
144 runcommand(server, ['showconfig'])
145
145
146 # but not for this repo
146 # but not for this repo
147 runcommand(server, ['init', 'foo'])
147 runcommand(server, ['init', 'foo'])
148 runcommand(server, ['-R', 'foo', 'showconfig', 'ui', 'defaults'])
148 runcommand(server, ['-R', 'foo', 'showconfig', 'ui', 'defaults'])
149 shutil.rmtree('foo')
149 shutil.rmtree('foo')
150
150
151 def hook(**args):
151 def hook(**args):
152 print 'hook talking'
152 print 'hook talking'
153 print 'now try to read something: %r' % sys.stdin.read()
153 print 'now try to read something: %r' % sys.stdin.read()
154
154
155 def hookoutput(server):
155 def hookoutput(server):
156 readchannel(server)
156 readchannel(server)
157 runcommand(server, ['--config',
157 runcommand(server, ['--config',
158 'hooks.pre-identify=python:test-commandserver.hook', 'id'],
158 'hooks.pre-identify=python:test-commandserver.hook', 'id'],
159 input=cStringIO.StringIO('some input'))
159 input=cStringIO.StringIO('some input'))
160
160
161 def outsidechanges(server):
161 def outsidechanges(server):
162 readchannel(server)
162 readchannel(server)
163 f = open('a', 'ab')
163 f = open('a', 'ab')
164 f.write('a\n')
164 f.write('a\n')
165 f.close()
165 f.close()
166 runcommand(server, ['status'])
166 os.system('hg ci -Am2')
167 os.system('hg ci -Am2')
167 runcommand(server, ['tip'])
168 runcommand(server, ['tip'])
169 runcommand(server, ['status'])
168
170
169 def bookmarks(server):
171 def bookmarks(server):
170 readchannel(server)
172 readchannel(server)
171 runcommand(server, ['bookmarks'])
173 runcommand(server, ['bookmarks'])
172
174
173 # changes .hg/bookmarks
175 # changes .hg/bookmarks
174 os.system('hg bookmark -i bm1')
176 os.system('hg bookmark -i bm1')
175 os.system('hg bookmark -i bm2')
177 os.system('hg bookmark -i bm2')
176 runcommand(server, ['bookmarks'])
178 runcommand(server, ['bookmarks'])
177
179
178 # changes .hg/bookmarks.current
180 # changes .hg/bookmarks.current
179 os.system('hg upd bm1 -q')
181 os.system('hg upd bm1 -q')
180 runcommand(server, ['bookmarks'])
182 runcommand(server, ['bookmarks'])
181
183
182 def tagscache(server):
184 def tagscache(server):
183 readchannel(server)
185 readchannel(server)
184 runcommand(server, ['id', '-t', '-r', '0'])
186 runcommand(server, ['id', '-t', '-r', '0'])
185 os.system('hg tag -r 0 foo')
187 os.system('hg tag -r 0 foo')
186 runcommand(server, ['id', '-t', '-r', '0'])
188 runcommand(server, ['id', '-t', '-r', '0'])
187
189
188 def setphase(server):
190 def setphase(server):
189 readchannel(server)
191 readchannel(server)
190 runcommand(server, ['phase', '-r', '.'])
192 runcommand(server, ['phase', '-r', '.'])
191 os.system('hg phase -r . -p')
193 os.system('hg phase -r . -p')
192 runcommand(server, ['phase', '-r', '.'])
194 runcommand(server, ['phase', '-r', '.'])
193
195
194 if __name__ == '__main__':
196 if __name__ == '__main__':
195 os.system('hg init')
197 os.system('hg init')
196
198
197 check(hellomessage)
199 check(hellomessage)
198 check(unknowncommand)
200 check(unknowncommand)
199 check(checkruncommand)
201 check(checkruncommand)
200 check(inputeof)
202 check(inputeof)
201 check(serverinput)
203 check(serverinput)
202 check(cwd)
204 check(cwd)
203
205
204 hgrc = open('.hg/hgrc', 'a')
206 hgrc = open('.hg/hgrc', 'a')
205 hgrc.write('[ui]\nfoo=bar\n')
207 hgrc.write('[ui]\nfoo=bar\n')
206 hgrc.close()
208 hgrc.close()
207 check(localhgrc)
209 check(localhgrc)
208 check(hookoutput)
210 check(hookoutput)
209 check(outsidechanges)
211 check(outsidechanges)
210 check(bookmarks)
212 check(bookmarks)
211 check(tagscache)
213 check(tagscache)
212 check(setphase)
214 check(setphase)
@@ -1,127 +1,130 b''
1
1
2 testing hellomessage:
2 testing hellomessage:
3
3
4 o, 'capabilities: getencoding runcommand\nencoding: ***'
4 o, 'capabilities: getencoding runcommand\nencoding: ***'
5 runcommand id
5 runcommand id
6 000000000000 tip
6 000000000000 tip
7 abort: unknown command unknowncommand
7 abort: unknown command unknowncommand
8
8
9 testing unknowncommand:
9 testing unknowncommand:
10
10
11
11
12 testing checkruncommand:
12 testing checkruncommand:
13
13
14 runcommand
14 runcommand
15 Mercurial Distributed SCM
15 Mercurial Distributed SCM
16
16
17 basic commands:
17 basic commands:
18
18
19 add add the specified files on the next commit
19 add add the specified files on the next commit
20 annotate show changeset information by line for each file
20 annotate show changeset information by line for each file
21 clone make a copy of an existing repository
21 clone make a copy of an existing repository
22 commit commit the specified files or all outstanding changes
22 commit commit the specified files or all outstanding changes
23 diff diff repository (or selected files)
23 diff diff repository (or selected files)
24 export dump the header and diffs for one or more changesets
24 export dump the header and diffs for one or more changesets
25 forget forget the specified files on the next commit
25 forget forget the specified files on the next commit
26 init create a new repository in the given directory
26 init create a new repository in the given directory
27 log show revision history of entire repository or files
27 log show revision history of entire repository or files
28 merge merge working directory with another revision
28 merge merge working directory with another revision
29 phase set or show the current phase name
29 phase set or show the current phase name
30 pull pull changes from the specified source
30 pull pull changes from the specified source
31 push push changes to the specified destination
31 push push changes to the specified destination
32 remove remove the specified files on the next commit
32 remove remove the specified files on the next commit
33 serve start stand-alone webserver
33 serve start stand-alone webserver
34 status show changed files in the working directory
34 status show changed files in the working directory
35 summary summarize working directory state
35 summary summarize working directory state
36 update update working directory (or switch revisions)
36 update update working directory (or switch revisions)
37
37
38 use "hg help" for the full list of commands or "hg -v" for details
38 use "hg help" for the full list of commands or "hg -v" for details
39 runcommand id --quiet
39 runcommand id --quiet
40 000000000000
40 000000000000
41 runcommand id
41 runcommand id
42 000000000000 tip
42 000000000000 tip
43 runcommand id --config ui.quiet=True
43 runcommand id --config ui.quiet=True
44 000000000000
44 000000000000
45 runcommand id
45 runcommand id
46 000000000000 tip
46 000000000000 tip
47
47
48 testing inputeof:
48 testing inputeof:
49
49
50 server exit code = 1
50 server exit code = 1
51
51
52 testing serverinput:
52 testing serverinput:
53
53
54 runcommand import -
54 runcommand import -
55 applying patch from stdin
55 applying patch from stdin
56 runcommand log
56 runcommand log
57 changeset: 0:eff892de26ec
57 changeset: 0:eff892de26ec
58 tag: tip
58 tag: tip
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:00 1970 +0000
60 date: Thu Jan 01 00:00:00 1970 +0000
61 summary: 1
61 summary: 1
62
62
63
63
64 testing cwd:
64 testing cwd:
65
65
66 runcommand --cwd foo st bar
66 runcommand --cwd foo st bar
67 ? bar
67 ? bar
68 runcommand st foo/bar
68 runcommand st foo/bar
69 ? foo/bar
69 ? foo/bar
70
70
71 testing localhgrc:
71 testing localhgrc:
72
72
73 runcommand showconfig
73 runcommand showconfig
74 bundle.mainreporoot=$TESTTMP
74 bundle.mainreporoot=$TESTTMP
75 defaults.backout=-d "0 0"
75 defaults.backout=-d "0 0"
76 defaults.commit=-d "0 0"
76 defaults.commit=-d "0 0"
77 defaults.tag=-d "0 0"
77 defaults.tag=-d "0 0"
78 ui.slash=True
78 ui.slash=True
79 ui.foo=bar
79 ui.foo=bar
80 runcommand init foo
80 runcommand init foo
81 runcommand -R foo showconfig ui defaults
81 runcommand -R foo showconfig ui defaults
82 defaults.backout=-d "0 0"
82 defaults.backout=-d "0 0"
83 defaults.commit=-d "0 0"
83 defaults.commit=-d "0 0"
84 defaults.tag=-d "0 0"
84 defaults.tag=-d "0 0"
85 ui.slash=True
85 ui.slash=True
86
86
87 testing hookoutput:
87 testing hookoutput:
88
88
89 runcommand --config hooks.pre-identify=python:test-commandserver.hook id
89 runcommand --config hooks.pre-identify=python:test-commandserver.hook id
90 hook talking
90 hook talking
91 now try to read something: 'some input'
91 now try to read something: 'some input'
92 eff892de26ec tip
92 eff892de26ec tip
93
93
94 testing outsidechanges:
94 testing outsidechanges:
95
95
96 runcommand status
97 M a
96 runcommand tip
98 runcommand tip
97 changeset: 1:d3a0a68be6de
99 changeset: 1:d3a0a68be6de
98 tag: tip
100 tag: tip
99 user: test
101 user: test
100 date: Thu Jan 01 00:00:00 1970 +0000
102 date: Thu Jan 01 00:00:00 1970 +0000
101 summary: 2
103 summary: 2
102
104
105 runcommand status
103
106
104 testing bookmarks:
107 testing bookmarks:
105
108
106 runcommand bookmarks
109 runcommand bookmarks
107 no bookmarks set
110 no bookmarks set
108 runcommand bookmarks
111 runcommand bookmarks
109 bm1 1:d3a0a68be6de
112 bm1 1:d3a0a68be6de
110 bm2 1:d3a0a68be6de
113 bm2 1:d3a0a68be6de
111 runcommand bookmarks
114 runcommand bookmarks
112 * bm1 1:d3a0a68be6de
115 * bm1 1:d3a0a68be6de
113 bm2 1:d3a0a68be6de
116 bm2 1:d3a0a68be6de
114
117
115 testing tagscache:
118 testing tagscache:
116
119
117 runcommand id -t -r 0
120 runcommand id -t -r 0
118
121
119 runcommand id -t -r 0
122 runcommand id -t -r 0
120 foo
123 foo
121
124
122 testing setphase:
125 testing setphase:
123
126
124 runcommand phase -r .
127 runcommand phase -r .
125 2: draft
128 2: draft
126 runcommand phase -r .
129 runcommand phase -r .
127 2: public
130 2: public
General Comments 0
You need to be logged in to leave comments. Login now