##// END OF EJS Templates
formatter: convert timestamp to int...
Yuya Nishihara -
r37788:31750413 default
parent child Browse files
Show More
@@ -1,609 +1,611 b''
1 1 # formatter.py - generic output formatting for mercurial
2 2 #
3 3 # Copyright 2012 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 """Generic output formatting for Mercurial
9 9
10 10 The formatter provides API to show data in various ways. The following
11 11 functions should be used in place of ui.write():
12 12
13 13 - fm.write() for unconditional output
14 14 - fm.condwrite() to show some extra data conditionally in plain output
15 15 - fm.context() to provide changectx to template output
16 16 - fm.data() to provide extra data to JSON or template output
17 17 - fm.plain() to show raw text that isn't provided to JSON or template output
18 18
19 19 To show structured data (e.g. date tuples, dicts, lists), apply fm.format*()
20 20 beforehand so the data is converted to the appropriate data type. Use
21 21 fm.isplain() if you need to convert or format data conditionally which isn't
22 22 supported by the formatter API.
23 23
24 24 To build nested structure (i.e. a list of dicts), use fm.nested().
25 25
26 26 See also https://www.mercurial-scm.org/wiki/GenericTemplatingPlan
27 27
28 28 fm.condwrite() vs 'if cond:':
29 29
30 30 In most cases, use fm.condwrite() so users can selectively show the data
31 31 in template output. If it's costly to build data, use plain 'if cond:' with
32 32 fm.write().
33 33
34 34 fm.nested() vs fm.formatdict() (or fm.formatlist()):
35 35
36 36 fm.nested() should be used to form a tree structure (a list of dicts of
37 37 lists of dicts...) which can be accessed through template keywords, e.g.
38 38 "{foo % "{bar % {...}} {baz % {...}}"}". On the other hand, fm.formatdict()
39 39 exports a dict-type object to template, which can be accessed by e.g.
40 40 "{get(foo, key)}" function.
41 41
42 42 Doctest helper:
43 43
44 44 >>> def show(fn, verbose=False, **opts):
45 45 ... import sys
46 46 ... from . import ui as uimod
47 47 ... ui = uimod.ui()
48 48 ... ui.verbose = verbose
49 49 ... ui.pushbuffer()
50 50 ... try:
51 51 ... return fn(ui, ui.formatter(pycompat.sysbytes(fn.__name__),
52 52 ... pycompat.byteskwargs(opts)))
53 53 ... finally:
54 54 ... print(pycompat.sysstr(ui.popbuffer()), end='')
55 55
56 56 Basic example:
57 57
58 58 >>> def files(ui, fm):
59 59 ... files = [(b'foo', 123, (0, 0)), (b'bar', 456, (1, 0))]
60 60 ... for f in files:
61 61 ... fm.startitem()
62 62 ... fm.write(b'path', b'%s', f[0])
63 63 ... fm.condwrite(ui.verbose, b'date', b' %s',
64 64 ... fm.formatdate(f[2], b'%Y-%m-%d %H:%M:%S'))
65 65 ... fm.data(size=f[1])
66 66 ... fm.plain(b'\\n')
67 67 ... fm.end()
68 68 >>> show(files)
69 69 foo
70 70 bar
71 71 >>> show(files, verbose=True)
72 72 foo 1970-01-01 00:00:00
73 73 bar 1970-01-01 00:00:01
74 74 >>> show(files, template=b'json')
75 75 [
76 76 {
77 77 "date": [0, 0],
78 78 "path": "foo",
79 79 "size": 123
80 80 },
81 81 {
82 82 "date": [1, 0],
83 83 "path": "bar",
84 84 "size": 456
85 85 }
86 86 ]
87 87 >>> show(files, template=b'path: {path}\\ndate: {date|rfc3339date}\\n')
88 88 path: foo
89 89 date: 1970-01-01T00:00:00+00:00
90 90 path: bar
91 91 date: 1970-01-01T00:00:01+00:00
92 92
93 93 Nested example:
94 94
95 95 >>> def subrepos(ui, fm):
96 96 ... fm.startitem()
97 97 ... fm.write(b'reponame', b'[%s]\\n', b'baz')
98 98 ... files(ui, fm.nested(b'files', tmpl=b'{reponame}'))
99 99 ... fm.end()
100 100 >>> show(subrepos)
101 101 [baz]
102 102 foo
103 103 bar
104 104 >>> show(subrepos, template=b'{reponame}: {join(files % "{path}", ", ")}\\n')
105 105 baz: foo, bar
106 106 """
107 107
108 108 from __future__ import absolute_import, print_function
109 109
110 110 import collections
111 111 import contextlib
112 112 import itertools
113 113 import os
114 114
115 115 from .i18n import _
116 116 from .node import (
117 117 hex,
118 118 short,
119 119 )
120 120
121 121 from . import (
122 122 error,
123 123 pycompat,
124 124 templatefilters,
125 125 templatekw,
126 126 templater,
127 127 templateutil,
128 128 util,
129 129 )
130 130 from .utils import dateutil
131 131
132 132 pickle = util.pickle
133 133
134 134 class _nullconverter(object):
135 135 '''convert non-primitive data types to be processed by formatter'''
136 136
137 137 # set to True if context object should be stored as item
138 138 storecontext = False
139 139
140 140 @staticmethod
141 141 def wrapnested(data, tmpl, sep):
142 142 '''wrap nested data by appropriate type'''
143 143 return data
144 144 @staticmethod
145 145 def formatdate(date, fmt):
146 146 '''convert date tuple to appropriate format'''
147 return date
147 # timestamp can be float, but the canonical form should be int
148 ts, tz = date
149 return (int(ts), tz)
148 150 @staticmethod
149 151 def formatdict(data, key, value, fmt, sep):
150 152 '''convert dict or key-value pairs to appropriate dict format'''
151 153 # use plain dict instead of util.sortdict so that data can be
152 154 # serialized as a builtin dict in pickle output
153 155 return dict(data)
154 156 @staticmethod
155 157 def formatlist(data, name, fmt, sep):
156 158 '''convert iterable to appropriate list format'''
157 159 return list(data)
158 160
159 161 class baseformatter(object):
160 162 def __init__(self, ui, topic, opts, converter):
161 163 self._ui = ui
162 164 self._topic = topic
163 165 self._opts = opts
164 166 self._converter = converter
165 167 self._item = None
166 168 # function to convert node to string suitable for this output
167 169 self.hexfunc = hex
168 170 def __enter__(self):
169 171 return self
170 172 def __exit__(self, exctype, excvalue, traceback):
171 173 if exctype is None:
172 174 self.end()
173 175 def _showitem(self):
174 176 '''show a formatted item once all data is collected'''
175 177 def startitem(self):
176 178 '''begin an item in the format list'''
177 179 if self._item is not None:
178 180 self._showitem()
179 181 self._item = {}
180 182 def formatdate(self, date, fmt='%a %b %d %H:%M:%S %Y %1%2'):
181 183 '''convert date tuple to appropriate format'''
182 184 return self._converter.formatdate(date, fmt)
183 185 def formatdict(self, data, key='key', value='value', fmt=None, sep=' '):
184 186 '''convert dict or key-value pairs to appropriate dict format'''
185 187 return self._converter.formatdict(data, key, value, fmt, sep)
186 188 def formatlist(self, data, name, fmt=None, sep=' '):
187 189 '''convert iterable to appropriate list format'''
188 190 # name is mandatory argument for now, but it could be optional if
189 191 # we have default template keyword, e.g. {item}
190 192 return self._converter.formatlist(data, name, fmt, sep)
191 193 def context(self, **ctxs):
192 194 '''insert context objects to be used to render template keywords'''
193 195 ctxs = pycompat.byteskwargs(ctxs)
194 196 assert all(k in {'ctx', 'fctx'} for k in ctxs)
195 197 if self._converter.storecontext:
196 198 self._item.update(ctxs)
197 199 def data(self, **data):
198 200 '''insert data into item that's not shown in default output'''
199 201 data = pycompat.byteskwargs(data)
200 202 self._item.update(data)
201 203 def write(self, fields, deftext, *fielddata, **opts):
202 204 '''do default text output while assigning data to item'''
203 205 fieldkeys = fields.split()
204 206 assert len(fieldkeys) == len(fielddata)
205 207 self._item.update(zip(fieldkeys, fielddata))
206 208 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
207 209 '''do conditional write (primarily for plain formatter)'''
208 210 fieldkeys = fields.split()
209 211 assert len(fieldkeys) == len(fielddata)
210 212 self._item.update(zip(fieldkeys, fielddata))
211 213 def plain(self, text, **opts):
212 214 '''show raw text for non-templated mode'''
213 215 def isplain(self):
214 216 '''check for plain formatter usage'''
215 217 return False
216 218 def nested(self, field, tmpl=None, sep=''):
217 219 '''sub formatter to store nested data in the specified field'''
218 220 data = []
219 221 self._item[field] = self._converter.wrapnested(data, tmpl, sep)
220 222 return _nestedformatter(self._ui, self._converter, data)
221 223 def end(self):
222 224 '''end output for the formatter'''
223 225 if self._item is not None:
224 226 self._showitem()
225 227
226 228 def nullformatter(ui, topic, opts):
227 229 '''formatter that prints nothing'''
228 230 return baseformatter(ui, topic, opts, converter=_nullconverter)
229 231
230 232 class _nestedformatter(baseformatter):
231 233 '''build sub items and store them in the parent formatter'''
232 234 def __init__(self, ui, converter, data):
233 235 baseformatter.__init__(self, ui, topic='', opts={}, converter=converter)
234 236 self._data = data
235 237 def _showitem(self):
236 238 self._data.append(self._item)
237 239
238 240 def _iteritems(data):
239 241 '''iterate key-value pairs in stable order'''
240 242 if isinstance(data, dict):
241 243 return sorted(data.iteritems())
242 244 return data
243 245
244 246 class _plainconverter(object):
245 247 '''convert non-primitive data types to text'''
246 248
247 249 storecontext = False
248 250
249 251 @staticmethod
250 252 def wrapnested(data, tmpl, sep):
251 253 raise error.ProgrammingError('plainformatter should never be nested')
252 254 @staticmethod
253 255 def formatdate(date, fmt):
254 256 '''stringify date tuple in the given format'''
255 257 return dateutil.datestr(date, fmt)
256 258 @staticmethod
257 259 def formatdict(data, key, value, fmt, sep):
258 260 '''stringify key-value pairs separated by sep'''
259 261 prefmt = pycompat.identity
260 262 if fmt is None:
261 263 fmt = '%s=%s'
262 264 prefmt = pycompat.bytestr
263 265 return sep.join(fmt % (prefmt(k), prefmt(v))
264 266 for k, v in _iteritems(data))
265 267 @staticmethod
266 268 def formatlist(data, name, fmt, sep):
267 269 '''stringify iterable separated by sep'''
268 270 prefmt = pycompat.identity
269 271 if fmt is None:
270 272 fmt = '%s'
271 273 prefmt = pycompat.bytestr
272 274 return sep.join(fmt % prefmt(e) for e in data)
273 275
274 276 class plainformatter(baseformatter):
275 277 '''the default text output scheme'''
276 278 def __init__(self, ui, out, topic, opts):
277 279 baseformatter.__init__(self, ui, topic, opts, _plainconverter)
278 280 if ui.debugflag:
279 281 self.hexfunc = hex
280 282 else:
281 283 self.hexfunc = short
282 284 if ui is out:
283 285 self._write = ui.write
284 286 else:
285 287 self._write = lambda s, **opts: out.write(s)
286 288 def startitem(self):
287 289 pass
288 290 def data(self, **data):
289 291 pass
290 292 def write(self, fields, deftext, *fielddata, **opts):
291 293 self._write(deftext % fielddata, **opts)
292 294 def condwrite(self, cond, fields, deftext, *fielddata, **opts):
293 295 '''do conditional write'''
294 296 if cond:
295 297 self._write(deftext % fielddata, **opts)
296 298 def plain(self, text, **opts):
297 299 self._write(text, **opts)
298 300 def isplain(self):
299 301 return True
300 302 def nested(self, field, tmpl=None, sep=''):
301 303 # nested data will be directly written to ui
302 304 return self
303 305 def end(self):
304 306 pass
305 307
306 308 class debugformatter(baseformatter):
307 309 def __init__(self, ui, out, topic, opts):
308 310 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
309 311 self._out = out
310 312 self._out.write("%s = [\n" % self._topic)
311 313 def _showitem(self):
312 314 self._out.write(' %s,\n' % pycompat.byterepr(self._item))
313 315 def end(self):
314 316 baseformatter.end(self)
315 317 self._out.write("]\n")
316 318
317 319 class pickleformatter(baseformatter):
318 320 def __init__(self, ui, out, topic, opts):
319 321 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
320 322 self._out = out
321 323 self._data = []
322 324 def _showitem(self):
323 325 self._data.append(self._item)
324 326 def end(self):
325 327 baseformatter.end(self)
326 328 self._out.write(pickle.dumps(self._data))
327 329
328 330 class jsonformatter(baseformatter):
329 331 def __init__(self, ui, out, topic, opts):
330 332 baseformatter.__init__(self, ui, topic, opts, _nullconverter)
331 333 self._out = out
332 334 self._out.write("[")
333 335 self._first = True
334 336 def _showitem(self):
335 337 if self._first:
336 338 self._first = False
337 339 else:
338 340 self._out.write(",")
339 341
340 342 self._out.write("\n {\n")
341 343 first = True
342 344 for k, v in sorted(self._item.items()):
343 345 if first:
344 346 first = False
345 347 else:
346 348 self._out.write(",\n")
347 349 u = templatefilters.json(v, paranoid=False)
348 350 self._out.write(' "%s": %s' % (k, u))
349 351 self._out.write("\n }")
350 352 def end(self):
351 353 baseformatter.end(self)
352 354 self._out.write("\n]\n")
353 355
354 356 class _templateconverter(object):
355 357 '''convert non-primitive data types to be processed by templater'''
356 358
357 359 storecontext = True
358 360
359 361 @staticmethod
360 362 def wrapnested(data, tmpl, sep):
361 363 '''wrap nested data by templatable type'''
362 364 return templateutil.mappinglist(data, tmpl=tmpl, sep=sep)
363 365 @staticmethod
364 366 def formatdate(date, fmt):
365 367 '''return date tuple'''
366 368 return date
367 369 @staticmethod
368 370 def formatdict(data, key, value, fmt, sep):
369 371 '''build object that can be evaluated as either plain string or dict'''
370 372 data = util.sortdict(_iteritems(data))
371 373 def f():
372 374 yield _plainconverter.formatdict(data, key, value, fmt, sep)
373 375 return templateutil.hybriddict(data, key=key, value=value, fmt=fmt,
374 376 gen=f)
375 377 @staticmethod
376 378 def formatlist(data, name, fmt, sep):
377 379 '''build object that can be evaluated as either plain string or list'''
378 380 data = list(data)
379 381 def f():
380 382 yield _plainconverter.formatlist(data, name, fmt, sep)
381 383 return templateutil.hybridlist(data, name=name, fmt=fmt, gen=f)
382 384
383 385 class templateformatter(baseformatter):
384 386 def __init__(self, ui, out, topic, opts):
385 387 baseformatter.__init__(self, ui, topic, opts, _templateconverter)
386 388 self._out = out
387 389 spec = lookuptemplate(ui, topic, opts.get('template', ''))
388 390 self._tref = spec.ref
389 391 self._t = loadtemplater(ui, spec, defaults=templatekw.keywords,
390 392 resources=templateresources(ui),
391 393 cache=templatekw.defaulttempl)
392 394 self._parts = templatepartsmap(spec, self._t,
393 395 ['docheader', 'docfooter', 'separator'])
394 396 self._counter = itertools.count()
395 397 self._renderitem('docheader', {})
396 398
397 399 def _showitem(self):
398 400 item = self._item.copy()
399 401 item['index'] = index = next(self._counter)
400 402 if index > 0:
401 403 self._renderitem('separator', {})
402 404 self._renderitem(self._tref, item)
403 405
404 406 def _renderitem(self, part, item):
405 407 if part not in self._parts:
406 408 return
407 409 ref = self._parts[part]
408 410 self._out.write(self._t.render(ref, item))
409 411
410 412 def end(self):
411 413 baseformatter.end(self)
412 414 self._renderitem('docfooter', {})
413 415
414 416 templatespec = collections.namedtuple(r'templatespec',
415 417 r'ref tmpl mapfile')
416 418
417 419 def lookuptemplate(ui, topic, tmpl):
418 420 """Find the template matching the given -T/--template spec 'tmpl'
419 421
420 422 'tmpl' can be any of the following:
421 423
422 424 - a literal template (e.g. '{rev}')
423 425 - a map-file name or path (e.g. 'changelog')
424 426 - a reference to [templates] in config file
425 427 - a path to raw template file
426 428
427 429 A map file defines a stand-alone template environment. If a map file
428 430 selected, all templates defined in the file will be loaded, and the
429 431 template matching the given topic will be rendered. Aliases won't be
430 432 loaded from user config, but from the map file.
431 433
432 434 If no map file selected, all templates in [templates] section will be
433 435 available as well as aliases in [templatealias].
434 436 """
435 437
436 438 # looks like a literal template?
437 439 if '{' in tmpl:
438 440 return templatespec('', tmpl, None)
439 441
440 442 # perhaps a stock style?
441 443 if not os.path.split(tmpl)[0]:
442 444 mapname = (templater.templatepath('map-cmdline.' + tmpl)
443 445 or templater.templatepath(tmpl))
444 446 if mapname and os.path.isfile(mapname):
445 447 return templatespec(topic, None, mapname)
446 448
447 449 # perhaps it's a reference to [templates]
448 450 if ui.config('templates', tmpl):
449 451 return templatespec(tmpl, None, None)
450 452
451 453 if tmpl == 'list':
452 454 ui.write(_("available styles: %s\n") % templater.stylelist())
453 455 raise error.Abort(_("specify a template"))
454 456
455 457 # perhaps it's a path to a map or a template
456 458 if ('/' in tmpl or '\\' in tmpl) and os.path.isfile(tmpl):
457 459 # is it a mapfile for a style?
458 460 if os.path.basename(tmpl).startswith("map-"):
459 461 return templatespec(topic, None, os.path.realpath(tmpl))
460 462 with util.posixfile(tmpl, 'rb') as f:
461 463 tmpl = f.read()
462 464 return templatespec('', tmpl, None)
463 465
464 466 # constant string?
465 467 return templatespec('', tmpl, None)
466 468
467 469 def templatepartsmap(spec, t, partnames):
468 470 """Create a mapping of {part: ref}"""
469 471 partsmap = {spec.ref: spec.ref} # initial ref must exist in t
470 472 if spec.mapfile:
471 473 partsmap.update((p, p) for p in partnames if p in t)
472 474 elif spec.ref:
473 475 for part in partnames:
474 476 ref = '%s:%s' % (spec.ref, part) # select config sub-section
475 477 if ref in t:
476 478 partsmap[part] = ref
477 479 return partsmap
478 480
479 481 def loadtemplater(ui, spec, defaults=None, resources=None, cache=None):
480 482 """Create a templater from either a literal template or loading from
481 483 a map file"""
482 484 assert not (spec.tmpl and spec.mapfile)
483 485 if spec.mapfile:
484 486 frommapfile = templater.templater.frommapfile
485 487 return frommapfile(spec.mapfile, defaults=defaults, resources=resources,
486 488 cache=cache)
487 489 return maketemplater(ui, spec.tmpl, defaults=defaults, resources=resources,
488 490 cache=cache)
489 491
490 492 def maketemplater(ui, tmpl, defaults=None, resources=None, cache=None):
491 493 """Create a templater from a string template 'tmpl'"""
492 494 aliases = ui.configitems('templatealias')
493 495 t = templater.templater(defaults=defaults, resources=resources,
494 496 cache=cache, aliases=aliases)
495 497 t.cache.update((k, templater.unquotestring(v))
496 498 for k, v in ui.configitems('templates'))
497 499 if tmpl:
498 500 t.cache[''] = tmpl
499 501 return t
500 502
501 503 class templateresources(templater.resourcemapper):
502 504 """Resource mapper designed for the default templatekw and function"""
503 505
504 506 def __init__(self, ui, repo=None):
505 507 self._resmap = {
506 508 'cache': {}, # for templatekw/funcs to store reusable data
507 509 'repo': repo,
508 510 'ui': ui,
509 511 }
510 512
511 513 def availablekeys(self, context, mapping):
512 514 return {k for k, g in self._gettermap.iteritems()
513 515 if g(self, context, mapping, k) is not None}
514 516
515 517 def knownkeys(self):
516 518 return self._knownkeys
517 519
518 520 def lookup(self, context, mapping, key):
519 521 get = self._gettermap.get(key)
520 522 if not get:
521 523 return None
522 524 return get(self, context, mapping, key)
523 525
524 526 def populatemap(self, context, origmapping, newmapping):
525 527 mapping = {}
526 528 if self._hasctx(newmapping):
527 529 mapping['revcache'] = {} # per-ctx cache
528 530 if (('node' in origmapping or self._hasctx(origmapping))
529 531 and ('node' in newmapping or self._hasctx(newmapping))):
530 532 orignode = templateutil.runsymbol(context, origmapping, 'node')
531 533 mapping['originalnode'] = orignode
532 534 return mapping
533 535
534 536 def _getsome(self, context, mapping, key):
535 537 v = mapping.get(key)
536 538 if v is not None:
537 539 return v
538 540 return self._resmap.get(key)
539 541
540 542 def _hasctx(self, mapping):
541 543 return 'ctx' in mapping or 'fctx' in mapping
542 544
543 545 def _getctx(self, context, mapping, key):
544 546 ctx = mapping.get('ctx')
545 547 if ctx is not None:
546 548 return ctx
547 549 fctx = mapping.get('fctx')
548 550 if fctx is not None:
549 551 return fctx.changectx()
550 552
551 553 def _getrepo(self, context, mapping, key):
552 554 ctx = self._getctx(context, mapping, 'ctx')
553 555 if ctx is not None:
554 556 return ctx.repo()
555 557 return self._getsome(context, mapping, key)
556 558
557 559 _gettermap = {
558 560 'cache': _getsome,
559 561 'ctx': _getctx,
560 562 'fctx': _getsome,
561 563 'repo': _getrepo,
562 564 'revcache': _getsome,
563 565 'ui': _getsome,
564 566 }
565 567 _knownkeys = set(_gettermap.keys())
566 568
567 569 def formatter(ui, out, topic, opts):
568 570 template = opts.get("template", "")
569 571 if template == "json":
570 572 return jsonformatter(ui, out, topic, opts)
571 573 elif template == "pickle":
572 574 return pickleformatter(ui, out, topic, opts)
573 575 elif template == "debug":
574 576 return debugformatter(ui, out, topic, opts)
575 577 elif template != "":
576 578 return templateformatter(ui, out, topic, opts)
577 579 # developer config: ui.formatdebug
578 580 elif ui.configbool('ui', 'formatdebug'):
579 581 return debugformatter(ui, out, topic, opts)
580 582 # deprecated config: ui.formatjson
581 583 elif ui.configbool('ui', 'formatjson'):
582 584 return jsonformatter(ui, out, topic, opts)
583 585 return plainformatter(ui, out, topic, opts)
584 586
585 587 @contextlib.contextmanager
586 588 def openformatter(ui, filename, topic, opts):
587 589 """Create a formatter that writes outputs to the specified file
588 590
589 591 Must be invoked using the 'with' statement.
590 592 """
591 593 with util.posixfile(filename, 'wb') as out:
592 594 with formatter(ui, out, topic, opts) as fm:
593 595 yield fm
594 596
595 597 @contextlib.contextmanager
596 598 def _neverending(fm):
597 599 yield fm
598 600
599 601 def maybereopen(fm, filename):
600 602 """Create a formatter backed by file if filename specified, else return
601 603 the given formatter
602 604
603 605 Must be invoked using the 'with' statement. This will never call fm.end()
604 606 of the given formatter.
605 607 """
606 608 if filename:
607 609 return openformatter(fm._ui, filename, fm._topic, fm._opts)
608 610 else:
609 611 return _neverending(fm)
@@ -1,367 +1,367 b''
1 1 $ hg init repo
2 2 $ cd repo
3 3 $ touch foo
4 4 $ hg add foo
5 5 $ for i in 0 1 2 3 4 5 6 7 8 9 10 11; do
6 6 > echo "foo-$i" >> foo
7 7 > hg ci -m "foo-$i"
8 8 > done
9 9
10 10 $ for out in "%nof%N" "%%%H" "%b-%R" "%h" "%r" "%m"; do
11 11 > echo
12 12 > echo "# foo-$out.patch"
13 13 > hg export -v -o "foo-$out.patch" 2:tip
14 14 > done
15 15
16 16 # foo-%nof%N.patch
17 17 exporting patches:
18 18 foo-01of10.patch
19 19 foo-02of10.patch
20 20 foo-03of10.patch
21 21 foo-04of10.patch
22 22 foo-05of10.patch
23 23 foo-06of10.patch
24 24 foo-07of10.patch
25 25 foo-08of10.patch
26 26 foo-09of10.patch
27 27 foo-10of10.patch
28 28
29 29 # foo-%%%H.patch
30 30 exporting patches:
31 31 foo-%617188a1c80f869a7b66c85134da88a6fb145f67.patch
32 32 foo-%dd41a5ff707a5225204105611ba49cc5c229d55f.patch
33 33 foo-%f95a5410f8664b6e1490a4af654e4b7d41a7b321.patch
34 34 foo-%4346bcfde53b4d9042489078bcfa9c3e28201db2.patch
35 35 foo-%afda8c3a009cc99449a05ad8aa4655648c4ecd34.patch
36 36 foo-%35284ce2b6b99c9d2ac66268fe99e68e1974e1aa.patch
37 37 foo-%9688c41894e6931305fa7165a37f6568050b4e9b.patch
38 38 foo-%747d3c68f8ec44bb35816bfcd59aeb50b9654c2f.patch
39 39 foo-%5f17a83f5fbd9414006a5e563eab4c8a00729efd.patch
40 40 foo-%f3acbafac161ec68f1598af38f794f28847ca5d3.patch
41 41
42 42 # foo-%b-%R.patch
43 43 exporting patches:
44 44 foo-repo-2.patch
45 45 foo-repo-3.patch
46 46 foo-repo-4.patch
47 47 foo-repo-5.patch
48 48 foo-repo-6.patch
49 49 foo-repo-7.patch
50 50 foo-repo-8.patch
51 51 foo-repo-9.patch
52 52 foo-repo-10.patch
53 53 foo-repo-11.patch
54 54
55 55 # foo-%h.patch
56 56 exporting patches:
57 57 foo-617188a1c80f.patch
58 58 foo-dd41a5ff707a.patch
59 59 foo-f95a5410f866.patch
60 60 foo-4346bcfde53b.patch
61 61 foo-afda8c3a009c.patch
62 62 foo-35284ce2b6b9.patch
63 63 foo-9688c41894e6.patch
64 64 foo-747d3c68f8ec.patch
65 65 foo-5f17a83f5fbd.patch
66 66 foo-f3acbafac161.patch
67 67
68 68 # foo-%r.patch
69 69 exporting patches:
70 70 foo-02.patch
71 71 foo-03.patch
72 72 foo-04.patch
73 73 foo-05.patch
74 74 foo-06.patch
75 75 foo-07.patch
76 76 foo-08.patch
77 77 foo-09.patch
78 78 foo-10.patch
79 79 foo-11.patch
80 80
81 81 # foo-%m.patch
82 82 exporting patches:
83 83 foo-foo_2.patch
84 84 foo-foo_3.patch
85 85 foo-foo_4.patch
86 86 foo-foo_5.patch
87 87 foo-foo_6.patch
88 88 foo-foo_7.patch
89 89 foo-foo_8.patch
90 90 foo-foo_9.patch
91 91 foo-foo_10.patch
92 92 foo-foo_11.patch
93 93
94 94 Doing it again clobbers the files rather than appending:
95 95 $ hg export -v -o "foo-%m.patch" 2:3
96 96 exporting patches:
97 97 foo-foo_2.patch
98 98 foo-foo_3.patch
99 99 $ grep HG foo-foo_2.patch | wc -l
100 100 \s*1 (re)
101 101 $ grep HG foo-foo_3.patch | wc -l
102 102 \s*1 (re)
103 103
104 104 Exporting 4 changesets to a file:
105 105
106 106 $ hg export -o export_internal 1 2 3 4
107 107 $ grep HG export_internal | wc -l
108 108 \s*4 (re)
109 109
110 110 Doing it again clobbers the file rather than appending:
111 111 $ hg export -o export_internal 1 2 3 4
112 112 $ grep HG export_internal | wc -l
113 113 \s*4 (re)
114 114
115 115 Exporting 4 changesets to stdout:
116 116
117 117 $ hg export 1 2 3 4 | grep HG | wc -l
118 118 \s*4 (re)
119 119
120 120 Exporting revision -2 to a file:
121 121
122 122 $ hg export -- -2
123 123 # HG changeset patch
124 124 # User test
125 125 # Date 0 0
126 126 # Thu Jan 01 00:00:00 1970 +0000
127 127 # Node ID 5f17a83f5fbd9414006a5e563eab4c8a00729efd
128 128 # Parent 747d3c68f8ec44bb35816bfcd59aeb50b9654c2f
129 129 foo-10
130 130
131 131 diff -r 747d3c68f8ec -r 5f17a83f5fbd foo
132 132 --- a/foo Thu Jan 01 00:00:00 1970 +0000
133 133 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
134 134 @@ -8,3 +8,4 @@
135 135 foo-7
136 136 foo-8
137 137 foo-9
138 138 +foo-10
139 139
140 140 Exporting wdir revision:
141 141
142 142 $ echo "foo-wdir" >> foo
143 143 $ hg export 'wdir()'
144 144 # HG changeset patch
145 145 # User test
146 146 # Date 0 0
147 147 # Thu Jan 01 00:00:00 1970 +0000
148 148 # Node ID ffffffffffffffffffffffffffffffffffffffff
149 149 # Parent f3acbafac161ec68f1598af38f794f28847ca5d3
150 150
151 151
152 152 diff -r f3acbafac161 foo
153 153 --- a/foo Thu Jan 01 00:00:00 1970 +0000
154 154 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
155 155 @@ -10,3 +10,4 @@
156 156 foo-9
157 157 foo-10
158 158 foo-11
159 159 +foo-wdir
160 160 $ hg revert -q foo
161 161
162 162 Templated output to stdout:
163 163
164 164 $ hg export -Tjson 0
165 165 [
166 166 {
167 167 "branch": "default",
168 "date": [0.0, 0],
168 "date": [0, 0],
169 169 "desc": "foo-0",
170 170 "diff": "diff -r 000000000000 -r 871558de6af2 foo\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n@@ -0,0 +1,1 @@\n+foo-0\n",
171 171 "node": "871558de6af2e8c244222f8eea69b782c94ce3df",
172 172 "parents": [],
173 173 "user": "test"
174 174 }
175 175 ]
176 176
177 177 Templated output to single file:
178 178
179 179 $ hg export -Tjson 0:1 -o out.json
180 180 $ cat out.json
181 181 [
182 182 {
183 183 "branch": "default",
184 "date": [0.0, 0],
184 "date": [0, 0],
185 185 "desc": "foo-0",
186 186 "diff": "diff -r 000000000000 -r 871558de6af2 foo\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n@@ -0,0 +1,1 @@\n+foo-0\n",
187 187 "node": "871558de6af2e8c244222f8eea69b782c94ce3df",
188 188 "parents": [],
189 189 "user": "test"
190 190 },
191 191 {
192 192 "branch": "default",
193 "date": [0.0, 0],
193 "date": [0, 0],
194 194 "desc": "foo-1",
195 195 "diff": "diff -r 871558de6af2 -r d1c9656e973c foo\n--- a/foo\tThu Jan 01 00:00:00 1970 +0000\n+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +1,2 @@\n foo-0\n+foo-1\n",
196 196 "node": "d1c9656e973cfb5aebd5499bbd2cb350e3b12266",
197 197 "parents": ["871558de6af2e8c244222f8eea69b782c94ce3df"],
198 198 "user": "test"
199 199 }
200 200 ]
201 201
202 202 Templated output to multiple files:
203 203
204 204 $ hg export -Tjson 0:1 -o 'out-{rev}.json'
205 205 $ cat out-0.json
206 206 [
207 207 {
208 208 "branch": "default",
209 "date": [0.0, 0],
209 "date": [0, 0],
210 210 "desc": "foo-0",
211 211 "diff": "diff -r 000000000000 -r 871558de6af2 foo\n--- /dev/null\tThu Jan 01 00:00:00 1970 +0000\n+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n@@ -0,0 +1,1 @@\n+foo-0\n",
212 212 "node": "871558de6af2e8c244222f8eea69b782c94ce3df",
213 213 "parents": [],
214 214 "user": "test"
215 215 }
216 216 ]
217 217 $ cat out-1.json
218 218 [
219 219 {
220 220 "branch": "default",
221 "date": [0.0, 0],
221 "date": [0, 0],
222 222 "desc": "foo-1",
223 223 "diff": "diff -r 871558de6af2 -r d1c9656e973c foo\n--- a/foo\tThu Jan 01 00:00:00 1970 +0000\n+++ b/foo\tThu Jan 01 00:00:00 1970 +0000\n@@ -1,1 +1,2 @@\n foo-0\n+foo-1\n",
224 224 "node": "d1c9656e973cfb5aebd5499bbd2cb350e3b12266",
225 225 "parents": ["871558de6af2e8c244222f8eea69b782c94ce3df"],
226 226 "user": "test"
227 227 }
228 228 ]
229 229
230 230 Template keywrods:
231 231
232 232 $ hg export 0 -T '# {node|shortest}\n\n{diff}'
233 233 # 8715
234 234
235 235 diff -r 000000000000 -r 871558de6af2 foo
236 236 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
237 237 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
238 238 @@ -0,0 +1,1 @@
239 239 +foo-0
240 240
241 241 No filename should be printed if stdout is specified explicitly:
242 242
243 243 $ hg export -v 1 -o -
244 244 exporting patch:
245 245 # HG changeset patch
246 246 # User test
247 247 # Date 0 0
248 248 # Thu Jan 01 00:00:00 1970 +0000
249 249 # Node ID d1c9656e973cfb5aebd5499bbd2cb350e3b12266
250 250 # Parent 871558de6af2e8c244222f8eea69b782c94ce3df
251 251 foo-1
252 252
253 253 diff -r 871558de6af2 -r d1c9656e973c foo
254 254 --- a/foo Thu Jan 01 00:00:00 1970 +0000
255 255 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
256 256 @@ -1,1 +1,2 @@
257 257 foo-0
258 258 +foo-1
259 259
260 260 Checking if only alphanumeric characters are used in the file name (%m option):
261 261
262 262 $ echo "line" >> foo
263 263 $ hg commit -m " !\"#$%&(,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]"'^'"_\`abcdefghijklmnopqrstuvwxyz{|}~"
264 264 $ hg export -v -o %m.patch tip
265 265 exporting patch:
266 266 ___________0123456789_______ABCDEFGHIJKLMNOPQRSTUVWXYZ______abcdefghijklmnopqrstuvwxyz____.patch
267 267
268 268 Template fragments in file name:
269 269
270 270 $ hg export -v -o '{node|shortest}.patch' tip
271 271 exporting patch:
272 272 197e.patch
273 273
274 274 Backslash should be preserved because it is a directory separator on Windows:
275 275
276 276 $ mkdir out
277 277 $ hg export -v -o 'out\{node|shortest}.patch' tip
278 278 exporting patch:
279 279 out\197e.patch
280 280
281 281 Still backslash is taken as an escape character in inner template strings:
282 282
283 283 $ hg export -v -o '{"out\{foo}.patch"}' tip
284 284 exporting patch:
285 285 out{foo}.patch
286 286
287 287 Invalid pattern in file name:
288 288
289 289 $ hg export -o '%x.patch' tip
290 290 abort: invalid format spec '%x' in output filename
291 291 [255]
292 292 $ hg export -o '%' tip
293 293 abort: incomplete format spec in output filename
294 294 [255]
295 295 $ hg export -o '%{"foo"}' tip
296 296 abort: incomplete format spec in output filename
297 297 [255]
298 298 $ hg export -o '%m{' tip
299 299 hg: parse error at 3: unterminated template expansion
300 300 (%m{
301 301 ^ here)
302 302 [255]
303 303 $ hg export -o '%\' tip
304 304 abort: invalid format spec '%\' in output filename
305 305 [255]
306 306 $ hg export -o '\%' tip
307 307 abort: incomplete format spec in output filename
308 308 [255]
309 309
310 310 Catch exporting unknown revisions (especially empty revsets, see issue3353)
311 311
312 312 $ hg export
313 313 # HG changeset patch
314 314 # User test
315 315 # Date 0 0
316 316 # Thu Jan 01 00:00:00 1970 +0000
317 317 # Node ID 197ecd81a57f760b54f34a58817ad5b04991fa47
318 318 # Parent f3acbafac161ec68f1598af38f794f28847ca5d3
319 319 !"#$%&(,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
320 320
321 321 diff -r f3acbafac161 -r 197ecd81a57f foo
322 322 --- a/foo Thu Jan 01 00:00:00 1970 +0000
323 323 +++ b/foo Thu Jan 01 00:00:00 1970 +0000
324 324 @@ -10,3 +10,4 @@
325 325 foo-9
326 326 foo-10
327 327 foo-11
328 328 +line
329 329
330 330 $ hg export ""
331 331 hg: parse error: empty query
332 332 [255]
333 333 $ hg export 999
334 334 abort: unknown revision '999'!
335 335 [255]
336 336 $ hg export "not all()"
337 337 abort: export requires at least one changeset
338 338 [255]
339 339
340 340 Check for color output
341 341 $ cat <<EOF >> $HGRCPATH
342 342 > [color]
343 343 > mode = ansi
344 344 > [extensions]
345 345 > color =
346 346 > EOF
347 347
348 348 $ hg export --color always --nodates tip
349 349 # HG changeset patch
350 350 # User test
351 351 # Date 0 0
352 352 # Thu Jan 01 00:00:00 1970 +0000
353 353 # Node ID * (glob)
354 354 # Parent * (glob)
355 355 !"#$%&(,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
356 356
357 357 \x1b[0;1mdiff -r f3acbafac161 -r 197ecd81a57f foo\x1b[0m (esc)
358 358 \x1b[0;31;1m--- a/foo\x1b[0m (esc)
359 359 \x1b[0;32;1m+++ b/foo\x1b[0m (esc)
360 360 \x1b[0;35m@@ -10,3 +10,4 @@\x1b[0m (esc)
361 361 foo-9
362 362 foo-10
363 363 foo-11
364 364 \x1b[0;32m+line\x1b[0m (esc)
365 365
366 366
367 367 $ cd ..
@@ -1,370 +1,370 b''
1 1 $ hg init t
2 2 $ cd t
3 3 $ echo import > port
4 4 $ hg add port
5 5 $ hg commit -m 0 -u spam -d '0 0'
6 6 $ echo export >> port
7 7 $ hg commit -m 1 -u eggs -d '1 0'
8 8 $ echo export > port
9 9 $ echo vaportight >> port
10 10 $ echo 'import/export' >> port
11 11 $ hg commit -m 2 -u spam -d '2 0'
12 12 $ echo 'import/export' >> port
13 13 $ hg commit -m 3 -u eggs -d '3 0'
14 14 $ head -n 3 port > port1
15 15 $ mv port1 port
16 16 $ hg commit -m 4 -u spam -d '4 0'
17 17
18 18 pattern error
19 19
20 20 $ hg grep '**test**'
21 21 grep: invalid match pattern: nothing to repeat
22 22 [1]
23 23
24 24 simple
25 25
26 26 $ hg grep '.*'
27 27 port:4:export
28 28 port:4:vaportight
29 29 port:4:import/export
30 30 $ hg grep port port
31 31 port:4:export
32 32 port:4:vaportight
33 33 port:4:import/export
34 34
35 35 simple with color
36 36
37 37 $ hg --config extensions.color= grep --config color.mode=ansi \
38 38 > --color=always port port
39 39 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc)
40 40 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc)
41 41 \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc)
42 42
43 43 simple templated
44 44
45 45 $ hg grep port \
46 46 > -T '{file}:{rev}:{node|short}:{texts % "{if(matched, text|upper, text)}"}\n'
47 47 port:4:914fa752cdea:exPORT
48 48 port:4:914fa752cdea:vaPORTight
49 49 port:4:914fa752cdea:imPORT/exPORT
50 50
51 51 $ hg grep port -T '{file}:{rev}:{texts}\n'
52 52 port:4:export
53 53 port:4:vaportight
54 54 port:4:import/export
55 55
56 56 simple JSON (no "change" field)
57 57
58 58 $ hg grep -Tjson port
59 59 [
60 60 {
61 "date": [4.0, 0],
61 "date": [4, 0],
62 62 "file": "port",
63 63 "line_number": 1,
64 64 "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
65 65 "rev": 4,
66 66 "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}],
67 67 "user": "spam"
68 68 },
69 69 {
70 "date": [4.0, 0],
70 "date": [4, 0],
71 71 "file": "port",
72 72 "line_number": 2,
73 73 "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
74 74 "rev": 4,
75 75 "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}],
76 76 "user": "spam"
77 77 },
78 78 {
79 "date": [4.0, 0],
79 "date": [4, 0],
80 80 "file": "port",
81 81 "line_number": 3,
82 82 "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
83 83 "rev": 4,
84 84 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}],
85 85 "user": "spam"
86 86 }
87 87 ]
88 88
89 89 simple JSON without matching lines
90 90
91 91 $ hg grep -Tjson -l port
92 92 [
93 93 {
94 "date": [4.0, 0],
94 "date": [4, 0],
95 95 "file": "port",
96 96 "line_number": 1,
97 97 "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
98 98 "rev": 4,
99 99 "user": "spam"
100 100 }
101 101 ]
102 102
103 103 all
104 104
105 105 $ hg grep --traceback --all -nu port port
106 106 port:4:4:-:spam:import/export
107 107 port:3:4:+:eggs:import/export
108 108 port:2:1:-:spam:import
109 109 port:2:2:-:spam:export
110 110 port:2:1:+:spam:export
111 111 port:2:2:+:spam:vaportight
112 112 port:2:3:+:spam:import/export
113 113 port:1:2:+:eggs:export
114 114 port:0:1:+:spam:import
115 115
116 116 all JSON
117 117
118 118 $ hg grep --all -Tjson port port
119 119 [
120 120 {
121 121 "change": "-",
122 "date": [4.0, 0],
122 "date": [4, 0],
123 123 "file": "port",
124 124 "line_number": 4,
125 125 "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c",
126 126 "rev": 4,
127 127 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}],
128 128 "user": "spam"
129 129 },
130 130 {
131 131 "change": "+",
132 "date": [3.0, 0],
132 "date": [3, 0],
133 133 "file": "port",
134 134 "line_number": 4,
135 135 "node": "95040cfd017d658c536071c6290230a613c4c2a6",
136 136 "rev": 3,
137 137 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}],
138 138 "user": "eggs"
139 139 },
140 140 {
141 141 "change": "-",
142 "date": [2.0, 0],
142 "date": [2, 0],
143 143 "file": "port",
144 144 "line_number": 1,
145 145 "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47",
146 146 "rev": 2,
147 147 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}],
148 148 "user": "spam"
149 149 },
150 150 {
151 151 "change": "-",
152 "date": [2.0, 0],
152 "date": [2, 0],
153 153 "file": "port",
154 154 "line_number": 2,
155 155 "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47",
156 156 "rev": 2,
157 157 "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}],
158 158 "user": "spam"
159 159 },
160 160 {
161 161 "change": "+",
162 "date": [2.0, 0],
162 "date": [2, 0],
163 163 "file": "port",
164 164 "line_number": 1,
165 165 "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47",
166 166 "rev": 2,
167 167 "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}],
168 168 "user": "spam"
169 169 },
170 170 {
171 171 "change": "+",
172 "date": [2.0, 0],
172 "date": [2, 0],
173 173 "file": "port",
174 174 "line_number": 2,
175 175 "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47",
176 176 "rev": 2,
177 177 "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}],
178 178 "user": "spam"
179 179 },
180 180 {
181 181 "change": "+",
182 "date": [2.0, 0],
182 "date": [2, 0],
183 183 "file": "port",
184 184 "line_number": 3,
185 185 "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47",
186 186 "rev": 2,
187 187 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}],
188 188 "user": "spam"
189 189 },
190 190 {
191 191 "change": "+",
192 "date": [1.0, 0],
192 "date": [1, 0],
193 193 "file": "port",
194 194 "line_number": 2,
195 195 "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587",
196 196 "rev": 1,
197 197 "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}],
198 198 "user": "eggs"
199 199 },
200 200 {
201 201 "change": "+",
202 "date": [0.0, 0],
202 "date": [0, 0],
203 203 "file": "port",
204 204 "line_number": 1,
205 205 "node": "f31323c9217050ba245ee8b537c713ec2e8ab226",
206 206 "rev": 0,
207 207 "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}],
208 208 "user": "spam"
209 209 }
210 210 ]
211 211
212 212 other
213 213
214 214 $ hg grep -l port port
215 215 port:4
216 216 $ hg grep import port
217 217 port:4:import/export
218 218
219 219 $ hg cp port port2
220 220 $ hg commit -m 4 -u spam -d '5 0'
221 221
222 222 follow
223 223
224 224 $ hg grep --traceback -f 'import\n\Z' port2
225 225 port:0:import
226 226
227 227 $ echo deport >> port2
228 228 $ hg commit -m 5 -u eggs -d '6 0'
229 229 $ hg grep -f --all -nu port port2
230 230 port2:6:4:+:eggs:deport
231 231 port:4:4:-:spam:import/export
232 232 port:3:4:+:eggs:import/export
233 233 port:2:1:-:spam:import
234 234 port:2:2:-:spam:export
235 235 port:2:1:+:spam:export
236 236 port:2:2:+:spam:vaportight
237 237 port:2:3:+:spam:import/export
238 238 port:1:2:+:eggs:export
239 239 port:0:1:+:spam:import
240 240
241 241 $ hg up -q null
242 242 $ hg grep -f port
243 243 [1]
244 244
245 245 Test wdir
246 246 (at least, this shouldn't crash)
247 247
248 248 $ hg up -q
249 249 $ echo wport >> port2
250 250 $ hg stat
251 251 M port2
252 252 $ hg grep -r 'wdir()' port
253 253 abort: working directory revision cannot be specified
254 254 [255]
255 255
256 256 $ cd ..
257 257 $ hg init t2
258 258 $ cd t2
259 259 $ hg grep foobar foo
260 260 [1]
261 261 $ hg grep foobar
262 262 [1]
263 263 $ echo blue >> color
264 264 $ echo black >> color
265 265 $ hg add color
266 266 $ hg ci -m 0
267 267 $ echo orange >> color
268 268 $ hg ci -m 1
269 269 $ echo black > color
270 270 $ hg ci -m 2
271 271 $ echo orange >> color
272 272 $ echo blue >> color
273 273 $ hg ci -m 3
274 274 $ hg grep orange
275 275 color:3:orange
276 276 $ hg grep --all orange
277 277 color:3:+:orange
278 278 color:2:-:orange
279 279 color:1:+:orange
280 280
281 281 test substring match: '^' should only match at the beginning
282 282
283 283 $ hg grep '^.' --config extensions.color= --color debug
284 284 [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lack
285 285 [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|o]range
286 286 [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lue
287 287
288 288 match in last "line" without newline
289 289
290 290 $ $PYTHON -c 'fp = open("noeol", "wb"); fp.write(b"no infinite loop"); fp.close();'
291 291 $ hg ci -Amnoeol
292 292 adding noeol
293 293 $ hg grep loop
294 294 noeol:4:no infinite loop
295 295
296 296 $ cd ..
297 297
298 298 Issue685: traceback in grep -r after rename
299 299
300 300 Got a traceback when using grep on a single
301 301 revision with renamed files.
302 302
303 303 $ hg init issue685
304 304 $ cd issue685
305 305 $ echo octarine > color
306 306 $ hg ci -Amcolor
307 307 adding color
308 308 $ hg rename color colour
309 309 $ hg ci -Am rename
310 310 $ hg grep octarine
311 311 colour:1:octarine
312 312 color:0:octarine
313 313
314 314 Used to crash here
315 315
316 316 $ hg grep -r 1 octarine
317 317 colour:1:octarine
318 318 $ cd ..
319 319
320 320
321 321 Issue337: test that grep follows parent-child relationships instead
322 322 of just using revision numbers.
323 323
324 324 $ hg init issue337
325 325 $ cd issue337
326 326
327 327 $ echo white > color
328 328 $ hg commit -A -m "0 white"
329 329 adding color
330 330
331 331 $ echo red > color
332 332 $ hg commit -A -m "1 red"
333 333
334 334 $ hg update 0
335 335 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
336 336 $ echo black > color
337 337 $ hg commit -A -m "2 black"
338 338 created new head
339 339
340 340 $ hg update --clean 1
341 341 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
342 342 $ echo blue > color
343 343 $ hg commit -A -m "3 blue"
344 344
345 345 $ hg grep --all red
346 346 color:3:-:red
347 347 color:1:+:red
348 348
349 349 Issue3885: test that changing revision order does not alter the
350 350 revisions printed, just their order.
351 351
352 352 $ hg grep --all red -r "all()"
353 353 color:1:+:red
354 354 color:3:-:red
355 355
356 356 $ hg grep --all red -r "reverse(all())"
357 357 color:3:-:red
358 358 color:1:+:red
359 359
360 360 $ cd ..
361 361
362 362 $ hg init a
363 363 $ cd a
364 364 $ cp "$TESTDIR/binfile.bin" .
365 365 $ hg add binfile.bin
366 366 $ hg ci -m 'add binfile.bin'
367 367 $ hg grep "MaCam" --all
368 368 binfile.bin:0:+: Binary file matches
369 369
370 370 $ cd ..
@@ -1,242 +1,242 b''
1 1 Tests for the journal extension; records bookmark locations.
2 2
3 3 $ cat >> testmocks.py << EOF
4 4 > # mock out procutil.getuser() and util.makedate() to supply testable values
5 5 > import os
6 6 > from mercurial import util, pycompat
7 7 > from mercurial.utils import dateutil, procutil
8 8 > def mockgetuser():
9 9 > return b'foobar'
10 10 >
11 11 > def mockmakedate():
12 12 > filename = os.path.join(os.environ['TESTTMP'], 'testtime')
13 13 > try:
14 14 > with open(filename, 'rb') as timef:
15 15 > time = float(timef.read()) + 1
16 16 > except IOError:
17 17 > time = 0.0
18 18 > with open(filename, 'wb') as timef:
19 19 > timef.write(pycompat.bytestr(time))
20 20 > return (time, 0)
21 21 >
22 22 > procutil.getuser = mockgetuser
23 23 > dateutil.makedate = mockmakedate
24 24 > EOF
25 25
26 26 $ cat >> $HGRCPATH << EOF
27 27 > [extensions]
28 28 > journal=
29 29 > testmocks=`pwd`/testmocks.py
30 30 > EOF
31 31
32 32 Setup repo
33 33
34 34 $ hg init repo
35 35 $ cd repo
36 36
37 37 Test empty journal
38 38
39 39 $ hg journal
40 40 previous locations of '.':
41 41 no recorded locations
42 42 $ hg journal foo
43 43 previous locations of 'foo':
44 44 no recorded locations
45 45
46 46 Test that working copy changes are tracked
47 47
48 48 $ echo a > a
49 49 $ hg commit -Aqm a
50 50 $ hg journal
51 51 previous locations of '.':
52 52 cb9a9f314b8b commit -Aqm a
53 53 $ echo b > a
54 54 $ hg commit -Aqm b
55 55 $ hg journal
56 56 previous locations of '.':
57 57 1e6c11564562 commit -Aqm b
58 58 cb9a9f314b8b commit -Aqm a
59 59 $ hg up 0
60 60 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
61 61 $ hg journal
62 62 previous locations of '.':
63 63 cb9a9f314b8b up 0
64 64 1e6c11564562 commit -Aqm b
65 65 cb9a9f314b8b commit -Aqm a
66 66
67 67 Test that bookmarks are tracked
68 68
69 69 $ hg book -r tip bar
70 70 $ hg journal bar
71 71 previous locations of 'bar':
72 72 1e6c11564562 book -r tip bar
73 73 $ hg book -f bar
74 74 $ hg journal bar
75 75 previous locations of 'bar':
76 76 cb9a9f314b8b book -f bar
77 77 1e6c11564562 book -r tip bar
78 78 $ hg up
79 79 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
80 80 updating bookmark bar
81 81 $ hg journal bar
82 82 previous locations of 'bar':
83 83 1e6c11564562 up
84 84 cb9a9f314b8b book -f bar
85 85 1e6c11564562 book -r tip bar
86 86
87 87 Test that bookmarks and working copy tracking is not mixed
88 88
89 89 $ hg journal
90 90 previous locations of '.':
91 91 1e6c11564562 up
92 92 cb9a9f314b8b up 0
93 93 1e6c11564562 commit -Aqm b
94 94 cb9a9f314b8b commit -Aqm a
95 95
96 96 Test that you can list all entries as well as limit the list or filter on them
97 97
98 98 $ hg book -r tip baz
99 99 $ hg journal --all
100 100 previous locations of the working copy and bookmarks:
101 101 1e6c11564562 baz book -r tip baz
102 102 1e6c11564562 bar up
103 103 1e6c11564562 . up
104 104 cb9a9f314b8b bar book -f bar
105 105 1e6c11564562 bar book -r tip bar
106 106 cb9a9f314b8b . up 0
107 107 1e6c11564562 . commit -Aqm b
108 108 cb9a9f314b8b . commit -Aqm a
109 109 $ hg journal --limit 2
110 110 previous locations of '.':
111 111 1e6c11564562 up
112 112 cb9a9f314b8b up 0
113 113 $ hg journal bar
114 114 previous locations of 'bar':
115 115 1e6c11564562 up
116 116 cb9a9f314b8b book -f bar
117 117 1e6c11564562 book -r tip bar
118 118 $ hg journal foo
119 119 previous locations of 'foo':
120 120 no recorded locations
121 121 $ hg journal .
122 122 previous locations of '.':
123 123 1e6c11564562 up
124 124 cb9a9f314b8b up 0
125 125 1e6c11564562 commit -Aqm b
126 126 cb9a9f314b8b commit -Aqm a
127 127 $ hg journal "re:ba."
128 128 previous locations of 're:ba.':
129 129 1e6c11564562 baz book -r tip baz
130 130 1e6c11564562 bar up
131 131 cb9a9f314b8b bar book -f bar
132 132 1e6c11564562 bar book -r tip bar
133 133
134 134 Test that verbose, JSON, template and commit output work
135 135
136 136 $ hg journal --verbose --all
137 137 previous locations of the working copy and bookmarks:
138 138 000000000000 -> 1e6c11564562 foobar baz 1970-01-01 00:00 +0000 book -r tip baz
139 139 cb9a9f314b8b -> 1e6c11564562 foobar bar 1970-01-01 00:00 +0000 up
140 140 cb9a9f314b8b -> 1e6c11564562 foobar . 1970-01-01 00:00 +0000 up
141 141 1e6c11564562 -> cb9a9f314b8b foobar bar 1970-01-01 00:00 +0000 book -f bar
142 142 000000000000 -> 1e6c11564562 foobar bar 1970-01-01 00:00 +0000 book -r tip bar
143 143 1e6c11564562 -> cb9a9f314b8b foobar . 1970-01-01 00:00 +0000 up 0
144 144 cb9a9f314b8b -> 1e6c11564562 foobar . 1970-01-01 00:00 +0000 commit -Aqm b
145 145 000000000000 -> cb9a9f314b8b foobar . 1970-01-01 00:00 +0000 commit -Aqm a
146 146 $ hg journal --verbose -Tjson
147 147 [
148 148 {
149 149 "command": "up",
150 "date": [5.0, 0],
150 "date": [5, 0],
151 151 "name": ".",
152 152 "newhashes": ["1e6c11564562b4ed919baca798bc4338bd299d6a"],
153 153 "oldhashes": ["cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b"],
154 154 "user": "foobar"
155 155 },
156 156 {
157 157 "command": "up 0",
158 "date": [2.0, 0],
158 "date": [2, 0],
159 159 "name": ".",
160 160 "newhashes": ["cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b"],
161 161 "oldhashes": ["1e6c11564562b4ed919baca798bc4338bd299d6a"],
162 162 "user": "foobar"
163 163 },
164 164 {
165 165 "command": "commit -Aqm b",
166 "date": [1.0, 0],
166 "date": [1, 0],
167 167 "name": ".",
168 168 "newhashes": ["1e6c11564562b4ed919baca798bc4338bd299d6a"],
169 169 "oldhashes": ["cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b"],
170 170 "user": "foobar"
171 171 },
172 172 {
173 173 "command": "commit -Aqm a",
174 "date": [0.0, 0],
174 "date": [0, 0],
175 175 "name": ".",
176 176 "newhashes": ["cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b"],
177 177 "oldhashes": ["0000000000000000000000000000000000000000"],
178 178 "user": "foobar"
179 179 }
180 180 ]
181 181
182 182 $ cat <<EOF >> $HGRCPATH
183 183 > [templates]
184 184 > j = "{oldhashes % '{node|upper}'} -> {newhashes % '{node|upper}'}
185 185 > - user: {user}
186 186 > - command: {command}
187 187 > - date: {date|rfc3339date}
188 188 > - newhashes: {newhashes}
189 189 > - oldhashes: {oldhashes}
190 190 > "
191 191 > EOF
192 192 $ hg journal -Tj -l1
193 193 previous locations of '.':
194 194 CB9A9F314B8B07BA71012FCDBC544B5A4D82FF5B -> 1E6C11564562B4ED919BACA798BC4338BD299D6A
195 195 - user: foobar
196 196 - command: up
197 197 - date: 1970-01-01T00:00:05+00:00
198 198 - newhashes: 1e6c11564562b4ed919baca798bc4338bd299d6a
199 199 - oldhashes: cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b
200 200
201 201 $ hg journal --commit
202 202 previous locations of '.':
203 203 1e6c11564562 up
204 204 changeset: 1:1e6c11564562
205 205 bookmark: bar
206 206 bookmark: baz
207 207 tag: tip
208 208 user: test
209 209 date: Thu Jan 01 00:00:00 1970 +0000
210 210 summary: b
211 211
212 212 cb9a9f314b8b up 0
213 213 changeset: 0:cb9a9f314b8b
214 214 user: test
215 215 date: Thu Jan 01 00:00:00 1970 +0000
216 216 summary: a
217 217
218 218 1e6c11564562 commit -Aqm b
219 219 changeset: 1:1e6c11564562
220 220 bookmark: bar
221 221 bookmark: baz
222 222 tag: tip
223 223 user: test
224 224 date: Thu Jan 01 00:00:00 1970 +0000
225 225 summary: b
226 226
227 227 cb9a9f314b8b commit -Aqm a
228 228 changeset: 0:cb9a9f314b8b
229 229 user: test
230 230 date: Thu Jan 01 00:00:00 1970 +0000
231 231 summary: a
232 232
233 233
234 234 Test for behaviour on unexpected storage version information
235 235
236 236 $ printf '42\0' > .hg/namejournal
237 237 $ hg journal
238 238 previous locations of '.':
239 239 abort: unknown journal file version '42'
240 240 [255]
241 241 $ hg book -r tip doomed
242 242 unsupported journal file version '42'
@@ -1,1618 +1,1618 b''
1 1 $ cat >> $HGRCPATH << EOF
2 2 > [phases]
3 3 > # public changeset are not obsolete
4 4 > publish=false
5 5 > [ui]
6 6 > logtemplate="{rev}:{node|short} ({phase}{if(obsolete, ' *{obsolete}*')}{if(instabilities, ' {instabilities}')}) [{tags} {bookmarks}] {desc|firstline}{if(obsfate, " [{join(obsfate, "; ")}]")}\n"
7 7 > EOF
8 8 $ mkcommit() {
9 9 > echo "$1" > "$1"
10 10 > hg add "$1"
11 11 > hg ci -m "add $1"
12 12 > }
13 13 $ getid() {
14 14 > hg log -T "{node}\n" --hidden -r "desc('$1')"
15 15 > }
16 16
17 17 $ cat > debugkeys.py <<EOF
18 18 > def reposetup(ui, repo):
19 19 > class debugkeysrepo(repo.__class__):
20 20 > def listkeys(self, namespace):
21 21 > ui.write(b'listkeys %s\n' % (namespace,))
22 22 > return super(debugkeysrepo, self).listkeys(namespace)
23 23 >
24 24 > if repo.local():
25 25 > repo.__class__ = debugkeysrepo
26 26 > EOF
27 27
28 28 $ hg init tmpa
29 29 $ cd tmpa
30 30 $ mkcommit kill_me
31 31
32 32 Checking that the feature is properly disabled
33 33
34 34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
35 35 abort: creating obsolete markers is not enabled on this repo
36 36 [255]
37 37
38 38 Enabling it
39 39
40 40 $ cat >> $HGRCPATH << EOF
41 41 > [experimental]
42 42 > evolution=exchange
43 43 > evolution.createmarkers=True
44 44 > EOF
45 45
46 46 Killing a single changeset without replacement
47 47
48 48 $ hg debugobsolete 0
49 49 abort: changeset references must be full hexadecimal node identifiers
50 50 [255]
51 51 $ hg debugobsolete '00'
52 52 abort: changeset references must be full hexadecimal node identifiers
53 53 [255]
54 54 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
55 55 obsoleted 1 changesets
56 56 $ hg debugobsolete
57 57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'babar'}
58 58
59 59 (test that mercurial is not confused)
60 60
61 61 $ hg up null --quiet # having 0 as parent prevents it to be hidden
62 62 $ hg tip
63 63 -1:000000000000 (public) [tip ]
64 64 $ hg up --hidden tip --quiet
65 65 updating to a hidden changeset 97b7c2d76b18
66 66 (hidden revision '97b7c2d76b18' is pruned)
67 67
68 68 Killing a single changeset with itself should fail
69 69 (simple local safeguard)
70 70
71 71 $ hg debugobsolete `getid kill_me` `getid kill_me`
72 72 abort: bad obsmarker input: in-marker cycle with 97b7c2d76b1845ed3eb988cd612611e72406cef0
73 73 [255]
74 74
75 75 $ cd ..
76 76
77 77 Killing a single changeset with replacement
78 78 (and testing the format option)
79 79
80 80 $ hg init tmpb
81 81 $ cd tmpb
82 82 $ mkcommit a
83 83 $ mkcommit b
84 84 $ mkcommit original_c
85 85 $ hg up "desc('b')"
86 86 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
87 87 $ mkcommit new_c
88 88 created new head
89 89 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
90 90 $ hg debugobsolete --config format.obsstore-version=0 --flag 12 `getid original_c` `getid new_c` -d '121 120'
91 91 obsoleted 1 changesets
92 92 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
93 93 2:245bde4270cd add original_c
94 94 $ hg debugrevlog -cd
95 95 # rev p1rev p2rev start end deltastart base p1 p2 rawsize totalsize compression heads chainlen
96 96 0 -1 -1 0 59 0 0 0 0 58 58 0 1 0
97 97 1 0 -1 59 118 59 59 0 0 58 116 0 1 0
98 98 2 1 -1 118 193 118 118 59 0 76 192 0 1 0
99 99 3 1 -1 193 260 193 193 59 0 66 258 0 2 0
100 100 $ hg debugobsolete
101 101 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
102 102
103 103 (check for version number of the obsstore)
104 104
105 105 $ dd bs=1 count=1 if=.hg/store/obsstore 2>/dev/null
106 106 \x00 (no-eol) (esc)
107 107
108 108 do it again (it read the obsstore before adding new changeset)
109 109
110 110 $ hg up '.^'
111 111 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
112 112 $ mkcommit new_2_c
113 113 created new head
114 114 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
115 115 obsoleted 1 changesets
116 116 $ hg debugobsolete
117 117 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
118 118 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
119 119
120 120 Register two markers with a missing node
121 121
122 122 $ hg up '.^'
123 123 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
124 124 $ mkcommit new_3_c
125 125 created new head
126 126 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
127 127 obsoleted 1 changesets
128 128 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
129 129 $ hg debugobsolete
130 130 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
131 131 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
132 132 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
133 133 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
134 134
135 135 Test the --index option of debugobsolete command
136 136 $ hg debugobsolete --index
137 137 0 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
138 138 1 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
139 139 2 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
140 140 3 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
141 141
142 142 Refuse pathological nullid successors
143 143 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
144 144 transaction abort!
145 145 rollback completed
146 146 abort: bad obsolescence marker detected: invalid successors nullid
147 147 [255]
148 148
149 149 Check that graphlog detect that a changeset is obsolete:
150 150
151 151 $ hg log -G
152 152 @ 5:5601fb93a350 (draft) [tip ] add new_3_c
153 153 |
154 154 o 1:7c3bad9141dc (draft) [ ] add b
155 155 |
156 156 o 0:1f0dee641bb7 (draft) [ ] add a
157 157
158 158
159 159 check that heads does not report them
160 160
161 161 $ hg heads
162 162 5:5601fb93a350 (draft) [tip ] add new_3_c
163 163 $ hg heads --hidden
164 164 5:5601fb93a350 (draft) [tip ] add new_3_c
165 165 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
166 166 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
167 167 2:245bde4270cd (draft *obsolete*) [ ] add original_c [rewritten as 3:cdbce2fbb163]
168 168
169 169
170 170 check that summary does not report them
171 171
172 172 $ hg init ../sink
173 173 $ echo '[paths]' >> .hg/hgrc
174 174 $ echo 'default=../sink' >> .hg/hgrc
175 175 $ hg summary --remote
176 176 parent: 5:5601fb93a350 tip
177 177 add new_3_c
178 178 branch: default
179 179 commit: (clean)
180 180 update: (current)
181 181 phases: 3 draft
182 182 remote: 3 outgoing
183 183
184 184 $ hg summary --remote --hidden
185 185 parent: 5:5601fb93a350 tip
186 186 add new_3_c
187 187 branch: default
188 188 commit: (clean)
189 189 update: 3 new changesets, 4 branch heads (merge)
190 190 phases: 6 draft
191 191 remote: 3 outgoing
192 192
193 193 check that various commands work well with filtering
194 194
195 195 $ hg tip
196 196 5:5601fb93a350 (draft) [tip ] add new_3_c
197 197 $ hg log -r 6
198 198 abort: unknown revision '6'!
199 199 [255]
200 200 $ hg log -r 4
201 201 abort: hidden revision '4' was rewritten as: 5601fb93a350!
202 202 (use --hidden to access hidden revisions)
203 203 [255]
204 204 $ hg debugrevspec 'rev(6)'
205 205 $ hg debugrevspec 'rev(4)'
206 206 $ hg debugrevspec 'null'
207 207 -1
208 208
209 209 Check that public changeset are not accounted as obsolete:
210 210
211 211 $ hg --hidden phase --public 2
212 212 1 new phase-divergent changesets
213 213 $ hg log -G
214 214 @ 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
215 215 |
216 216 | o 2:245bde4270cd (public) [ ] add original_c
217 217 |/
218 218 o 1:7c3bad9141dc (public) [ ] add b
219 219 |
220 220 o 0:1f0dee641bb7 (public) [ ] add a
221 221
222 222
223 223 And that bumped changeset are detected
224 224 --------------------------------------
225 225
226 226 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
227 227 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
228 228 the public changeset
229 229
230 230 $ hg log --hidden -r 'phasedivergent()'
231 231 5:5601fb93a350 (draft phase-divergent) [tip ] add new_3_c
232 232
233 233 And that we can't push bumped changeset
234 234
235 235 $ hg push ../tmpa -r 0 --force #(make repo related)
236 236 pushing to ../tmpa
237 237 searching for changes
238 238 warning: repository is unrelated
239 239 adding changesets
240 240 adding manifests
241 241 adding file changes
242 242 added 1 changesets with 1 changes to 1 files (+1 heads)
243 243 $ hg push ../tmpa
244 244 pushing to ../tmpa
245 245 searching for changes
246 246 abort: push includes phase-divergent changeset: 5601fb93a350!
247 247 [255]
248 248
249 249 Fixing "bumped" situation
250 250 We need to create a clone of 5 and add a special marker with a flag
251 251
252 252 $ hg summary
253 253 parent: 5:5601fb93a350 tip (phase-divergent)
254 254 add new_3_c
255 255 branch: default
256 256 commit: (clean)
257 257 update: 1 new changesets, 2 branch heads (merge)
258 258 phases: 1 draft
259 259 phase-divergent: 1 changesets
260 260 $ hg up '5^'
261 261 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
262 262 $ hg revert -ar 5
263 263 adding new_3_c
264 264 $ hg ci -m 'add n3w_3_c'
265 265 created new head
266 266 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
267 267 obsoleted 1 changesets
268 268 $ hg log -r 'phasedivergent()'
269 269 $ hg log -G
270 270 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
271 271 |
272 272 | o 2:245bde4270cd (public) [ ] add original_c
273 273 |/
274 274 o 1:7c3bad9141dc (public) [ ] add b
275 275 |
276 276 o 0:1f0dee641bb7 (public) [ ] add a
277 277
278 278
279 279 Basic exclusive testing
280 280
281 281 $ hg log -G --hidden
282 282 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
283 283 |
284 284 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
285 285 |/
286 286 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
287 287 |/
288 288 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
289 289 |/
290 290 | o 2:245bde4270cd (public) [ ] add original_c
291 291 |/
292 292 o 1:7c3bad9141dc (public) [ ] add b
293 293 |
294 294 o 0:1f0dee641bb7 (public) [ ] add a
295 295
296 296 $ hg debugobsolete --rev 6f9641995072
297 297 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
298 298 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
299 299 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
300 300 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
301 301 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
302 302 $ hg debugobsolete --rev 6f9641995072 --exclusive
303 303 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
304 304 $ hg debugobsolete --rev 5601fb93a350 --hidden
305 305 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
306 306 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
307 307 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
308 308 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
309 309 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
310 310 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
311 311 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
312 312 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
313 313 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
314 314
315 315 $ cd ..
316 316
317 317 Revision 0 is hidden
318 318 --------------------
319 319
320 320 $ hg init rev0hidden
321 321 $ cd rev0hidden
322 322
323 323 $ mkcommit kill0
324 324 $ hg up -q null
325 325 $ hg debugobsolete `getid kill0`
326 326 obsoleted 1 changesets
327 327 $ mkcommit a
328 328 $ mkcommit b
329 329
330 330 Should pick the first visible revision as "repo" node
331 331
332 332 $ hg archive ../archive-null
333 333 $ cat ../archive-null/.hg_archival.txt
334 334 repo: 1f0dee641bb7258c56bd60e93edfa2405381c41e
335 335 node: 7c3bad9141dcb46ff89abf5f61856facd56e476c
336 336 branch: default
337 337 latesttag: null
338 338 latesttagdistance: 2
339 339 changessincelatesttag: 2
340 340
341 341
342 342 $ cd ..
343 343
344 344 Can disable transaction summary report
345 345
346 346 $ hg init transaction-summary
347 347 $ cd transaction-summary
348 348 $ mkcommit a
349 349 $ mkcommit b
350 350 $ hg up -q null
351 351 $ hg --config experimental.evolution.report-instabilities=false debugobsolete `getid a`
352 352 obsoleted 1 changesets
353 353 $ cd ..
354 354
355 355 Exchange Test
356 356 ============================
357 357
358 358 Destination repo does not have any data
359 359 ---------------------------------------
360 360
361 361 Simple incoming test
362 362
363 363 $ hg init tmpc
364 364 $ cd tmpc
365 365 $ hg incoming ../tmpb
366 366 comparing with ../tmpb
367 367 0:1f0dee641bb7 (public) [ ] add a
368 368 1:7c3bad9141dc (public) [ ] add b
369 369 2:245bde4270cd (public) [ ] add original_c
370 370 6:6f9641995072 (draft) [tip ] add n3w_3_c
371 371
372 372 Try to pull markers
373 373 (extinct changeset are excluded but marker are pushed)
374 374
375 375 $ hg pull ../tmpb
376 376 pulling from ../tmpb
377 377 requesting all changes
378 378 adding changesets
379 379 adding manifests
380 380 adding file changes
381 381 added 4 changesets with 4 changes to 4 files (+1 heads)
382 382 5 new obsolescence markers
383 383 new changesets 1f0dee641bb7:6f9641995072
384 384 (run 'hg heads' to see heads, 'hg merge' to merge)
385 385 $ hg debugobsolete
386 386 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
387 387 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
388 388 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
389 389 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
390 390 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
391 391
392 392 Rollback//Transaction support
393 393
394 394 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
395 395 $ hg debugobsolete
396 396 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
397 397 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
398 398 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
399 399 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
400 400 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
401 401 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 (Thu Jan 01 00:22:20 1970 +0000) {'user': 'test'}
402 402 $ hg rollback -n
403 403 repository tip rolled back to revision 3 (undo debugobsolete)
404 404 $ hg rollback
405 405 repository tip rolled back to revision 3 (undo debugobsolete)
406 406 $ hg debugobsolete
407 407 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
408 408 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
409 409 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
410 410 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
411 411 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
412 412
413 413 $ cd ..
414 414
415 415 Try to push markers
416 416
417 417 $ hg init tmpd
418 418 $ hg -R tmpb push tmpd
419 419 pushing to tmpd
420 420 searching for changes
421 421 adding changesets
422 422 adding manifests
423 423 adding file changes
424 424 added 4 changesets with 4 changes to 4 files (+1 heads)
425 425 5 new obsolescence markers
426 426 $ hg -R tmpd debugobsolete | sort
427 427 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
428 428 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
429 429 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
430 430 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
431 431 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
432 432
433 433 Check obsolete keys are exchanged only if source has an obsolete store
434 434
435 435 $ hg init empty
436 436 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
437 437 pushing to tmpd
438 438 listkeys phases
439 439 listkeys bookmarks
440 440 no changes found
441 441 listkeys phases
442 442 [1]
443 443
444 444 clone support
445 445 (markers are copied and extinct changesets are included to allow hardlinks)
446 446
447 447 $ hg clone tmpb clone-dest
448 448 updating to branch default
449 449 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 450 $ hg -R clone-dest log -G --hidden
451 451 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
452 452 |
453 453 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c [rewritten as 6:6f9641995072]
454 454 |/
455 455 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c [rewritten as 5:5601fb93a350]
456 456 |/
457 457 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c [rewritten as 4:ca819180edb9]
458 458 |/
459 459 | o 2:245bde4270cd (public) [ ] add original_c
460 460 |/
461 461 o 1:7c3bad9141dc (public) [ ] add b
462 462 |
463 463 o 0:1f0dee641bb7 (public) [ ] add a
464 464
465 465 $ hg -R clone-dest debugobsolete
466 466 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
467 467 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
468 468 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
469 469 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
470 470 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
471 471
472 472
473 473 Destination repo have existing data
474 474 ---------------------------------------
475 475
476 476 On pull
477 477
478 478 $ hg init tmpe
479 479 $ cd tmpe
480 480 $ hg debugobsolete -d '1339 0' 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00
481 481 $ hg pull ../tmpb
482 482 pulling from ../tmpb
483 483 requesting all changes
484 484 adding changesets
485 485 adding manifests
486 486 adding file changes
487 487 added 4 changesets with 4 changes to 4 files (+1 heads)
488 488 5 new obsolescence markers
489 489 new changesets 1f0dee641bb7:6f9641995072
490 490 (run 'hg heads' to see heads, 'hg merge' to merge)
491 491 $ hg debugobsolete
492 492 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
493 493 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
494 494 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
495 495 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
496 496 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
497 497 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
498 498
499 499
500 500 On push
501 501
502 502 $ hg push ../tmpc
503 503 pushing to ../tmpc
504 504 searching for changes
505 505 no changes found
506 506 1 new obsolescence markers
507 507 [1]
508 508 $ hg -R ../tmpc debugobsolete
509 509 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
510 510 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
511 511 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
512 512 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
513 513 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
514 514 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
515 515
516 516 detect outgoing obsolete and unstable
517 517 ---------------------------------------
518 518
519 519
520 520 $ hg log -G
521 521 o 3:6f9641995072 (draft) [tip ] add n3w_3_c
522 522 |
523 523 | o 2:245bde4270cd (public) [ ] add original_c
524 524 |/
525 525 o 1:7c3bad9141dc (public) [ ] add b
526 526 |
527 527 o 0:1f0dee641bb7 (public) [ ] add a
528 528
529 529 $ hg up 'desc("n3w_3_c")'
530 530 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
531 531 $ mkcommit original_d
532 532 $ mkcommit original_e
533 533 $ hg debugobsolete --record-parents `getid original_d` -d '0 0'
534 534 obsoleted 1 changesets
535 535 1 new orphan changesets
536 536 $ hg debugobsolete | grep `getid original_d`
537 537 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
538 538 $ hg log -r 'obsolete()'
539 539 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
540 540 $ hg summary
541 541 parent: 5:cda648ca50f5 tip (orphan)
542 542 add original_e
543 543 branch: default
544 544 commit: (clean)
545 545 update: 1 new changesets, 2 branch heads (merge)
546 546 phases: 3 draft
547 547 orphan: 1 changesets
548 548 $ hg log -G -r '::orphan()'
549 549 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
550 550 |
551 551 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
552 552 |
553 553 o 3:6f9641995072 (draft) [ ] add n3w_3_c
554 554 |
555 555 o 1:7c3bad9141dc (public) [ ] add b
556 556 |
557 557 o 0:1f0dee641bb7 (public) [ ] add a
558 558
559 559
560 560 refuse to push obsolete changeset
561 561
562 562 $ hg push ../tmpc/ -r 'desc("original_d")'
563 563 pushing to ../tmpc/
564 564 searching for changes
565 565 abort: push includes obsolete changeset: 94b33453f93b!
566 566 [255]
567 567
568 568 refuse to push unstable changeset
569 569
570 570 $ hg push ../tmpc/
571 571 pushing to ../tmpc/
572 572 searching for changes
573 573 abort: push includes orphan changeset: cda648ca50f5!
574 574 [255]
575 575
576 576 Test that extinct changeset are properly detected
577 577
578 578 $ hg log -r 'extinct()'
579 579
580 580 Don't try to push extinct changeset
581 581
582 582 $ hg init ../tmpf
583 583 $ hg out ../tmpf
584 584 comparing with ../tmpf
585 585 searching for changes
586 586 0:1f0dee641bb7 (public) [ ] add a
587 587 1:7c3bad9141dc (public) [ ] add b
588 588 2:245bde4270cd (public) [ ] add original_c
589 589 3:6f9641995072 (draft) [ ] add n3w_3_c
590 590 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
591 591 5:cda648ca50f5 (draft orphan) [tip ] add original_e
592 592 $ hg push ../tmpf -f # -f because be push unstable too
593 593 pushing to ../tmpf
594 594 searching for changes
595 595 adding changesets
596 596 adding manifests
597 597 adding file changes
598 598 added 6 changesets with 6 changes to 6 files (+1 heads)
599 599 7 new obsolescence markers
600 600 1 new orphan changesets
601 601
602 602 no warning displayed
603 603
604 604 $ hg push ../tmpf
605 605 pushing to ../tmpf
606 606 searching for changes
607 607 no changes found
608 608 [1]
609 609
610 610 Do not warn about new head when the new head is a successors of a remote one
611 611
612 612 $ hg log -G
613 613 @ 5:cda648ca50f5 (draft orphan) [tip ] add original_e
614 614 |
615 615 x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
616 616 |
617 617 o 3:6f9641995072 (draft) [ ] add n3w_3_c
618 618 |
619 619 | o 2:245bde4270cd (public) [ ] add original_c
620 620 |/
621 621 o 1:7c3bad9141dc (public) [ ] add b
622 622 |
623 623 o 0:1f0dee641bb7 (public) [ ] add a
624 624
625 625 $ hg up -q 'desc(n3w_3_c)'
626 626 $ mkcommit obsolete_e
627 627 created new head
628 628 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'` \
629 629 > -u 'test <test@example.net>'
630 630 obsoleted 1 changesets
631 631 $ hg outgoing ../tmpf # parasite hg outgoing testin
632 632 comparing with ../tmpf
633 633 searching for changes
634 634 6:3de5eca88c00 (draft) [tip ] add obsolete_e
635 635 $ hg push ../tmpf
636 636 pushing to ../tmpf
637 637 searching for changes
638 638 adding changesets
639 639 adding manifests
640 640 adding file changes
641 641 added 1 changesets with 1 changes to 1 files (+1 heads)
642 642 1 new obsolescence markers
643 643 obsoleted 1 changesets
644 644
645 645 test relevance computation
646 646 ---------------------------------------
647 647
648 648 Checking simple case of "marker relevance".
649 649
650 650
651 651 Reminder of the repo situation
652 652
653 653 $ hg log --hidden --graph
654 654 @ 6:3de5eca88c00 (draft) [tip ] add obsolete_e
655 655 |
656 656 | x 5:cda648ca50f5 (draft *obsolete*) [ ] add original_e [rewritten as 6:3de5eca88c00 by test <test@example.net>]
657 657 | |
658 658 | x 4:94b33453f93b (draft *obsolete*) [ ] add original_d [pruned]
659 659 |/
660 660 o 3:6f9641995072 (draft) [ ] add n3w_3_c
661 661 |
662 662 | o 2:245bde4270cd (public) [ ] add original_c
663 663 |/
664 664 o 1:7c3bad9141dc (public) [ ] add b
665 665 |
666 666 o 0:1f0dee641bb7 (public) [ ] add a
667 667
668 668
669 669 List of all markers
670 670
671 671 $ hg debugobsolete
672 672 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
673 673 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
674 674 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
675 675 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
676 676 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
677 677 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
678 678 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
679 679 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
680 680
681 681 List of changesets with no chain
682 682
683 683 $ hg debugobsolete --hidden --rev ::2
684 684
685 685 List of changesets that are included on marker chain
686 686
687 687 $ hg debugobsolete --hidden --rev 6
688 688 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
689 689
690 690 List of changesets with a longer chain, (including a pruned children)
691 691
692 692 $ hg debugobsolete --hidden --rev 3
693 693 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
694 694 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
695 695 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
696 696 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
697 697 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
698 698 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
699 699 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
700 700
701 701 List of both
702 702
703 703 $ hg debugobsolete --hidden --rev 3::6
704 704 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
705 705 1339133913391339133913391339133913391339 ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
706 706 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
707 707 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
708 708 94b33453f93bdb8d457ef9b770851a618bf413e1 0 {6f96419950729f3671185b847352890f074f7557} (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
709 709 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
710 710 cda648ca50f50482b7055c0b0c4c117bba6733d9 3de5eca88c00aa039da7399a220f4a5221faa585 0 (*) {'user': 'test <test@example.net>'} (glob)
711 711 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
712 712
713 713 List of all markers in JSON
714 714
715 715 $ hg debugobsolete -Tjson
716 716 [
717 717 {
718 "date": [1339.0, 0],
718 "date": [1339, 0],
719 719 "flag": 0,
720 720 "metadata": {"user": "test"},
721 721 "prednode": "1339133913391339133913391339133913391339",
722 722 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
723 723 },
724 724 {
725 "date": [1339.0, 0],
725 "date": [1339, 0],
726 726 "flag": 0,
727 727 "metadata": {"user": "test"},
728 728 "prednode": "1337133713371337133713371337133713371337",
729 729 "succnodes": ["5601fb93a350734d935195fee37f4054c529ff39"]
730 730 },
731 731 {
732 "date": [121.0, 120],
732 "date": [121, 120],
733 733 "flag": 12,
734 734 "metadata": {"user": "test"},
735 735 "prednode": "245bde4270cd1072a27757984f9cda8ba26f08ca",
736 736 "succnodes": ["cdbce2fbb16313928851e97e0d85413f3f7eb77f"]
737 737 },
738 738 {
739 "date": [1338.0, 0],
739 "date": [1338, 0],
740 740 "flag": 1,
741 741 "metadata": {"user": "test"},
742 742 "prednode": "5601fb93a350734d935195fee37f4054c529ff39",
743 743 "succnodes": ["6f96419950729f3671185b847352890f074f7557"]
744 744 },
745 745 {
746 "date": [1338.0, 0],
746 "date": [1338, 0],
747 747 "flag": 0,
748 748 "metadata": {"user": "test"},
749 749 "prednode": "ca819180edb99ed25ceafb3e9584ac287e240b00",
750 750 "succnodes": ["1337133713371337133713371337133713371337"]
751 751 },
752 752 {
753 "date": [1337.0, 0],
753 "date": [1337, 0],
754 754 "flag": 0,
755 755 "metadata": {"user": "test"},
756 756 "prednode": "cdbce2fbb16313928851e97e0d85413f3f7eb77f",
757 757 "succnodes": ["ca819180edb99ed25ceafb3e9584ac287e240b00"]
758 758 },
759 759 {
760 "date": [0.0, 0],
760 "date": [0, 0],
761 761 "flag": 0,
762 762 "metadata": {"user": "test"},
763 763 "parentnodes": ["6f96419950729f3671185b847352890f074f7557"],
764 764 "prednode": "94b33453f93bdb8d457ef9b770851a618bf413e1",
765 765 "succnodes": []
766 766 },
767 767 {
768 768 "date": *, (glob)
769 769 "flag": 0,
770 770 "metadata": {"user": "test <test@example.net>"},
771 771 "prednode": "cda648ca50f50482b7055c0b0c4c117bba6733d9",
772 772 "succnodes": ["3de5eca88c00aa039da7399a220f4a5221faa585"]
773 773 }
774 774 ]
775 775
776 776 Template keywords
777 777
778 778 $ hg debugobsolete -r6 -T '{succnodes % "{node|short}"} {date|shortdate}\n'
779 779 3de5eca88c00 ????-??-?? (glob)
780 780 $ hg debugobsolete -r6 -T '{join(metadata % "{key}={value}", " ")}\n'
781 781 user=test <test@example.net>
782 782 $ hg debugobsolete -r6 -T '{metadata}\n{metadata}\n'
783 783 'user': 'test <test@example.net>'
784 784 'user': 'test <test@example.net>'
785 785 $ hg debugobsolete -r6 -T '{succnodes}\n{succnodes}\n'
786 786 3de5eca88c00aa039da7399a220f4a5221faa585
787 787 3de5eca88c00aa039da7399a220f4a5221faa585
788 788 $ hg debugobsolete -r6 -T '{flag} {get(metadata, "user")}\n'
789 789 0 test <test@example.net>
790 790
791 791 Test the debug output for exchange
792 792 ----------------------------------
793 793
794 794 $ hg pull ../tmpb --config 'experimental.obsmarkers-exchange-debug=True' # bundle2
795 795 pulling from ../tmpb
796 796 searching for changes
797 797 no changes found
798 798 obsmarker-exchange: 346 bytes received
799 799
800 800 check hgweb does not explode
801 801 ====================================
802 802
803 803 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
804 804 adding changesets
805 805 adding manifests
806 806 adding file changes
807 807 added 62 changesets with 63 changes to 9 files (+60 heads)
808 808 new changesets 50c51b361e60:c15e9edfca13
809 809 (run 'hg heads .' to see heads, 'hg merge' to merge)
810 810 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
811 811 > do
812 812 > hg debugobsolete $node
813 813 > done
814 814 obsoleted 1 changesets
815 815 obsoleted 1 changesets
816 816 obsoleted 1 changesets
817 817 obsoleted 1 changesets
818 818 obsoleted 1 changesets
819 819 obsoleted 1 changesets
820 820 obsoleted 1 changesets
821 821 obsoleted 1 changesets
822 822 obsoleted 1 changesets
823 823 obsoleted 1 changesets
824 824 obsoleted 1 changesets
825 825 obsoleted 1 changesets
826 826 obsoleted 1 changesets
827 827 obsoleted 1 changesets
828 828 obsoleted 1 changesets
829 829 obsoleted 1 changesets
830 830 obsoleted 1 changesets
831 831 obsoleted 1 changesets
832 832 obsoleted 1 changesets
833 833 obsoleted 1 changesets
834 834 obsoleted 1 changesets
835 835 obsoleted 1 changesets
836 836 obsoleted 1 changesets
837 837 obsoleted 1 changesets
838 838 obsoleted 1 changesets
839 839 obsoleted 1 changesets
840 840 obsoleted 1 changesets
841 841 obsoleted 1 changesets
842 842 obsoleted 1 changesets
843 843 obsoleted 1 changesets
844 844 obsoleted 1 changesets
845 845 obsoleted 1 changesets
846 846 obsoleted 1 changesets
847 847 obsoleted 1 changesets
848 848 obsoleted 1 changesets
849 849 obsoleted 1 changesets
850 850 obsoleted 1 changesets
851 851 obsoleted 1 changesets
852 852 obsoleted 1 changesets
853 853 obsoleted 1 changesets
854 854 obsoleted 1 changesets
855 855 obsoleted 1 changesets
856 856 obsoleted 1 changesets
857 857 obsoleted 1 changesets
858 858 obsoleted 1 changesets
859 859 obsoleted 1 changesets
860 860 obsoleted 1 changesets
861 861 obsoleted 1 changesets
862 862 obsoleted 1 changesets
863 863 obsoleted 1 changesets
864 864 obsoleted 1 changesets
865 865 obsoleted 1 changesets
866 866 obsoleted 1 changesets
867 867 obsoleted 1 changesets
868 868 obsoleted 1 changesets
869 869 obsoleted 1 changesets
870 870 obsoleted 1 changesets
871 871 obsoleted 1 changesets
872 872 obsoleted 1 changesets
873 873 obsoleted 1 changesets
874 874 $ hg up tip
875 875 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
876 876
877 877 #if serve
878 878
879 879 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
880 880 $ cat hg.pid >> $DAEMON_PIDS
881 881
882 882 check changelog view
883 883
884 884 $ get-with-headers.py --headeronly localhost:$HGPORT 'shortlog/'
885 885 200 Script output follows
886 886
887 887 check graph view
888 888
889 889 $ get-with-headers.py --headeronly localhost:$HGPORT 'graph'
890 890 200 Script output follows
891 891
892 892 check filelog view
893 893
894 894 $ get-with-headers.py --headeronly localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar'
895 895 200 Script output follows
896 896
897 897 check filelog view for hidden commits (obsolete ones are hidden here)
898 898
899 899 $ get-with-headers.py localhost:$HGPORT 'log/'`hg log -r . -T "{node}"`/'babar' | grep obsolete
900 900 [1]
901 901
902 902 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/68'
903 903 200 Script output follows
904 904 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
905 905 404 Not Found
906 906 [1]
907 907
908 908 check that web.view config option:
909 909
910 910 $ killdaemons.py hg.pid
911 911 $ cat >> .hg/hgrc << EOF
912 912 > [web]
913 913 > view=all
914 914 > EOF
915 915 $ wait
916 916 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
917 917 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/67'
918 918 200 Script output follows
919 919 $ killdaemons.py hg.pid
920 920
921 921 Checking _enable=False warning if obsolete marker exists
922 922
923 923 $ echo '[experimental]' >> $HGRCPATH
924 924 $ echo "evolution=" >> $HGRCPATH
925 925 $ hg log -r tip
926 926 68:c15e9edfca13 (draft) [tip ] add celestine
927 927
928 928 reenable for later test
929 929
930 930 $ echo '[experimental]' >> $HGRCPATH
931 931 $ echo "evolution.exchange=True" >> $HGRCPATH
932 932 $ echo "evolution.createmarkers=True" >> $HGRCPATH
933 933
934 934 $ rm hg.pid access.log errors.log
935 935 #endif
936 936
937 937 Several troubles on the same changeset (create an unstable and bumped changeset)
938 938
939 939 $ hg debugobsolete `getid obsolete_e`
940 940 obsoleted 1 changesets
941 941 2 new orphan changesets
942 942 $ hg debugobsolete `getid original_c` `getid babar`
943 943 1 new phase-divergent changesets
944 944 $ hg log --config ui.logtemplate= -r 'phasedivergent() and orphan()'
945 945 changeset: 7:50c51b361e60
946 946 user: test
947 947 date: Thu Jan 01 00:00:00 1970 +0000
948 948 instability: orphan, phase-divergent
949 949 summary: add babar
950 950
951 951
952 952 test the "obsolete" templatekw
953 953
954 954 $ hg log -r 'obsolete()'
955 955 6:3de5eca88c00 (draft *obsolete*) [ ] add obsolete_e [pruned]
956 956
957 957 test the "troubles" templatekw
958 958
959 959 $ hg log -r 'phasedivergent() and orphan()'
960 960 7:50c51b361e60 (draft orphan phase-divergent) [ ] add babar
961 961
962 962 test the default cmdline template
963 963
964 964 $ hg log -T default -r 'phasedivergent()'
965 965 changeset: 7:50c51b361e60
966 966 user: test
967 967 date: Thu Jan 01 00:00:00 1970 +0000
968 968 instability: orphan, phase-divergent
969 969 summary: add babar
970 970
971 971 $ hg log -T default -r 'obsolete()'
972 972 changeset: 6:3de5eca88c00
973 973 parent: 3:6f9641995072
974 974 user: test
975 975 date: Thu Jan 01 00:00:00 1970 +0000
976 976 obsolete: pruned
977 977 summary: add obsolete_e
978 978
979 979
980 980 test the obsolete labels
981 981
982 982 $ hg log --config ui.logtemplate= --color=debug -r 'phasedivergent()'
983 983 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
984 984 [log.user|user: test]
985 985 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
986 986 [log.instability|instability: orphan, phase-divergent]
987 987 [log.summary|summary: add babar]
988 988
989 989
990 990 $ hg log -T default -r 'phasedivergent()' --color=debug
991 991 [log.changeset changeset.draft changeset.unstable instability.orphan instability.phase-divergent|changeset: 7:50c51b361e60]
992 992 [log.user|user: test]
993 993 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
994 994 [log.instability|instability: orphan, phase-divergent]
995 995 [log.summary|summary: add babar]
996 996
997 997
998 998 $ hg log --config ui.logtemplate= --color=debug -r "obsolete()"
999 999 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1000 1000 [log.parent changeset.draft|parent: 3:6f9641995072]
1001 1001 [log.user|user: test]
1002 1002 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1003 1003 [log.obsfate|obsolete: pruned]
1004 1004 [log.summary|summary: add obsolete_e]
1005 1005
1006 1006
1007 1007 $ hg log -T default -r 'obsolete()' --color=debug
1008 1008 [log.changeset changeset.draft changeset.obsolete|changeset: 6:3de5eca88c00]
1009 1009 [log.parent changeset.draft|parent: 3:6f9641995072]
1010 1010 [log.user|user: test]
1011 1011 [log.date|date: Thu Jan 01 00:00:00 1970 +0000]
1012 1012 [log.obsfate|obsolete: pruned]
1013 1013 [log.summary|summary: add obsolete_e]
1014 1014
1015 1015
1016 1016 test summary output
1017 1017
1018 1018 $ hg up -r 'phasedivergent() and orphan()'
1019 1019 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1020 1020 $ hg summary
1021 1021 parent: 7:50c51b361e60 (orphan, phase-divergent)
1022 1022 add babar
1023 1023 branch: default
1024 1024 commit: (clean)
1025 1025 update: 2 new changesets (update)
1026 1026 phases: 4 draft
1027 1027 orphan: 2 changesets
1028 1028 phase-divergent: 1 changesets
1029 1029 $ hg up -r 'obsolete()'
1030 1030 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1031 1031 $ hg summary
1032 1032 parent: 6:3de5eca88c00 (obsolete)
1033 1033 add obsolete_e
1034 1034 branch: default
1035 1035 commit: (clean)
1036 1036 update: 3 new changesets (update)
1037 1037 phases: 4 draft
1038 1038 orphan: 2 changesets
1039 1039 phase-divergent: 1 changesets
1040 1040
1041 1041 test debugwhyunstable output
1042 1042
1043 1043 $ hg debugwhyunstable 50c51b361e60
1044 1044 orphan: obsolete parent 3de5eca88c00aa039da7399a220f4a5221faa585
1045 1045 phase-divergent: immutable predecessor 245bde4270cd1072a27757984f9cda8ba26f08ca
1046 1046
1047 1047 test whyunstable template keyword
1048 1048
1049 1049 $ hg log -r 50c51b361e60 -T '{whyunstable}\n'
1050 1050 orphan: obsolete parent 3de5eca88c00
1051 1051 phase-divergent: immutable predecessor 245bde4270cd
1052 1052 $ hg log -r 50c51b361e60 -T '{whyunstable % "{instability}: {reason} {node|shortest}\n"}'
1053 1053 orphan: obsolete parent 3de5
1054 1054 phase-divergent: immutable predecessor 245b
1055 1055
1056 1056 #if serve
1057 1057
1058 1058 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1059 1059 $ cat hg.pid >> $DAEMON_PIDS
1060 1060
1061 1061 check obsolete changeset
1062 1062
1063 1063 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=paper' | grep '<span class="obsolete">'
1064 1064 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1065 1065 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=coal' | grep '<span class="obsolete">'
1066 1066 <span class="phase">draft</span> <span class="obsolete">obsolete</span>
1067 1067 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=gitweb' | grep '<span class="logtags">'
1068 1068 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1069 1069 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=monoblue' | grep '<span class="logtags">'
1070 1070 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="obsoletetag" title="obsolete">obsolete</span> </span>
1071 1071 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(obsolete())&style=spartan' | grep 'class="obsolete"'
1072 1072 <th class="obsolete">obsolete:</th>
1073 1073 <td class="obsolete">pruned by &#116;&#101;&#115;&#116; <span class="age">Thu, 01 Jan 1970 00:00:00 +0000</span></td>
1074 1074
1075 1075 check changeset with instabilities
1076 1076
1077 1077 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=paper' | grep '<span class="instability">'
1078 1078 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1079 1079 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=coal' | grep '<span class="instability">'
1080 1080 <span class="phase">draft</span> <span class="instability">orphan</span> <span class="instability">phase-divergent</span>
1081 1081 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=gitweb' | grep '<span class="logtags">'
1082 1082 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1083 1083 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=monoblue' | grep '<span class="logtags">'
1084 1084 <span class="logtags"><span class="phasetag" title="draft">draft</span> <span class="instabilitytag" title="orphan">orphan</span> <span class="instabilitytag" title="phase-divergent">phase-divergent</span> </span>
1085 1085 $ get-with-headers.py localhost:$HGPORT 'log?rev=first(phasedivergent())&style=spartan' | grep 'class="unstable"'
1086 1086 <th class="unstable">unstable:</th>
1087 1087 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1088 1088 <th class="unstable">unstable:</th>
1089 1089 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1090 1090
1091 1091 check explanation for an orphan and phase-divergent changeset
1092 1092
1093 1093 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=paper' | egrep '(orphan|phase-divergent):'
1094 1094 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=paper">3de5eca88c00</a><br>
1095 1095 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=paper">245bde4270cd</a></td>
1096 1096 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=coal' | egrep '(orphan|phase-divergent):'
1097 1097 <td>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=coal">3de5eca88c00</a><br>
1098 1098 phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=coal">245bde4270cd</a></td>
1099 1099 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=gitweb' | egrep '(orphan|phase-divergent):'
1100 1100 <td>orphan: obsolete parent <a class="list" href="/rev/3de5eca88c00?style=gitweb">3de5eca88c00</a></td>
1101 1101 <td>phase-divergent: immutable predecessor <a class="list" href="/rev/245bde4270cd?style=gitweb">245bde4270cd</a></td>
1102 1102 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=monoblue' | egrep '(orphan|phase-divergent):'
1103 1103 <dd>orphan: obsolete parent <a href="/rev/3de5eca88c00?style=monoblue">3de5eca88c00</a></dd>
1104 1104 <dd>phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=monoblue">245bde4270cd</a></dd>
1105 1105 $ get-with-headers.py localhost:$HGPORT 'rev/50c51b361e60?style=spartan' | egrep '(orphan|phase-divergent):'
1106 1106 <td class="unstable">orphan: obsolete parent <a href="/rev/3de5eca88c00?style=spartan">3de5eca88c00</a></td>
1107 1107 <td class="unstable">phase-divergent: immutable predecessor <a href="/rev/245bde4270cd?style=spartan">245bde4270cd</a></td>
1108 1108
1109 1109 $ killdaemons.py
1110 1110
1111 1111 $ rm hg.pid access.log errors.log
1112 1112
1113 1113 #endif
1114 1114
1115 1115 Test incoming/outcoming with changesets obsoleted remotely, known locally
1116 1116 ===============================================================================
1117 1117
1118 1118 This test issue 3805
1119 1119
1120 1120 $ hg init repo-issue3805
1121 1121 $ cd repo-issue3805
1122 1122 $ echo "base" > base
1123 1123 $ hg ci -Am "base"
1124 1124 adding base
1125 1125 $ echo "foo" > foo
1126 1126 $ hg ci -Am "A"
1127 1127 adding foo
1128 1128 $ hg clone . ../other-issue3805
1129 1129 updating to branch default
1130 1130 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1131 1131 $ echo "bar" >> foo
1132 1132 $ hg ci --amend
1133 1133 $ cd ../other-issue3805
1134 1134 $ hg log -G
1135 1135 @ 1:29f0c6921ddd (draft) [tip ] A
1136 1136 |
1137 1137 o 0:d20a80d4def3 (draft) [ ] base
1138 1138
1139 1139 $ hg log -G -R ../repo-issue3805
1140 1140 @ 2:323a9c3ddd91 (draft) [tip ] A
1141 1141 |
1142 1142 o 0:d20a80d4def3 (draft) [ ] base
1143 1143
1144 1144 $ hg incoming
1145 1145 comparing with $TESTTMP/tmpe/repo-issue3805
1146 1146 searching for changes
1147 1147 2:323a9c3ddd91 (draft) [tip ] A
1148 1148 $ hg incoming --bundle ../issue3805.hg
1149 1149 comparing with $TESTTMP/tmpe/repo-issue3805
1150 1150 searching for changes
1151 1151 2:323a9c3ddd91 (draft) [tip ] A
1152 1152 $ hg outgoing
1153 1153 comparing with $TESTTMP/tmpe/repo-issue3805
1154 1154 searching for changes
1155 1155 1:29f0c6921ddd (draft) [tip ] A
1156 1156
1157 1157 #if serve
1158 1158
1159 1159 $ hg serve -R ../repo-issue3805 -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1160 1160 $ cat hg.pid >> $DAEMON_PIDS
1161 1161
1162 1162 $ hg incoming http://localhost:$HGPORT
1163 1163 comparing with http://localhost:$HGPORT/
1164 1164 searching for changes
1165 1165 2:323a9c3ddd91 (draft) [tip ] A
1166 1166 $ hg outgoing http://localhost:$HGPORT
1167 1167 comparing with http://localhost:$HGPORT/
1168 1168 searching for changes
1169 1169 1:29f0c6921ddd (draft) [tip ] A
1170 1170
1171 1171 $ killdaemons.py
1172 1172
1173 1173 #endif
1174 1174
1175 1175 This test issue 3814
1176 1176
1177 1177 (nothing to push but locally hidden changeset)
1178 1178
1179 1179 $ cd ..
1180 1180 $ hg init repo-issue3814
1181 1181 $ cd repo-issue3805
1182 1182 $ hg push -r 323a9c3ddd91 ../repo-issue3814
1183 1183 pushing to ../repo-issue3814
1184 1184 searching for changes
1185 1185 adding changesets
1186 1186 adding manifests
1187 1187 adding file changes
1188 1188 added 2 changesets with 2 changes to 2 files
1189 1189 1 new obsolescence markers
1190 1190 $ hg out ../repo-issue3814
1191 1191 comparing with ../repo-issue3814
1192 1192 searching for changes
1193 1193 no changes found
1194 1194 [1]
1195 1195
1196 1196 Test that a local tag blocks a changeset from being hidden
1197 1197
1198 1198 $ hg tag -l visible -r 1 --hidden
1199 1199 $ hg log -G
1200 1200 @ 2:323a9c3ddd91 (draft) [tip ] A
1201 1201 |
1202 1202 | x 1:29f0c6921ddd (draft *obsolete*) [visible ] A [rewritten using amend as 2:323a9c3ddd91]
1203 1203 |/
1204 1204 o 0:d20a80d4def3 (draft) [ ] base
1205 1205
1206 1206 Test that removing a local tag does not cause some commands to fail
1207 1207
1208 1208 $ hg tag -l -r tip tiptag
1209 1209 $ hg tags
1210 1210 tiptag 2:323a9c3ddd91
1211 1211 tip 2:323a9c3ddd91
1212 1212 visible 1:29f0c6921ddd
1213 1213 $ hg --config extensions.strip= strip -r tip --no-backup
1214 1214 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1215 1215 $ hg tags
1216 1216 visible 1:29f0c6921ddd
1217 1217 tip 1:29f0c6921ddd
1218 1218
1219 1219 Test bundle overlay onto hidden revision
1220 1220
1221 1221 $ cd ..
1222 1222 $ hg init repo-bundleoverlay
1223 1223 $ cd repo-bundleoverlay
1224 1224 $ echo "A" > foo
1225 1225 $ hg ci -Am "A"
1226 1226 adding foo
1227 1227 $ echo "B" >> foo
1228 1228 $ hg ci -m "B"
1229 1229 $ hg up 0
1230 1230 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1231 1231 $ echo "C" >> foo
1232 1232 $ hg ci -m "C"
1233 1233 created new head
1234 1234 $ hg log -G
1235 1235 @ 2:c186d7714947 (draft) [tip ] C
1236 1236 |
1237 1237 | o 1:44526ebb0f98 (draft) [ ] B
1238 1238 |/
1239 1239 o 0:4b34ecfb0d56 (draft) [ ] A
1240 1240
1241 1241
1242 1242 $ hg clone -r1 . ../other-bundleoverlay
1243 1243 adding changesets
1244 1244 adding manifests
1245 1245 adding file changes
1246 1246 added 2 changesets with 2 changes to 1 files
1247 1247 new changesets 4b34ecfb0d56:44526ebb0f98
1248 1248 updating to branch default
1249 1249 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1250 1250 $ cd ../other-bundleoverlay
1251 1251 $ echo "B+" >> foo
1252 1252 $ hg ci --amend -m "B+"
1253 1253 $ hg log -G --hidden
1254 1254 @ 2:b7d587542d40 (draft) [tip ] B+
1255 1255 |
1256 1256 | x 1:44526ebb0f98 (draft *obsolete*) [ ] B [rewritten using amend as 2:b7d587542d40]
1257 1257 |/
1258 1258 o 0:4b34ecfb0d56 (draft) [ ] A
1259 1259
1260 1260
1261 1261 #if repobundlerepo
1262 1262 $ hg incoming ../repo-bundleoverlay --bundle ../bundleoverlay.hg
1263 1263 comparing with ../repo-bundleoverlay
1264 1264 searching for changes
1265 1265 1:44526ebb0f98 (draft) [ ] B
1266 1266 2:c186d7714947 (draft) [tip ] C
1267 1267 $ hg log -G -R ../bundleoverlay.hg
1268 1268 o 3:c186d7714947 (draft) [tip ] C
1269 1269 |
1270 1270 | @ 2:b7d587542d40 (draft) [ ] B+
1271 1271 |/
1272 1272 o 0:4b34ecfb0d56 (draft) [ ] A
1273 1273
1274 1274 #endif
1275 1275
1276 1276 #if serve
1277 1277
1278 1278 Test issue 4506
1279 1279
1280 1280 $ cd ..
1281 1281 $ hg init repo-issue4506
1282 1282 $ cd repo-issue4506
1283 1283 $ echo "0" > foo
1284 1284 $ hg add foo
1285 1285 $ hg ci -m "content-0"
1286 1286
1287 1287 $ hg up null
1288 1288 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1289 1289 $ echo "1" > bar
1290 1290 $ hg add bar
1291 1291 $ hg ci -m "content-1"
1292 1292 created new head
1293 1293 $ hg up 0
1294 1294 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1295 1295 $ hg graft 1
1296 1296 grafting 1:1c9eddb02162 "content-1" (tip)
1297 1297
1298 1298 $ hg debugobsolete `hg log -r1 -T'{node}'` `hg log -r2 -T'{node}'`
1299 1299 obsoleted 1 changesets
1300 1300
1301 1301 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
1302 1302 $ cat hg.pid >> $DAEMON_PIDS
1303 1303
1304 1304 $ get-with-headers.py --headeronly localhost:$HGPORT 'rev/1'
1305 1305 404 Not Found
1306 1306 [1]
1307 1307 $ get-with-headers.py --headeronly localhost:$HGPORT 'file/tip/bar'
1308 1308 200 Script output follows
1309 1309 $ get-with-headers.py --headeronly localhost:$HGPORT 'annotate/tip/bar'
1310 1310 200 Script output follows
1311 1311
1312 1312 $ killdaemons.py
1313 1313
1314 1314 #endif
1315 1315
1316 1316 Test heads computation on pending index changes with obsolescence markers
1317 1317 $ cd ..
1318 1318 $ cat >$TESTTMP/test_extension.py << EOF
1319 1319 > from __future__ import absolute_import
1320 1320 > from mercurial.i18n import _
1321 1321 > from mercurial import cmdutil, registrar
1322 1322 >
1323 1323 > cmdtable = {}
1324 1324 > command = registrar.command(cmdtable)
1325 1325 > @command(b"amendtransient",[], _(b'hg amendtransient [rev]'))
1326 1326 > def amend(ui, repo, *pats, **opts):
1327 1327 > opts['message'] = 'Test'
1328 1328 > opts['logfile'] = None
1329 1329 > cmdutil.amend(ui, repo, repo['.'], {}, pats, opts)
1330 1330 > ui.write(b'%s\n' % repo.changelog.headrevs())
1331 1331 > EOF
1332 1332 $ cat >> $HGRCPATH << EOF
1333 1333 > [extensions]
1334 1334 > testextension=$TESTTMP/test_extension.py
1335 1335 > EOF
1336 1336 $ hg init repo-issue-nativerevs-pending-changes
1337 1337 $ cd repo-issue-nativerevs-pending-changes
1338 1338 $ mkcommit a
1339 1339 $ mkcommit b
1340 1340 $ hg up ".^"
1341 1341 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1342 1342 $ echo aa > a
1343 1343 $ hg amendtransient
1344 1344 1 new orphan changesets
1345 1345 [1, 2]
1346 1346
1347 1347 Test cache consistency for the visible filter
1348 1348 1) We want to make sure that the cached filtered revs are invalidated when
1349 1349 bookmarks change
1350 1350 $ cd ..
1351 1351 $ cat >$TESTTMP/test_extension.py << EOF
1352 1352 > from __future__ import absolute_import, print_function
1353 1353 > import weakref
1354 1354 > from mercurial import (
1355 1355 > bookmarks,
1356 1356 > cmdutil,
1357 1357 > extensions,
1358 1358 > repoview,
1359 1359 > )
1360 1360 > def _bookmarkchanged(orig, bkmstoreinst, *args, **kwargs):
1361 1361 > reporef = weakref.ref(bkmstoreinst._repo)
1362 1362 > def trhook(tr):
1363 1363 > repo = reporef()
1364 1364 > hidden1 = repoview.computehidden(repo)
1365 1365 > hidden = repoview.filterrevs(repo, b'visible')
1366 1366 > if sorted(hidden1) != sorted(hidden):
1367 1367 > print("cache inconsistency")
1368 1368 > bkmstoreinst._repo.currenttransaction().addpostclose('test_extension', trhook)
1369 1369 > orig(bkmstoreinst, *args, **kwargs)
1370 1370 > def extsetup(ui):
1371 1371 > extensions.wrapfunction(bookmarks.bmstore, '_recordchange',
1372 1372 > _bookmarkchanged)
1373 1373 > EOF
1374 1374
1375 1375 $ hg init repo-cache-inconsistency
1376 1376 $ cd repo-issue-nativerevs-pending-changes
1377 1377 $ mkcommit a
1378 1378 a already tracked!
1379 1379 $ mkcommit b
1380 1380 $ hg id
1381 1381 13bedc178fce tip
1382 1382 $ echo "hello" > b
1383 1383 $ hg commit --amend -m "message"
1384 1384 $ hg book bookb -r 13bedc178fce --hidden
1385 1385 bookmarking hidden changeset 13bedc178fce
1386 1386 (hidden revision '13bedc178fce' was rewritten as: a9b1f8652753)
1387 1387 $ hg log -r 13bedc178fce
1388 1388 4:13bedc178fce (draft *obsolete*) [ bookb] add b [rewritten using amend as 5:a9b1f8652753]
1389 1389 $ hg book -d bookb
1390 1390 $ hg log -r 13bedc178fce
1391 1391 abort: hidden revision '13bedc178fce' was rewritten as: a9b1f8652753!
1392 1392 (use --hidden to access hidden revisions)
1393 1393 [255]
1394 1394
1395 1395 Empty out the test extension, as it isn't compatible with later parts
1396 1396 of the test.
1397 1397 $ echo > $TESTTMP/test_extension.py
1398 1398
1399 1399 Test ability to pull changeset with locally applying obsolescence markers
1400 1400 (issue4945)
1401 1401
1402 1402 $ cd ..
1403 1403 $ hg init issue4845
1404 1404 $ cd issue4845
1405 1405
1406 1406 $ echo foo > f0
1407 1407 $ hg add f0
1408 1408 $ hg ci -m '0'
1409 1409 $ echo foo > f1
1410 1410 $ hg add f1
1411 1411 $ hg ci -m '1'
1412 1412 $ echo foo > f2
1413 1413 $ hg add f2
1414 1414 $ hg ci -m '2'
1415 1415
1416 1416 $ echo bar > f2
1417 1417 $ hg commit --amend --config experimental.evolution.createmarkers=True
1418 1418 $ hg log -G
1419 1419 @ 3:b0551702f918 (draft) [tip ] 2
1420 1420 |
1421 1421 o 1:e016b03fd86f (draft) [ ] 1
1422 1422 |
1423 1423 o 0:a78f55e5508c (draft) [ ] 0
1424 1424
1425 1425 $ hg log -G --hidden
1426 1426 @ 3:b0551702f918 (draft) [tip ] 2
1427 1427 |
1428 1428 | x 2:e008cf283490 (draft *obsolete*) [ ] 2 [rewritten using amend as 3:b0551702f918]
1429 1429 |/
1430 1430 o 1:e016b03fd86f (draft) [ ] 1
1431 1431 |
1432 1432 o 0:a78f55e5508c (draft) [ ] 0
1433 1433
1434 1434
1435 1435 $ hg strip --hidden -r 2 --config extensions.strip= --config devel.strip-obsmarkers=no
1436 1436 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e008cf283490-ede36964-backup.hg
1437 1437 $ hg debugobsolete
1438 1438 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1439 1439 $ hg log -G
1440 1440 @ 2:b0551702f918 (draft) [tip ] 2
1441 1441 |
1442 1442 o 1:e016b03fd86f (draft) [ ] 1
1443 1443 |
1444 1444 o 0:a78f55e5508c (draft) [ ] 0
1445 1445
1446 1446 $ hg log -G --hidden
1447 1447 @ 2:b0551702f918 (draft) [tip ] 2
1448 1448 |
1449 1449 o 1:e016b03fd86f (draft) [ ] 1
1450 1450 |
1451 1451 o 0:a78f55e5508c (draft) [ ] 0
1452 1452
1453 1453 $ hg debugbundle .hg/strip-backup/e008cf283490-*-backup.hg
1454 1454 Stream params: {Compression: BZ}
1455 1455 changegroup -- {nbchanges: 1, version: 02}
1456 1456 e008cf2834908e5d6b0f792a9d4b0e2272260fb8
1457 1457 cache:rev-branch-cache -- {}
1458 1458 phase-heads -- {}
1459 1459 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 draft
1460 1460
1461 1461 #if repobundlerepo
1462 1462 $ hg pull .hg/strip-backup/e008cf283490-*-backup.hg
1463 1463 pulling from .hg/strip-backup/e008cf283490-ede36964-backup.hg
1464 1464 searching for changes
1465 1465 no changes found
1466 1466 #endif
1467 1467 $ hg debugobsolete
1468 1468 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1469 1469 $ hg log -G
1470 1470 @ 2:b0551702f918 (draft) [tip ] 2
1471 1471 |
1472 1472 o 1:e016b03fd86f (draft) [ ] 1
1473 1473 |
1474 1474 o 0:a78f55e5508c (draft) [ ] 0
1475 1475
1476 1476 $ hg log -G --hidden
1477 1477 @ 2:b0551702f918 (draft) [tip ] 2
1478 1478 |
1479 1479 o 1:e016b03fd86f (draft) [ ] 1
1480 1480 |
1481 1481 o 0:a78f55e5508c (draft) [ ] 0
1482 1482
1483 1483
1484 1484 Testing that strip remove markers:
1485 1485
1486 1486 $ hg strip -r 1 --config extensions.strip=
1487 1487 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1488 1488 saved backup bundle to $TESTTMP/tmpe/issue4845/.hg/strip-backup/e016b03fd86f-65ede734-backup.hg
1489 1489 $ hg debugobsolete
1490 1490 $ hg log -G
1491 1491 @ 0:a78f55e5508c (draft) [tip ] 0
1492 1492
1493 1493 $ hg log -G --hidden
1494 1494 @ 0:a78f55e5508c (draft) [tip ] 0
1495 1495
1496 1496 $ hg debugbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1497 1497 Stream params: {Compression: BZ}
1498 1498 changegroup -- {nbchanges: 2, version: 02}
1499 1499 e016b03fd86fcccc54817d120b90b751aaf367d6
1500 1500 b0551702f918510f01ae838ab03a463054c67b46
1501 1501 cache:rev-branch-cache -- {}
1502 1502 obsmarkers -- {}
1503 1503 version: 1 (92 bytes)
1504 1504 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1505 1505 phase-heads -- {}
1506 1506 b0551702f918510f01ae838ab03a463054c67b46 draft
1507 1507
1508 1508 $ hg unbundle .hg/strip-backup/e016b03fd86f-*-backup.hg
1509 1509 adding changesets
1510 1510 adding manifests
1511 1511 adding file changes
1512 1512 added 2 changesets with 2 changes to 2 files
1513 1513 1 new obsolescence markers
1514 1514 new changesets e016b03fd86f:b0551702f918
1515 1515 (run 'hg update' to get a working copy)
1516 1516 $ hg debugobsolete | sort
1517 1517 e008cf2834908e5d6b0f792a9d4b0e2272260fb8 b0551702f918510f01ae838ab03a463054c67b46 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'}
1518 1518 $ hg log -G
1519 1519 o 2:b0551702f918 (draft) [tip ] 2
1520 1520 |
1521 1521 o 1:e016b03fd86f (draft) [ ] 1
1522 1522 |
1523 1523 @ 0:a78f55e5508c (draft) [ ] 0
1524 1524
1525 1525 $ hg log -G --hidden
1526 1526 o 2:b0551702f918 (draft) [tip ] 2
1527 1527 |
1528 1528 o 1:e016b03fd86f (draft) [ ] 1
1529 1529 |
1530 1530 @ 0:a78f55e5508c (draft) [ ] 0
1531 1531
1532 1532 Test that 'hg debugobsolete --index --rev' can show indices of obsmarkers when
1533 1533 only a subset of those are displayed (because of --rev option)
1534 1534 $ hg init doindexrev
1535 1535 $ cd doindexrev
1536 1536 $ echo a > a
1537 1537 $ hg ci -Am a
1538 1538 adding a
1539 1539 $ hg ci --amend -m aa
1540 1540 $ echo b > b
1541 1541 $ hg ci -Am b
1542 1542 adding b
1543 1543 $ hg ci --amend -m bb
1544 1544 $ echo c > c
1545 1545 $ hg ci -Am c
1546 1546 adding c
1547 1547 $ hg ci --amend -m cc
1548 1548 $ echo d > d
1549 1549 $ hg ci -Am d
1550 1550 adding d
1551 1551 $ hg ci --amend -m dd --config experimental.evolution.track-operation=1
1552 1552 $ hg debugobsolete --index --rev "3+7"
1553 1553 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1554 1554 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1555 1555 $ hg debugobsolete --index --rev "3+7" -Tjson
1556 1556 [
1557 1557 {
1558 "date": [0.0, 0],
1558 "date": [0, 0],
1559 1559 "flag": 0,
1560 1560 "index": 1,
1561 1561 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1562 1562 "prednode": "6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1",
1563 1563 "succnodes": ["d27fb9b066076fd921277a4b9e8b9cb48c95bc6a"]
1564 1564 },
1565 1565 {
1566 "date": [0.0, 0],
1566 "date": [0, 0],
1567 1567 "flag": 0,
1568 1568 "index": 3,
1569 1569 "metadata": {"ef1": "1", "operation": "amend", "user": "test"},
1570 1570 "prednode": "4715cf767440ed891755448016c2b8cf70760c30",
1571 1571 "succnodes": ["7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d"]
1572 1572 }
1573 1573 ]
1574 1574
1575 1575 Test the --delete option of debugobsolete command
1576 1576 $ hg debugobsolete --index
1577 1577 0 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1578 1578 1 6fdef60fcbabbd3d50e9b9cbc2a240724b91a5e1 d27fb9b066076fd921277a4b9e8b9cb48c95bc6a 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1579 1579 2 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1580 1580 3 4715cf767440ed891755448016c2b8cf70760c30 7ae79c5d60f049c7b0dd02f5f25b9d60aaf7b36d 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1581 1581 $ hg debugobsolete --delete 1 --delete 3
1582 1582 deleted 2 obsolescence markers
1583 1583 $ hg debugobsolete
1584 1584 cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b f9bd49731b0b175e42992a3c8fa6c678b2bc11f1 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1585 1585 1ab51af8f9b41ef8c7f6f3312d4706d870b1fb74 29346082e4a9e27042b62d2da0e2de211c027621 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '1', 'operation': 'amend', 'user': 'test'}
1586 1586
1587 1587 Test adding changeset after obsmarkers affecting it
1588 1588 (eg: during pull, or unbundle)
1589 1589
1590 1590 $ mkcommit e
1591 1591 $ hg bundle -r . --base .~1 ../bundle-2.hg
1592 1592 1 changesets found
1593 1593 $ getid .
1594 1594 $ hg --config extensions.strip= strip -r .
1595 1595 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1596 1596 saved backup bundle to $TESTTMP/tmpe/issue4845/doindexrev/.hg/strip-backup/9bc153528424-ee80edd4-backup.hg
1597 1597 $ hg debugobsolete 9bc153528424ea266d13e57f9ff0d799dfe61e4b
1598 1598 $ hg unbundle ../bundle-2.hg
1599 1599 adding changesets
1600 1600 adding manifests
1601 1601 adding file changes
1602 1602 added 1 changesets with 1 changes to 1 files
1603 1603 (run 'hg update' to get a working copy)
1604 1604 $ hg log -G
1605 1605 @ 7:7ae79c5d60f0 (draft) [tip ] dd
1606 1606 |
1607 1607 | o 6:4715cf767440 (draft) [ ] d
1608 1608 |/
1609 1609 o 5:29346082e4a9 (draft) [ ] cc
1610 1610 |
1611 1611 o 3:d27fb9b06607 (draft) [ ] bb
1612 1612 |
1613 1613 | o 2:6fdef60fcbab (draft) [ ] b
1614 1614 |/
1615 1615 o 1:f9bd49731b0b (draft) [ ] aa
1616 1616
1617 1617
1618 1618 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now