##// END OF EJS Templates
py3: add a __str__ method to Abort...
Denis Laxalde -
r43720:40bf3d7e stable
parent child Browse files
Show More
@@ -1,430 +1,433 b''
1 # error.py - Mercurial exceptions
1 # error.py - Mercurial exceptions
2 #
2 #
3 # Copyright 2005-2008 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2008 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 """Mercurial exceptions.
8 """Mercurial exceptions.
9
9
10 This allows us to catch exceptions at higher levels without forcing
10 This allows us to catch exceptions at higher levels without forcing
11 imports.
11 imports.
12 """
12 """
13
13
14 from __future__ import absolute_import
14 from __future__ import absolute_import
15
15
16 # Do not import anything but pycompat here, please
16 # Do not import anything but pycompat here, please
17 from . import pycompat
17 from . import pycompat
18
18
19
19
20 def _tobytes(exc):
20 def _tobytes(exc):
21 """Byte-stringify exception in the same way as BaseException_str()"""
21 """Byte-stringify exception in the same way as BaseException_str()"""
22 if not exc.args:
22 if not exc.args:
23 return b''
23 return b''
24 if len(exc.args) == 1:
24 if len(exc.args) == 1:
25 return pycompat.bytestr(exc.args[0])
25 return pycompat.bytestr(exc.args[0])
26 return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
26 return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
27
27
28
28
29 class Hint(object):
29 class Hint(object):
30 """Mix-in to provide a hint of an error
30 """Mix-in to provide a hint of an error
31
31
32 This should come first in the inheritance list to consume a hint and
32 This should come first in the inheritance list to consume a hint and
33 pass remaining arguments to the exception class.
33 pass remaining arguments to the exception class.
34 """
34 """
35
35
36 def __init__(self, *args, **kw):
36 def __init__(self, *args, **kw):
37 self.hint = kw.pop(r'hint', None)
37 self.hint = kw.pop(r'hint', None)
38 super(Hint, self).__init__(*args, **kw)
38 super(Hint, self).__init__(*args, **kw)
39
39
40
40
41 class StorageError(Hint, Exception):
41 class StorageError(Hint, Exception):
42 """Raised when an error occurs in a storage layer.
42 """Raised when an error occurs in a storage layer.
43
43
44 Usually subclassed by a storage-specific exception.
44 Usually subclassed by a storage-specific exception.
45 """
45 """
46
46
47 __bytes__ = _tobytes
47 __bytes__ = _tobytes
48
48
49
49
50 class RevlogError(StorageError):
50 class RevlogError(StorageError):
51 __bytes__ = _tobytes
51 __bytes__ = _tobytes
52
52
53
53
54 class SidedataHashError(RevlogError):
54 class SidedataHashError(RevlogError):
55 def __init__(self, key, expected, got):
55 def __init__(self, key, expected, got):
56 self.sidedatakey = key
56 self.sidedatakey = key
57 self.expecteddigest = expected
57 self.expecteddigest = expected
58 self.actualdigest = got
58 self.actualdigest = got
59
59
60
60
61 class FilteredIndexError(IndexError):
61 class FilteredIndexError(IndexError):
62 __bytes__ = _tobytes
62 __bytes__ = _tobytes
63
63
64
64
65 class LookupError(RevlogError, KeyError):
65 class LookupError(RevlogError, KeyError):
66 def __init__(self, name, index, message):
66 def __init__(self, name, index, message):
67 self.name = name
67 self.name = name
68 self.index = index
68 self.index = index
69 # this can't be called 'message' because at least some installs of
69 # this can't be called 'message' because at least some installs of
70 # Python 2.6+ complain about the 'message' property being deprecated
70 # Python 2.6+ complain about the 'message' property being deprecated
71 self.lookupmessage = message
71 self.lookupmessage = message
72 if isinstance(name, bytes) and len(name) == 20:
72 if isinstance(name, bytes) and len(name) == 20:
73 from .node import short
73 from .node import short
74
74
75 name = short(name)
75 name = short(name)
76 RevlogError.__init__(self, b'%s@%s: %s' % (index, name, message))
76 RevlogError.__init__(self, b'%s@%s: %s' % (index, name, message))
77
77
78 def __bytes__(self):
78 def __bytes__(self):
79 return RevlogError.__bytes__(self)
79 return RevlogError.__bytes__(self)
80
80
81 def __str__(self):
81 def __str__(self):
82 return RevlogError.__str__(self)
82 return RevlogError.__str__(self)
83
83
84
84
85 class AmbiguousPrefixLookupError(LookupError):
85 class AmbiguousPrefixLookupError(LookupError):
86 pass
86 pass
87
87
88
88
89 class FilteredLookupError(LookupError):
89 class FilteredLookupError(LookupError):
90 pass
90 pass
91
91
92
92
93 class ManifestLookupError(LookupError):
93 class ManifestLookupError(LookupError):
94 pass
94 pass
95
95
96
96
97 class CommandError(Exception):
97 class CommandError(Exception):
98 """Exception raised on errors in parsing the command line."""
98 """Exception raised on errors in parsing the command line."""
99
99
100 __bytes__ = _tobytes
100 __bytes__ = _tobytes
101
101
102
102
103 class InterventionRequired(Hint, Exception):
103 class InterventionRequired(Hint, Exception):
104 """Exception raised when a command requires human intervention."""
104 """Exception raised when a command requires human intervention."""
105
105
106 __bytes__ = _tobytes
106 __bytes__ = _tobytes
107
107
108
108
109 class Abort(Hint, Exception):
109 class Abort(Hint, Exception):
110 """Raised if a command needs to print an error and exit."""
110 """Raised if a command needs to print an error and exit."""
111
111
112 __bytes__ = _tobytes
112 __bytes__ = _tobytes
113
113
114 def __str__(self):
115 return pycompat.sysstr(self.__bytes__())
116
114
117
115 class HookLoadError(Abort):
118 class HookLoadError(Abort):
116 """raised when loading a hook fails, aborting an operation
119 """raised when loading a hook fails, aborting an operation
117
120
118 Exists to allow more specialized catching."""
121 Exists to allow more specialized catching."""
119
122
120
123
121 class HookAbort(Abort):
124 class HookAbort(Abort):
122 """raised when a validation hook fails, aborting an operation
125 """raised when a validation hook fails, aborting an operation
123
126
124 Exists to allow more specialized catching."""
127 Exists to allow more specialized catching."""
125
128
126
129
127 class ConfigError(Abort):
130 class ConfigError(Abort):
128 """Exception raised when parsing config files"""
131 """Exception raised when parsing config files"""
129
132
130
133
131 class UpdateAbort(Abort):
134 class UpdateAbort(Abort):
132 """Raised when an update is aborted for destination issue"""
135 """Raised when an update is aborted for destination issue"""
133
136
134
137
135 class MergeDestAbort(Abort):
138 class MergeDestAbort(Abort):
136 """Raised when an update is aborted for destination issues"""
139 """Raised when an update is aborted for destination issues"""
137
140
138
141
139 class NoMergeDestAbort(MergeDestAbort):
142 class NoMergeDestAbort(MergeDestAbort):
140 """Raised when an update is aborted because there is nothing to merge"""
143 """Raised when an update is aborted because there is nothing to merge"""
141
144
142
145
143 class ManyMergeDestAbort(MergeDestAbort):
146 class ManyMergeDestAbort(MergeDestAbort):
144 """Raised when an update is aborted because destination is ambiguous"""
147 """Raised when an update is aborted because destination is ambiguous"""
145
148
146
149
147 class ResponseExpected(Abort):
150 class ResponseExpected(Abort):
148 """Raised when an EOF is received for a prompt"""
151 """Raised when an EOF is received for a prompt"""
149
152
150 def __init__(self):
153 def __init__(self):
151 from .i18n import _
154 from .i18n import _
152
155
153 Abort.__init__(self, _(b'response expected'))
156 Abort.__init__(self, _(b'response expected'))
154
157
155
158
156 class OutOfBandError(Hint, Exception):
159 class OutOfBandError(Hint, Exception):
157 """Exception raised when a remote repo reports failure"""
160 """Exception raised when a remote repo reports failure"""
158
161
159 __bytes__ = _tobytes
162 __bytes__ = _tobytes
160
163
161
164
162 class ParseError(Hint, Exception):
165 class ParseError(Hint, Exception):
163 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
166 """Raised when parsing config files and {rev,file}sets (msg[, pos])"""
164
167
165 __bytes__ = _tobytes
168 __bytes__ = _tobytes
166
169
167
170
168 class PatchError(Exception):
171 class PatchError(Exception):
169 __bytes__ = _tobytes
172 __bytes__ = _tobytes
170
173
171
174
172 class UnknownIdentifier(ParseError):
175 class UnknownIdentifier(ParseError):
173 """Exception raised when a {rev,file}set references an unknown identifier"""
176 """Exception raised when a {rev,file}set references an unknown identifier"""
174
177
175 def __init__(self, function, symbols):
178 def __init__(self, function, symbols):
176 from .i18n import _
179 from .i18n import _
177
180
178 ParseError.__init__(self, _(b"unknown identifier: %s") % function)
181 ParseError.__init__(self, _(b"unknown identifier: %s") % function)
179 self.function = function
182 self.function = function
180 self.symbols = symbols
183 self.symbols = symbols
181
184
182
185
183 class RepoError(Hint, Exception):
186 class RepoError(Hint, Exception):
184 __bytes__ = _tobytes
187 __bytes__ = _tobytes
185
188
186
189
187 class RepoLookupError(RepoError):
190 class RepoLookupError(RepoError):
188 pass
191 pass
189
192
190
193
191 class FilteredRepoLookupError(RepoLookupError):
194 class FilteredRepoLookupError(RepoLookupError):
192 pass
195 pass
193
196
194
197
195 class CapabilityError(RepoError):
198 class CapabilityError(RepoError):
196 pass
199 pass
197
200
198
201
199 class RequirementError(RepoError):
202 class RequirementError(RepoError):
200 """Exception raised if .hg/requires has an unknown entry."""
203 """Exception raised if .hg/requires has an unknown entry."""
201
204
202
205
203 class StdioError(IOError):
206 class StdioError(IOError):
204 """Raised if I/O to stdout or stderr fails"""
207 """Raised if I/O to stdout or stderr fails"""
205
208
206 def __init__(self, err):
209 def __init__(self, err):
207 IOError.__init__(self, err.errno, err.strerror)
210 IOError.__init__(self, err.errno, err.strerror)
208
211
209 # no __bytes__() because error message is derived from the standard IOError
212 # no __bytes__() because error message is derived from the standard IOError
210
213
211
214
212 class UnsupportedMergeRecords(Abort):
215 class UnsupportedMergeRecords(Abort):
213 def __init__(self, recordtypes):
216 def __init__(self, recordtypes):
214 from .i18n import _
217 from .i18n import _
215
218
216 self.recordtypes = sorted(recordtypes)
219 self.recordtypes = sorted(recordtypes)
217 s = b' '.join(self.recordtypes)
220 s = b' '.join(self.recordtypes)
218 Abort.__init__(
221 Abort.__init__(
219 self,
222 self,
220 _(b'unsupported merge state records: %s') % s,
223 _(b'unsupported merge state records: %s') % s,
221 hint=_(
224 hint=_(
222 b'see https://mercurial-scm.org/wiki/MergeStateRecords for '
225 b'see https://mercurial-scm.org/wiki/MergeStateRecords for '
223 b'more information'
226 b'more information'
224 ),
227 ),
225 )
228 )
226
229
227
230
228 class UnknownVersion(Abort):
231 class UnknownVersion(Abort):
229 """generic exception for aborting from an encounter with an unknown version
232 """generic exception for aborting from an encounter with an unknown version
230 """
233 """
231
234
232 def __init__(self, msg, hint=None, version=None):
235 def __init__(self, msg, hint=None, version=None):
233 self.version = version
236 self.version = version
234 super(UnknownVersion, self).__init__(msg, hint=hint)
237 super(UnknownVersion, self).__init__(msg, hint=hint)
235
238
236
239
237 class LockError(IOError):
240 class LockError(IOError):
238 def __init__(self, errno, strerror, filename, desc):
241 def __init__(self, errno, strerror, filename, desc):
239 IOError.__init__(self, errno, strerror, filename)
242 IOError.__init__(self, errno, strerror, filename)
240 self.desc = desc
243 self.desc = desc
241
244
242 # no __bytes__() because error message is derived from the standard IOError
245 # no __bytes__() because error message is derived from the standard IOError
243
246
244
247
245 class LockHeld(LockError):
248 class LockHeld(LockError):
246 def __init__(self, errno, filename, desc, locker):
249 def __init__(self, errno, filename, desc, locker):
247 LockError.__init__(self, errno, b'Lock held', filename, desc)
250 LockError.__init__(self, errno, b'Lock held', filename, desc)
248 self.locker = locker
251 self.locker = locker
249
252
250
253
251 class LockUnavailable(LockError):
254 class LockUnavailable(LockError):
252 pass
255 pass
253
256
254
257
255 # LockError is for errors while acquiring the lock -- this is unrelated
258 # LockError is for errors while acquiring the lock -- this is unrelated
256 class LockInheritanceContractViolation(RuntimeError):
259 class LockInheritanceContractViolation(RuntimeError):
257 __bytes__ = _tobytes
260 __bytes__ = _tobytes
258
261
259
262
260 class ResponseError(Exception):
263 class ResponseError(Exception):
261 """Raised to print an error with part of output and exit."""
264 """Raised to print an error with part of output and exit."""
262
265
263 __bytes__ = _tobytes
266 __bytes__ = _tobytes
264
267
265
268
266 class UnknownCommand(Exception):
269 class UnknownCommand(Exception):
267 """Exception raised if command is not in the command table."""
270 """Exception raised if command is not in the command table."""
268
271
269 __bytes__ = _tobytes
272 __bytes__ = _tobytes
270
273
271
274
272 class AmbiguousCommand(Exception):
275 class AmbiguousCommand(Exception):
273 """Exception raised if command shortcut matches more than one command."""
276 """Exception raised if command shortcut matches more than one command."""
274
277
275 __bytes__ = _tobytes
278 __bytes__ = _tobytes
276
279
277
280
278 # derived from KeyboardInterrupt to simplify some breakout code
281 # derived from KeyboardInterrupt to simplify some breakout code
279 class SignalInterrupt(KeyboardInterrupt):
282 class SignalInterrupt(KeyboardInterrupt):
280 """Exception raised on SIGTERM and SIGHUP."""
283 """Exception raised on SIGTERM and SIGHUP."""
281
284
282
285
283 class SignatureError(Exception):
286 class SignatureError(Exception):
284 __bytes__ = _tobytes
287 __bytes__ = _tobytes
285
288
286
289
287 class PushRaced(RuntimeError):
290 class PushRaced(RuntimeError):
288 """An exception raised during unbundling that indicate a push race"""
291 """An exception raised during unbundling that indicate a push race"""
289
292
290 __bytes__ = _tobytes
293 __bytes__ = _tobytes
291
294
292
295
293 class ProgrammingError(Hint, RuntimeError):
296 class ProgrammingError(Hint, RuntimeError):
294 """Raised if a mercurial (core or extension) developer made a mistake"""
297 """Raised if a mercurial (core or extension) developer made a mistake"""
295
298
296 def __init__(self, msg, *args, **kwargs):
299 def __init__(self, msg, *args, **kwargs):
297 # On Python 3, turn the message back into a string since this is
300 # On Python 3, turn the message back into a string since this is
298 # an internal-only error that won't be printed except in a
301 # an internal-only error that won't be printed except in a
299 # stack traces.
302 # stack traces.
300 msg = pycompat.sysstr(msg)
303 msg = pycompat.sysstr(msg)
301 super(ProgrammingError, self).__init__(msg, *args, **kwargs)
304 super(ProgrammingError, self).__init__(msg, *args, **kwargs)
302
305
303 __bytes__ = _tobytes
306 __bytes__ = _tobytes
304
307
305
308
306 class WdirUnsupported(Exception):
309 class WdirUnsupported(Exception):
307 """An exception which is raised when 'wdir()' is not supported"""
310 """An exception which is raised when 'wdir()' is not supported"""
308
311
309 __bytes__ = _tobytes
312 __bytes__ = _tobytes
310
313
311
314
312 # bundle2 related errors
315 # bundle2 related errors
313 class BundleValueError(ValueError):
316 class BundleValueError(ValueError):
314 """error raised when bundle2 cannot be processed"""
317 """error raised when bundle2 cannot be processed"""
315
318
316 __bytes__ = _tobytes
319 __bytes__ = _tobytes
317
320
318
321
319 class BundleUnknownFeatureError(BundleValueError):
322 class BundleUnknownFeatureError(BundleValueError):
320 def __init__(self, parttype=None, params=(), values=()):
323 def __init__(self, parttype=None, params=(), values=()):
321 self.parttype = parttype
324 self.parttype = parttype
322 self.params = params
325 self.params = params
323 self.values = values
326 self.values = values
324 if self.parttype is None:
327 if self.parttype is None:
325 msg = b'Stream Parameter'
328 msg = b'Stream Parameter'
326 else:
329 else:
327 msg = parttype
330 msg = parttype
328 entries = self.params
331 entries = self.params
329 if self.params and self.values:
332 if self.params and self.values:
330 assert len(self.params) == len(self.values)
333 assert len(self.params) == len(self.values)
331 entries = []
334 entries = []
332 for idx, par in enumerate(self.params):
335 for idx, par in enumerate(self.params):
333 val = self.values[idx]
336 val = self.values[idx]
334 if val is None:
337 if val is None:
335 entries.append(val)
338 entries.append(val)
336 else:
339 else:
337 entries.append(b"%s=%r" % (par, pycompat.maybebytestr(val)))
340 entries.append(b"%s=%r" % (par, pycompat.maybebytestr(val)))
338 if entries:
341 if entries:
339 msg = b'%s - %s' % (msg, b', '.join(entries))
342 msg = b'%s - %s' % (msg, b', '.join(entries))
340 ValueError.__init__(self, msg)
343 ValueError.__init__(self, msg)
341
344
342
345
343 class ReadOnlyPartError(RuntimeError):
346 class ReadOnlyPartError(RuntimeError):
344 """error raised when code tries to alter a part being generated"""
347 """error raised when code tries to alter a part being generated"""
345
348
346 __bytes__ = _tobytes
349 __bytes__ = _tobytes
347
350
348
351
349 class PushkeyFailed(Abort):
352 class PushkeyFailed(Abort):
350 """error raised when a pushkey part failed to update a value"""
353 """error raised when a pushkey part failed to update a value"""
351
354
352 def __init__(
355 def __init__(
353 self, partid, namespace=None, key=None, new=None, old=None, ret=None
356 self, partid, namespace=None, key=None, new=None, old=None, ret=None
354 ):
357 ):
355 self.partid = partid
358 self.partid = partid
356 self.namespace = namespace
359 self.namespace = namespace
357 self.key = key
360 self.key = key
358 self.new = new
361 self.new = new
359 self.old = old
362 self.old = old
360 self.ret = ret
363 self.ret = ret
361 # no i18n expected to be processed into a better message
364 # no i18n expected to be processed into a better message
362 Abort.__init__(
365 Abort.__init__(
363 self, b'failed to update value for "%s/%s"' % (namespace, key)
366 self, b'failed to update value for "%s/%s"' % (namespace, key)
364 )
367 )
365
368
366
369
367 class CensoredNodeError(StorageError):
370 class CensoredNodeError(StorageError):
368 """error raised when content verification fails on a censored node
371 """error raised when content verification fails on a censored node
369
372
370 Also contains the tombstone data substituted for the uncensored data.
373 Also contains the tombstone data substituted for the uncensored data.
371 """
374 """
372
375
373 def __init__(self, filename, node, tombstone):
376 def __init__(self, filename, node, tombstone):
374 from .node import short
377 from .node import short
375
378
376 StorageError.__init__(self, b'%s:%s' % (filename, short(node)))
379 StorageError.__init__(self, b'%s:%s' % (filename, short(node)))
377 self.tombstone = tombstone
380 self.tombstone = tombstone
378
381
379
382
380 class CensoredBaseError(StorageError):
383 class CensoredBaseError(StorageError):
381 """error raised when a delta is rejected because its base is censored
384 """error raised when a delta is rejected because its base is censored
382
385
383 A delta based on a censored revision must be formed as single patch
386 A delta based on a censored revision must be formed as single patch
384 operation which replaces the entire base with new content. This ensures
387 operation which replaces the entire base with new content. This ensures
385 the delta may be applied by clones which have not censored the base.
388 the delta may be applied by clones which have not censored the base.
386 """
389 """
387
390
388
391
389 class InvalidBundleSpecification(Exception):
392 class InvalidBundleSpecification(Exception):
390 """error raised when a bundle specification is invalid.
393 """error raised when a bundle specification is invalid.
391
394
392 This is used for syntax errors as opposed to support errors.
395 This is used for syntax errors as opposed to support errors.
393 """
396 """
394
397
395 __bytes__ = _tobytes
398 __bytes__ = _tobytes
396
399
397
400
398 class UnsupportedBundleSpecification(Exception):
401 class UnsupportedBundleSpecification(Exception):
399 """error raised when a bundle specification is not supported."""
402 """error raised when a bundle specification is not supported."""
400
403
401 __bytes__ = _tobytes
404 __bytes__ = _tobytes
402
405
403
406
404 class CorruptedState(Exception):
407 class CorruptedState(Exception):
405 """error raised when a command is not able to read its state from file"""
408 """error raised when a command is not able to read its state from file"""
406
409
407 __bytes__ = _tobytes
410 __bytes__ = _tobytes
408
411
409
412
410 class PeerTransportError(Abort):
413 class PeerTransportError(Abort):
411 """Transport-level I/O error when communicating with a peer repo."""
414 """Transport-level I/O error when communicating with a peer repo."""
412
415
413
416
414 class InMemoryMergeConflictsError(Exception):
417 class InMemoryMergeConflictsError(Exception):
415 """Exception raised when merge conflicts arose during an in-memory merge."""
418 """Exception raised when merge conflicts arose during an in-memory merge."""
416
419
417 __bytes__ = _tobytes
420 __bytes__ = _tobytes
418
421
419
422
420 class WireprotoCommandError(Exception):
423 class WireprotoCommandError(Exception):
421 """Represents an error during execution of a wire protocol command.
424 """Represents an error during execution of a wire protocol command.
422
425
423 Should only be thrown by wire protocol version 2 commands.
426 Should only be thrown by wire protocol version 2 commands.
424
427
425 The error is a formatter string and an optional iterable of arguments.
428 The error is a formatter string and an optional iterable of arguments.
426 """
429 """
427
430
428 def __init__(self, message, args=None):
431 def __init__(self, message, args=None):
429 self.message = message
432 self.message = message
430 self.messageargs = args
433 self.messageargs = args
@@ -1,304 +1,304 b''
1 # Create server
1 # Create server
2 $ hg init server
2 $ hg init server
3 $ cd server
3 $ cd server
4 $ cat >> .hg/hgrc << EOF
4 $ cat >> .hg/hgrc << EOF
5 > [extensions]
5 > [extensions]
6 > extension=$TESTDIR/flagprocessorext.py
6 > extension=$TESTDIR/flagprocessorext.py
7 > EOF
7 > EOF
8 $ cd ../
8 $ cd ../
9
9
10 # Clone server and enable extensions
10 # Clone server and enable extensions
11 $ hg clone -q server client
11 $ hg clone -q server client
12 $ cd client
12 $ cd client
13 $ cat >> .hg/hgrc << EOF
13 $ cat >> .hg/hgrc << EOF
14 > [extensions]
14 > [extensions]
15 > extension=$TESTDIR/flagprocessorext.py
15 > extension=$TESTDIR/flagprocessorext.py
16 > EOF
16 > EOF
17
17
18 # Commit file that will trigger the noop extension
18 # Commit file that will trigger the noop extension
19 $ echo '[NOOP]' > noop
19 $ echo '[NOOP]' > noop
20 $ hg commit -Aqm "noop"
20 $ hg commit -Aqm "noop"
21
21
22 # Commit file that will trigger the base64 extension
22 # Commit file that will trigger the base64 extension
23 $ echo '[BASE64]' > base64
23 $ echo '[BASE64]' > base64
24 $ hg commit -Aqm 'base64'
24 $ hg commit -Aqm 'base64'
25
25
26 # Commit file that will trigger the gzip extension
26 # Commit file that will trigger the gzip extension
27 $ echo '[GZIP]' > gzip
27 $ echo '[GZIP]' > gzip
28 $ hg commit -Aqm 'gzip'
28 $ hg commit -Aqm 'gzip'
29
29
30 # Commit file that will trigger noop and base64
30 # Commit file that will trigger noop and base64
31 $ echo '[NOOP][BASE64]' > noop-base64
31 $ echo '[NOOP][BASE64]' > noop-base64
32 $ hg commit -Aqm 'noop+base64'
32 $ hg commit -Aqm 'noop+base64'
33
33
34 # Commit file that will trigger noop and gzip
34 # Commit file that will trigger noop and gzip
35 $ echo '[NOOP][GZIP]' > noop-gzip
35 $ echo '[NOOP][GZIP]' > noop-gzip
36 $ hg commit -Aqm 'noop+gzip'
36 $ hg commit -Aqm 'noop+gzip'
37
37
38 # Commit file that will trigger base64 and gzip
38 # Commit file that will trigger base64 and gzip
39 $ echo '[BASE64][GZIP]' > base64-gzip
39 $ echo '[BASE64][GZIP]' > base64-gzip
40 $ hg commit -Aqm 'base64+gzip'
40 $ hg commit -Aqm 'base64+gzip'
41
41
42 # Commit file that will trigger base64, gzip and noop
42 # Commit file that will trigger base64, gzip and noop
43 $ echo '[BASE64][GZIP][NOOP]' > base64-gzip-noop
43 $ echo '[BASE64][GZIP][NOOP]' > base64-gzip-noop
44 $ hg commit -Aqm 'base64+gzip+noop'
44 $ hg commit -Aqm 'base64+gzip+noop'
45
45
46 # TEST: ensure the revision data is consistent
46 # TEST: ensure the revision data is consistent
47 $ hg cat noop
47 $ hg cat noop
48 [NOOP]
48 [NOOP]
49 $ hg debugdata noop 0
49 $ hg debugdata noop 0
50 [NOOP]
50 [NOOP]
51
51
52 $ hg cat -r . base64
52 $ hg cat -r . base64
53 [BASE64]
53 [BASE64]
54 $ hg debugdata base64 0
54 $ hg debugdata base64 0
55 W0JBU0U2NF0K (no-eol)
55 W0JBU0U2NF0K (no-eol)
56
56
57 $ hg cat -r . gzip
57 $ hg cat -r . gzip
58 [GZIP]
58 [GZIP]
59 $ hg debugdata gzip 0
59 $ hg debugdata gzip 0
60 x\x9c\x8bv\x8f\xf2\x0c\x88\xe5\x02\x00\x08\xc8\x01\xfd (no-eol) (esc)
60 x\x9c\x8bv\x8f\xf2\x0c\x88\xe5\x02\x00\x08\xc8\x01\xfd (no-eol) (esc)
61
61
62 $ hg cat -r . noop-base64
62 $ hg cat -r . noop-base64
63 [NOOP][BASE64]
63 [NOOP][BASE64]
64 $ hg debugdata noop-base64 0
64 $ hg debugdata noop-base64 0
65 W05PT1BdW0JBU0U2NF0K (no-eol)
65 W05PT1BdW0JBU0U2NF0K (no-eol)
66
66
67 $ hg cat -r . noop-gzip
67 $ hg cat -r . noop-gzip
68 [NOOP][GZIP]
68 [NOOP][GZIP]
69 $ hg debugdata noop-gzip 0
69 $ hg debugdata noop-gzip 0
70 x\x9c\x8b\xf6\xf3\xf7\x0f\x88\x8dv\x8f\xf2\x0c\x88\xe5\x02\x00\x1dH\x03\xf1 (no-eol) (esc)
70 x\x9c\x8b\xf6\xf3\xf7\x0f\x88\x8dv\x8f\xf2\x0c\x88\xe5\x02\x00\x1dH\x03\xf1 (no-eol) (esc)
71
71
72 $ hg cat -r . base64-gzip
72 $ hg cat -r . base64-gzip
73 [BASE64][GZIP]
73 [BASE64][GZIP]
74 $ hg debugdata base64-gzip 0
74 $ hg debugdata base64-gzip 0
75 eJyLdnIMdjUziY12j/IMiOUCACLBBDo= (no-eol)
75 eJyLdnIMdjUziY12j/IMiOUCACLBBDo= (no-eol)
76
76
77 $ hg cat -r . base64-gzip-noop
77 $ hg cat -r . base64-gzip-noop
78 [BASE64][GZIP][NOOP]
78 [BASE64][GZIP][NOOP]
79 $ hg debugdata base64-gzip-noop 0
79 $ hg debugdata base64-gzip-noop 0
80 eJyLdnIMdjUziY12j/IMiI328/cPiOUCAESjBi4= (no-eol)
80 eJyLdnIMdjUziY12j/IMiI328/cPiOUCAESjBi4= (no-eol)
81
81
82 # Push to the server
82 # Push to the server
83 $ hg push
83 $ hg push
84 pushing to $TESTTMP/server
84 pushing to $TESTTMP/server
85 searching for changes
85 searching for changes
86 adding changesets
86 adding changesets
87 adding manifests
87 adding manifests
88 adding file changes
88 adding file changes
89 added 7 changesets with 7 changes to 7 files
89 added 7 changesets with 7 changes to 7 files
90
90
91 Ensure the data got to the server OK
91 Ensure the data got to the server OK
92
92
93 $ cd ../server
93 $ cd ../server
94 $ hg cat -r 6e48f4215d24 noop
94 $ hg cat -r 6e48f4215d24 noop
95 [NOOP]
95 [NOOP]
96 $ hg debugdata noop 0
96 $ hg debugdata noop 0
97 [NOOP]
97 [NOOP]
98
98
99 $ hg cat -r 6e48f4215d24 base64
99 $ hg cat -r 6e48f4215d24 base64
100 [BASE64]
100 [BASE64]
101 $ hg debugdata base64 0
101 $ hg debugdata base64 0
102 W0JBU0U2NF0K (no-eol)
102 W0JBU0U2NF0K (no-eol)
103
103
104 $ hg cat -r 6e48f4215d24 gzip
104 $ hg cat -r 6e48f4215d24 gzip
105 [GZIP]
105 [GZIP]
106 $ hg debugdata gzip 0
106 $ hg debugdata gzip 0
107 x\x9c\x8bv\x8f\xf2\x0c\x88\xe5\x02\x00\x08\xc8\x01\xfd (no-eol) (esc)
107 x\x9c\x8bv\x8f\xf2\x0c\x88\xe5\x02\x00\x08\xc8\x01\xfd (no-eol) (esc)
108
108
109 $ hg cat -r 6e48f4215d24 noop-base64
109 $ hg cat -r 6e48f4215d24 noop-base64
110 [NOOP][BASE64]
110 [NOOP][BASE64]
111 $ hg debugdata noop-base64 0
111 $ hg debugdata noop-base64 0
112 W05PT1BdW0JBU0U2NF0K (no-eol)
112 W05PT1BdW0JBU0U2NF0K (no-eol)
113
113
114 $ hg cat -r 6e48f4215d24 noop-gzip
114 $ hg cat -r 6e48f4215d24 noop-gzip
115 [NOOP][GZIP]
115 [NOOP][GZIP]
116 $ hg debugdata noop-gzip 0
116 $ hg debugdata noop-gzip 0
117 x\x9c\x8b\xf6\xf3\xf7\x0f\x88\x8dv\x8f\xf2\x0c\x88\xe5\x02\x00\x1dH\x03\xf1 (no-eol) (esc)
117 x\x9c\x8b\xf6\xf3\xf7\x0f\x88\x8dv\x8f\xf2\x0c\x88\xe5\x02\x00\x1dH\x03\xf1 (no-eol) (esc)
118
118
119 $ hg cat -r 6e48f4215d24 base64-gzip
119 $ hg cat -r 6e48f4215d24 base64-gzip
120 [BASE64][GZIP]
120 [BASE64][GZIP]
121 $ hg debugdata base64-gzip 0
121 $ hg debugdata base64-gzip 0
122 eJyLdnIMdjUziY12j/IMiOUCACLBBDo= (no-eol)
122 eJyLdnIMdjUziY12j/IMiOUCACLBBDo= (no-eol)
123
123
124 $ hg cat -r 6e48f4215d24 base64-gzip-noop
124 $ hg cat -r 6e48f4215d24 base64-gzip-noop
125 [BASE64][GZIP][NOOP]
125 [BASE64][GZIP][NOOP]
126 $ hg debugdata base64-gzip-noop 0
126 $ hg debugdata base64-gzip-noop 0
127 eJyLdnIMdjUziY12j/IMiI328/cPiOUCAESjBi4= (no-eol)
127 eJyLdnIMdjUziY12j/IMiI328/cPiOUCAESjBi4= (no-eol)
128
128
129 # Initialize new client (not cloning) and setup extension
129 # Initialize new client (not cloning) and setup extension
130 $ cd ..
130 $ cd ..
131 $ hg init client2
131 $ hg init client2
132 $ cd client2
132 $ cd client2
133 $ cat >> .hg/hgrc << EOF
133 $ cat >> .hg/hgrc << EOF
134 > [paths]
134 > [paths]
135 > default = $TESTTMP/server
135 > default = $TESTTMP/server
136 > [extensions]
136 > [extensions]
137 > extension=$TESTDIR/flagprocessorext.py
137 > extension=$TESTDIR/flagprocessorext.py
138 > EOF
138 > EOF
139
139
140 # Pull from server and update to latest revision
140 # Pull from server and update to latest revision
141 $ hg pull default
141 $ hg pull default
142 pulling from $TESTTMP/server
142 pulling from $TESTTMP/server
143 requesting all changes
143 requesting all changes
144 adding changesets
144 adding changesets
145 adding manifests
145 adding manifests
146 adding file changes
146 adding file changes
147 added 7 changesets with 7 changes to 7 files
147 added 7 changesets with 7 changes to 7 files
148 new changesets 07b1b9442c5b:6e48f4215d24
148 new changesets 07b1b9442c5b:6e48f4215d24
149 (run 'hg update' to get a working copy)
149 (run 'hg update' to get a working copy)
150 $ hg update
150 $ hg update
151 7 files updated, 0 files merged, 0 files removed, 0 files unresolved
151 7 files updated, 0 files merged, 0 files removed, 0 files unresolved
152
152
153 # TEST: ensure the revision data is consistent
153 # TEST: ensure the revision data is consistent
154 $ hg cat noop
154 $ hg cat noop
155 [NOOP]
155 [NOOP]
156 $ hg debugdata noop 0
156 $ hg debugdata noop 0
157 [NOOP]
157 [NOOP]
158
158
159 $ hg cat -r . base64
159 $ hg cat -r . base64
160 [BASE64]
160 [BASE64]
161 $ hg debugdata base64 0
161 $ hg debugdata base64 0
162 W0JBU0U2NF0K (no-eol)
162 W0JBU0U2NF0K (no-eol)
163
163
164 $ hg cat -r . gzip
164 $ hg cat -r . gzip
165 [GZIP]
165 [GZIP]
166 $ hg debugdata gzip 0
166 $ hg debugdata gzip 0
167 x\x9c\x8bv\x8f\xf2\x0c\x88\xe5\x02\x00\x08\xc8\x01\xfd (no-eol) (esc)
167 x\x9c\x8bv\x8f\xf2\x0c\x88\xe5\x02\x00\x08\xc8\x01\xfd (no-eol) (esc)
168
168
169 $ hg cat -r . noop-base64
169 $ hg cat -r . noop-base64
170 [NOOP][BASE64]
170 [NOOP][BASE64]
171 $ hg debugdata noop-base64 0
171 $ hg debugdata noop-base64 0
172 W05PT1BdW0JBU0U2NF0K (no-eol)
172 W05PT1BdW0JBU0U2NF0K (no-eol)
173
173
174 $ hg cat -r . noop-gzip
174 $ hg cat -r . noop-gzip
175 [NOOP][GZIP]
175 [NOOP][GZIP]
176 $ hg debugdata noop-gzip 0
176 $ hg debugdata noop-gzip 0
177 x\x9c\x8b\xf6\xf3\xf7\x0f\x88\x8dv\x8f\xf2\x0c\x88\xe5\x02\x00\x1dH\x03\xf1 (no-eol) (esc)
177 x\x9c\x8b\xf6\xf3\xf7\x0f\x88\x8dv\x8f\xf2\x0c\x88\xe5\x02\x00\x1dH\x03\xf1 (no-eol) (esc)
178
178
179 $ hg cat -r . base64-gzip
179 $ hg cat -r . base64-gzip
180 [BASE64][GZIP]
180 [BASE64][GZIP]
181 $ hg debugdata base64-gzip 0
181 $ hg debugdata base64-gzip 0
182 eJyLdnIMdjUziY12j/IMiOUCACLBBDo= (no-eol)
182 eJyLdnIMdjUziY12j/IMiOUCACLBBDo= (no-eol)
183
183
184 $ hg cat -r . base64-gzip-noop
184 $ hg cat -r . base64-gzip-noop
185 [BASE64][GZIP][NOOP]
185 [BASE64][GZIP][NOOP]
186 $ hg debugdata base64-gzip-noop 0
186 $ hg debugdata base64-gzip-noop 0
187 eJyLdnIMdjUziY12j/IMiI328/cPiOUCAESjBi4= (no-eol)
187 eJyLdnIMdjUziY12j/IMiI328/cPiOUCAESjBi4= (no-eol)
188
188
189 # TEST: ensure a missing processor is handled
189 # TEST: ensure a missing processor is handled
190 $ echo '[FAIL][BASE64][GZIP][NOOP]' > fail-base64-gzip-noop
190 $ echo '[FAIL][BASE64][GZIP][NOOP]' > fail-base64-gzip-noop
191 $ hg commit -Aqm 'fail+base64+gzip+noop'
191 $ hg commit -Aqm 'fail+base64+gzip+noop'
192 abort: missing processor for flag '0x1'!
192 abort: missing processor for flag '0x1'!
193 [255]
193 [255]
194 $ rm fail-base64-gzip-noop
194 $ rm fail-base64-gzip-noop
195
195
196 # TEST: ensure we cannot register several flag processors on the same flag
196 # TEST: ensure we cannot register several flag processors on the same flag
197 $ cat >> .hg/hgrc << EOF
197 $ cat >> .hg/hgrc << EOF
198 > [extensions]
198 > [extensions]
199 > extension=$TESTDIR/flagprocessorext.py
199 > extension=$TESTDIR/flagprocessorext.py
200 > duplicate=$TESTDIR/flagprocessorext.py
200 > duplicate=$TESTDIR/flagprocessorext.py
201 > EOF
201 > EOF
202 $ hg debugrebuilddirstate
202 $ hg debugrebuilddirstate
203 Traceback (most recent call last):
203 Traceback (most recent call last):
204 File "*/mercurial/extensions.py", line *, in _runextsetup (glob)
204 File "*/mercurial/extensions.py", line *, in _runextsetup (glob)
205 extsetup(ui)
205 extsetup(ui)
206 File "*/tests/flagprocessorext.py", line *, in extsetup (glob)
206 File "*/tests/flagprocessorext.py", line *, in extsetup (glob)
207 REVIDX_NOOP, (noopdonothingread, noopdonothing, validatehash,)
207 REVIDX_NOOP, (noopdonothingread, noopdonothing, validatehash,)
208 File "*/mercurial/revlogutils/flagutil.py", line *, in addflagprocessor (glob)
208 File "*/mercurial/revlogutils/flagutil.py", line *, in addflagprocessor (glob)
209 insertflagprocessor(flag, processor, flagprocessors)
209 insertflagprocessor(flag, processor, flagprocessors)
210 File "*/mercurial/revlogutils/flagutil.py", line *, in insertflagprocessor (glob)
210 File "*/mercurial/revlogutils/flagutil.py", line *, in insertflagprocessor (glob)
211 raise error.Abort(msg)
211 raise error.Abort(msg)
212 mercurial.error.Abort: b"cannot register multiple processors on flag '0x8'." (py3 !)
212 mercurial.error.Abort: cannot register multiple processors on flag '0x8'. (py3 !)
213 Abort: cannot register multiple processors on flag '0x8'. (no-py3 !)
213 Abort: cannot register multiple processors on flag '0x8'. (no-py3 !)
214 *** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
214 *** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
215 $ hg st 2>&1 | egrep 'cannot register multiple processors|flagprocessorext'
215 $ hg st 2>&1 | egrep 'cannot register multiple processors|flagprocessorext'
216 File "*/tests/flagprocessorext.py", line *, in extsetup (glob)
216 File "*/tests/flagprocessorext.py", line *, in extsetup (glob)
217 mercurial.error.Abort: b"cannot register multiple processors on flag '0x8'." (py3 !)
217 mercurial.error.Abort: cannot register multiple processors on flag '0x8'. (py3 !)
218 Abort: cannot register multiple processors on flag '0x8'. (no-py3 !)
218 Abort: cannot register multiple processors on flag '0x8'. (no-py3 !)
219 *** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
219 *** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
220 File "*/tests/flagprocessorext.py", line *, in b64decode (glob)
220 File "*/tests/flagprocessorext.py", line *, in b64decode (glob)
221
221
222 $ cd ..
222 $ cd ..
223
223
224 # TEST: bundle repo
224 # TEST: bundle repo
225 $ hg init bundletest
225 $ hg init bundletest
226 $ cd bundletest
226 $ cd bundletest
227
227
228 $ cat >> .hg/hgrc << EOF
228 $ cat >> .hg/hgrc << EOF
229 > [extensions]
229 > [extensions]
230 > flagprocessor=$TESTDIR/flagprocessorext.py
230 > flagprocessor=$TESTDIR/flagprocessorext.py
231 > EOF
231 > EOF
232
232
233 $ for i in 0 single two three 4; do
233 $ for i in 0 single two three 4; do
234 > echo '[BASE64]a-bit-longer-'$i > base64
234 > echo '[BASE64]a-bit-longer-'$i > base64
235 > hg commit -m base64-$i -A base64
235 > hg commit -m base64-$i -A base64
236 > done
236 > done
237
237
238 $ hg update 2 -q
238 $ hg update 2 -q
239 $ echo '[BASE64]a-bit-longer-branching' > base64
239 $ echo '[BASE64]a-bit-longer-branching' > base64
240 $ hg commit -q -m branching
240 $ hg commit -q -m branching
241
241
242 #if repobundlerepo
242 #if repobundlerepo
243 $ hg bundle --base 1 bundle.hg
243 $ hg bundle --base 1 bundle.hg
244 4 changesets found
244 4 changesets found
245 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
245 $ hg --config extensions.strip= strip -r 2 --no-backup --force -q
246 $ hg -R bundle.hg log --stat -T '{rev} {desc}\n' base64
246 $ hg -R bundle.hg log --stat -T '{rev} {desc}\n' base64
247 5 branching
247 5 branching
248 base64 | 2 +-
248 base64 | 2 +-
249 1 files changed, 1 insertions(+), 1 deletions(-)
249 1 files changed, 1 insertions(+), 1 deletions(-)
250
250
251 4 base64-4
251 4 base64-4
252 base64 | 2 +-
252 base64 | 2 +-
253 1 files changed, 1 insertions(+), 1 deletions(-)
253 1 files changed, 1 insertions(+), 1 deletions(-)
254
254
255 3 base64-three
255 3 base64-three
256 base64 | 2 +-
256 base64 | 2 +-
257 1 files changed, 1 insertions(+), 1 deletions(-)
257 1 files changed, 1 insertions(+), 1 deletions(-)
258
258
259 2 base64-two
259 2 base64-two
260 base64 | 2 +-
260 base64 | 2 +-
261 1 files changed, 1 insertions(+), 1 deletions(-)
261 1 files changed, 1 insertions(+), 1 deletions(-)
262
262
263 1 base64-single
263 1 base64-single
264 base64 | 2 +-
264 base64 | 2 +-
265 1 files changed, 1 insertions(+), 1 deletions(-)
265 1 files changed, 1 insertions(+), 1 deletions(-)
266
266
267 0 base64-0
267 0 base64-0
268 base64 | 1 +
268 base64 | 1 +
269 1 files changed, 1 insertions(+), 0 deletions(-)
269 1 files changed, 1 insertions(+), 0 deletions(-)
270
270
271
271
272 $ hg bundle -R bundle.hg --base 1 bundle-again.hg -q
272 $ hg bundle -R bundle.hg --base 1 bundle-again.hg -q
273 $ hg -R bundle-again.hg log --stat -T '{rev} {desc}\n' base64
273 $ hg -R bundle-again.hg log --stat -T '{rev} {desc}\n' base64
274 5 branching
274 5 branching
275 base64 | 2 +-
275 base64 | 2 +-
276 1 files changed, 1 insertions(+), 1 deletions(-)
276 1 files changed, 1 insertions(+), 1 deletions(-)
277
277
278 4 base64-4
278 4 base64-4
279 base64 | 2 +-
279 base64 | 2 +-
280 1 files changed, 1 insertions(+), 1 deletions(-)
280 1 files changed, 1 insertions(+), 1 deletions(-)
281
281
282 3 base64-three
282 3 base64-three
283 base64 | 2 +-
283 base64 | 2 +-
284 1 files changed, 1 insertions(+), 1 deletions(-)
284 1 files changed, 1 insertions(+), 1 deletions(-)
285
285
286 2 base64-two
286 2 base64-two
287 base64 | 2 +-
287 base64 | 2 +-
288 1 files changed, 1 insertions(+), 1 deletions(-)
288 1 files changed, 1 insertions(+), 1 deletions(-)
289
289
290 1 base64-single
290 1 base64-single
291 base64 | 2 +-
291 base64 | 2 +-
292 1 files changed, 1 insertions(+), 1 deletions(-)
292 1 files changed, 1 insertions(+), 1 deletions(-)
293
293
294 0 base64-0
294 0 base64-0
295 base64 | 1 +
295 base64 | 1 +
296 1 files changed, 1 insertions(+), 0 deletions(-)
296 1 files changed, 1 insertions(+), 0 deletions(-)
297
297
298 $ rm bundle.hg bundle-again.hg
298 $ rm bundle.hg bundle-again.hg
299 #endif
299 #endif
300
300
301 # TEST: hg status
301 # TEST: hg status
302
302
303 $ hg status
303 $ hg status
304 $ hg diff
304 $ hg diff
@@ -1,1390 +1,1390 b''
1 commit hooks can see env vars
1 commit hooks can see env vars
2 (and post-transaction one are run unlocked)
2 (and post-transaction one are run unlocked)
3
3
4
4
5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
5 $ cat > $TESTTMP/txnabort.checkargs.py <<EOF
6 > from mercurial import pycompat
6 > from mercurial import pycompat
7 > def showargs(ui, repo, hooktype, **kwargs):
7 > def showargs(ui, repo, hooktype, **kwargs):
8 > kwargs = pycompat.byteskwargs(kwargs)
8 > kwargs = pycompat.byteskwargs(kwargs)
9 > ui.write(b'%s Python hook: %s\n' % (hooktype,
9 > ui.write(b'%s Python hook: %s\n' % (hooktype,
10 > b','.join(sorted(kwargs))))
10 > b','.join(sorted(kwargs))))
11 > EOF
11 > EOF
12
12
13 $ hg init a
13 $ hg init a
14 $ cd a
14 $ cd a
15 $ cat > .hg/hgrc <<EOF
15 $ cat > .hg/hgrc <<EOF
16 > [hooks]
16 > [hooks]
17 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit"
17 > commit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit"
18 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit.b"
18 > commit.b = sh -c "HG_LOCAL= HG_TAG= printenv.py --line commit.b"
19 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py --line precommit"
19 > precommit = sh -c "HG_LOCAL= HG_NODE= HG_TAG= printenv.py --line precommit"
20 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxncommit"
20 > pretxncommit = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxncommit"
21 > pretxncommit.tip = hg -q tip
21 > pretxncommit.tip = hg -q tip
22 > pre-identify = sh -c "printenv.py --line pre-identify 1"
22 > pre-identify = sh -c "printenv.py --line pre-identify 1"
23 > pre-cat = sh -c "printenv.py --line pre-cat"
23 > pre-cat = sh -c "printenv.py --line pre-cat"
24 > post-cat = sh -c "printenv.py --line post-cat"
24 > post-cat = sh -c "printenv.py --line post-cat"
25 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnopen"
25 > pretxnopen = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnopen"
26 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnclose"
26 > pretxnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line pretxnclose"
27 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnclose"
27 > txnclose = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnclose"
28 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
28 > txnabort.0 = python:$TESTTMP/txnabort.checkargs.py:showargs
29 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnabort"
29 > txnabort.1 = sh -c "HG_LOCAL= HG_TAG= printenv.py --line txnabort"
30 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
30 > txnclose.checklock = sh -c "hg debuglock > /dev/null"
31 > EOF
31 > EOF
32 $ echo a > a
32 $ echo a > a
33 $ hg add a
33 $ hg add a
34 $ hg commit -m a
34 $ hg commit -m a
35 precommit hook: HG_HOOKNAME=precommit
35 precommit hook: HG_HOOKNAME=precommit
36 HG_HOOKTYPE=precommit
36 HG_HOOKTYPE=precommit
37 HG_PARENT1=0000000000000000000000000000000000000000
37 HG_PARENT1=0000000000000000000000000000000000000000
38
38
39 pretxnopen hook: HG_HOOKNAME=pretxnopen
39 pretxnopen hook: HG_HOOKNAME=pretxnopen
40 HG_HOOKTYPE=pretxnopen
40 HG_HOOKTYPE=pretxnopen
41 HG_TXNID=TXN:$ID$
41 HG_TXNID=TXN:$ID$
42 HG_TXNNAME=commit
42 HG_TXNNAME=commit
43
43
44 pretxncommit hook: HG_HOOKNAME=pretxncommit
44 pretxncommit hook: HG_HOOKNAME=pretxncommit
45 HG_HOOKTYPE=pretxncommit
45 HG_HOOKTYPE=pretxncommit
46 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
46 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
47 HG_PARENT1=0000000000000000000000000000000000000000
47 HG_PARENT1=0000000000000000000000000000000000000000
48 HG_PENDING=$TESTTMP/a
48 HG_PENDING=$TESTTMP/a
49
49
50 0:cb9a9f314b8b
50 0:cb9a9f314b8b
51 pretxnclose hook: HG_HOOKNAME=pretxnclose
51 pretxnclose hook: HG_HOOKNAME=pretxnclose
52 HG_HOOKTYPE=pretxnclose
52 HG_HOOKTYPE=pretxnclose
53 HG_PENDING=$TESTTMP/a
53 HG_PENDING=$TESTTMP/a
54 HG_PHASES_MOVED=1
54 HG_PHASES_MOVED=1
55 HG_TXNID=TXN:$ID$
55 HG_TXNID=TXN:$ID$
56 HG_TXNNAME=commit
56 HG_TXNNAME=commit
57
57
58 txnclose hook: HG_HOOKNAME=txnclose
58 txnclose hook: HG_HOOKNAME=txnclose
59 HG_HOOKTYPE=txnclose
59 HG_HOOKTYPE=txnclose
60 HG_PHASES_MOVED=1
60 HG_PHASES_MOVED=1
61 HG_TXNID=TXN:$ID$
61 HG_TXNID=TXN:$ID$
62 HG_TXNNAME=commit
62 HG_TXNNAME=commit
63
63
64 commit hook: HG_HOOKNAME=commit
64 commit hook: HG_HOOKNAME=commit
65 HG_HOOKTYPE=commit
65 HG_HOOKTYPE=commit
66 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
66 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
67 HG_PARENT1=0000000000000000000000000000000000000000
67 HG_PARENT1=0000000000000000000000000000000000000000
68
68
69 commit.b hook: HG_HOOKNAME=commit.b
69 commit.b hook: HG_HOOKNAME=commit.b
70 HG_HOOKTYPE=commit
70 HG_HOOKTYPE=commit
71 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
71 HG_NODE=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
72 HG_PARENT1=0000000000000000000000000000000000000000
72 HG_PARENT1=0000000000000000000000000000000000000000
73
73
74
74
75 $ hg clone . ../b
75 $ hg clone . ../b
76 updating to branch default
76 updating to branch default
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
77 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
78 $ cd ../b
78 $ cd ../b
79
79
80 changegroup hooks can see env vars
80 changegroup hooks can see env vars
81
81
82 $ cat > .hg/hgrc <<EOF
82 $ cat > .hg/hgrc <<EOF
83 > [hooks]
83 > [hooks]
84 > prechangegroup = sh -c "printenv.py --line prechangegroup"
84 > prechangegroup = sh -c "printenv.py --line prechangegroup"
85 > changegroup = sh -c "printenv.py --line changegroup"
85 > changegroup = sh -c "printenv.py --line changegroup"
86 > incoming = sh -c "printenv.py --line incoming"
86 > incoming = sh -c "printenv.py --line incoming"
87 > EOF
87 > EOF
88
88
89 pretxncommit and commit hooks can see both parents of merge
89 pretxncommit and commit hooks can see both parents of merge
90
90
91 $ cd ../a
91 $ cd ../a
92 $ echo b >> a
92 $ echo b >> a
93 $ hg commit -m a1 -d "1 0"
93 $ hg commit -m a1 -d "1 0"
94 precommit hook: HG_HOOKNAME=precommit
94 precommit hook: HG_HOOKNAME=precommit
95 HG_HOOKTYPE=precommit
95 HG_HOOKTYPE=precommit
96 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
96 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
97
97
98 pretxnopen hook: HG_HOOKNAME=pretxnopen
98 pretxnopen hook: HG_HOOKNAME=pretxnopen
99 HG_HOOKTYPE=pretxnopen
99 HG_HOOKTYPE=pretxnopen
100 HG_TXNID=TXN:$ID$
100 HG_TXNID=TXN:$ID$
101 HG_TXNNAME=commit
101 HG_TXNNAME=commit
102
102
103 pretxncommit hook: HG_HOOKNAME=pretxncommit
103 pretxncommit hook: HG_HOOKNAME=pretxncommit
104 HG_HOOKTYPE=pretxncommit
104 HG_HOOKTYPE=pretxncommit
105 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
105 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
106 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
106 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
107 HG_PENDING=$TESTTMP/a
107 HG_PENDING=$TESTTMP/a
108
108
109 1:ab228980c14d
109 1:ab228980c14d
110 pretxnclose hook: HG_HOOKNAME=pretxnclose
110 pretxnclose hook: HG_HOOKNAME=pretxnclose
111 HG_HOOKTYPE=pretxnclose
111 HG_HOOKTYPE=pretxnclose
112 HG_PENDING=$TESTTMP/a
112 HG_PENDING=$TESTTMP/a
113 HG_TXNID=TXN:$ID$
113 HG_TXNID=TXN:$ID$
114 HG_TXNNAME=commit
114 HG_TXNNAME=commit
115
115
116 txnclose hook: HG_HOOKNAME=txnclose
116 txnclose hook: HG_HOOKNAME=txnclose
117 HG_HOOKTYPE=txnclose
117 HG_HOOKTYPE=txnclose
118 HG_TXNID=TXN:$ID$
118 HG_TXNID=TXN:$ID$
119 HG_TXNNAME=commit
119 HG_TXNNAME=commit
120
120
121 commit hook: HG_HOOKNAME=commit
121 commit hook: HG_HOOKNAME=commit
122 HG_HOOKTYPE=commit
122 HG_HOOKTYPE=commit
123 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
123 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
124 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
124 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
125
125
126 commit.b hook: HG_HOOKNAME=commit.b
126 commit.b hook: HG_HOOKNAME=commit.b
127 HG_HOOKTYPE=commit
127 HG_HOOKTYPE=commit
128 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
128 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
129 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
129 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
130
130
131 $ hg update -C 0
131 $ hg update -C 0
132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
132 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
133 $ echo b > b
133 $ echo b > b
134 $ hg add b
134 $ hg add b
135 $ hg commit -m b -d '1 0'
135 $ hg commit -m b -d '1 0'
136 precommit hook: HG_HOOKNAME=precommit
136 precommit hook: HG_HOOKNAME=precommit
137 HG_HOOKTYPE=precommit
137 HG_HOOKTYPE=precommit
138 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
138 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
139
139
140 pretxnopen hook: HG_HOOKNAME=pretxnopen
140 pretxnopen hook: HG_HOOKNAME=pretxnopen
141 HG_HOOKTYPE=pretxnopen
141 HG_HOOKTYPE=pretxnopen
142 HG_TXNID=TXN:$ID$
142 HG_TXNID=TXN:$ID$
143 HG_TXNNAME=commit
143 HG_TXNNAME=commit
144
144
145 pretxncommit hook: HG_HOOKNAME=pretxncommit
145 pretxncommit hook: HG_HOOKNAME=pretxncommit
146 HG_HOOKTYPE=pretxncommit
146 HG_HOOKTYPE=pretxncommit
147 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
147 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
148 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
148 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
149 HG_PENDING=$TESTTMP/a
149 HG_PENDING=$TESTTMP/a
150
150
151 2:ee9deb46ab31
151 2:ee9deb46ab31
152 pretxnclose hook: HG_HOOKNAME=pretxnclose
152 pretxnclose hook: HG_HOOKNAME=pretxnclose
153 HG_HOOKTYPE=pretxnclose
153 HG_HOOKTYPE=pretxnclose
154 HG_PENDING=$TESTTMP/a
154 HG_PENDING=$TESTTMP/a
155 HG_TXNID=TXN:$ID$
155 HG_TXNID=TXN:$ID$
156 HG_TXNNAME=commit
156 HG_TXNNAME=commit
157
157
158 created new head
158 created new head
159 txnclose hook: HG_HOOKNAME=txnclose
159 txnclose hook: HG_HOOKNAME=txnclose
160 HG_HOOKTYPE=txnclose
160 HG_HOOKTYPE=txnclose
161 HG_TXNID=TXN:$ID$
161 HG_TXNID=TXN:$ID$
162 HG_TXNNAME=commit
162 HG_TXNNAME=commit
163
163
164 commit hook: HG_HOOKNAME=commit
164 commit hook: HG_HOOKNAME=commit
165 HG_HOOKTYPE=commit
165 HG_HOOKTYPE=commit
166 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
166 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
167 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
167 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
168
168
169 commit.b hook: HG_HOOKNAME=commit.b
169 commit.b hook: HG_HOOKNAME=commit.b
170 HG_HOOKTYPE=commit
170 HG_HOOKTYPE=commit
171 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
171 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
172 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
172 HG_PARENT1=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
173
173
174 $ hg merge 1
174 $ hg merge 1
175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
175 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 (branch merge, don't forget to commit)
176 (branch merge, don't forget to commit)
177 $ hg commit -m merge -d '2 0'
177 $ hg commit -m merge -d '2 0'
178 precommit hook: HG_HOOKNAME=precommit
178 precommit hook: HG_HOOKNAME=precommit
179 HG_HOOKTYPE=precommit
179 HG_HOOKTYPE=precommit
180 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
180 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
181 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
181 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
182
182
183 pretxnopen hook: HG_HOOKNAME=pretxnopen
183 pretxnopen hook: HG_HOOKNAME=pretxnopen
184 HG_HOOKTYPE=pretxnopen
184 HG_HOOKTYPE=pretxnopen
185 HG_TXNID=TXN:$ID$
185 HG_TXNID=TXN:$ID$
186 HG_TXNNAME=commit
186 HG_TXNNAME=commit
187
187
188 pretxncommit hook: HG_HOOKNAME=pretxncommit
188 pretxncommit hook: HG_HOOKNAME=pretxncommit
189 HG_HOOKTYPE=pretxncommit
189 HG_HOOKTYPE=pretxncommit
190 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
190 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
191 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
191 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
192 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
192 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
193 HG_PENDING=$TESTTMP/a
193 HG_PENDING=$TESTTMP/a
194
194
195 3:07f3376c1e65
195 3:07f3376c1e65
196 pretxnclose hook: HG_HOOKNAME=pretxnclose
196 pretxnclose hook: HG_HOOKNAME=pretxnclose
197 HG_HOOKTYPE=pretxnclose
197 HG_HOOKTYPE=pretxnclose
198 HG_PENDING=$TESTTMP/a
198 HG_PENDING=$TESTTMP/a
199 HG_TXNID=TXN:$ID$
199 HG_TXNID=TXN:$ID$
200 HG_TXNNAME=commit
200 HG_TXNNAME=commit
201
201
202 txnclose hook: HG_HOOKNAME=txnclose
202 txnclose hook: HG_HOOKNAME=txnclose
203 HG_HOOKTYPE=txnclose
203 HG_HOOKTYPE=txnclose
204 HG_TXNID=TXN:$ID$
204 HG_TXNID=TXN:$ID$
205 HG_TXNNAME=commit
205 HG_TXNNAME=commit
206
206
207 commit hook: HG_HOOKNAME=commit
207 commit hook: HG_HOOKNAME=commit
208 HG_HOOKTYPE=commit
208 HG_HOOKTYPE=commit
209 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
209 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
210 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
210 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
211 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
211 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
212
212
213 commit.b hook: HG_HOOKNAME=commit.b
213 commit.b hook: HG_HOOKNAME=commit.b
214 HG_HOOKTYPE=commit
214 HG_HOOKTYPE=commit
215 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
215 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
216 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
216 HG_PARENT1=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
217 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
217 HG_PARENT2=ab228980c14deea8b9555d91c9581127383e40fd
218
218
219
219
220 test generic hooks
220 test generic hooks
221
221
222 $ hg id
222 $ hg id
223 pre-identify hook: HG_ARGS=id
223 pre-identify hook: HG_ARGS=id
224 HG_HOOKNAME=pre-identify
224 HG_HOOKNAME=pre-identify
225 HG_HOOKTYPE=pre-identify
225 HG_HOOKTYPE=pre-identify
226 HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None, 'template': ''}
226 HG_OPTS={'bookmarks': None, 'branch': None, 'id': None, 'insecure': None, 'num': None, 'remotecmd': '', 'rev': '', 'ssh': '', 'tags': None, 'template': ''}
227 HG_PATS=[]
227 HG_PATS=[]
228
228
229 abort: pre-identify hook exited with status 1
229 abort: pre-identify hook exited with status 1
230 [255]
230 [255]
231 $ hg cat b
231 $ hg cat b
232 pre-cat hook: HG_ARGS=cat b
232 pre-cat hook: HG_ARGS=cat b
233 HG_HOOKNAME=pre-cat
233 HG_HOOKNAME=pre-cat
234 HG_HOOKTYPE=pre-cat
234 HG_HOOKTYPE=pre-cat
235 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
235 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
236 HG_PATS=['b']
236 HG_PATS=['b']
237
237
238 b
238 b
239 post-cat hook: HG_ARGS=cat b
239 post-cat hook: HG_ARGS=cat b
240 HG_HOOKNAME=post-cat
240 HG_HOOKNAME=post-cat
241 HG_HOOKTYPE=post-cat
241 HG_HOOKTYPE=post-cat
242 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
242 HG_OPTS={'decode': None, 'exclude': [], 'include': [], 'output': '', 'rev': '', 'template': ''}
243 HG_PATS=['b']
243 HG_PATS=['b']
244 HG_RESULT=0
244 HG_RESULT=0
245
245
246
246
247 $ cd ../b
247 $ cd ../b
248 $ hg pull ../a
248 $ hg pull ../a
249 pulling from ../a
249 pulling from ../a
250 searching for changes
250 searching for changes
251 prechangegroup hook: HG_HOOKNAME=prechangegroup
251 prechangegroup hook: HG_HOOKNAME=prechangegroup
252 HG_HOOKTYPE=prechangegroup
252 HG_HOOKTYPE=prechangegroup
253 HG_SOURCE=pull
253 HG_SOURCE=pull
254 HG_TXNID=TXN:$ID$
254 HG_TXNID=TXN:$ID$
255 HG_TXNNAME=pull
255 HG_TXNNAME=pull
256 file:/*/$TESTTMP/a (glob)
256 file:/*/$TESTTMP/a (glob)
257 HG_URL=file:$TESTTMP/a
257 HG_URL=file:$TESTTMP/a
258
258
259 adding changesets
259 adding changesets
260 adding manifests
260 adding manifests
261 adding file changes
261 adding file changes
262 added 3 changesets with 2 changes to 2 files
262 added 3 changesets with 2 changes to 2 files
263 new changesets ab228980c14d:07f3376c1e65
263 new changesets ab228980c14d:07f3376c1e65
264 changegroup hook: HG_HOOKNAME=changegroup
264 changegroup hook: HG_HOOKNAME=changegroup
265 HG_HOOKTYPE=changegroup
265 HG_HOOKTYPE=changegroup
266 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
266 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
267 HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2
267 HG_NODE_LAST=07f3376c1e655977439df2a814e3cc14b27abac2
268 HG_SOURCE=pull
268 HG_SOURCE=pull
269 HG_TXNID=TXN:$ID$
269 HG_TXNID=TXN:$ID$
270 HG_TXNNAME=pull
270 HG_TXNNAME=pull
271 file:/*/$TESTTMP/a (glob)
271 file:/*/$TESTTMP/a (glob)
272 HG_URL=file:$TESTTMP/a
272 HG_URL=file:$TESTTMP/a
273
273
274 incoming hook: HG_HOOKNAME=incoming
274 incoming hook: HG_HOOKNAME=incoming
275 HG_HOOKTYPE=incoming
275 HG_HOOKTYPE=incoming
276 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
276 HG_NODE=ab228980c14deea8b9555d91c9581127383e40fd
277 HG_SOURCE=pull
277 HG_SOURCE=pull
278 HG_TXNID=TXN:$ID$
278 HG_TXNID=TXN:$ID$
279 HG_TXNNAME=pull
279 HG_TXNNAME=pull
280 file:/*/$TESTTMP/a (glob)
280 file:/*/$TESTTMP/a (glob)
281 HG_URL=file:$TESTTMP/a
281 HG_URL=file:$TESTTMP/a
282
282
283 incoming hook: HG_HOOKNAME=incoming
283 incoming hook: HG_HOOKNAME=incoming
284 HG_HOOKTYPE=incoming
284 HG_HOOKTYPE=incoming
285 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
285 HG_NODE=ee9deb46ab31e4cc3310f3cf0c3d668e4d8fffc2
286 HG_SOURCE=pull
286 HG_SOURCE=pull
287 HG_TXNID=TXN:$ID$
287 HG_TXNID=TXN:$ID$
288 HG_TXNNAME=pull
288 HG_TXNNAME=pull
289 file:/*/$TESTTMP/a (glob)
289 file:/*/$TESTTMP/a (glob)
290 HG_URL=file:$TESTTMP/a
290 HG_URL=file:$TESTTMP/a
291
291
292 incoming hook: HG_HOOKNAME=incoming
292 incoming hook: HG_HOOKNAME=incoming
293 HG_HOOKTYPE=incoming
293 HG_HOOKTYPE=incoming
294 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
294 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
295 HG_SOURCE=pull
295 HG_SOURCE=pull
296 HG_TXNID=TXN:$ID$
296 HG_TXNID=TXN:$ID$
297 HG_TXNNAME=pull
297 HG_TXNNAME=pull
298 file:/*/$TESTTMP/a (glob)
298 file:/*/$TESTTMP/a (glob)
299 HG_URL=file:$TESTTMP/a
299 HG_URL=file:$TESTTMP/a
300
300
301 (run 'hg update' to get a working copy)
301 (run 'hg update' to get a working copy)
302
302
303 tag hooks can see env vars
303 tag hooks can see env vars
304
304
305 $ cd ../a
305 $ cd ../a
306 $ cat >> .hg/hgrc <<EOF
306 $ cat >> .hg/hgrc <<EOF
307 > pretag = sh -c "printenv.py --line pretag"
307 > pretag = sh -c "printenv.py --line pretag"
308 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py --line tag"
308 > tag = sh -c "HG_PARENT1= HG_PARENT2= printenv.py --line tag"
309 > EOF
309 > EOF
310 $ hg tag -d '3 0' a
310 $ hg tag -d '3 0' a
311 pretag hook: HG_HOOKNAME=pretag
311 pretag hook: HG_HOOKNAME=pretag
312 HG_HOOKTYPE=pretag
312 HG_HOOKTYPE=pretag
313 HG_LOCAL=0
313 HG_LOCAL=0
314 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
314 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
315 HG_TAG=a
315 HG_TAG=a
316
316
317 precommit hook: HG_HOOKNAME=precommit
317 precommit hook: HG_HOOKNAME=precommit
318 HG_HOOKTYPE=precommit
318 HG_HOOKTYPE=precommit
319 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
319 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
320
320
321 pretxnopen hook: HG_HOOKNAME=pretxnopen
321 pretxnopen hook: HG_HOOKNAME=pretxnopen
322 HG_HOOKTYPE=pretxnopen
322 HG_HOOKTYPE=pretxnopen
323 HG_TXNID=TXN:$ID$
323 HG_TXNID=TXN:$ID$
324 HG_TXNNAME=commit
324 HG_TXNNAME=commit
325
325
326 pretxncommit hook: HG_HOOKNAME=pretxncommit
326 pretxncommit hook: HG_HOOKNAME=pretxncommit
327 HG_HOOKTYPE=pretxncommit
327 HG_HOOKTYPE=pretxncommit
328 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
328 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
329 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
329 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
330 HG_PENDING=$TESTTMP/a
330 HG_PENDING=$TESTTMP/a
331
331
332 4:539e4b31b6dc
332 4:539e4b31b6dc
333 pretxnclose hook: HG_HOOKNAME=pretxnclose
333 pretxnclose hook: HG_HOOKNAME=pretxnclose
334 HG_HOOKTYPE=pretxnclose
334 HG_HOOKTYPE=pretxnclose
335 HG_PENDING=$TESTTMP/a
335 HG_PENDING=$TESTTMP/a
336 HG_TXNID=TXN:$ID$
336 HG_TXNID=TXN:$ID$
337 HG_TXNNAME=commit
337 HG_TXNNAME=commit
338
338
339 tag hook: HG_HOOKNAME=tag
339 tag hook: HG_HOOKNAME=tag
340 HG_HOOKTYPE=tag
340 HG_HOOKTYPE=tag
341 HG_LOCAL=0
341 HG_LOCAL=0
342 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
342 HG_NODE=07f3376c1e655977439df2a814e3cc14b27abac2
343 HG_TAG=a
343 HG_TAG=a
344
344
345 txnclose hook: HG_HOOKNAME=txnclose
345 txnclose hook: HG_HOOKNAME=txnclose
346 HG_HOOKTYPE=txnclose
346 HG_HOOKTYPE=txnclose
347 HG_TXNID=TXN:$ID$
347 HG_TXNID=TXN:$ID$
348 HG_TXNNAME=commit
348 HG_TXNNAME=commit
349
349
350 commit hook: HG_HOOKNAME=commit
350 commit hook: HG_HOOKNAME=commit
351 HG_HOOKTYPE=commit
351 HG_HOOKTYPE=commit
352 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
352 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
353 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
353 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
354
354
355 commit.b hook: HG_HOOKNAME=commit.b
355 commit.b hook: HG_HOOKNAME=commit.b
356 HG_HOOKTYPE=commit
356 HG_HOOKTYPE=commit
357 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
357 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
358 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
358 HG_PARENT1=07f3376c1e655977439df2a814e3cc14b27abac2
359
359
360 $ hg tag -l la
360 $ hg tag -l la
361 pretag hook: HG_HOOKNAME=pretag
361 pretag hook: HG_HOOKNAME=pretag
362 HG_HOOKTYPE=pretag
362 HG_HOOKTYPE=pretag
363 HG_LOCAL=1
363 HG_LOCAL=1
364 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
364 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
365 HG_TAG=la
365 HG_TAG=la
366
366
367 tag hook: HG_HOOKNAME=tag
367 tag hook: HG_HOOKNAME=tag
368 HG_HOOKTYPE=tag
368 HG_HOOKTYPE=tag
369 HG_LOCAL=1
369 HG_LOCAL=1
370 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
370 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
371 HG_TAG=la
371 HG_TAG=la
372
372
373
373
374 pretag hook can forbid tagging
374 pretag hook can forbid tagging
375
375
376 $ cat >> .hg/hgrc <<EOF
376 $ cat >> .hg/hgrc <<EOF
377 > pretag.forbid = sh -c "printenv.py --line pretag.forbid 1"
377 > pretag.forbid = sh -c "printenv.py --line pretag.forbid 1"
378 > EOF
378 > EOF
379 $ hg tag -d '4 0' fa
379 $ hg tag -d '4 0' fa
380 pretag hook: HG_HOOKNAME=pretag
380 pretag hook: HG_HOOKNAME=pretag
381 HG_HOOKTYPE=pretag
381 HG_HOOKTYPE=pretag
382 HG_LOCAL=0
382 HG_LOCAL=0
383 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
383 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
384 HG_TAG=fa
384 HG_TAG=fa
385
385
386 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
386 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
387 HG_HOOKTYPE=pretag
387 HG_HOOKTYPE=pretag
388 HG_LOCAL=0
388 HG_LOCAL=0
389 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
389 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
390 HG_TAG=fa
390 HG_TAG=fa
391
391
392 abort: pretag.forbid hook exited with status 1
392 abort: pretag.forbid hook exited with status 1
393 [255]
393 [255]
394 $ hg tag -l fla
394 $ hg tag -l fla
395 pretag hook: HG_HOOKNAME=pretag
395 pretag hook: HG_HOOKNAME=pretag
396 HG_HOOKTYPE=pretag
396 HG_HOOKTYPE=pretag
397 HG_LOCAL=1
397 HG_LOCAL=1
398 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
398 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
399 HG_TAG=fla
399 HG_TAG=fla
400
400
401 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
401 pretag.forbid hook: HG_HOOKNAME=pretag.forbid
402 HG_HOOKTYPE=pretag
402 HG_HOOKTYPE=pretag
403 HG_LOCAL=1
403 HG_LOCAL=1
404 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
404 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
405 HG_TAG=fla
405 HG_TAG=fla
406
406
407 abort: pretag.forbid hook exited with status 1
407 abort: pretag.forbid hook exited with status 1
408 [255]
408 [255]
409
409
410 pretxncommit hook can see changeset, can roll back txn, changeset no
410 pretxncommit hook can see changeset, can roll back txn, changeset no
411 more there after
411 more there after
412
412
413 $ cat >> .hg/hgrc <<EOF
413 $ cat >> .hg/hgrc <<EOF
414 > pretxncommit.forbid0 = sh -c "hg tip -q"
414 > pretxncommit.forbid0 = sh -c "hg tip -q"
415 > pretxncommit.forbid1 = sh -c "printenv.py --line pretxncommit.forbid 1"
415 > pretxncommit.forbid1 = sh -c "printenv.py --line pretxncommit.forbid 1"
416 > EOF
416 > EOF
417 $ echo z > z
417 $ echo z > z
418 $ hg add z
418 $ hg add z
419 $ hg -q tip
419 $ hg -q tip
420 4:539e4b31b6dc
420 4:539e4b31b6dc
421 $ hg commit -m 'fail' -d '4 0'
421 $ hg commit -m 'fail' -d '4 0'
422 precommit hook: HG_HOOKNAME=precommit
422 precommit hook: HG_HOOKNAME=precommit
423 HG_HOOKTYPE=precommit
423 HG_HOOKTYPE=precommit
424 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
424 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
425
425
426 pretxnopen hook: HG_HOOKNAME=pretxnopen
426 pretxnopen hook: HG_HOOKNAME=pretxnopen
427 HG_HOOKTYPE=pretxnopen
427 HG_HOOKTYPE=pretxnopen
428 HG_TXNID=TXN:$ID$
428 HG_TXNID=TXN:$ID$
429 HG_TXNNAME=commit
429 HG_TXNNAME=commit
430
430
431 pretxncommit hook: HG_HOOKNAME=pretxncommit
431 pretxncommit hook: HG_HOOKNAME=pretxncommit
432 HG_HOOKTYPE=pretxncommit
432 HG_HOOKTYPE=pretxncommit
433 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
433 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
434 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
434 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
435 HG_PENDING=$TESTTMP/a
435 HG_PENDING=$TESTTMP/a
436
436
437 5:6f611f8018c1
437 5:6f611f8018c1
438 5:6f611f8018c1
438 5:6f611f8018c1
439 pretxncommit.forbid hook: HG_HOOKNAME=pretxncommit.forbid1
439 pretxncommit.forbid hook: HG_HOOKNAME=pretxncommit.forbid1
440 HG_HOOKTYPE=pretxncommit
440 HG_HOOKTYPE=pretxncommit
441 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
441 HG_NODE=6f611f8018c10e827fee6bd2bc807f937e761567
442 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
442 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
443 HG_PENDING=$TESTTMP/a
443 HG_PENDING=$TESTTMP/a
444
444
445 transaction abort!
445 transaction abort!
446 txnabort Python hook: txnid,txnname
446 txnabort Python hook: txnid,txnname
447 txnabort hook: HG_HOOKNAME=txnabort.1
447 txnabort hook: HG_HOOKNAME=txnabort.1
448 HG_HOOKTYPE=txnabort
448 HG_HOOKTYPE=txnabort
449 HG_TXNID=TXN:$ID$
449 HG_TXNID=TXN:$ID$
450 HG_TXNNAME=commit
450 HG_TXNNAME=commit
451
451
452 rollback completed
452 rollback completed
453 abort: pretxncommit.forbid1 hook exited with status 1
453 abort: pretxncommit.forbid1 hook exited with status 1
454 [255]
454 [255]
455 $ hg -q tip
455 $ hg -q tip
456 4:539e4b31b6dc
456 4:539e4b31b6dc
457
457
458 (Check that no 'changelog.i.a' file were left behind)
458 (Check that no 'changelog.i.a' file were left behind)
459
459
460 $ ls -1 .hg/store/
460 $ ls -1 .hg/store/
461 00changelog.i
461 00changelog.i
462 00manifest.i
462 00manifest.i
463 data
463 data
464 fncache (repofncache !)
464 fncache (repofncache !)
465 journal.phaseroots
465 journal.phaseroots
466 phaseroots
466 phaseroots
467 undo
467 undo
468 undo.backup.fncache (repofncache !)
468 undo.backup.fncache (repofncache !)
469 undo.backupfiles
469 undo.backupfiles
470 undo.phaseroots
470 undo.phaseroots
471
471
472
472
473 precommit hook can prevent commit
473 precommit hook can prevent commit
474
474
475 $ cat >> .hg/hgrc <<EOF
475 $ cat >> .hg/hgrc <<EOF
476 > precommit.forbid = sh -c "printenv.py --line precommit.forbid 1"
476 > precommit.forbid = sh -c "printenv.py --line precommit.forbid 1"
477 > EOF
477 > EOF
478 $ hg commit -m 'fail' -d '4 0'
478 $ hg commit -m 'fail' -d '4 0'
479 precommit hook: HG_HOOKNAME=precommit
479 precommit hook: HG_HOOKNAME=precommit
480 HG_HOOKTYPE=precommit
480 HG_HOOKTYPE=precommit
481 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
481 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
482
482
483 precommit.forbid hook: HG_HOOKNAME=precommit.forbid
483 precommit.forbid hook: HG_HOOKNAME=precommit.forbid
484 HG_HOOKTYPE=precommit
484 HG_HOOKTYPE=precommit
485 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
485 HG_PARENT1=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
486
486
487 abort: precommit.forbid hook exited with status 1
487 abort: precommit.forbid hook exited with status 1
488 [255]
488 [255]
489 $ hg -q tip
489 $ hg -q tip
490 4:539e4b31b6dc
490 4:539e4b31b6dc
491
491
492 preupdate hook can prevent update
492 preupdate hook can prevent update
493
493
494 $ cat >> .hg/hgrc <<EOF
494 $ cat >> .hg/hgrc <<EOF
495 > preupdate = sh -c "printenv.py --line preupdate"
495 > preupdate = sh -c "printenv.py --line preupdate"
496 > EOF
496 > EOF
497 $ hg update 1
497 $ hg update 1
498 preupdate hook: HG_HOOKNAME=preupdate
498 preupdate hook: HG_HOOKNAME=preupdate
499 HG_HOOKTYPE=preupdate
499 HG_HOOKTYPE=preupdate
500 HG_PARENT1=ab228980c14d
500 HG_PARENT1=ab228980c14d
501
501
502 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
502 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
503
503
504 update hook
504 update hook
505
505
506 $ cat >> .hg/hgrc <<EOF
506 $ cat >> .hg/hgrc <<EOF
507 > update = sh -c "printenv.py --line update"
507 > update = sh -c "printenv.py --line update"
508 > EOF
508 > EOF
509 $ hg update
509 $ hg update
510 preupdate hook: HG_HOOKNAME=preupdate
510 preupdate hook: HG_HOOKNAME=preupdate
511 HG_HOOKTYPE=preupdate
511 HG_HOOKTYPE=preupdate
512 HG_PARENT1=539e4b31b6dc
512 HG_PARENT1=539e4b31b6dc
513
513
514 update hook: HG_ERROR=0
514 update hook: HG_ERROR=0
515 HG_HOOKNAME=update
515 HG_HOOKNAME=update
516 HG_HOOKTYPE=update
516 HG_HOOKTYPE=update
517 HG_PARENT1=539e4b31b6dc
517 HG_PARENT1=539e4b31b6dc
518
518
519 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
519 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
520
520
521 pushkey hook
521 pushkey hook
522
522
523 $ cat >> .hg/hgrc <<EOF
523 $ cat >> .hg/hgrc <<EOF
524 > pushkey = sh -c "printenv.py --line pushkey"
524 > pushkey = sh -c "printenv.py --line pushkey"
525 > EOF
525 > EOF
526 $ cd ../b
526 $ cd ../b
527 $ hg bookmark -r null foo
527 $ hg bookmark -r null foo
528 $ hg push -B foo ../a
528 $ hg push -B foo ../a
529 pushing to ../a
529 pushing to ../a
530 searching for changes
530 searching for changes
531 no changes found
531 no changes found
532 pretxnopen hook: HG_HOOKNAME=pretxnopen
532 pretxnopen hook: HG_HOOKNAME=pretxnopen
533 HG_HOOKTYPE=pretxnopen
533 HG_HOOKTYPE=pretxnopen
534 HG_TXNID=TXN:$ID$
534 HG_TXNID=TXN:$ID$
535 HG_TXNNAME=push
535 HG_TXNNAME=push
536
536
537 pretxnclose hook: HG_BOOKMARK_MOVED=1
537 pretxnclose hook: HG_BOOKMARK_MOVED=1
538 HG_BUNDLE2=1
538 HG_BUNDLE2=1
539 HG_HOOKNAME=pretxnclose
539 HG_HOOKNAME=pretxnclose
540 HG_HOOKTYPE=pretxnclose
540 HG_HOOKTYPE=pretxnclose
541 HG_PENDING=$TESTTMP/a
541 HG_PENDING=$TESTTMP/a
542 HG_SOURCE=push
542 HG_SOURCE=push
543 HG_TXNID=TXN:$ID$
543 HG_TXNID=TXN:$ID$
544 HG_TXNNAME=push
544 HG_TXNNAME=push
545 HG_URL=file:$TESTTMP/a
545 HG_URL=file:$TESTTMP/a
546
546
547 pushkey hook: HG_BUNDLE2=1
547 pushkey hook: HG_BUNDLE2=1
548 HG_HOOKNAME=pushkey
548 HG_HOOKNAME=pushkey
549 HG_HOOKTYPE=pushkey
549 HG_HOOKTYPE=pushkey
550 HG_KEY=foo
550 HG_KEY=foo
551 HG_NAMESPACE=bookmarks
551 HG_NAMESPACE=bookmarks
552 HG_NEW=0000000000000000000000000000000000000000
552 HG_NEW=0000000000000000000000000000000000000000
553 HG_PUSHKEYCOMPAT=1
553 HG_PUSHKEYCOMPAT=1
554 HG_SOURCE=push
554 HG_SOURCE=push
555 HG_TXNID=TXN:$ID$
555 HG_TXNID=TXN:$ID$
556 HG_TXNNAME=push
556 HG_TXNNAME=push
557 HG_URL=file:$TESTTMP/a
557 HG_URL=file:$TESTTMP/a
558
558
559 txnclose hook: HG_BOOKMARK_MOVED=1
559 txnclose hook: HG_BOOKMARK_MOVED=1
560 HG_BUNDLE2=1
560 HG_BUNDLE2=1
561 HG_HOOKNAME=txnclose
561 HG_HOOKNAME=txnclose
562 HG_HOOKTYPE=txnclose
562 HG_HOOKTYPE=txnclose
563 HG_SOURCE=push
563 HG_SOURCE=push
564 HG_TXNID=TXN:$ID$
564 HG_TXNID=TXN:$ID$
565 HG_TXNNAME=push
565 HG_TXNNAME=push
566 HG_URL=file:$TESTTMP/a
566 HG_URL=file:$TESTTMP/a
567
567
568 exporting bookmark foo
568 exporting bookmark foo
569 [1]
569 [1]
570 $ cd ../a
570 $ cd ../a
571
571
572 listkeys hook
572 listkeys hook
573
573
574 $ cat >> .hg/hgrc <<EOF
574 $ cat >> .hg/hgrc <<EOF
575 > listkeys = sh -c "printenv.py --line listkeys"
575 > listkeys = sh -c "printenv.py --line listkeys"
576 > EOF
576 > EOF
577 $ hg bookmark -r null bar
577 $ hg bookmark -r null bar
578 pretxnopen hook: HG_HOOKNAME=pretxnopen
578 pretxnopen hook: HG_HOOKNAME=pretxnopen
579 HG_HOOKTYPE=pretxnopen
579 HG_HOOKTYPE=pretxnopen
580 HG_TXNID=TXN:$ID$
580 HG_TXNID=TXN:$ID$
581 HG_TXNNAME=bookmark
581 HG_TXNNAME=bookmark
582
582
583 pretxnclose hook: HG_BOOKMARK_MOVED=1
583 pretxnclose hook: HG_BOOKMARK_MOVED=1
584 HG_HOOKNAME=pretxnclose
584 HG_HOOKNAME=pretxnclose
585 HG_HOOKTYPE=pretxnclose
585 HG_HOOKTYPE=pretxnclose
586 HG_PENDING=$TESTTMP/a
586 HG_PENDING=$TESTTMP/a
587 HG_TXNID=TXN:$ID$
587 HG_TXNID=TXN:$ID$
588 HG_TXNNAME=bookmark
588 HG_TXNNAME=bookmark
589
589
590 txnclose hook: HG_BOOKMARK_MOVED=1
590 txnclose hook: HG_BOOKMARK_MOVED=1
591 HG_HOOKNAME=txnclose
591 HG_HOOKNAME=txnclose
592 HG_HOOKTYPE=txnclose
592 HG_HOOKTYPE=txnclose
593 HG_TXNID=TXN:$ID$
593 HG_TXNID=TXN:$ID$
594 HG_TXNNAME=bookmark
594 HG_TXNNAME=bookmark
595
595
596 $ cd ../b
596 $ cd ../b
597 $ hg pull -B bar ../a
597 $ hg pull -B bar ../a
598 pulling from ../a
598 pulling from ../a
599 listkeys hook: HG_HOOKNAME=listkeys
599 listkeys hook: HG_HOOKNAME=listkeys
600 HG_HOOKTYPE=listkeys
600 HG_HOOKTYPE=listkeys
601 HG_NAMESPACE=bookmarks
601 HG_NAMESPACE=bookmarks
602 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
602 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
603
603
604 no changes found
604 no changes found
605 adding remote bookmark bar
605 adding remote bookmark bar
606 $ cd ../a
606 $ cd ../a
607
607
608 test that prepushkey can prevent incoming keys
608 test that prepushkey can prevent incoming keys
609
609
610 $ cat >> .hg/hgrc <<EOF
610 $ cat >> .hg/hgrc <<EOF
611 > prepushkey = sh -c "printenv.py --line prepushkey.forbid 1"
611 > prepushkey = sh -c "printenv.py --line prepushkey.forbid 1"
612 > EOF
612 > EOF
613 $ cd ../b
613 $ cd ../b
614 $ hg bookmark -r null baz
614 $ hg bookmark -r null baz
615 $ hg push -B baz ../a
615 $ hg push -B baz ../a
616 pushing to ../a
616 pushing to ../a
617 searching for changes
617 searching for changes
618 listkeys hook: HG_HOOKNAME=listkeys
618 listkeys hook: HG_HOOKNAME=listkeys
619 HG_HOOKTYPE=listkeys
619 HG_HOOKTYPE=listkeys
620 HG_NAMESPACE=phases
620 HG_NAMESPACE=phases
621 HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
621 HG_VALUES={'cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b': '1', 'publishing': 'True'}
622
622
623 listkeys hook: HG_HOOKNAME=listkeys
623 listkeys hook: HG_HOOKNAME=listkeys
624 HG_HOOKTYPE=listkeys
624 HG_HOOKTYPE=listkeys
625 HG_NAMESPACE=bookmarks
625 HG_NAMESPACE=bookmarks
626 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
626 HG_VALUES={'bar': '0000000000000000000000000000000000000000', 'foo': '0000000000000000000000000000000000000000'}
627
627
628 no changes found
628 no changes found
629 pretxnopen hook: HG_HOOKNAME=pretxnopen
629 pretxnopen hook: HG_HOOKNAME=pretxnopen
630 HG_HOOKTYPE=pretxnopen
630 HG_HOOKTYPE=pretxnopen
631 HG_TXNID=TXN:$ID$
631 HG_TXNID=TXN:$ID$
632 HG_TXNNAME=push
632 HG_TXNNAME=push
633
633
634 prepushkey.forbid hook: HG_BUNDLE2=1
634 prepushkey.forbid hook: HG_BUNDLE2=1
635 HG_HOOKNAME=prepushkey
635 HG_HOOKNAME=prepushkey
636 HG_HOOKTYPE=prepushkey
636 HG_HOOKTYPE=prepushkey
637 HG_KEY=baz
637 HG_KEY=baz
638 HG_NAMESPACE=bookmarks
638 HG_NAMESPACE=bookmarks
639 HG_NEW=0000000000000000000000000000000000000000
639 HG_NEW=0000000000000000000000000000000000000000
640 HG_PUSHKEYCOMPAT=1
640 HG_PUSHKEYCOMPAT=1
641 HG_SOURCE=push
641 HG_SOURCE=push
642 HG_TXNID=TXN:$ID$
642 HG_TXNID=TXN:$ID$
643 HG_TXNNAME=push
643 HG_TXNNAME=push
644 HG_URL=file:$TESTTMP/a
644 HG_URL=file:$TESTTMP/a
645
645
646 abort: prepushkey hook exited with status 1
646 abort: prepushkey hook exited with status 1
647 [255]
647 [255]
648 $ cd ../a
648 $ cd ../a
649
649
650 test that prelistkeys can prevent listing keys
650 test that prelistkeys can prevent listing keys
651
651
652 $ cat >> .hg/hgrc <<EOF
652 $ cat >> .hg/hgrc <<EOF
653 > prelistkeys = sh -c "printenv.py --line prelistkeys.forbid 1"
653 > prelistkeys = sh -c "printenv.py --line prelistkeys.forbid 1"
654 > EOF
654 > EOF
655 $ hg bookmark -r null quux
655 $ hg bookmark -r null quux
656 pretxnopen hook: HG_HOOKNAME=pretxnopen
656 pretxnopen hook: HG_HOOKNAME=pretxnopen
657 HG_HOOKTYPE=pretxnopen
657 HG_HOOKTYPE=pretxnopen
658 HG_TXNID=TXN:$ID$
658 HG_TXNID=TXN:$ID$
659 HG_TXNNAME=bookmark
659 HG_TXNNAME=bookmark
660
660
661 pretxnclose hook: HG_BOOKMARK_MOVED=1
661 pretxnclose hook: HG_BOOKMARK_MOVED=1
662 HG_HOOKNAME=pretxnclose
662 HG_HOOKNAME=pretxnclose
663 HG_HOOKTYPE=pretxnclose
663 HG_HOOKTYPE=pretxnclose
664 HG_PENDING=$TESTTMP/a
664 HG_PENDING=$TESTTMP/a
665 HG_TXNID=TXN:$ID$
665 HG_TXNID=TXN:$ID$
666 HG_TXNNAME=bookmark
666 HG_TXNNAME=bookmark
667
667
668 txnclose hook: HG_BOOKMARK_MOVED=1
668 txnclose hook: HG_BOOKMARK_MOVED=1
669 HG_HOOKNAME=txnclose
669 HG_HOOKNAME=txnclose
670 HG_HOOKTYPE=txnclose
670 HG_HOOKTYPE=txnclose
671 HG_TXNID=TXN:$ID$
671 HG_TXNID=TXN:$ID$
672 HG_TXNNAME=bookmark
672 HG_TXNNAME=bookmark
673
673
674 $ cd ../b
674 $ cd ../b
675 $ hg pull -B quux ../a
675 $ hg pull -B quux ../a
676 pulling from ../a
676 pulling from ../a
677 prelistkeys.forbid hook: HG_HOOKNAME=prelistkeys
677 prelistkeys.forbid hook: HG_HOOKNAME=prelistkeys
678 HG_HOOKTYPE=prelistkeys
678 HG_HOOKTYPE=prelistkeys
679 HG_NAMESPACE=bookmarks
679 HG_NAMESPACE=bookmarks
680
680
681 abort: prelistkeys hook exited with status 1
681 abort: prelistkeys hook exited with status 1
682 [255]
682 [255]
683 $ cd ../a
683 $ cd ../a
684 $ rm .hg/hgrc
684 $ rm .hg/hgrc
685
685
686 prechangegroup hook can prevent incoming changes
686 prechangegroup hook can prevent incoming changes
687
687
688 $ cd ../b
688 $ cd ../b
689 $ hg -q tip
689 $ hg -q tip
690 3:07f3376c1e65
690 3:07f3376c1e65
691 $ cat > .hg/hgrc <<EOF
691 $ cat > .hg/hgrc <<EOF
692 > [hooks]
692 > [hooks]
693 > prechangegroup.forbid = sh -c "printenv.py --line prechangegroup.forbid 1"
693 > prechangegroup.forbid = sh -c "printenv.py --line prechangegroup.forbid 1"
694 > EOF
694 > EOF
695 $ hg pull ../a
695 $ hg pull ../a
696 pulling from ../a
696 pulling from ../a
697 searching for changes
697 searching for changes
698 prechangegroup.forbid hook: HG_HOOKNAME=prechangegroup.forbid
698 prechangegroup.forbid hook: HG_HOOKNAME=prechangegroup.forbid
699 HG_HOOKTYPE=prechangegroup
699 HG_HOOKTYPE=prechangegroup
700 HG_SOURCE=pull
700 HG_SOURCE=pull
701 HG_TXNID=TXN:$ID$
701 HG_TXNID=TXN:$ID$
702 HG_TXNNAME=pull
702 HG_TXNNAME=pull
703 file:/*/$TESTTMP/a (glob)
703 file:/*/$TESTTMP/a (glob)
704 HG_URL=file:$TESTTMP/a
704 HG_URL=file:$TESTTMP/a
705
705
706 abort: prechangegroup.forbid hook exited with status 1
706 abort: prechangegroup.forbid hook exited with status 1
707 [255]
707 [255]
708
708
709 pretxnchangegroup hook can see incoming changes, can roll back txn,
709 pretxnchangegroup hook can see incoming changes, can roll back txn,
710 incoming changes no longer there after
710 incoming changes no longer there after
711
711
712 $ cat > .hg/hgrc <<EOF
712 $ cat > .hg/hgrc <<EOF
713 > [hooks]
713 > [hooks]
714 > pretxnchangegroup.forbid0 = hg tip -q
714 > pretxnchangegroup.forbid0 = hg tip -q
715 > pretxnchangegroup.forbid1 = sh -c "printenv.py --line pretxnchangegroup.forbid 1"
715 > pretxnchangegroup.forbid1 = sh -c "printenv.py --line pretxnchangegroup.forbid 1"
716 > EOF
716 > EOF
717 $ hg pull ../a
717 $ hg pull ../a
718 pulling from ../a
718 pulling from ../a
719 searching for changes
719 searching for changes
720 adding changesets
720 adding changesets
721 adding manifests
721 adding manifests
722 adding file changes
722 adding file changes
723 4:539e4b31b6dc
723 4:539e4b31b6dc
724 pretxnchangegroup.forbid hook: HG_HOOKNAME=pretxnchangegroup.forbid1
724 pretxnchangegroup.forbid hook: HG_HOOKNAME=pretxnchangegroup.forbid1
725 HG_HOOKTYPE=pretxnchangegroup
725 HG_HOOKTYPE=pretxnchangegroup
726 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
726 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
727 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
727 HG_NODE_LAST=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
728 HG_PENDING=$TESTTMP/b
728 HG_PENDING=$TESTTMP/b
729 HG_SOURCE=pull
729 HG_SOURCE=pull
730 HG_TXNID=TXN:$ID$
730 HG_TXNID=TXN:$ID$
731 HG_TXNNAME=pull
731 HG_TXNNAME=pull
732 file:/*/$TESTTMP/a (glob)
732 file:/*/$TESTTMP/a (glob)
733 HG_URL=file:$TESTTMP/a
733 HG_URL=file:$TESTTMP/a
734
734
735 transaction abort!
735 transaction abort!
736 rollback completed
736 rollback completed
737 abort: pretxnchangegroup.forbid1 hook exited with status 1
737 abort: pretxnchangegroup.forbid1 hook exited with status 1
738 [255]
738 [255]
739 $ hg -q tip
739 $ hg -q tip
740 3:07f3376c1e65
740 3:07f3376c1e65
741
741
742 outgoing hooks can see env vars
742 outgoing hooks can see env vars
743
743
744 $ rm .hg/hgrc
744 $ rm .hg/hgrc
745 $ cat > ../a/.hg/hgrc <<EOF
745 $ cat > ../a/.hg/hgrc <<EOF
746 > [hooks]
746 > [hooks]
747 > preoutgoing = sh -c "printenv.py --line preoutgoing"
747 > preoutgoing = sh -c "printenv.py --line preoutgoing"
748 > outgoing = sh -c "printenv.py --line outgoing"
748 > outgoing = sh -c "printenv.py --line outgoing"
749 > EOF
749 > EOF
750 $ hg pull ../a
750 $ hg pull ../a
751 pulling from ../a
751 pulling from ../a
752 searching for changes
752 searching for changes
753 preoutgoing hook: HG_HOOKNAME=preoutgoing
753 preoutgoing hook: HG_HOOKNAME=preoutgoing
754 HG_HOOKTYPE=preoutgoing
754 HG_HOOKTYPE=preoutgoing
755 HG_SOURCE=pull
755 HG_SOURCE=pull
756
756
757 outgoing hook: HG_HOOKNAME=outgoing
757 outgoing hook: HG_HOOKNAME=outgoing
758 HG_HOOKTYPE=outgoing
758 HG_HOOKTYPE=outgoing
759 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
759 HG_NODE=539e4b31b6dc99b3cfbaa6b53cbc1c1f9a1e3a10
760 HG_SOURCE=pull
760 HG_SOURCE=pull
761
761
762 adding changesets
762 adding changesets
763 adding manifests
763 adding manifests
764 adding file changes
764 adding file changes
765 adding remote bookmark quux
765 adding remote bookmark quux
766 added 1 changesets with 1 changes to 1 files
766 added 1 changesets with 1 changes to 1 files
767 new changesets 539e4b31b6dc
767 new changesets 539e4b31b6dc
768 (run 'hg update' to get a working copy)
768 (run 'hg update' to get a working copy)
769 $ hg rollback
769 $ hg rollback
770 repository tip rolled back to revision 3 (undo pull)
770 repository tip rolled back to revision 3 (undo pull)
771
771
772 preoutgoing hook can prevent outgoing changes
772 preoutgoing hook can prevent outgoing changes
773
773
774 $ cat >> ../a/.hg/hgrc <<EOF
774 $ cat >> ../a/.hg/hgrc <<EOF
775 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
775 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
776 > EOF
776 > EOF
777 $ hg pull ../a
777 $ hg pull ../a
778 pulling from ../a
778 pulling from ../a
779 searching for changes
779 searching for changes
780 preoutgoing hook: HG_HOOKNAME=preoutgoing
780 preoutgoing hook: HG_HOOKNAME=preoutgoing
781 HG_HOOKTYPE=preoutgoing
781 HG_HOOKTYPE=preoutgoing
782 HG_SOURCE=pull
782 HG_SOURCE=pull
783
783
784 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
784 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
785 HG_HOOKTYPE=preoutgoing
785 HG_HOOKTYPE=preoutgoing
786 HG_SOURCE=pull
786 HG_SOURCE=pull
787
787
788 abort: preoutgoing.forbid hook exited with status 1
788 abort: preoutgoing.forbid hook exited with status 1
789 [255]
789 [255]
790
790
791 outgoing hooks work for local clones
791 outgoing hooks work for local clones
792
792
793 $ cd ..
793 $ cd ..
794 $ cat > a/.hg/hgrc <<EOF
794 $ cat > a/.hg/hgrc <<EOF
795 > [hooks]
795 > [hooks]
796 > preoutgoing = sh -c "printenv.py --line preoutgoing"
796 > preoutgoing = sh -c "printenv.py --line preoutgoing"
797 > outgoing = sh -c "printenv.py --line outgoing"
797 > outgoing = sh -c "printenv.py --line outgoing"
798 > EOF
798 > EOF
799 $ hg clone a c
799 $ hg clone a c
800 preoutgoing hook: HG_HOOKNAME=preoutgoing
800 preoutgoing hook: HG_HOOKNAME=preoutgoing
801 HG_HOOKTYPE=preoutgoing
801 HG_HOOKTYPE=preoutgoing
802 HG_SOURCE=clone
802 HG_SOURCE=clone
803
803
804 outgoing hook: HG_HOOKNAME=outgoing
804 outgoing hook: HG_HOOKNAME=outgoing
805 HG_HOOKTYPE=outgoing
805 HG_HOOKTYPE=outgoing
806 HG_NODE=0000000000000000000000000000000000000000
806 HG_NODE=0000000000000000000000000000000000000000
807 HG_SOURCE=clone
807 HG_SOURCE=clone
808
808
809 updating to branch default
809 updating to branch default
810 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
810 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
811 $ rm -rf c
811 $ rm -rf c
812
812
813 preoutgoing hook can prevent outgoing changes for local clones
813 preoutgoing hook can prevent outgoing changes for local clones
814
814
815 $ cat >> a/.hg/hgrc <<EOF
815 $ cat >> a/.hg/hgrc <<EOF
816 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
816 > preoutgoing.forbid = sh -c "printenv.py --line preoutgoing.forbid 1"
817 > EOF
817 > EOF
818 $ hg clone a zzz
818 $ hg clone a zzz
819 preoutgoing hook: HG_HOOKNAME=preoutgoing
819 preoutgoing hook: HG_HOOKNAME=preoutgoing
820 HG_HOOKTYPE=preoutgoing
820 HG_HOOKTYPE=preoutgoing
821 HG_SOURCE=clone
821 HG_SOURCE=clone
822
822
823 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
823 preoutgoing.forbid hook: HG_HOOKNAME=preoutgoing.forbid
824 HG_HOOKTYPE=preoutgoing
824 HG_HOOKTYPE=preoutgoing
825 HG_SOURCE=clone
825 HG_SOURCE=clone
826
826
827 abort: preoutgoing.forbid hook exited with status 1
827 abort: preoutgoing.forbid hook exited with status 1
828 [255]
828 [255]
829
829
830 $ cd "$TESTTMP/b"
830 $ cd "$TESTTMP/b"
831
831
832 $ cat > hooktests.py <<EOF
832 $ cat > hooktests.py <<EOF
833 > from __future__ import print_function
833 > from __future__ import print_function
834 > from mercurial import (
834 > from mercurial import (
835 > error,
835 > error,
836 > pycompat,
836 > pycompat,
837 > )
837 > )
838 >
838 >
839 > uncallable = 0
839 > uncallable = 0
840 >
840 >
841 > def printargs(ui, args):
841 > def printargs(ui, args):
842 > a = list(pycompat.byteskwargs(args).items())
842 > a = list(pycompat.byteskwargs(args).items())
843 > a.sort()
843 > a.sort()
844 > ui.write(b'hook args:\n')
844 > ui.write(b'hook args:\n')
845 > for k, v in a:
845 > for k, v in a:
846 > ui.write(b' %s %s\n' % (k, v))
846 > ui.write(b' %s %s\n' % (k, v))
847 >
847 >
848 > def passhook(ui, repo, **args):
848 > def passhook(ui, repo, **args):
849 > printargs(ui, args)
849 > printargs(ui, args)
850 >
850 >
851 > def failhook(ui, repo, **args):
851 > def failhook(ui, repo, **args):
852 > printargs(ui, args)
852 > printargs(ui, args)
853 > return True
853 > return True
854 >
854 >
855 > class LocalException(Exception):
855 > class LocalException(Exception):
856 > pass
856 > pass
857 >
857 >
858 > def raisehook(**args):
858 > def raisehook(**args):
859 > raise LocalException('exception from hook')
859 > raise LocalException('exception from hook')
860 >
860 >
861 > def aborthook(**args):
861 > def aborthook(**args):
862 > raise error.Abort(b'raise abort from hook')
862 > raise error.Abort(b'raise abort from hook')
863 >
863 >
864 > def brokenhook(**args):
864 > def brokenhook(**args):
865 > return 1 + {}
865 > return 1 + {}
866 >
866 >
867 > def verbosehook(ui, **args):
867 > def verbosehook(ui, **args):
868 > ui.note(b'verbose output from hook\n')
868 > ui.note(b'verbose output from hook\n')
869 >
869 >
870 > def printtags(ui, repo, **args):
870 > def printtags(ui, repo, **args):
871 > ui.write(b'[%s]\n' % b', '.join(sorted(repo.tags())))
871 > ui.write(b'[%s]\n' % b', '.join(sorted(repo.tags())))
872 >
872 >
873 > class container(object):
873 > class container(object):
874 > unreachable = 1
874 > unreachable = 1
875 > EOF
875 > EOF
876
876
877 $ cat > syntaxerror.py << NO_CHECK_EOF
877 $ cat > syntaxerror.py << NO_CHECK_EOF
878 > (foo
878 > (foo
879 > NO_CHECK_EOF
879 > NO_CHECK_EOF
880
880
881 test python hooks
881 test python hooks
882
882
883 #if windows
883 #if windows
884 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
884 $ PYTHONPATH="$TESTTMP/b;$PYTHONPATH"
885 #else
885 #else
886 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
886 $ PYTHONPATH="$TESTTMP/b:$PYTHONPATH"
887 #endif
887 #endif
888 $ export PYTHONPATH
888 $ export PYTHONPATH
889
889
890 $ echo '[hooks]' > ../a/.hg/hgrc
890 $ echo '[hooks]' > ../a/.hg/hgrc
891 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
891 $ echo 'preoutgoing.broken = python:hooktests.brokenhook' >> ../a/.hg/hgrc
892 $ hg pull ../a 2>&1 | grep 'raised an exception'
892 $ hg pull ../a 2>&1 | grep 'raised an exception'
893 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
893 error: preoutgoing.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
894
894
895 $ echo '[hooks]' > ../a/.hg/hgrc
895 $ echo '[hooks]' > ../a/.hg/hgrc
896 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
896 $ echo 'preoutgoing.raise = python:hooktests.raisehook' >> ../a/.hg/hgrc
897 $ hg pull ../a 2>&1 | grep 'raised an exception'
897 $ hg pull ../a 2>&1 | grep 'raised an exception'
898 error: preoutgoing.raise hook raised an exception: exception from hook
898 error: preoutgoing.raise hook raised an exception: exception from hook
899
899
900 $ echo '[hooks]' > ../a/.hg/hgrc
900 $ echo '[hooks]' > ../a/.hg/hgrc
901 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
901 $ echo 'preoutgoing.abort = python:hooktests.aborthook' >> ../a/.hg/hgrc
902 $ hg pull ../a
902 $ hg pull ../a
903 pulling from ../a
903 pulling from ../a
904 searching for changes
904 searching for changes
905 error: preoutgoing.abort hook failed: raise abort from hook
905 error: preoutgoing.abort hook failed: raise abort from hook
906 abort: raise abort from hook
906 abort: raise abort from hook
907 [255]
907 [255]
908
908
909 $ echo '[hooks]' > ../a/.hg/hgrc
909 $ echo '[hooks]' > ../a/.hg/hgrc
910 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
910 $ echo 'preoutgoing.fail = python:hooktests.failhook' >> ../a/.hg/hgrc
911 $ hg pull ../a
911 $ hg pull ../a
912 pulling from ../a
912 pulling from ../a
913 searching for changes
913 searching for changes
914 hook args:
914 hook args:
915 hooktype preoutgoing
915 hooktype preoutgoing
916 source pull
916 source pull
917 abort: preoutgoing.fail hook failed
917 abort: preoutgoing.fail hook failed
918 [255]
918 [255]
919
919
920 $ echo '[hooks]' > ../a/.hg/hgrc
920 $ echo '[hooks]' > ../a/.hg/hgrc
921 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
921 $ echo 'preoutgoing.uncallable = python:hooktests.uncallable' >> ../a/.hg/hgrc
922 $ hg pull ../a
922 $ hg pull ../a
923 pulling from ../a
923 pulling from ../a
924 searching for changes
924 searching for changes
925 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
925 abort: preoutgoing.uncallable hook is invalid: "hooktests.uncallable" is not callable
926 [255]
926 [255]
927
927
928 $ echo '[hooks]' > ../a/.hg/hgrc
928 $ echo '[hooks]' > ../a/.hg/hgrc
929 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
929 $ echo 'preoutgoing.nohook = python:hooktests.nohook' >> ../a/.hg/hgrc
930 $ hg pull ../a
930 $ hg pull ../a
931 pulling from ../a
931 pulling from ../a
932 searching for changes
932 searching for changes
933 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
933 abort: preoutgoing.nohook hook is invalid: "hooktests.nohook" is not defined
934 [255]
934 [255]
935
935
936 $ echo '[hooks]' > ../a/.hg/hgrc
936 $ echo '[hooks]' > ../a/.hg/hgrc
937 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
937 $ echo 'preoutgoing.nomodule = python:nomodule' >> ../a/.hg/hgrc
938 $ hg pull ../a
938 $ hg pull ../a
939 pulling from ../a
939 pulling from ../a
940 searching for changes
940 searching for changes
941 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
941 abort: preoutgoing.nomodule hook is invalid: "nomodule" not in a module
942 [255]
942 [255]
943
943
944 $ echo '[hooks]' > ../a/.hg/hgrc
944 $ echo '[hooks]' > ../a/.hg/hgrc
945 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
945 $ echo 'preoutgoing.badmodule = python:nomodule.nowhere' >> ../a/.hg/hgrc
946 $ hg pull ../a
946 $ hg pull ../a
947 pulling from ../a
947 pulling from ../a
948 searching for changes
948 searching for changes
949 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
949 abort: preoutgoing.badmodule hook is invalid: import of "nomodule" failed
950 (run with --traceback for stack trace)
950 (run with --traceback for stack trace)
951 [255]
951 [255]
952
952
953 $ echo '[hooks]' > ../a/.hg/hgrc
953 $ echo '[hooks]' > ../a/.hg/hgrc
954 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
954 $ echo 'preoutgoing.unreachable = python:hooktests.container.unreachable' >> ../a/.hg/hgrc
955 $ hg pull ../a
955 $ hg pull ../a
956 pulling from ../a
956 pulling from ../a
957 searching for changes
957 searching for changes
958 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
958 abort: preoutgoing.unreachable hook is invalid: import of "hooktests.container" failed
959 (run with --traceback for stack trace)
959 (run with --traceback for stack trace)
960 [255]
960 [255]
961
961
962 $ echo '[hooks]' > ../a/.hg/hgrc
962 $ echo '[hooks]' > ../a/.hg/hgrc
963 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
963 $ echo 'preoutgoing.syntaxerror = python:syntaxerror.syntaxerror' >> ../a/.hg/hgrc
964 $ hg pull ../a
964 $ hg pull ../a
965 pulling from ../a
965 pulling from ../a
966 searching for changes
966 searching for changes
967 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
967 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
968 (run with --traceback for stack trace)
968 (run with --traceback for stack trace)
969 [255]
969 [255]
970
970
971 $ hg pull ../a --traceback 2>&1 | egrep 'pulling|searching|^exception|Traceback|SyntaxError|ImportError|ModuleNotFoundError|HookLoadError|abort'
971 $ hg pull ../a --traceback 2>&1 | egrep 'pulling|searching|^exception|Traceback|SyntaxError|ImportError|ModuleNotFoundError|HookLoadError|abort'
972 pulling from ../a
972 pulling from ../a
973 searching for changes
973 searching for changes
974 exception from first failed import attempt:
974 exception from first failed import attempt:
975 Traceback (most recent call last):
975 Traceback (most recent call last):
976 SyntaxError: * (glob)
976 SyntaxError: * (glob)
977 exception from second failed import attempt:
977 exception from second failed import attempt:
978 Traceback (most recent call last): (py3 !)
978 Traceback (most recent call last): (py3 !)
979 SyntaxError: * (glob) (py3 !)
979 SyntaxError: * (glob) (py3 !)
980 Traceback (most recent call last):
980 Traceback (most recent call last):
981 ImportError: No module named hgext_syntaxerror (no-py3 !)
981 ImportError: No module named hgext_syntaxerror (no-py3 !)
982 ImportError: No module named 'hgext_syntaxerror' (py3 no-py36 !)
982 ImportError: No module named 'hgext_syntaxerror' (py3 no-py36 !)
983 ModuleNotFoundError: No module named 'hgext_syntaxerror' (py36 !)
983 ModuleNotFoundError: No module named 'hgext_syntaxerror' (py36 !)
984 Traceback (most recent call last):
984 Traceback (most recent call last):
985 SyntaxError: * (glob) (py3 !)
985 SyntaxError: * (glob) (py3 !)
986 Traceback (most recent call last): (py3 !)
986 Traceback (most recent call last): (py3 !)
987 ImportError: No module named 'hgext_syntaxerror' (py3 no-py36 !)
987 ImportError: No module named 'hgext_syntaxerror' (py3 no-py36 !)
988 ModuleNotFoundError: No module named 'hgext_syntaxerror' (py36 !)
988 ModuleNotFoundError: No module named 'hgext_syntaxerror' (py36 !)
989 Traceback (most recent call last): (py3 !)
989 Traceback (most recent call last): (py3 !)
990 HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed (no-py3 !)
990 HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed (no-py3 !)
991 mercurial.error.HookLoadError: b'preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed' (py3 !)
991 mercurial.error.HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed (py3 !)
992 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
992 abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
993
993
994 $ echo '[hooks]' > ../a/.hg/hgrc
994 $ echo '[hooks]' > ../a/.hg/hgrc
995 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
995 $ echo 'preoutgoing.pass = python:hooktests.passhook' >> ../a/.hg/hgrc
996 $ hg pull ../a
996 $ hg pull ../a
997 pulling from ../a
997 pulling from ../a
998 searching for changes
998 searching for changes
999 hook args:
999 hook args:
1000 hooktype preoutgoing
1000 hooktype preoutgoing
1001 source pull
1001 source pull
1002 adding changesets
1002 adding changesets
1003 adding manifests
1003 adding manifests
1004 adding file changes
1004 adding file changes
1005 adding remote bookmark quux
1005 adding remote bookmark quux
1006 added 1 changesets with 1 changes to 1 files
1006 added 1 changesets with 1 changes to 1 files
1007 new changesets 539e4b31b6dc
1007 new changesets 539e4b31b6dc
1008 (run 'hg update' to get a working copy)
1008 (run 'hg update' to get a working copy)
1009
1009
1010 post- python hooks that fail to *run* don't cause an abort
1010 post- python hooks that fail to *run* don't cause an abort
1011 $ rm ../a/.hg/hgrc
1011 $ rm ../a/.hg/hgrc
1012 $ echo '[hooks]' > .hg/hgrc
1012 $ echo '[hooks]' > .hg/hgrc
1013 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
1013 $ echo 'post-pull.broken = python:hooktests.brokenhook' >> .hg/hgrc
1014 $ hg pull ../a
1014 $ hg pull ../a
1015 pulling from ../a
1015 pulling from ../a
1016 searching for changes
1016 searching for changes
1017 no changes found
1017 no changes found
1018 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
1018 error: post-pull.broken hook raised an exception: unsupported operand type(s) for +: 'int' and 'dict'
1019 (run with --traceback for stack trace)
1019 (run with --traceback for stack trace)
1020
1020
1021 but post- python hooks that fail to *load* do
1021 but post- python hooks that fail to *load* do
1022 $ echo '[hooks]' > .hg/hgrc
1022 $ echo '[hooks]' > .hg/hgrc
1023 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
1023 $ echo 'post-pull.nomodule = python:nomodule' >> .hg/hgrc
1024 $ hg pull ../a
1024 $ hg pull ../a
1025 pulling from ../a
1025 pulling from ../a
1026 searching for changes
1026 searching for changes
1027 no changes found
1027 no changes found
1028 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
1028 abort: post-pull.nomodule hook is invalid: "nomodule" not in a module
1029 [255]
1029 [255]
1030
1030
1031 $ echo '[hooks]' > .hg/hgrc
1031 $ echo '[hooks]' > .hg/hgrc
1032 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
1032 $ echo 'post-pull.badmodule = python:nomodule.nowhere' >> .hg/hgrc
1033 $ hg pull ../a
1033 $ hg pull ../a
1034 pulling from ../a
1034 pulling from ../a
1035 searching for changes
1035 searching for changes
1036 no changes found
1036 no changes found
1037 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
1037 abort: post-pull.badmodule hook is invalid: import of "nomodule" failed
1038 (run with --traceback for stack trace)
1038 (run with --traceback for stack trace)
1039 [255]
1039 [255]
1040
1040
1041 $ echo '[hooks]' > .hg/hgrc
1041 $ echo '[hooks]' > .hg/hgrc
1042 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
1042 $ echo 'post-pull.nohook = python:hooktests.nohook' >> .hg/hgrc
1043 $ hg pull ../a
1043 $ hg pull ../a
1044 pulling from ../a
1044 pulling from ../a
1045 searching for changes
1045 searching for changes
1046 no changes found
1046 no changes found
1047 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
1047 abort: post-pull.nohook hook is invalid: "hooktests.nohook" is not defined
1048 [255]
1048 [255]
1049
1049
1050 make sure --traceback works
1050 make sure --traceback works
1051
1051
1052 $ echo '[hooks]' > .hg/hgrc
1052 $ echo '[hooks]' > .hg/hgrc
1053 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
1053 $ echo 'commit.abort = python:hooktests.aborthook' >> .hg/hgrc
1054
1054
1055 $ echo aa > a
1055 $ echo aa > a
1056 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
1056 $ hg --traceback commit -d '0 0' -ma 2>&1 | grep '^Traceback'
1057 Traceback (most recent call last):
1057 Traceback (most recent call last):
1058
1058
1059 $ cd ..
1059 $ cd ..
1060 $ hg init c
1060 $ hg init c
1061 $ cd c
1061 $ cd c
1062
1062
1063 $ cat > hookext.py <<EOF
1063 $ cat > hookext.py <<EOF
1064 > def autohook(ui, **args):
1064 > def autohook(ui, **args):
1065 > ui.write(b'Automatically installed hook\n')
1065 > ui.write(b'Automatically installed hook\n')
1066 >
1066 >
1067 > def reposetup(ui, repo):
1067 > def reposetup(ui, repo):
1068 > repo.ui.setconfig(b"hooks", b"commit.auto", autohook)
1068 > repo.ui.setconfig(b"hooks", b"commit.auto", autohook)
1069 > EOF
1069 > EOF
1070 $ echo '[extensions]' >> .hg/hgrc
1070 $ echo '[extensions]' >> .hg/hgrc
1071 $ echo 'hookext = hookext.py' >> .hg/hgrc
1071 $ echo 'hookext = hookext.py' >> .hg/hgrc
1072
1072
1073 $ touch foo
1073 $ touch foo
1074 $ hg add foo
1074 $ hg add foo
1075 $ hg ci -d '0 0' -m 'add foo'
1075 $ hg ci -d '0 0' -m 'add foo'
1076 Automatically installed hook
1076 Automatically installed hook
1077 $ echo >> foo
1077 $ echo >> foo
1078 $ hg ci --debug -d '0 0' -m 'change foo'
1078 $ hg ci --debug -d '0 0' -m 'change foo'
1079 committing files:
1079 committing files:
1080 foo
1080 foo
1081 committing manifest
1081 committing manifest
1082 committing changelog
1082 committing changelog
1083 updating the branch cache
1083 updating the branch cache
1084 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
1084 committed changeset 1:52998019f6252a2b893452765fcb0a47351a5708
1085 calling hook commit.auto: hgext_hookext.autohook
1085 calling hook commit.auto: hgext_hookext.autohook
1086 Automatically installed hook
1086 Automatically installed hook
1087
1087
1088 $ hg showconfig hooks
1088 $ hg showconfig hooks
1089 hooks.commit.auto=<function autohook at *> (glob)
1089 hooks.commit.auto=<function autohook at *> (glob)
1090
1090
1091 test python hook configured with python:[file]:[hook] syntax
1091 test python hook configured with python:[file]:[hook] syntax
1092
1092
1093 $ cd ..
1093 $ cd ..
1094 $ mkdir d
1094 $ mkdir d
1095 $ cd d
1095 $ cd d
1096 $ hg init repo
1096 $ hg init repo
1097 $ mkdir hooks
1097 $ mkdir hooks
1098
1098
1099 $ cd hooks
1099 $ cd hooks
1100 $ cat > testhooks.py <<EOF
1100 $ cat > testhooks.py <<EOF
1101 > def testhook(ui, **args):
1101 > def testhook(ui, **args):
1102 > ui.write(b'hook works\n')
1102 > ui.write(b'hook works\n')
1103 > EOF
1103 > EOF
1104 $ echo '[hooks]' > ../repo/.hg/hgrc
1104 $ echo '[hooks]' > ../repo/.hg/hgrc
1105 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
1105 $ echo "pre-commit.test = python:`pwd`/testhooks.py:testhook" >> ../repo/.hg/hgrc
1106
1106
1107 $ cd ../repo
1107 $ cd ../repo
1108 $ hg commit -d '0 0'
1108 $ hg commit -d '0 0'
1109 hook works
1109 hook works
1110 nothing changed
1110 nothing changed
1111 [1]
1111 [1]
1112
1112
1113 $ echo '[hooks]' > .hg/hgrc
1113 $ echo '[hooks]' > .hg/hgrc
1114 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
1114 $ echo "update.ne = python:`pwd`/nonexistent.py:testhook" >> .hg/hgrc
1115 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
1115 $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc
1116
1116
1117 $ hg up null
1117 $ hg up null
1118 loading update.ne hook failed:
1118 loading update.ne hook failed:
1119 abort: $ENOENT$: '$TESTTMP/d/repo/nonexistent.py'
1119 abort: $ENOENT$: '$TESTTMP/d/repo/nonexistent.py'
1120 [255]
1120 [255]
1121
1121
1122 $ hg id
1122 $ hg id
1123 loading pre-identify.npmd hook failed:
1123 loading pre-identify.npmd hook failed:
1124 abort: No module named repo! (no-py3 !)
1124 abort: No module named repo! (no-py3 !)
1125 abort: No module named 'repo'! (py3 !)
1125 abort: No module named 'repo'! (py3 !)
1126 [255]
1126 [255]
1127
1127
1128 $ cd ../../b
1128 $ cd ../../b
1129
1129
1130 make sure --traceback works on hook import failure
1130 make sure --traceback works on hook import failure
1131
1131
1132 $ cat > importfail.py <<EOF
1132 $ cat > importfail.py <<EOF
1133 > import somebogusmodule
1133 > import somebogusmodule
1134 > # dereference something in the module to force demandimport to load it
1134 > # dereference something in the module to force demandimport to load it
1135 > somebogusmodule.whatever
1135 > somebogusmodule.whatever
1136 > EOF
1136 > EOF
1137
1137
1138 $ echo '[hooks]' > .hg/hgrc
1138 $ echo '[hooks]' > .hg/hgrc
1139 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
1139 $ echo 'precommit.importfail = python:importfail.whatever' >> .hg/hgrc
1140
1140
1141 $ echo a >> a
1141 $ echo a >> a
1142 $ hg --traceback commit -ma 2>&1 | egrep '^exception|ImportError|ModuleNotFoundError|Traceback|HookLoadError|abort'
1142 $ hg --traceback commit -ma 2>&1 | egrep '^exception|ImportError|ModuleNotFoundError|Traceback|HookLoadError|abort'
1143 exception from first failed import attempt:
1143 exception from first failed import attempt:
1144 Traceback (most recent call last):
1144 Traceback (most recent call last):
1145 ImportError: No module named somebogusmodule (no-py3 !)
1145 ImportError: No module named somebogusmodule (no-py3 !)
1146 ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
1146 ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
1147 ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
1147 ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
1148 exception from second failed import attempt:
1148 exception from second failed import attempt:
1149 Traceback (most recent call last): (py3 !)
1149 Traceback (most recent call last): (py3 !)
1150 ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
1150 ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
1151 ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
1151 ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
1152 Traceback (most recent call last): (py3 !)
1152 Traceback (most recent call last): (py3 !)
1153 ImportError: No module named 'hgext_importfail' (py3 no-py36 !)
1153 ImportError: No module named 'hgext_importfail' (py3 no-py36 !)
1154 ModuleNotFoundError: No module named 'hgext_importfail' (py36 !)
1154 ModuleNotFoundError: No module named 'hgext_importfail' (py36 !)
1155 Traceback (most recent call last): (py3 !)
1155 Traceback (most recent call last): (py3 !)
1156 ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
1156 ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
1157 ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
1157 ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
1158 Traceback (most recent call last):
1158 Traceback (most recent call last):
1159 ImportError: No module named hgext_importfail (no-py3 !)
1159 ImportError: No module named hgext_importfail (no-py3 !)
1160 ImportError: No module named 'hgext_importfail' (py3 no-py36 !)
1160 ImportError: No module named 'hgext_importfail' (py3 no-py36 !)
1161 ModuleNotFoundError: No module named 'hgext_importfail' (py36 !)
1161 ModuleNotFoundError: No module named 'hgext_importfail' (py36 !)
1162 Traceback (most recent call last):
1162 Traceback (most recent call last):
1163 HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed (no-py3 !)
1163 HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed (no-py3 !)
1164 mercurial.error.HookLoadError: b'precommit.importfail hook is invalid: import of "importfail" failed' (py3 !)
1164 mercurial.error.HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed (py3 !)
1165 abort: precommit.importfail hook is invalid: import of "importfail" failed
1165 abort: precommit.importfail hook is invalid: import of "importfail" failed
1166
1166
1167 Issue1827: Hooks Update & Commit not completely post operation
1167 Issue1827: Hooks Update & Commit not completely post operation
1168
1168
1169 commit and update hooks should run after command completion. The largefiles
1169 commit and update hooks should run after command completion. The largefiles
1170 use demonstrates a recursive wlock, showing the hook doesn't run until the
1170 use demonstrates a recursive wlock, showing the hook doesn't run until the
1171 final release (and dirstate flush).
1171 final release (and dirstate flush).
1172
1172
1173 $ echo '[hooks]' > .hg/hgrc
1173 $ echo '[hooks]' > .hg/hgrc
1174 $ echo 'commit = hg id' >> .hg/hgrc
1174 $ echo 'commit = hg id' >> .hg/hgrc
1175 $ echo 'update = hg id' >> .hg/hgrc
1175 $ echo 'update = hg id' >> .hg/hgrc
1176 $ echo bb > a
1176 $ echo bb > a
1177 $ hg ci -ma
1177 $ hg ci -ma
1178 223eafe2750c tip
1178 223eafe2750c tip
1179 $ hg up 0 --config extensions.largefiles=
1179 $ hg up 0 --config extensions.largefiles=
1180 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
1180 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
1181 cb9a9f314b8b
1181 cb9a9f314b8b
1182 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1182 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1183
1183
1184 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
1184 make sure --verbose (and --quiet/--debug etc.) are propagated to the local ui
1185 that is passed to pre/post hooks
1185 that is passed to pre/post hooks
1186
1186
1187 $ echo '[hooks]' > .hg/hgrc
1187 $ echo '[hooks]' > .hg/hgrc
1188 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
1188 $ echo 'pre-identify = python:hooktests.verbosehook' >> .hg/hgrc
1189 $ hg id
1189 $ hg id
1190 cb9a9f314b8b
1190 cb9a9f314b8b
1191 $ hg id --verbose
1191 $ hg id --verbose
1192 calling hook pre-identify: hooktests.verbosehook
1192 calling hook pre-identify: hooktests.verbosehook
1193 verbose output from hook
1193 verbose output from hook
1194 cb9a9f314b8b
1194 cb9a9f314b8b
1195
1195
1196 Ensure hooks can be prioritized
1196 Ensure hooks can be prioritized
1197
1197
1198 $ echo '[hooks]' > .hg/hgrc
1198 $ echo '[hooks]' > .hg/hgrc
1199 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
1199 $ echo 'pre-identify.a = python:hooktests.verbosehook' >> .hg/hgrc
1200 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
1200 $ echo 'pre-identify.b = python:hooktests.verbosehook' >> .hg/hgrc
1201 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
1201 $ echo 'priority.pre-identify.b = 1' >> .hg/hgrc
1202 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
1202 $ echo 'pre-identify.c = python:hooktests.verbosehook' >> .hg/hgrc
1203 $ hg id --verbose
1203 $ hg id --verbose
1204 calling hook pre-identify.b: hooktests.verbosehook
1204 calling hook pre-identify.b: hooktests.verbosehook
1205 verbose output from hook
1205 verbose output from hook
1206 calling hook pre-identify.a: hooktests.verbosehook
1206 calling hook pre-identify.a: hooktests.verbosehook
1207 verbose output from hook
1207 verbose output from hook
1208 calling hook pre-identify.c: hooktests.verbosehook
1208 calling hook pre-identify.c: hooktests.verbosehook
1209 verbose output from hook
1209 verbose output from hook
1210 cb9a9f314b8b
1210 cb9a9f314b8b
1211
1211
1212 new tags must be visible in pretxncommit (issue3210)
1212 new tags must be visible in pretxncommit (issue3210)
1213
1213
1214 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
1214 $ echo 'pretxncommit.printtags = python:hooktests.printtags' >> .hg/hgrc
1215 $ hg tag -f foo
1215 $ hg tag -f foo
1216 [a, foo, tip]
1216 [a, foo, tip]
1217
1217
1218 post-init hooks must not crash (issue4983)
1218 post-init hooks must not crash (issue4983)
1219 This also creates the `to` repo for the next test block.
1219 This also creates the `to` repo for the next test block.
1220
1220
1221 $ cd ..
1221 $ cd ..
1222 $ cat << EOF >> hgrc-with-post-init-hook
1222 $ cat << EOF >> hgrc-with-post-init-hook
1223 > [hooks]
1223 > [hooks]
1224 > post-init = sh -c "printenv.py --line post-init"
1224 > post-init = sh -c "printenv.py --line post-init"
1225 > EOF
1225 > EOF
1226 $ HGRCPATH=hgrc-with-post-init-hook hg init to
1226 $ HGRCPATH=hgrc-with-post-init-hook hg init to
1227 post-init hook: HG_ARGS=init to
1227 post-init hook: HG_ARGS=init to
1228 HG_HOOKNAME=post-init
1228 HG_HOOKNAME=post-init
1229 HG_HOOKTYPE=post-init
1229 HG_HOOKTYPE=post-init
1230 HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''}
1230 HG_OPTS={'insecure': None, 'remotecmd': '', 'ssh': ''}
1231 HG_PATS=['to']
1231 HG_PATS=['to']
1232 HG_RESULT=0
1232 HG_RESULT=0
1233
1233
1234
1234
1235 new commits must be visible in pretxnchangegroup (issue3428)
1235 new commits must be visible in pretxnchangegroup (issue3428)
1236
1236
1237 $ echo '[hooks]' >> to/.hg/hgrc
1237 $ echo '[hooks]' >> to/.hg/hgrc
1238 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
1238 $ echo 'prechangegroup = hg --traceback tip' >> to/.hg/hgrc
1239 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
1239 $ echo 'pretxnchangegroup = hg --traceback tip' >> to/.hg/hgrc
1240 $ echo a >> to/a
1240 $ echo a >> to/a
1241 $ hg --cwd to ci -Ama
1241 $ hg --cwd to ci -Ama
1242 adding a
1242 adding a
1243 $ hg clone to from
1243 $ hg clone to from
1244 updating to branch default
1244 updating to branch default
1245 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1245 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1246 $ echo aa >> from/a
1246 $ echo aa >> from/a
1247 $ hg --cwd from ci -mb
1247 $ hg --cwd from ci -mb
1248 $ hg --cwd from push
1248 $ hg --cwd from push
1249 pushing to $TESTTMP/to
1249 pushing to $TESTTMP/to
1250 searching for changes
1250 searching for changes
1251 changeset: 0:cb9a9f314b8b
1251 changeset: 0:cb9a9f314b8b
1252 tag: tip
1252 tag: tip
1253 user: test
1253 user: test
1254 date: Thu Jan 01 00:00:00 1970 +0000
1254 date: Thu Jan 01 00:00:00 1970 +0000
1255 summary: a
1255 summary: a
1256
1256
1257 adding changesets
1257 adding changesets
1258 adding manifests
1258 adding manifests
1259 adding file changes
1259 adding file changes
1260 changeset: 1:9836a07b9b9d
1260 changeset: 1:9836a07b9b9d
1261 tag: tip
1261 tag: tip
1262 user: test
1262 user: test
1263 date: Thu Jan 01 00:00:00 1970 +0000
1263 date: Thu Jan 01 00:00:00 1970 +0000
1264 summary: b
1264 summary: b
1265
1265
1266 added 1 changesets with 1 changes to 1 files
1266 added 1 changesets with 1 changes to 1 files
1267
1267
1268 pretxnclose hook failure should abort the transaction
1268 pretxnclose hook failure should abort the transaction
1269
1269
1270 $ hg init txnfailure
1270 $ hg init txnfailure
1271 $ cd txnfailure
1271 $ cd txnfailure
1272 $ touch a && hg commit -Aqm a
1272 $ touch a && hg commit -Aqm a
1273 $ cat >> .hg/hgrc <<EOF
1273 $ cat >> .hg/hgrc <<EOF
1274 > [hooks]
1274 > [hooks]
1275 > pretxnclose.error = exit 1
1275 > pretxnclose.error = exit 1
1276 > EOF
1276 > EOF
1277 $ hg strip -r 0 --config extensions.strip=
1277 $ hg strip -r 0 --config extensions.strip=
1278 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1278 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1279 saved backup bundle to * (glob)
1279 saved backup bundle to * (glob)
1280 transaction abort!
1280 transaction abort!
1281 rollback completed
1281 rollback completed
1282 strip failed, backup bundle stored in * (glob)
1282 strip failed, backup bundle stored in * (glob)
1283 abort: pretxnclose.error hook exited with status 1
1283 abort: pretxnclose.error hook exited with status 1
1284 [255]
1284 [255]
1285 $ hg recover
1285 $ hg recover
1286 no interrupted transaction available
1286 no interrupted transaction available
1287 [1]
1287 [1]
1288 $ cd ..
1288 $ cd ..
1289
1289
1290 check whether HG_PENDING makes pending changes only in related
1290 check whether HG_PENDING makes pending changes only in related
1291 repositories visible to an external hook.
1291 repositories visible to an external hook.
1292
1292
1293 (emulate a transaction running concurrently by copied
1293 (emulate a transaction running concurrently by copied
1294 .hg/store/00changelog.i.a in subsequent test)
1294 .hg/store/00changelog.i.a in subsequent test)
1295
1295
1296 $ cat > $TESTTMP/savepending.sh <<EOF
1296 $ cat > $TESTTMP/savepending.sh <<EOF
1297 > cp .hg/store/00changelog.i.a .hg/store/00changelog.i.a.saved
1297 > cp .hg/store/00changelog.i.a .hg/store/00changelog.i.a.saved
1298 > exit 1 # to avoid adding new revision for subsequent tests
1298 > exit 1 # to avoid adding new revision for subsequent tests
1299 > EOF
1299 > EOF
1300 $ cd a
1300 $ cd a
1301 $ hg tip -q
1301 $ hg tip -q
1302 4:539e4b31b6dc
1302 4:539e4b31b6dc
1303 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
1303 $ hg --config hooks.pretxnclose="sh $TESTTMP/savepending.sh" commit -m "invisible"
1304 transaction abort!
1304 transaction abort!
1305 rollback completed
1305 rollback completed
1306 abort: pretxnclose hook exited with status 1
1306 abort: pretxnclose hook exited with status 1
1307 [255]
1307 [255]
1308 $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
1308 $ cp .hg/store/00changelog.i.a.saved .hg/store/00changelog.i.a
1309
1309
1310 (check (in)visibility of new changeset while transaction running in
1310 (check (in)visibility of new changeset while transaction running in
1311 repo)
1311 repo)
1312
1312
1313 $ cat > $TESTTMP/checkpending.sh <<EOF
1313 $ cat > $TESTTMP/checkpending.sh <<EOF
1314 > echo '@a'
1314 > echo '@a'
1315 > hg -R "$TESTTMP/a" tip -q
1315 > hg -R "$TESTTMP/a" tip -q
1316 > echo '@a/nested'
1316 > echo '@a/nested'
1317 > hg -R "$TESTTMP/a/nested" tip -q
1317 > hg -R "$TESTTMP/a/nested" tip -q
1318 > exit 1 # to avoid adding new revision for subsequent tests
1318 > exit 1 # to avoid adding new revision for subsequent tests
1319 > EOF
1319 > EOF
1320 $ hg init nested
1320 $ hg init nested
1321 $ cd nested
1321 $ cd nested
1322 $ echo a > a
1322 $ echo a > a
1323 $ hg add a
1323 $ hg add a
1324 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
1324 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkpending.sh" commit -m '#0'
1325 @a
1325 @a
1326 4:539e4b31b6dc
1326 4:539e4b31b6dc
1327 @a/nested
1327 @a/nested
1328 0:bf5e395ced2c
1328 0:bf5e395ced2c
1329 transaction abort!
1329 transaction abort!
1330 rollback completed
1330 rollback completed
1331 abort: pretxnclose hook exited with status 1
1331 abort: pretxnclose hook exited with status 1
1332 [255]
1332 [255]
1333
1333
1334 Hook from untrusted hgrc are reported as failure
1334 Hook from untrusted hgrc are reported as failure
1335 ================================================
1335 ================================================
1336
1336
1337 $ cat << EOF > $TESTTMP/untrusted.py
1337 $ cat << EOF > $TESTTMP/untrusted.py
1338 > from mercurial import scmutil, util
1338 > from mercurial import scmutil, util
1339 > def uisetup(ui):
1339 > def uisetup(ui):
1340 > class untrustedui(ui.__class__):
1340 > class untrustedui(ui.__class__):
1341 > def _trusted(self, fp, f):
1341 > def _trusted(self, fp, f):
1342 > if util.normpath(fp.name).endswith(b'untrusted/.hg/hgrc'):
1342 > if util.normpath(fp.name).endswith(b'untrusted/.hg/hgrc'):
1343 > return False
1343 > return False
1344 > return super(untrustedui, self)._trusted(fp, f)
1344 > return super(untrustedui, self)._trusted(fp, f)
1345 > ui.__class__ = untrustedui
1345 > ui.__class__ = untrustedui
1346 > EOF
1346 > EOF
1347 $ cat << EOF >> $HGRCPATH
1347 $ cat << EOF >> $HGRCPATH
1348 > [extensions]
1348 > [extensions]
1349 > untrusted=$TESTTMP/untrusted.py
1349 > untrusted=$TESTTMP/untrusted.py
1350 > EOF
1350 > EOF
1351 $ hg init untrusted
1351 $ hg init untrusted
1352 $ cd untrusted
1352 $ cd untrusted
1353
1353
1354 Non-blocking hook
1354 Non-blocking hook
1355 -----------------
1355 -----------------
1356
1356
1357 $ cat << EOF >> .hg/hgrc
1357 $ cat << EOF >> .hg/hgrc
1358 > [hooks]
1358 > [hooks]
1359 > txnclose.testing=echo txnclose hook called
1359 > txnclose.testing=echo txnclose hook called
1360 > EOF
1360 > EOF
1361 $ touch a && hg commit -Aqm a
1361 $ touch a && hg commit -Aqm a
1362 warning: untrusted hook txnclose.testing not executed
1362 warning: untrusted hook txnclose.testing not executed
1363 $ hg log
1363 $ hg log
1364 changeset: 0:3903775176ed
1364 changeset: 0:3903775176ed
1365 tag: tip
1365 tag: tip
1366 user: test
1366 user: test
1367 date: Thu Jan 01 00:00:00 1970 +0000
1367 date: Thu Jan 01 00:00:00 1970 +0000
1368 summary: a
1368 summary: a
1369
1369
1370
1370
1371 Non-blocking hook
1371 Non-blocking hook
1372 -----------------
1372 -----------------
1373
1373
1374 $ cat << EOF >> .hg/hgrc
1374 $ cat << EOF >> .hg/hgrc
1375 > [hooks]
1375 > [hooks]
1376 > pretxnclose.testing=echo pre-txnclose hook called
1376 > pretxnclose.testing=echo pre-txnclose hook called
1377 > EOF
1377 > EOF
1378 $ touch b && hg commit -Aqm a
1378 $ touch b && hg commit -Aqm a
1379 transaction abort!
1379 transaction abort!
1380 rollback completed
1380 rollback completed
1381 abort: untrusted hook pretxnclose.testing not executed
1381 abort: untrusted hook pretxnclose.testing not executed
1382 (see 'hg help config.trusted')
1382 (see 'hg help config.trusted')
1383 [255]
1383 [255]
1384 $ hg log
1384 $ hg log
1385 changeset: 0:3903775176ed
1385 changeset: 0:3903775176ed
1386 tag: tip
1386 tag: tip
1387 user: test
1387 user: test
1388 date: Thu Jan 01 00:00:00 1970 +0000
1388 date: Thu Jan 01 00:00:00 1970 +0000
1389 summary: a
1389 summary: a
1390
1390
@@ -1,508 +1,508 b''
1 #require serve no-reposimplestore no-chg
1 #require serve no-reposimplestore no-chg
2
2
3 $ cat >> $HGRCPATH <<EOF
3 $ cat >> $HGRCPATH <<EOF
4 > [extensions]
4 > [extensions]
5 > lfs=
5 > lfs=
6 > [lfs]
6 > [lfs]
7 > track=all()
7 > track=all()
8 > [web]
8 > [web]
9 > push_ssl = False
9 > push_ssl = False
10 > allow-push = *
10 > allow-push = *
11 > EOF
11 > EOF
12
12
13 Serving LFS files can experimentally be turned off. The long term solution is
13 Serving LFS files can experimentally be turned off. The long term solution is
14 to support the 'verify' action in both client and server, so that the server can
14 to support the 'verify' action in both client and server, so that the server can
15 tell the client to store files elsewhere.
15 tell the client to store files elsewhere.
16
16
17 $ hg init server
17 $ hg init server
18 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
18 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
19 > --config experimental.lfs.serve=False -R server serve -d \
19 > --config experimental.lfs.serve=False -R server serve -d \
20 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
20 > -p $HGPORT --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
21 $ cat hg.pid >> $DAEMON_PIDS
21 $ cat hg.pid >> $DAEMON_PIDS
22
22
23 Uploads fail...
23 Uploads fail...
24
24
25 $ hg init client
25 $ hg init client
26 $ echo 'this-is-an-lfs-file' > client/lfs.bin
26 $ echo 'this-is-an-lfs-file' > client/lfs.bin
27 $ hg -R client ci -Am 'initial commit'
27 $ hg -R client ci -Am 'initial commit'
28 adding lfs.bin
28 adding lfs.bin
29 $ hg -R client push http://localhost:$HGPORT
29 $ hg -R client push http://localhost:$HGPORT
30 pushing to http://localhost:$HGPORT/
30 pushing to http://localhost:$HGPORT/
31 searching for changes
31 searching for changes
32 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
32 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
33 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
33 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "upload" is supported)
34 [255]
34 [255]
35
35
36 ... so do a local push to make the data available. Remove the blob from the
36 ... so do a local push to make the data available. Remove the blob from the
37 default cache, so it attempts to download.
37 default cache, so it attempts to download.
38 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
38 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
39 > --config "lfs.url=null://" \
39 > --config "lfs.url=null://" \
40 > -R client push -q server
40 > -R client push -q server
41 $ mv `hg config lfs.usercache` $TESTTMP/servercache
41 $ mv `hg config lfs.usercache` $TESTTMP/servercache
42
42
43 Downloads fail...
43 Downloads fail...
44
44
45 $ hg clone http://localhost:$HGPORT httpclone
45 $ hg clone http://localhost:$HGPORT httpclone
46 (remote is using large file support (lfs); lfs will be enabled for this repository)
46 (remote is using large file support (lfs); lfs will be enabled for this repository)
47 requesting all changes
47 requesting all changes
48 adding changesets
48 adding changesets
49 adding manifests
49 adding manifests
50 adding file changes
50 adding file changes
51 added 1 changesets with 1 changes to 1 files
51 added 1 changesets with 1 changes to 1 files
52 new changesets 525251863cad
52 new changesets 525251863cad
53 updating to branch default
53 updating to branch default
54 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
54 abort: LFS HTTP error: HTTP Error 400: no such method: .git!
55 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
55 (check that lfs serving is enabled on http://localhost:$HGPORT/.git/info/lfs and "download" is supported)
56 [255]
56 [255]
57
57
58 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
58 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
59
59
60 $ cat $TESTTMP/access.log $TESTTMP/errors.log
60 $ cat $TESTTMP/access.log $TESTTMP/errors.log
61 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
61 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
62 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
62 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
63 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
63 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
64 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
64 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
65 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
65 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
66 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
66 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
67 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
67 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
68 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
68 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
69 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
69 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 400 - (glob)
70
70
71 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
71 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
72 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
72 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server serve -d \
73 > -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
73 > -p $HGPORT --pid-file=hg.pid --prefix=subdir/mount/point \
74 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
74 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
75 $ cat hg.pid >> $DAEMON_PIDS
75 $ cat hg.pid >> $DAEMON_PIDS
76
76
77 Reasonable hint for a misconfigured blob server
77 Reasonable hint for a misconfigured blob server
78
78
79 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
79 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT/missing
80 abort: LFS HTTP error: HTTP Error 404: Not Found!
80 abort: LFS HTTP error: HTTP Error 404: Not Found!
81 (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
81 (the "lfs.url" config may be used to override http://localhost:$HGPORT/missing)
82 [255]
82 [255]
83
83
84 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT2/missing
84 $ hg -R httpclone update default --config lfs.url=http://localhost:$HGPORT2/missing
85 abort: LFS error: *onnection *refused*! (glob) (?)
85 abort: LFS error: *onnection *refused*! (glob) (?)
86 abort: LFS error: $EADDRNOTAVAIL$! (glob) (?)
86 abort: LFS error: $EADDRNOTAVAIL$! (glob) (?)
87 abort: LFS error: No route to host! (?)
87 abort: LFS error: No route to host! (?)
88 (the "lfs.url" config may be used to override http://localhost:$HGPORT2/missing)
88 (the "lfs.url" config may be used to override http://localhost:$HGPORT2/missing)
89 [255]
89 [255]
90
90
91 Blob URIs are correct when --prefix is used
91 Blob URIs are correct when --prefix is used
92
92
93 $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
93 $ hg clone --debug http://localhost:$HGPORT/subdir/mount/point cloned2
94 using http://localhost:$HGPORT/subdir/mount/point
94 using http://localhost:$HGPORT/subdir/mount/point
95 sending capabilities command
95 sending capabilities command
96 (remote is using large file support (lfs); lfs will be enabled for this repository)
96 (remote is using large file support (lfs); lfs will be enabled for this repository)
97 query 1; heads
97 query 1; heads
98 sending batch command
98 sending batch command
99 requesting all changes
99 requesting all changes
100 sending getbundle command
100 sending getbundle command
101 bundle2-input-bundle: with-transaction
101 bundle2-input-bundle: with-transaction
102 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
102 bundle2-input-part: "changegroup" (params: 1 mandatory 1 advisory) supported
103 adding changesets
103 adding changesets
104 add changeset 525251863cad
104 add changeset 525251863cad
105 adding manifests
105 adding manifests
106 adding file changes
106 adding file changes
107 adding lfs.bin revisions
107 adding lfs.bin revisions
108 bundle2-input-part: total payload size 648
108 bundle2-input-part: total payload size 648
109 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
109 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
110 bundle2-input-part: "phase-heads" supported
110 bundle2-input-part: "phase-heads" supported
111 bundle2-input-part: total payload size 24
111 bundle2-input-part: total payload size 24
112 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
112 bundle2-input-part: "cache:rev-branch-cache" (advisory) supported
113 bundle2-input-part: total payload size 39
113 bundle2-input-part: total payload size 39
114 bundle2-input-bundle: 4 parts total
114 bundle2-input-bundle: 4 parts total
115 checking for updated bookmarks
115 checking for updated bookmarks
116 updating the branch cache
116 updating the branch cache
117 added 1 changesets with 1 changes to 1 files
117 added 1 changesets with 1 changes to 1 files
118 new changesets 525251863cad
118 new changesets 525251863cad
119 updating to branch default
119 updating to branch default
120 resolving manifests
120 resolving manifests
121 branchmerge: False, force: False, partial: False
121 branchmerge: False, force: False, partial: False
122 ancestor: 000000000000, local: 000000000000+, remote: 525251863cad
122 ancestor: 000000000000, local: 000000000000+, remote: 525251863cad
123 lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs
123 lfs: assuming remote store: http://localhost:$HGPORT/subdir/mount/point/.git/info/lfs
124 Status: 200
124 Status: 200
125 Content-Length: 371
125 Content-Length: 371
126 Content-Type: application/vnd.git-lfs+json
126 Content-Type: application/vnd.git-lfs+json
127 Date: $HTTP_DATE$
127 Date: $HTTP_DATE$
128 Server: testing stub value
128 Server: testing stub value
129 {
129 {
130 "objects": [
130 "objects": [
131 {
131 {
132 "actions": {
132 "actions": {
133 "download": {
133 "download": {
134 "expires_at": "$ISO_8601_DATE_TIME$"
134 "expires_at": "$ISO_8601_DATE_TIME$"
135 "header": {
135 "header": {
136 "Accept": "application/vnd.git-lfs"
136 "Accept": "application/vnd.git-lfs"
137 }
137 }
138 "href": "http://localhost:$HGPORT/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
138 "href": "http://localhost:$HGPORT/subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
139 }
139 }
140 }
140 }
141 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
141 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
142 "size": 20
142 "size": 20
143 }
143 }
144 ]
144 ]
145 "transfer": "basic"
145 "transfer": "basic"
146 }
146 }
147 lfs: downloading f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e (20 bytes)
147 lfs: downloading f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e (20 bytes)
148 Status: 200
148 Status: 200
149 Content-Length: 20
149 Content-Length: 20
150 Content-Type: application/octet-stream
150 Content-Type: application/octet-stream
151 Date: $HTTP_DATE$
151 Date: $HTTP_DATE$
152 Server: testing stub value
152 Server: testing stub value
153 lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache
153 lfs: adding f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e to the usercache
154 lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
154 lfs: processed: f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
155 lfs: downloaded 1 files (20 bytes)
155 lfs: downloaded 1 files (20 bytes)
156 lfs.bin: remote created -> g
156 lfs.bin: remote created -> g
157 getting lfs.bin
157 getting lfs.bin
158 lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store
158 lfs: found f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e in the local lfs store
159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
160 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
160 (sent 3 HTTP requests and * bytes; received * bytes in responses) (glob)
161
161
162 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
162 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
163
163
164 $ cat $TESTTMP/access.log $TESTTMP/errors.log
164 $ cat $TESTTMP/access.log $TESTTMP/errors.log
165 $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
165 $LOCALIP - - [$LOGDATE$] "POST /missing/objects/batch HTTP/1.1" 404 - (glob)
166 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=capabilities HTTP/1.1" 200 - (glob)
166 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=capabilities HTTP/1.1" 200 - (glob)
167 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
167 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
168 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
168 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
169 $LOCALIP - - [$LOGDATE$] "POST /subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
169 $LOCALIP - - [$LOGDATE$] "POST /subdir/mount/point/.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
170 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e HTTP/1.1" 200 - (glob)
170 $LOCALIP - - [$LOGDATE$] "GET /subdir/mount/point/.hg/lfs/objects/f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e HTTP/1.1" 200 - (glob)
171
171
172 Blobs that already exist in the usercache are linked into the repo store, even
172 Blobs that already exist in the usercache are linked into the repo store, even
173 though the client doesn't send the blob.
173 though the client doesn't send the blob.
174
174
175 $ hg init server2
175 $ hg init server2
176 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server2 serve -d \
176 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R server2 serve -d \
177 > -p $HGPORT --pid-file=hg.pid \
177 > -p $HGPORT --pid-file=hg.pid \
178 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
178 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
179 $ cat hg.pid >> $DAEMON_PIDS
179 $ cat hg.pid >> $DAEMON_PIDS
180
180
181 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R cloned2 --debug \
181 $ hg --config "lfs.usercache=$TESTTMP/servercache" -R cloned2 --debug \
182 > push http://localhost:$HGPORT | grep '^[{} ]'
182 > push http://localhost:$HGPORT | grep '^[{} ]'
183 {
183 {
184 "objects": [
184 "objects": [
185 {
185 {
186 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
186 "oid": "f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e"
187 "size": 20
187 "size": 20
188 }
188 }
189 ]
189 ]
190 "transfer": "basic"
190 "transfer": "basic"
191 }
191 }
192 $ find server2/.hg/store/lfs/objects | sort
192 $ find server2/.hg/store/lfs/objects | sort
193 server2/.hg/store/lfs/objects
193 server2/.hg/store/lfs/objects
194 server2/.hg/store/lfs/objects/f0
194 server2/.hg/store/lfs/objects/f0
195 server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
195 server2/.hg/store/lfs/objects/f0/3217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e
196 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
196 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
197 $ cat $TESTTMP/errors.log
197 $ cat $TESTTMP/errors.log
198
198
199 $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
199 $ cat >> $TESTTMP/lfsstoreerror.py <<EOF
200 > import errno
200 > import errno
201 > from hgext.lfs import blobstore
201 > from hgext.lfs import blobstore
202 >
202 >
203 > _numverifies = 0
203 > _numverifies = 0
204 > _readerr = True
204 > _readerr = True
205 >
205 >
206 > def reposetup(ui, repo):
206 > def reposetup(ui, repo):
207 > # Nothing to do with a remote repo
207 > # Nothing to do with a remote repo
208 > if not repo.local():
208 > if not repo.local():
209 > return
209 > return
210 >
210 >
211 > store = repo.svfs.lfslocalblobstore
211 > store = repo.svfs.lfslocalblobstore
212 > class badstore(store.__class__):
212 > class badstore(store.__class__):
213 > def download(self, oid, src):
213 > def download(self, oid, src):
214 > '''Called in the server to handle reading from the client in a
214 > '''Called in the server to handle reading from the client in a
215 > PUT request.'''
215 > PUT request.'''
216 > origread = src.read
216 > origread = src.read
217 > def _badread(nbytes):
217 > def _badread(nbytes):
218 > # Simulate bad data/checksum failure from the client
218 > # Simulate bad data/checksum failure from the client
219 > return b'0' * len(origread(nbytes))
219 > return b'0' * len(origread(nbytes))
220 > src.read = _badread
220 > src.read = _badread
221 > super(badstore, self).download(oid, src)
221 > super(badstore, self).download(oid, src)
222 >
222 >
223 > def _read(self, vfs, oid, verify):
223 > def _read(self, vfs, oid, verify):
224 > '''Called in the server to read data for a GET request, and then
224 > '''Called in the server to read data for a GET request, and then
225 > calls self._verify() on it before returning.'''
225 > calls self._verify() on it before returning.'''
226 > global _readerr
226 > global _readerr
227 > # One time simulation of a read error
227 > # One time simulation of a read error
228 > if _readerr:
228 > if _readerr:
229 > _readerr = False
229 > _readerr = False
230 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
230 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
231 > # Simulate corrupt content on client download
231 > # Simulate corrupt content on client download
232 > blobstore._verify(oid, b'dummy content')
232 > blobstore._verify(oid, b'dummy content')
233 >
233 >
234 > def verify(self, oid):
234 > def verify(self, oid):
235 > '''Called in the server to populate the Batch API response,
235 > '''Called in the server to populate the Batch API response,
236 > letting the client re-upload if the file is corrupt.'''
236 > letting the client re-upload if the file is corrupt.'''
237 > # Fail verify in Batch API for one clone command and one push
237 > # Fail verify in Batch API for one clone command and one push
238 > # command with an IOError. Then let it through to access other
238 > # command with an IOError. Then let it through to access other
239 > # functions. Checksum failure is tested elsewhere.
239 > # functions. Checksum failure is tested elsewhere.
240 > global _numverifies
240 > global _numverifies
241 > _numverifies += 1
241 > _numverifies += 1
242 > if _numverifies <= 2:
242 > if _numverifies <= 2:
243 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
243 > raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
244 > return super(badstore, self).verify(oid)
244 > return super(badstore, self).verify(oid)
245 >
245 >
246 > store.__class__ = badstore
246 > store.__class__ = badstore
247 > EOF
247 > EOF
248
248
249 $ rm -rf `hg config lfs.usercache`
249 $ rm -rf `hg config lfs.usercache`
250 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
250 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
251 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
251 $ hg --config "lfs.usercache=$TESTTMP/servercache" \
252 > --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
252 > --config extensions.lfsstoreerror=$TESTTMP/lfsstoreerror.py \
253 > -R server serve -d \
253 > -R server serve -d \
254 > -p $HGPORT1 --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
254 > -p $HGPORT1 --pid-file=hg.pid -A $TESTTMP/access.log -E $TESTTMP/errors.log
255 $ cat hg.pid >> $DAEMON_PIDS
255 $ cat hg.pid >> $DAEMON_PIDS
256
256
257 Test an I/O error in localstore.verify() (Batch API) with GET
257 Test an I/O error in localstore.verify() (Batch API) with GET
258
258
259 $ hg clone http://localhost:$HGPORT1 httpclone2
259 $ hg clone http://localhost:$HGPORT1 httpclone2
260 (remote is using large file support (lfs); lfs will be enabled for this repository)
260 (remote is using large file support (lfs); lfs will be enabled for this repository)
261 requesting all changes
261 requesting all changes
262 adding changesets
262 adding changesets
263 adding manifests
263 adding manifests
264 adding file changes
264 adding file changes
265 added 1 changesets with 1 changes to 1 files
265 added 1 changesets with 1 changes to 1 files
266 new changesets 525251863cad
266 new changesets 525251863cad
267 updating to branch default
267 updating to branch default
268 abort: LFS server error for "lfs.bin": Internal server error!
268 abort: LFS server error for "lfs.bin": Internal server error!
269 [255]
269 [255]
270
270
271 Test an I/O error in localstore.verify() (Batch API) with PUT
271 Test an I/O error in localstore.verify() (Batch API) with PUT
272
272
273 $ echo foo > client/lfs.bin
273 $ echo foo > client/lfs.bin
274 $ hg -R client ci -m 'mod lfs'
274 $ hg -R client ci -m 'mod lfs'
275 $ hg -R client push http://localhost:$HGPORT1
275 $ hg -R client push http://localhost:$HGPORT1
276 pushing to http://localhost:$HGPORT1/
276 pushing to http://localhost:$HGPORT1/
277 searching for changes
277 searching for changes
278 abort: LFS server error for "unknown": Internal server error!
278 abort: LFS server error for "unknown": Internal server error!
279 [255]
279 [255]
280 TODO: figure out how to associate the file name in the error above
280 TODO: figure out how to associate the file name in the error above
281
281
282 Test a bad checksum sent by the client in the transfer API
282 Test a bad checksum sent by the client in the transfer API
283
283
284 $ hg -R client push http://localhost:$HGPORT1
284 $ hg -R client push http://localhost:$HGPORT1
285 pushing to http://localhost:$HGPORT1/
285 pushing to http://localhost:$HGPORT1/
286 searching for changes
286 searching for changes
287 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)!
287 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c, action=upload)!
288 [255]
288 [255]
289
289
290 $ echo 'test lfs file' > server/lfs3.bin
290 $ echo 'test lfs file' > server/lfs3.bin
291 $ hg --config experimental.lfs.disableusercache=True \
291 $ hg --config experimental.lfs.disableusercache=True \
292 > -R server ci -Aqm 'another lfs file'
292 > -R server ci -Aqm 'another lfs file'
293 $ hg -R client pull -q http://localhost:$HGPORT1
293 $ hg -R client pull -q http://localhost:$HGPORT1
294
294
295 Test an I/O error during the processing of the GET request
295 Test an I/O error during the processing of the GET request
296
296
297 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
297 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
298 > -R client update -r tip
298 > -R client update -r tip
299 abort: LFS HTTP error: HTTP Error 500: Internal Server Error (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)!
299 abort: LFS HTTP error: HTTP Error 500: Internal Server Error (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)!
300 [255]
300 [255]
301
301
302 Test a checksum failure during the processing of the GET request
302 Test a checksum failure during the processing of the GET request
303
303
304 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
304 $ hg --config lfs.url=http://localhost:$HGPORT1/.git/info/lfs \
305 > -R client update -r tip
305 > -R client update -r tip
306 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)!
306 abort: LFS HTTP error: HTTP Error 422: corrupt blob (oid=276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d, action=download)!
307 [255]
307 [255]
308
308
309 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
309 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
310
310
311 $ cat $TESTTMP/access.log
311 $ cat $TESTTMP/access.log
312 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
312 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
313 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
313 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
314 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
314 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
315 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
315 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
316 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
316 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
317 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
317 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
318 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
318 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
319 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
319 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
320 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
320 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
321 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
321 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
322 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
322 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
323 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
323 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
324 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
324 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
325 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
325 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
326 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
326 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
327 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
327 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
328 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
328 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
329 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
329 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
330 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" 422 - (glob)
330 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c HTTP/1.1" 422 - (glob)
331 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
331 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
332 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
332 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D392c05922088bacf8e68a6939b480017afbf245d x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
333 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
333 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=525251863cad618e55d483555f3d00a2ca99597e&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
334 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
334 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
335 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob)
335 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 500 - (glob)
336 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
336 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
337 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 422 - (glob)
337 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 422 - (glob)
338
338
339 $ grep -v ' File "' $TESTTMP/errors.log
339 $ grep -v ' File "' $TESTTMP/errors.log
340 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
340 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
341 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
341 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
342 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
342 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
343 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
343 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
344 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob)
344 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] f03217a32529a28a42d03b1244fe09b6e0f9fd06d7b966d4d50567be2abe6c0e: I/O error (glob)
345 $LOCALIP - - [$ERRDATE$] HG error: (glob)
345 $LOCALIP - - [$ERRDATE$] HG error: (glob)
346 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
346 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.git/info/lfs/objects/batch': (glob)
347 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
347 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
348 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
348 $LOCALIP - - [$ERRDATE$] HG error: verifies = store.verify(oid) (glob)
349 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
349 $LOCALIP - - [$ERRDATE$] HG error: raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8")) (glob)
350 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob)
350 $LOCALIP - - [$ERRDATE$] HG error: *Error: [Errno 5] b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c: I/O error (glob)
351 $LOCALIP - - [$ERRDATE$] HG error: (glob)
351 $LOCALIP - - [$ERRDATE$] HG error: (glob)
352 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob)
352 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c': (glob)
353 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
353 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
354 $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh) (glob)
354 $LOCALIP - - [$ERRDATE$] HG error: localstore.download(oid, req.bodyfh) (glob)
355 $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src) (glob)
355 $LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src) (glob)
356 $LOCALIP - - [$ERRDATE$] HG error: _(b'corrupt remote lfs object: %s') % oid (glob)
356 $LOCALIP - - [$ERRDATE$] HG error: _(b'corrupt remote lfs object: %s') % oid (glob)
357 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (no-py3 !)
357 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (no-py3 !)
358 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: b'corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c' (py3 !)
358 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (py3 !)
359 $LOCALIP - - [$ERRDATE$] HG error: (glob)
359 $LOCALIP - - [$ERRDATE$] HG error: (glob)
360 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
360 $LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
361 Traceback (most recent call last):
361 Traceback (most recent call last):
362 self.do_write()
362 self.do_write()
363 self.do_hgweb()
363 self.do_hgweb()
364 for chunk in self.server.application(env, self._start_response):
364 for chunk in self.server.application(env, self._start_response):
365 for r in self._runwsgi(req, res, repo):
365 for r in self._runwsgi(req, res, repo):
366 rctx, req, res, self.check_perm
366 rctx, req, res, self.check_perm
367 return func(*(args + a), **kw) (no-py3 !)
367 return func(*(args + a), **kw) (no-py3 !)
368 rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm)
368 rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm)
369 res.setbodybytes(localstore.read(oid))
369 res.setbodybytes(localstore.read(oid))
370 blob = self._read(self.vfs, oid, verify)
370 blob = self._read(self.vfs, oid, verify)
371 raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
371 raise IOError(errno.EIO, r'%s: I/O error' % oid.decode("utf-8"))
372 *Error: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob)
372 *Error: [Errno 5] 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d: I/O error (glob)
373
373
374 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
374 $LOCALIP - - [$ERRDATE$] HG error: Exception happened while processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
375 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
375 $LOCALIP - - [$ERRDATE$] HG error: Traceback (most recent call last): (glob)
376 $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob)
376 $LOCALIP - - [$ERRDATE$] HG error: res.setbodybytes(localstore.read(oid)) (glob)
377 $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob)
377 $LOCALIP - - [$ERRDATE$] HG error: blob = self._read(self.vfs, oid, verify) (glob)
378 $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
378 $LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
379 $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify'), (glob)
379 $LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify'), (glob)
380 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (no-py3 !)
380 $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (no-py3 !)
381 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: b'detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d' (py3 !)
381 $LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (py3 !)
382 $LOCALIP - - [$ERRDATE$] HG error: (glob)
382 $LOCALIP - - [$ERRDATE$] HG error: (glob)
383
383
384 Basic Authorization headers are returned by the Batch API, and sent back with
384 Basic Authorization headers are returned by the Batch API, and sent back with
385 the GET/PUT request.
385 the GET/PUT request.
386
386
387 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
387 $ rm -f $TESTTMP/access.log $TESTTMP/errors.log
388
388
389 $ cat >> $HGRCPATH << EOF
389 $ cat >> $HGRCPATH << EOF
390 > [experimental]
390 > [experimental]
391 > lfs.disableusercache = True
391 > lfs.disableusercache = True
392 > [auth]
392 > [auth]
393 > l.schemes=http
393 > l.schemes=http
394 > l.prefix=lo
394 > l.prefix=lo
395 > l.username=user
395 > l.username=user
396 > l.password=pass
396 > l.password=pass
397 > EOF
397 > EOF
398
398
399 $ hg --config extensions.x=$TESTDIR/httpserverauth.py \
399 $ hg --config extensions.x=$TESTDIR/httpserverauth.py \
400 > -R server serve -d -p $HGPORT1 --pid-file=hg.pid \
400 > -R server serve -d -p $HGPORT1 --pid-file=hg.pid \
401 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
401 > -A $TESTTMP/access.log -E $TESTTMP/errors.log
402 $ mv hg.pid $DAEMON_PIDS
402 $ mv hg.pid $DAEMON_PIDS
403
403
404 $ hg clone --debug http://localhost:$HGPORT1 auth_clone | egrep '^[{}]| '
404 $ hg clone --debug http://localhost:$HGPORT1 auth_clone | egrep '^[{}]| '
405 {
405 {
406 "objects": [
406 "objects": [
407 {
407 {
408 "actions": {
408 "actions": {
409 "download": {
409 "download": {
410 "expires_at": "$ISO_8601_DATE_TIME$"
410 "expires_at": "$ISO_8601_DATE_TIME$"
411 "header": {
411 "header": {
412 "Accept": "application/vnd.git-lfs"
412 "Accept": "application/vnd.git-lfs"
413 "Authorization": "Basic dXNlcjpwYXNz"
413 "Authorization": "Basic dXNlcjpwYXNz"
414 }
414 }
415 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
415 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
416 }
416 }
417 }
417 }
418 "oid": "276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
418 "oid": "276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d"
419 "size": 14
419 "size": 14
420 }
420 }
421 ]
421 ]
422 "transfer": "basic"
422 "transfer": "basic"
423 }
423 }
424
424
425 $ echo 'another blob' > auth_clone/lfs.blob
425 $ echo 'another blob' > auth_clone/lfs.blob
426 $ hg -R auth_clone ci -Aqm 'add blob'
426 $ hg -R auth_clone ci -Aqm 'add blob'
427
427
428 $ cat > use_digests.py << EOF
428 $ cat > use_digests.py << EOF
429 > from mercurial import (
429 > from mercurial import (
430 > exthelper,
430 > exthelper,
431 > url,
431 > url,
432 > )
432 > )
433 >
433 >
434 > eh = exthelper.exthelper()
434 > eh = exthelper.exthelper()
435 > uisetup = eh.finaluisetup
435 > uisetup = eh.finaluisetup
436 >
436 >
437 > @eh.wrapfunction(url, 'opener')
437 > @eh.wrapfunction(url, 'opener')
438 > def urlopener(orig, *args, **kwargs):
438 > def urlopener(orig, *args, **kwargs):
439 > opener = orig(*args, **kwargs)
439 > opener = orig(*args, **kwargs)
440 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
440 > opener.addheaders.append((r'X-HgTest-AuthType', r'Digest'))
441 > return opener
441 > return opener
442 > EOF
442 > EOF
443
443
444 Test that Digest Auth fails gracefully before testing the successful Basic Auth
444 Test that Digest Auth fails gracefully before testing the successful Basic Auth
445
445
446 $ hg -R auth_clone push --config extensions.x=use_digests.py
446 $ hg -R auth_clone push --config extensions.x=use_digests.py
447 pushing to http://localhost:$HGPORT1/
447 pushing to http://localhost:$HGPORT1/
448 searching for changes
448 searching for changes
449 abort: LFS HTTP error: HTTP Error 401: the server must support Basic Authentication!
449 abort: LFS HTTP error: HTTP Error 401: the server must support Basic Authentication!
450 (api=http://localhost:$HGPORT1/.git/info/lfs/objects/batch, action=upload)
450 (api=http://localhost:$HGPORT1/.git/info/lfs/objects/batch, action=upload)
451 [255]
451 [255]
452
452
453 $ hg -R auth_clone --debug push | egrep '^[{}]| '
453 $ hg -R auth_clone --debug push | egrep '^[{}]| '
454 {
454 {
455 "objects": [
455 "objects": [
456 {
456 {
457 "actions": {
457 "actions": {
458 "upload": {
458 "upload": {
459 "expires_at": "$ISO_8601_DATE_TIME$"
459 "expires_at": "$ISO_8601_DATE_TIME$"
460 "header": {
460 "header": {
461 "Accept": "application/vnd.git-lfs"
461 "Accept": "application/vnd.git-lfs"
462 "Authorization": "Basic dXNlcjpwYXNz"
462 "Authorization": "Basic dXNlcjpwYXNz"
463 }
463 }
464 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
464 "href": "http://localhost:$HGPORT1/.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
465 }
465 }
466 }
466 }
467 "oid": "df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
467 "oid": "df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3"
468 "size": 13
468 "size": 13
469 }
469 }
470 ]
470 ]
471 "transfer": "basic"
471 "transfer": "basic"
472 }
472 }
473
473
474 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
474 $ "$PYTHON" $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
475
475
476 $ cat $TESTTMP/access.log $TESTTMP/errors.log
476 $ cat $TESTTMP/access.log $TESTTMP/errors.log
477 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
477 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
478 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
478 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
479 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
479 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
480 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
480 $LOCALIP - - [$LOGDATE$] "GET /?cmd=getbundle HTTP/1.1" 200 - x-hgarg-1:bookmarks=1&bundlecaps=HG20%2Cbundle2%3DHG20%250Abookmarks%250Achangegroup%253D01%252C02%252C03%250Adigests%253Dmd5%252Csha1%252Csha512%250Aerror%253Dabort%252Cunsupportedcontent%252Cpushraced%252Cpushkey%250Ahgtagsfnodes%250Alistkeys%250Aphases%253Dheads%250Apushkey%250Aremote-changegroup%253Dhttp%252Chttps%250Arev-branch-cache%250Astream%253Dv2&cg=1&common=0000000000000000000000000000000000000000&heads=506bf3d83f78c54b89e81c6411adee19fdf02156+525251863cad618e55d483555f3d00a2ca99597e&listkeys=bookmarks&phases=1 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
481 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
481 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
482 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
482 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
483 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 200 - (glob)
483 $LOCALIP - - [$LOGDATE$] "GET /.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d HTTP/1.1" 200 - (glob)
484 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
484 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
485 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (glob)
485 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - x-hgtest-authtype:Digest (glob)
486 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 401 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
486 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 401 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
487 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
487 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
488 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
488 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
489 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
489 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
490 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
490 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
491 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
491 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
492 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
492 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 401 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
493 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
493 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
494 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
494 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 401 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
495 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
495 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull x-hgtest-authtype:Digest (glob)
496 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
496 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - x-hgtest-authtype:Digest (glob)
497 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
497 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 401 - (glob)
498 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
498 $LOCALIP - - [$LOGDATE$] "GET /?cmd=capabilities HTTP/1.1" 200 - (glob)
499 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
499 $LOCALIP - - [$LOGDATE$] "GET /?cmd=batch HTTP/1.1" 200 - x-hgarg-1:cmds=heads+%3Bknown+nodes%3D525251863cad618e55d483555f3d00a2ca99597e+4d9397055dc0c205f3132f331f36353ab1a525a3 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
500 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
500 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
501 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
501 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
502 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
502 $LOCALIP - - [$LOGDATE$] "GET /?cmd=branchmap HTTP/1.1" 200 - x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
503 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
503 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=bookmarks x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
504 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
504 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 401 - (glob)
505 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
505 $LOCALIP - - [$LOGDATE$] "POST /.git/info/lfs/objects/batch HTTP/1.1" 200 - (glob)
506 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3 HTTP/1.1" 201 - (glob)
506 $LOCALIP - - [$LOGDATE$] "PUT /.hg/lfs/objects/df14287d8d75f076a6459e7a3703ca583ca9fb3f4918caed10c77ac8622d49b3 HTTP/1.1" 201 - (glob)
507 $LOCALIP - - [$LOGDATE$] "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
507 $LOCALIP - - [$LOGDATE$] "POST /?cmd=unbundle HTTP/1.1" 200 - x-hgarg-1:heads=666f726365 x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
508 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
508 $LOCALIP - - [$LOGDATE$] "GET /?cmd=listkeys HTTP/1.1" 200 - x-hgarg-1:namespace=phases x-hgproto-1:0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull (glob)
@@ -1,130 +1,130 b''
1 Test UI worker interaction
1 Test UI worker interaction
2
2
3 $ cat > t.py <<EOF
3 $ cat > t.py <<EOF
4 > from __future__ import absolute_import, print_function
4 > from __future__ import absolute_import, print_function
5 > import time
5 > import time
6 > from mercurial import (
6 > from mercurial import (
7 > error,
7 > error,
8 > registrar,
8 > registrar,
9 > ui as uimod,
9 > ui as uimod,
10 > worker,
10 > worker,
11 > )
11 > )
12 > def abort(ui, args):
12 > def abort(ui, args):
13 > if args[0] == 0:
13 > if args[0] == 0:
14 > # by first worker for test stability
14 > # by first worker for test stability
15 > raise error.Abort(b'known exception')
15 > raise error.Abort(b'known exception')
16 > return runme(ui, [])
16 > return runme(ui, [])
17 > def exc(ui, args):
17 > def exc(ui, args):
18 > if args[0] == 0:
18 > if args[0] == 0:
19 > # by first worker for test stability
19 > # by first worker for test stability
20 > raise Exception('unknown exception')
20 > raise Exception('unknown exception')
21 > return runme(ui, [])
21 > return runme(ui, [])
22 > def runme(ui, args):
22 > def runme(ui, args):
23 > for arg in args:
23 > for arg in args:
24 > ui.status(b'run\n')
24 > ui.status(b'run\n')
25 > yield 1, arg
25 > yield 1, arg
26 > time.sleep(0.1) # easier to trigger killworkers code path
26 > time.sleep(0.1) # easier to trigger killworkers code path
27 > functable = {
27 > functable = {
28 > b'abort': abort,
28 > b'abort': abort,
29 > b'exc': exc,
29 > b'exc': exc,
30 > b'runme': runme,
30 > b'runme': runme,
31 > }
31 > }
32 > cmdtable = {}
32 > cmdtable = {}
33 > command = registrar.command(cmdtable)
33 > command = registrar.command(cmdtable)
34 > @command(b'test', [], b'hg test [COST] [FUNC]')
34 > @command(b'test', [], b'hg test [COST] [FUNC]')
35 > def t(ui, repo, cost=1.0, func=b'runme'):
35 > def t(ui, repo, cost=1.0, func=b'runme'):
36 > cost = float(cost)
36 > cost = float(cost)
37 > func = functable[func]
37 > func = functable[func]
38 > ui.status(b'start\n')
38 > ui.status(b'start\n')
39 > runs = worker.worker(ui, cost, func, (ui,), range(8))
39 > runs = worker.worker(ui, cost, func, (ui,), range(8))
40 > for n, i in runs:
40 > for n, i in runs:
41 > pass
41 > pass
42 > ui.status(b'done\n')
42 > ui.status(b'done\n')
43 > EOF
43 > EOF
44 $ abspath=`pwd`/t.py
44 $ abspath=`pwd`/t.py
45 $ hg init
45 $ hg init
46
46
47 Run tests with worker enable by forcing a heigh cost
47 Run tests with worker enable by forcing a heigh cost
48
48
49 $ hg --config "extensions.t=$abspath" test 100000.0
49 $ hg --config "extensions.t=$abspath" test 100000.0
50 start
50 start
51 run
51 run
52 run
52 run
53 run
53 run
54 run
54 run
55 run
55 run
56 run
56 run
57 run
57 run
58 run
58 run
59 done
59 done
60
60
61 Run tests without worker by forcing a low cost
61 Run tests without worker by forcing a low cost
62
62
63 $ hg --config "extensions.t=$abspath" test 0.0000001
63 $ hg --config "extensions.t=$abspath" test 0.0000001
64 start
64 start
65 run
65 run
66 run
66 run
67 run
67 run
68 run
68 run
69 run
69 run
70 run
70 run
71 run
71 run
72 run
72 run
73 done
73 done
74
74
75 #if no-windows
75 #if no-windows
76
76
77 Known exception should be caught, but printed if --traceback is enabled
77 Known exception should be caught, but printed if --traceback is enabled
78
78
79 $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=8' \
79 $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=8' \
80 > test 100000.0 abort 2>&1
80 > test 100000.0 abort 2>&1
81 start
81 start
82 abort: known exception
82 abort: known exception
83 [255]
83 [255]
84
84
85 $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=8' \
85 $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=8' \
86 > test 100000.0 abort --traceback 2>&1 | egrep '(SystemExit|Abort)'
86 > test 100000.0 abort --traceback 2>&1 | egrep '(SystemExit|Abort)'
87 raise error.Abort(b'known exception')
87 raise error.Abort(b'known exception')
88 mercurial.error.Abort: b'known exception' (py3 !)
88 mercurial.error.Abort: known exception (py3 !)
89 Abort: known exception (no-py3 !)
89 Abort: known exception (no-py3 !)
90 SystemExit: 255
90 SystemExit: 255
91
91
92 Traceback must be printed for unknown exceptions
92 Traceback must be printed for unknown exceptions
93
93
94 $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=8' \
94 $ hg --config "extensions.t=$abspath" --config 'worker.numcpus=8' \
95 > test 100000.0 exc 2>&1 | grep '^Exception'
95 > test 100000.0 exc 2>&1 | grep '^Exception'
96 Exception: unknown exception
96 Exception: unknown exception
97
97
98 Workers should not do cleanups in all cases
98 Workers should not do cleanups in all cases
99
99
100 $ cat > $TESTTMP/detectcleanup.py <<EOF
100 $ cat > $TESTTMP/detectcleanup.py <<EOF
101 > from __future__ import absolute_import
101 > from __future__ import absolute_import
102 > import atexit
102 > import atexit
103 > import os
103 > import os
104 > import time
104 > import time
105 > oldfork = os.fork
105 > oldfork = os.fork
106 > count = 0
106 > count = 0
107 > parentpid = os.getpid()
107 > parentpid = os.getpid()
108 > def delayedfork():
108 > def delayedfork():
109 > global count
109 > global count
110 > count += 1
110 > count += 1
111 > pid = oldfork()
111 > pid = oldfork()
112 > # make it easier to test SIGTERM hitting other workers when they have
112 > # make it easier to test SIGTERM hitting other workers when they have
113 > # not set up error handling yet.
113 > # not set up error handling yet.
114 > if count > 1 and pid == 0:
114 > if count > 1 and pid == 0:
115 > time.sleep(0.1)
115 > time.sleep(0.1)
116 > return pid
116 > return pid
117 > os.fork = delayedfork
117 > os.fork = delayedfork
118 > def cleanup():
118 > def cleanup():
119 > if os.getpid() != parentpid:
119 > if os.getpid() != parentpid:
120 > os.write(1, 'should never happen\n')
120 > os.write(1, 'should never happen\n')
121 > atexit.register(cleanup)
121 > atexit.register(cleanup)
122 > EOF
122 > EOF
123
123
124 $ hg --config "extensions.t=$abspath" --config worker.numcpus=8 --config \
124 $ hg --config "extensions.t=$abspath" --config worker.numcpus=8 --config \
125 > "extensions.d=$TESTTMP/detectcleanup.py" test 100000 abort
125 > "extensions.d=$TESTTMP/detectcleanup.py" test 100000 abort
126 start
126 start
127 abort: known exception
127 abort: known exception
128 [255]
128 [255]
129
129
130 #endif
130 #endif
General Comments 0
You need to be logged in to leave comments. Login now