##// END OF EJS Templates
log: make -frREV PATH detect missing files before falling back to slow path...
Yuya Nishihara -
r46045:5f0eeda2 default
parent child Browse files
Show More
@@ -1,1090 +1,1104 b''
1 1 # logcmdutil.py - utility for log-like commands
2 2 #
3 3 # Copyright 2005-2007 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 from __future__ import absolute_import
9 9
10 10 import itertools
11 11 import os
12 12 import posixpath
13 13
14 14 from .i18n import _
15 15 from .node import (
16 16 nullid,
17 17 wdirid,
18 18 wdirrev,
19 19 )
20 20
21 21 from . import (
22 22 dagop,
23 23 error,
24 24 formatter,
25 25 graphmod,
26 26 match as matchmod,
27 27 mdiff,
28 28 patch,
29 29 pathutil,
30 30 pycompat,
31 31 revset,
32 32 revsetlang,
33 33 scmutil,
34 34 smartset,
35 35 templatekw,
36 36 templater,
37 37 util,
38 38 )
39 39 from .utils import (
40 40 dateutil,
41 41 stringutil,
42 42 )
43 43
44 44
45 45 if pycompat.TYPE_CHECKING:
46 46 from typing import (
47 47 Any,
48 48 Optional,
49 49 Tuple,
50 50 )
51 51
52 52 for t in (Any, Optional, Tuple):
53 53 assert t
54 54
55 55
56 56 def getlimit(opts):
57 57 """get the log limit according to option -l/--limit"""
58 58 limit = opts.get(b'limit')
59 59 if limit:
60 60 try:
61 61 limit = int(limit)
62 62 except ValueError:
63 63 raise error.Abort(_(b'limit must be a positive integer'))
64 64 if limit <= 0:
65 65 raise error.Abort(_(b'limit must be positive'))
66 66 else:
67 67 limit = None
68 68 return limit
69 69
70 70
71 71 def diffordiffstat(
72 72 ui,
73 73 repo,
74 74 diffopts,
75 75 ctx1,
76 76 ctx2,
77 77 match,
78 78 changes=None,
79 79 stat=False,
80 80 fp=None,
81 81 graphwidth=0,
82 82 prefix=b'',
83 83 root=b'',
84 84 listsubrepos=False,
85 85 hunksfilterfn=None,
86 86 ):
87 87 '''show diff or diffstat.'''
88 88 if root:
89 89 relroot = pathutil.canonpath(repo.root, repo.getcwd(), root)
90 90 else:
91 91 relroot = b''
92 92 copysourcematch = None
93 93
94 94 def compose(f, g):
95 95 return lambda x: f(g(x))
96 96
97 97 def pathfn(f):
98 98 return posixpath.join(prefix, f)
99 99
100 100 if relroot != b'':
101 101 # XXX relative roots currently don't work if the root is within a
102 102 # subrepo
103 103 uipathfn = scmutil.getuipathfn(repo, legacyrelativevalue=True)
104 104 uirelroot = uipathfn(pathfn(relroot))
105 105 relroot += b'/'
106 106 for matchroot in match.files():
107 107 if not matchroot.startswith(relroot):
108 108 ui.warn(
109 109 _(b'warning: %s not inside relative root %s\n')
110 110 % (uipathfn(pathfn(matchroot)), uirelroot)
111 111 )
112 112
113 113 relrootmatch = scmutil.match(ctx2, pats=[relroot], default=b'path')
114 114 match = matchmod.intersectmatchers(match, relrootmatch)
115 115 copysourcematch = relrootmatch
116 116
117 117 checkroot = repo.ui.configbool(
118 118 b'devel', b'all-warnings'
119 119 ) or repo.ui.configbool(b'devel', b'check-relroot')
120 120
121 121 def relrootpathfn(f):
122 122 if checkroot and not f.startswith(relroot):
123 123 raise AssertionError(
124 124 b"file %s doesn't start with relroot %s" % (f, relroot)
125 125 )
126 126 return f[len(relroot) :]
127 127
128 128 pathfn = compose(relrootpathfn, pathfn)
129 129
130 130 if stat:
131 131 diffopts = diffopts.copy(context=0, noprefix=False)
132 132 width = 80
133 133 if not ui.plain():
134 134 width = ui.termwidth() - graphwidth
135 135 # If an explicit --root was given, don't respect ui.relative-paths
136 136 if not relroot:
137 137 pathfn = compose(scmutil.getuipathfn(repo), pathfn)
138 138
139 139 chunks = ctx2.diff(
140 140 ctx1,
141 141 match,
142 142 changes,
143 143 opts=diffopts,
144 144 pathfn=pathfn,
145 145 copysourcematch=copysourcematch,
146 146 hunksfilterfn=hunksfilterfn,
147 147 )
148 148
149 149 if fp is not None or ui.canwritewithoutlabels():
150 150 out = fp or ui
151 151 if stat:
152 152 chunks = [patch.diffstat(util.iterlines(chunks), width=width)]
153 153 for chunk in util.filechunkiter(util.chunkbuffer(chunks)):
154 154 out.write(chunk)
155 155 else:
156 156 if stat:
157 157 chunks = patch.diffstatui(util.iterlines(chunks), width=width)
158 158 else:
159 159 chunks = patch.difflabel(
160 160 lambda chunks, **kwargs: chunks, chunks, opts=diffopts
161 161 )
162 162 if ui.canbatchlabeledwrites():
163 163
164 164 def gen():
165 165 for chunk, label in chunks:
166 166 yield ui.label(chunk, label=label)
167 167
168 168 for chunk in util.filechunkiter(util.chunkbuffer(gen())):
169 169 ui.write(chunk)
170 170 else:
171 171 for chunk, label in chunks:
172 172 ui.write(chunk, label=label)
173 173
174 174 node2 = ctx2.node()
175 175 for subpath, sub in scmutil.itersubrepos(ctx1, ctx2):
176 176 tempnode2 = node2
177 177 try:
178 178 if node2 is not None:
179 179 tempnode2 = ctx2.substate[subpath][1]
180 180 except KeyError:
181 181 # A subrepo that existed in node1 was deleted between node1 and
182 182 # node2 (inclusive). Thus, ctx2's substate won't contain that
183 183 # subpath. The best we can do is to ignore it.
184 184 tempnode2 = None
185 185 submatch = matchmod.subdirmatcher(subpath, match)
186 186 subprefix = repo.wvfs.reljoin(prefix, subpath)
187 187 if listsubrepos or match.exact(subpath) or any(submatch.files()):
188 188 sub.diff(
189 189 ui,
190 190 diffopts,
191 191 tempnode2,
192 192 submatch,
193 193 changes=changes,
194 194 stat=stat,
195 195 fp=fp,
196 196 prefix=subprefix,
197 197 )
198 198
199 199
200 200 class changesetdiffer(object):
201 201 """Generate diff of changeset with pre-configured filtering functions"""
202 202
203 203 def _makefilematcher(self, ctx):
204 204 return scmutil.matchall(ctx.repo())
205 205
206 206 def _makehunksfilter(self, ctx):
207 207 return None
208 208
209 209 def showdiff(self, ui, ctx, diffopts, graphwidth=0, stat=False):
210 210 diffordiffstat(
211 211 ui,
212 212 ctx.repo(),
213 213 diffopts,
214 214 ctx.p1(),
215 215 ctx,
216 216 match=self._makefilematcher(ctx),
217 217 stat=stat,
218 218 graphwidth=graphwidth,
219 219 hunksfilterfn=self._makehunksfilter(ctx),
220 220 )
221 221
222 222
223 223 def changesetlabels(ctx):
224 224 labels = [b'log.changeset', b'changeset.%s' % ctx.phasestr()]
225 225 if ctx.obsolete():
226 226 labels.append(b'changeset.obsolete')
227 227 if ctx.isunstable():
228 228 labels.append(b'changeset.unstable')
229 229 for instability in ctx.instabilities():
230 230 labels.append(b'instability.%s' % instability)
231 231 return b' '.join(labels)
232 232
233 233
234 234 class changesetprinter(object):
235 235 '''show changeset information when templating not requested.'''
236 236
237 237 def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
238 238 self.ui = ui
239 239 self.repo = repo
240 240 self.buffered = buffered
241 241 self._differ = differ or changesetdiffer()
242 242 self._diffopts = patch.diffallopts(ui, diffopts)
243 243 self._includestat = diffopts and diffopts.get(b'stat')
244 244 self._includediff = diffopts and diffopts.get(b'patch')
245 245 self.header = {}
246 246 self.hunk = {}
247 247 self.lastheader = None
248 248 self.footer = None
249 249 self._columns = templatekw.getlogcolumns()
250 250
251 251 def flush(self, ctx):
252 252 rev = ctx.rev()
253 253 if rev in self.header:
254 254 h = self.header[rev]
255 255 if h != self.lastheader:
256 256 self.lastheader = h
257 257 self.ui.write(h)
258 258 del self.header[rev]
259 259 if rev in self.hunk:
260 260 self.ui.write(self.hunk[rev])
261 261 del self.hunk[rev]
262 262
263 263 def close(self):
264 264 if self.footer:
265 265 self.ui.write(self.footer)
266 266
267 267 def show(self, ctx, copies=None, **props):
268 268 props = pycompat.byteskwargs(props)
269 269 if self.buffered:
270 270 self.ui.pushbuffer(labeled=True)
271 271 self._show(ctx, copies, props)
272 272 self.hunk[ctx.rev()] = self.ui.popbuffer()
273 273 else:
274 274 self._show(ctx, copies, props)
275 275
276 276 def _show(self, ctx, copies, props):
277 277 '''show a single changeset or file revision'''
278 278 changenode = ctx.node()
279 279 graphwidth = props.get(b'graphwidth', 0)
280 280
281 281 if self.ui.quiet:
282 282 self.ui.write(
283 283 b"%s\n" % scmutil.formatchangeid(ctx), label=b'log.node'
284 284 )
285 285 return
286 286
287 287 columns = self._columns
288 288 self.ui.write(
289 289 columns[b'changeset'] % scmutil.formatchangeid(ctx),
290 290 label=changesetlabels(ctx),
291 291 )
292 292
293 293 # branches are shown first before any other names due to backwards
294 294 # compatibility
295 295 branch = ctx.branch()
296 296 # don't show the default branch name
297 297 if branch != b'default':
298 298 self.ui.write(columns[b'branch'] % branch, label=b'log.branch')
299 299
300 300 for nsname, ns in pycompat.iteritems(self.repo.names):
301 301 # branches has special logic already handled above, so here we just
302 302 # skip it
303 303 if nsname == b'branches':
304 304 continue
305 305 # we will use the templatename as the color name since those two
306 306 # should be the same
307 307 for name in ns.names(self.repo, changenode):
308 308 self.ui.write(ns.logfmt % name, label=b'log.%s' % ns.colorname)
309 309 if self.ui.debugflag:
310 310 self.ui.write(
311 311 columns[b'phase'] % ctx.phasestr(), label=b'log.phase'
312 312 )
313 313 for pctx in scmutil.meaningfulparents(self.repo, ctx):
314 314 label = b'log.parent changeset.%s' % pctx.phasestr()
315 315 self.ui.write(
316 316 columns[b'parent'] % scmutil.formatchangeid(pctx), label=label
317 317 )
318 318
319 319 if self.ui.debugflag:
320 320 mnode = ctx.manifestnode()
321 321 if mnode is None:
322 322 mnode = wdirid
323 323 mrev = wdirrev
324 324 else:
325 325 mrev = self.repo.manifestlog.rev(mnode)
326 326 self.ui.write(
327 327 columns[b'manifest']
328 328 % scmutil.formatrevnode(self.ui, mrev, mnode),
329 329 label=b'ui.debug log.manifest',
330 330 )
331 331 self.ui.write(columns[b'user'] % ctx.user(), label=b'log.user')
332 332 self.ui.write(
333 333 columns[b'date'] % dateutil.datestr(ctx.date()), label=b'log.date'
334 334 )
335 335
336 336 if ctx.isunstable():
337 337 instabilities = ctx.instabilities()
338 338 self.ui.write(
339 339 columns[b'instability'] % b', '.join(instabilities),
340 340 label=b'log.instability',
341 341 )
342 342
343 343 elif ctx.obsolete():
344 344 self._showobsfate(ctx)
345 345
346 346 self._exthook(ctx)
347 347
348 348 if self.ui.debugflag:
349 349 files = ctx.p1().status(ctx)
350 350 for key, value in zip(
351 351 [b'files', b'files+', b'files-'],
352 352 [files.modified, files.added, files.removed],
353 353 ):
354 354 if value:
355 355 self.ui.write(
356 356 columns[key] % b" ".join(value),
357 357 label=b'ui.debug log.files',
358 358 )
359 359 elif ctx.files() and self.ui.verbose:
360 360 self.ui.write(
361 361 columns[b'files'] % b" ".join(ctx.files()),
362 362 label=b'ui.note log.files',
363 363 )
364 364 if copies and self.ui.verbose:
365 365 copies = [b'%s (%s)' % c for c in copies]
366 366 self.ui.write(
367 367 columns[b'copies'] % b' '.join(copies),
368 368 label=b'ui.note log.copies',
369 369 )
370 370
371 371 extra = ctx.extra()
372 372 if extra and self.ui.debugflag:
373 373 for key, value in sorted(extra.items()):
374 374 self.ui.write(
375 375 columns[b'extra'] % (key, stringutil.escapestr(value)),
376 376 label=b'ui.debug log.extra',
377 377 )
378 378
379 379 description = ctx.description().strip()
380 380 if description:
381 381 if self.ui.verbose:
382 382 self.ui.write(
383 383 _(b"description:\n"), label=b'ui.note log.description'
384 384 )
385 385 self.ui.write(description, label=b'ui.note log.description')
386 386 self.ui.write(b"\n\n")
387 387 else:
388 388 self.ui.write(
389 389 columns[b'summary'] % description.splitlines()[0],
390 390 label=b'log.summary',
391 391 )
392 392 self.ui.write(b"\n")
393 393
394 394 self._showpatch(ctx, graphwidth)
395 395
396 396 def _showobsfate(self, ctx):
397 397 # TODO: do not depend on templater
398 398 tres = formatter.templateresources(self.repo.ui, self.repo)
399 399 t = formatter.maketemplater(
400 400 self.repo.ui,
401 401 b'{join(obsfate, "\n")}',
402 402 defaults=templatekw.keywords,
403 403 resources=tres,
404 404 )
405 405 obsfate = t.renderdefault({b'ctx': ctx}).splitlines()
406 406
407 407 if obsfate:
408 408 for obsfateline in obsfate:
409 409 self.ui.write(
410 410 self._columns[b'obsolete'] % obsfateline,
411 411 label=b'log.obsfate',
412 412 )
413 413
414 414 def _exthook(self, ctx):
415 415 '''empty method used by extension as a hook point
416 416 '''
417 417
418 418 def _showpatch(self, ctx, graphwidth=0):
419 419 if self._includestat:
420 420 self._differ.showdiff(
421 421 self.ui, ctx, self._diffopts, graphwidth, stat=True
422 422 )
423 423 if self._includestat and self._includediff:
424 424 self.ui.write(b"\n")
425 425 if self._includediff:
426 426 self._differ.showdiff(
427 427 self.ui, ctx, self._diffopts, graphwidth, stat=False
428 428 )
429 429 if self._includestat or self._includediff:
430 430 self.ui.write(b"\n")
431 431
432 432
433 433 class changesetformatter(changesetprinter):
434 434 """Format changeset information by generic formatter"""
435 435
436 436 def __init__(
437 437 self, ui, repo, fm, differ=None, diffopts=None, buffered=False
438 438 ):
439 439 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
440 440 self._diffopts = patch.difffeatureopts(ui, diffopts, git=True)
441 441 self._fm = fm
442 442
443 443 def close(self):
444 444 self._fm.end()
445 445
446 446 def _show(self, ctx, copies, props):
447 447 '''show a single changeset or file revision'''
448 448 fm = self._fm
449 449 fm.startitem()
450 450 fm.context(ctx=ctx)
451 451 fm.data(rev=scmutil.intrev(ctx), node=fm.hexfunc(scmutil.binnode(ctx)))
452 452
453 453 datahint = fm.datahint()
454 454 if self.ui.quiet and not datahint:
455 455 return
456 456
457 457 fm.data(
458 458 branch=ctx.branch(),
459 459 phase=ctx.phasestr(),
460 460 user=ctx.user(),
461 461 date=fm.formatdate(ctx.date()),
462 462 desc=ctx.description(),
463 463 bookmarks=fm.formatlist(ctx.bookmarks(), name=b'bookmark'),
464 464 tags=fm.formatlist(ctx.tags(), name=b'tag'),
465 465 parents=fm.formatlist(
466 466 [fm.hexfunc(c.node()) for c in ctx.parents()], name=b'node'
467 467 ),
468 468 )
469 469
470 470 if self.ui.debugflag or b'manifest' in datahint:
471 471 fm.data(manifest=fm.hexfunc(ctx.manifestnode() or wdirid))
472 472 if self.ui.debugflag or b'extra' in datahint:
473 473 fm.data(extra=fm.formatdict(ctx.extra()))
474 474
475 475 if (
476 476 self.ui.debugflag
477 477 or b'modified' in datahint
478 478 or b'added' in datahint
479 479 or b'removed' in datahint
480 480 ):
481 481 files = ctx.p1().status(ctx)
482 482 fm.data(
483 483 modified=fm.formatlist(files.modified, name=b'file'),
484 484 added=fm.formatlist(files.added, name=b'file'),
485 485 removed=fm.formatlist(files.removed, name=b'file'),
486 486 )
487 487
488 488 verbose = not self.ui.debugflag and self.ui.verbose
489 489 if verbose or b'files' in datahint:
490 490 fm.data(files=fm.formatlist(ctx.files(), name=b'file'))
491 491 if verbose and copies or b'copies' in datahint:
492 492 fm.data(
493 493 copies=fm.formatdict(copies or {}, key=b'name', value=b'source')
494 494 )
495 495
496 496 if self._includestat or b'diffstat' in datahint:
497 497 self.ui.pushbuffer()
498 498 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=True)
499 499 fm.data(diffstat=self.ui.popbuffer())
500 500 if self._includediff or b'diff' in datahint:
501 501 self.ui.pushbuffer()
502 502 self._differ.showdiff(self.ui, ctx, self._diffopts, stat=False)
503 503 fm.data(diff=self.ui.popbuffer())
504 504
505 505
506 506 class changesettemplater(changesetprinter):
507 507 '''format changeset information.
508 508
509 509 Note: there are a variety of convenience functions to build a
510 510 changesettemplater for common cases. See functions such as:
511 511 maketemplater, changesetdisplayer, buildcommittemplate, or other
512 512 functions that use changesest_templater.
513 513 '''
514 514
515 515 # Arguments before "buffered" used to be positional. Consider not
516 516 # adding/removing arguments before "buffered" to not break callers.
517 517 def __init__(
518 518 self, ui, repo, tmplspec, differ=None, diffopts=None, buffered=False
519 519 ):
520 520 changesetprinter.__init__(self, ui, repo, differ, diffopts, buffered)
521 521 # tres is shared with _graphnodeformatter()
522 522 self._tresources = tres = formatter.templateresources(ui, repo)
523 523 self.t = formatter.loadtemplater(
524 524 ui,
525 525 tmplspec,
526 526 defaults=templatekw.keywords,
527 527 resources=tres,
528 528 cache=templatekw.defaulttempl,
529 529 )
530 530 self._counter = itertools.count()
531 531
532 532 self._tref = tmplspec.ref
533 533 self._parts = {
534 534 b'header': b'',
535 535 b'footer': b'',
536 536 tmplspec.ref: tmplspec.ref,
537 537 b'docheader': b'',
538 538 b'docfooter': b'',
539 539 b'separator': b'',
540 540 }
541 541 if tmplspec.mapfile:
542 542 # find correct templates for current mode, for backward
543 543 # compatibility with 'log -v/-q/--debug' using a mapfile
544 544 tmplmodes = [
545 545 (True, b''),
546 546 (self.ui.verbose, b'_verbose'),
547 547 (self.ui.quiet, b'_quiet'),
548 548 (self.ui.debugflag, b'_debug'),
549 549 ]
550 550 for mode, postfix in tmplmodes:
551 551 for t in self._parts:
552 552 cur = t + postfix
553 553 if mode and cur in self.t:
554 554 self._parts[t] = cur
555 555 else:
556 556 partnames = [p for p in self._parts.keys() if p != tmplspec.ref]
557 557 m = formatter.templatepartsmap(tmplspec, self.t, partnames)
558 558 self._parts.update(m)
559 559
560 560 if self._parts[b'docheader']:
561 561 self.ui.write(self.t.render(self._parts[b'docheader'], {}))
562 562
563 563 def close(self):
564 564 if self._parts[b'docfooter']:
565 565 if not self.footer:
566 566 self.footer = b""
567 567 self.footer += self.t.render(self._parts[b'docfooter'], {})
568 568 return super(changesettemplater, self).close()
569 569
570 570 def _show(self, ctx, copies, props):
571 571 '''show a single changeset or file revision'''
572 572 props = props.copy()
573 573 props[b'ctx'] = ctx
574 574 props[b'index'] = index = next(self._counter)
575 575 props[b'revcache'] = {b'copies': copies}
576 576 graphwidth = props.get(b'graphwidth', 0)
577 577
578 578 # write separator, which wouldn't work well with the header part below
579 579 # since there's inherently a conflict between header (across items) and
580 580 # separator (per item)
581 581 if self._parts[b'separator'] and index > 0:
582 582 self.ui.write(self.t.render(self._parts[b'separator'], {}))
583 583
584 584 # write header
585 585 if self._parts[b'header']:
586 586 h = self.t.render(self._parts[b'header'], props)
587 587 if self.buffered:
588 588 self.header[ctx.rev()] = h
589 589 else:
590 590 if self.lastheader != h:
591 591 self.lastheader = h
592 592 self.ui.write(h)
593 593
594 594 # write changeset metadata, then patch if requested
595 595 key = self._parts[self._tref]
596 596 self.ui.write(self.t.render(key, props))
597 597 self._exthook(ctx)
598 598 self._showpatch(ctx, graphwidth)
599 599
600 600 if self._parts[b'footer']:
601 601 if not self.footer:
602 602 self.footer = self.t.render(self._parts[b'footer'], props)
603 603
604 604
605 605 def templatespec(tmpl, mapfile):
606 606 assert not (tmpl and mapfile)
607 607 if mapfile:
608 608 return formatter.mapfile_templatespec(b'changeset', mapfile)
609 609 else:
610 610 return formatter.literal_templatespec(tmpl)
611 611
612 612
613 613 def _lookuptemplate(ui, tmpl, style):
614 614 """Find the template matching the given template spec or style
615 615
616 616 See formatter.lookuptemplate() for details.
617 617 """
618 618
619 619 # ui settings
620 620 if not tmpl and not style: # template are stronger than style
621 621 tmpl = ui.config(b'ui', b'logtemplate')
622 622 if tmpl:
623 623 return formatter.literal_templatespec(templater.unquotestring(tmpl))
624 624 else:
625 625 style = util.expandpath(ui.config(b'ui', b'style'))
626 626
627 627 if not tmpl and style:
628 628 mapfile = style
629 629 fp = None
630 630 if not os.path.split(mapfile)[0]:
631 631 (mapname, fp) = templater.try_open_template(
632 632 b'map-cmdline.' + mapfile
633 633 ) or templater.try_open_template(mapfile)
634 634 if mapname:
635 635 mapfile = mapname
636 636 return formatter.mapfile_templatespec(b'changeset', mapfile, fp)
637 637
638 638 return formatter.lookuptemplate(ui, b'changeset', tmpl)
639 639
640 640
641 641 def maketemplater(ui, repo, tmpl, buffered=False):
642 642 """Create a changesettemplater from a literal template 'tmpl'
643 643 byte-string."""
644 644 spec = formatter.literal_templatespec(tmpl)
645 645 return changesettemplater(ui, repo, spec, buffered=buffered)
646 646
647 647
648 648 def changesetdisplayer(ui, repo, opts, differ=None, buffered=False):
649 649 """show one changeset using template or regular display.
650 650
651 651 Display format will be the first non-empty hit of:
652 652 1. option 'template'
653 653 2. option 'style'
654 654 3. [ui] setting 'logtemplate'
655 655 4. [ui] setting 'style'
656 656 If all of these values are either the unset or the empty string,
657 657 regular display via changesetprinter() is done.
658 658 """
659 659 postargs = (differ, opts, buffered)
660 660 spec = _lookuptemplate(ui, opts.get(b'template'), opts.get(b'style'))
661 661
662 662 # machine-readable formats have slightly different keyword set than
663 663 # plain templates, which are handled by changesetformatter.
664 664 # note that {b'pickle', b'debug'} can also be added to the list if needed.
665 665 if spec.ref in {b'cbor', b'json'}:
666 666 fm = ui.formatter(b'log', opts)
667 667 return changesetformatter(ui, repo, fm, *postargs)
668 668
669 669 if not spec.ref and not spec.tmpl and not spec.mapfile:
670 670 return changesetprinter(ui, repo, *postargs)
671 671
672 672 return changesettemplater(ui, repo, spec, *postargs)
673 673
674 674
675 675 def _makematcher(repo, revs, pats, opts):
676 676 """Build matcher and expanded patterns from log options
677 677
678 678 If --follow, revs are the revisions to follow from.
679 679
680 680 Returns (match, pats, slowpath) where
681 681 - match: a matcher built from the given pats and -I/-X opts
682 682 - pats: patterns used (globs are expanded on Windows)
683 683 - slowpath: True if patterns aren't as simple as scanning filelogs
684 684 """
685 685 # pats/include/exclude are passed to match.match() directly in
686 686 # _matchfiles() revset but walkchangerevs() builds its matcher with
687 687 # scmutil.match(). The difference is input pats are globbed on
688 688 # platforms without shell expansion (windows).
689 689 wctx = repo[None]
690 690 match, pats = scmutil.matchandpats(wctx, pats, opts)
691 691 slowpath = match.anypats() or (not match.always() and opts.get(b'removed'))
692 692 if not slowpath:
693 693 follow = opts.get(b'follow') or opts.get(b'follow_first')
694 694 if follow and opts.get(b'rev'):
695 # There may be the case that a path doesn't exist in some (but
696 # not all) of the specified start revisions, but let's consider
697 # the path is valid. Missing files will be warned by the matcher.
695 698 startctxs = [repo[r] for r in revs]
696 699 for f in match.files():
697 # No idea if the path was a directory at that revision, so
698 # take the slow path.
699 if any(f not in c for c in startctxs):
700 slowpath = True
701 break
700 found = False
701 for c in startctxs:
702 if f in c:
703 found = True
704 elif c.hasdir(f):
705 # If a directory exists in any of the start revisions,
706 # take the slow path.
707 found = slowpath = True
708 if not found:
709 raise error.Abort(
710 _(
711 b'cannot follow file not in any of the specified '
712 b'revisions: "%s"'
713 )
714 % f
715 )
702 716 elif follow:
703 717 for f in match.files():
704 718 if f not in wctx:
705 719 # If the file exists, it may be a directory, so let it
706 720 # take the slow path.
707 721 if os.path.exists(repo.wjoin(f)):
708 722 slowpath = True
709 723 continue
710 724 else:
711 725 raise error.Abort(
712 726 _(
713 727 b'cannot follow file not in parent '
714 728 b'revision: "%s"'
715 729 )
716 730 % f
717 731 )
718 732 filelog = repo.file(f)
719 733 if not filelog:
720 734 # A file exists in wdir but not in history, which means
721 735 # the file isn't committed yet.
722 736 raise error.Abort(
723 737 _(b'cannot follow nonexistent file: "%s"') % f
724 738 )
725 739 else:
726 740 for f in match.files():
727 741 filelog = repo.file(f)
728 742 if not filelog:
729 743 # A zero count may be a directory or deleted file, so
730 744 # try to find matching entries on the slow path.
731 745 slowpath = True
732 746
733 747 # We decided to fall back to the slowpath because at least one
734 748 # of the paths was not a file. Check to see if at least one of them
735 749 # existed in history - in that case, we'll continue down the
736 750 # slowpath; otherwise, we can turn off the slowpath
737 751 if slowpath:
738 752 for path in match.files():
739 753 if path == b'.' or path in repo.store:
740 754 break
741 755 else:
742 756 slowpath = False
743 757
744 758 return match, pats, slowpath
745 759
746 760
747 761 def _fileancestors(repo, revs, match, followfirst):
748 762 fctxs = []
749 763 for r in revs:
750 764 ctx = repo[r]
751 765 fctxs.extend(ctx[f].introfilectx() for f in ctx.walk(match))
752 766
753 767 # When displaying a revision with --patch --follow FILE, we have
754 768 # to know which file of the revision must be diffed. With
755 769 # --follow, we want the names of the ancestors of FILE in the
756 770 # revision, stored in "fcache". "fcache" is populated as a side effect
757 771 # of the graph traversal.
758 772 fcache = {}
759 773
760 774 def filematcher(ctx):
761 775 return scmutil.matchfiles(repo, fcache.get(scmutil.intrev(ctx), []))
762 776
763 777 def revgen():
764 778 for rev, cs in dagop.filectxancestors(fctxs, followfirst=followfirst):
765 779 fcache[rev] = [c.path() for c in cs]
766 780 yield rev
767 781
768 782 return smartset.generatorset(revgen(), iterasc=False), filematcher
769 783
770 784
771 785 def _makenofollowfilematcher(repo, pats, opts):
772 786 '''hook for extensions to override the filematcher for non-follow cases'''
773 787 return None
774 788
775 789
776 790 _opt2logrevset = {
777 791 b'no_merges': (b'not merge()', None),
778 792 b'only_merges': (b'merge()', None),
779 793 b'_matchfiles': (None, b'_matchfiles(%ps)'),
780 794 b'date': (b'date(%s)', None),
781 795 b'branch': (b'branch(%s)', b'%lr'),
782 796 b'_patslog': (b'filelog(%s)', b'%lr'),
783 797 b'keyword': (b'keyword(%s)', b'%lr'),
784 798 b'prune': (b'ancestors(%s)', b'not %lr'),
785 799 b'user': (b'user(%s)', b'%lr'),
786 800 }
787 801
788 802
789 803 def _makerevset(repo, match, pats, slowpath, opts):
790 804 """Return a revset string built from log options and file patterns"""
791 805 opts = dict(opts)
792 806 # follow or not follow?
793 807 follow = opts.get(b'follow') or opts.get(b'follow_first')
794 808
795 809 # branch and only_branch are really aliases and must be handled at
796 810 # the same time
797 811 opts[b'branch'] = opts.get(b'branch', []) + opts.get(b'only_branch', [])
798 812 opts[b'branch'] = [repo.lookupbranch(b) for b in opts[b'branch']]
799 813
800 814 if slowpath:
801 815 # See walkchangerevs() slow path.
802 816 #
803 817 # pats/include/exclude cannot be represented as separate
804 818 # revset expressions as their filtering logic applies at file
805 819 # level. For instance "-I a -X b" matches a revision touching
806 820 # "a" and "b" while "file(a) and not file(b)" does
807 821 # not. Besides, filesets are evaluated against the working
808 822 # directory.
809 823 matchargs = [b'r:', b'd:relpath']
810 824 for p in pats:
811 825 matchargs.append(b'p:' + p)
812 826 for p in opts.get(b'include', []):
813 827 matchargs.append(b'i:' + p)
814 828 for p in opts.get(b'exclude', []):
815 829 matchargs.append(b'x:' + p)
816 830 opts[b'_matchfiles'] = matchargs
817 831 elif not follow:
818 832 opts[b'_patslog'] = list(pats)
819 833
820 834 expr = []
821 835 for op, val in sorted(pycompat.iteritems(opts)):
822 836 if not val:
823 837 continue
824 838 if op not in _opt2logrevset:
825 839 continue
826 840 revop, listop = _opt2logrevset[op]
827 841 if revop and b'%' not in revop:
828 842 expr.append(revop)
829 843 elif not listop:
830 844 expr.append(revsetlang.formatspec(revop, val))
831 845 else:
832 846 if revop:
833 847 val = [revsetlang.formatspec(revop, v) for v in val]
834 848 expr.append(revsetlang.formatspec(listop, val))
835 849
836 850 if expr:
837 851 expr = b'(' + b' and '.join(expr) + b')'
838 852 else:
839 853 expr = None
840 854 return expr
841 855
842 856
843 857 def _initialrevs(repo, opts):
844 858 """Return the initial set of revisions to be filtered or followed"""
845 859 follow = opts.get(b'follow') or opts.get(b'follow_first')
846 860 if opts.get(b'rev'):
847 861 revs = scmutil.revrange(repo, opts[b'rev'])
848 862 elif follow and repo.dirstate.p1() == nullid:
849 863 revs = smartset.baseset()
850 864 elif follow:
851 865 revs = repo.revs(b'.')
852 866 else:
853 867 revs = smartset.spanset(repo)
854 868 revs.reverse()
855 869 return revs
856 870
857 871
858 872 def getrevs(repo, pats, opts):
859 873 # type: (Any, Any, Any) -> Tuple[smartset.abstractsmartset, Optional[changesetdiffer]]
860 874 """Return (revs, differ) where revs is a smartset
861 875
862 876 differ is a changesetdiffer with pre-configured file matcher.
863 877 """
864 878 follow = opts.get(b'follow') or opts.get(b'follow_first')
865 879 followfirst = opts.get(b'follow_first')
866 880 limit = getlimit(opts)
867 881 revs = _initialrevs(repo, opts)
868 882 if not revs:
869 883 return smartset.baseset(), None
870 884 match, pats, slowpath = _makematcher(repo, revs, pats, opts)
871 885 filematcher = None
872 886 if follow:
873 887 if slowpath or match.always():
874 888 revs = dagop.revancestors(repo, revs, followfirst=followfirst)
875 889 else:
876 890 revs, filematcher = _fileancestors(repo, revs, match, followfirst)
877 891 revs.reverse()
878 892 if filematcher is None:
879 893 filematcher = _makenofollowfilematcher(repo, pats, opts)
880 894 if filematcher is None:
881 895
882 896 def filematcher(ctx):
883 897 return match
884 898
885 899 expr = _makerevset(repo, match, pats, slowpath, opts)
886 900 if opts.get(b'graph'):
887 901 # User-specified revs might be unsorted, but don't sort before
888 902 # _makerevset because it might depend on the order of revs
889 903 if repo.ui.configbool(b'experimental', b'log.topo'):
890 904 if not revs.istopo():
891 905 revs = dagop.toposort(revs, repo.changelog.parentrevs)
892 906 # TODO: try to iterate the set lazily
893 907 revs = revset.baseset(list(revs), istopo=True)
894 908 elif not (revs.isdescending() or revs.istopo()):
895 909 revs.sort(reverse=True)
896 910 if expr:
897 911 matcher = revset.match(None, expr)
898 912 revs = matcher(repo, revs)
899 913 if limit is not None:
900 914 revs = revs.slice(0, limit)
901 915
902 916 differ = changesetdiffer()
903 917 differ._makefilematcher = filematcher
904 918 return revs, differ
905 919
906 920
907 921 def _parselinerangeopt(repo, opts):
908 922 """Parse --line-range log option and return a list of tuples (filename,
909 923 (fromline, toline)).
910 924 """
911 925 linerangebyfname = []
912 926 for pat in opts.get(b'line_range', []):
913 927 try:
914 928 pat, linerange = pat.rsplit(b',', 1)
915 929 except ValueError:
916 930 raise error.Abort(_(b'malformatted line-range pattern %s') % pat)
917 931 try:
918 932 fromline, toline = map(int, linerange.split(b':'))
919 933 except ValueError:
920 934 raise error.Abort(_(b"invalid line range for %s") % pat)
921 935 msg = _(b"line range pattern '%s' must match exactly one file") % pat
922 936 fname = scmutil.parsefollowlinespattern(repo, None, pat, msg)
923 937 linerangebyfname.append(
924 938 (fname, util.processlinerange(fromline, toline))
925 939 )
926 940 return linerangebyfname
927 941
928 942
929 943 def getlinerangerevs(repo, userrevs, opts):
930 944 """Return (revs, differ).
931 945
932 946 "revs" are revisions obtained by processing "line-range" log options and
933 947 walking block ancestors of each specified file/line-range.
934 948
935 949 "differ" is a changesetdiffer with pre-configured file matcher and hunks
936 950 filter.
937 951 """
938 952 wctx = repo[None]
939 953
940 954 # Two-levels map of "rev -> file ctx -> [line range]".
941 955 linerangesbyrev = {}
942 956 for fname, (fromline, toline) in _parselinerangeopt(repo, opts):
943 957 if fname not in wctx:
944 958 raise error.Abort(
945 959 _(b'cannot follow file not in parent revision: "%s"') % fname
946 960 )
947 961 fctx = wctx.filectx(fname)
948 962 for fctx, linerange in dagop.blockancestors(fctx, fromline, toline):
949 963 rev = fctx.introrev()
950 964 if rev is None:
951 965 rev = wdirrev
952 966 if rev not in userrevs:
953 967 continue
954 968 linerangesbyrev.setdefault(rev, {}).setdefault(
955 969 fctx.path(), []
956 970 ).append(linerange)
957 971
958 972 def nofilterhunksfn(fctx, hunks):
959 973 return hunks
960 974
961 975 def hunksfilter(ctx):
962 976 fctxlineranges = linerangesbyrev.get(scmutil.intrev(ctx))
963 977 if fctxlineranges is None:
964 978 return nofilterhunksfn
965 979
966 980 def filterfn(fctx, hunks):
967 981 lineranges = fctxlineranges.get(fctx.path())
968 982 if lineranges is not None:
969 983 for hr, lines in hunks:
970 984 if hr is None: # binary
971 985 yield hr, lines
972 986 continue
973 987 if any(mdiff.hunkinrange(hr[2:], lr) for lr in lineranges):
974 988 yield hr, lines
975 989 else:
976 990 for hunk in hunks:
977 991 yield hunk
978 992
979 993 return filterfn
980 994
981 995 def filematcher(ctx):
982 996 files = list(linerangesbyrev.get(scmutil.intrev(ctx), []))
983 997 return scmutil.matchfiles(repo, files)
984 998
985 999 revs = sorted(linerangesbyrev, reverse=True)
986 1000
987 1001 differ = changesetdiffer()
988 1002 differ._makefilematcher = filematcher
989 1003 differ._makehunksfilter = hunksfilter
990 1004 return smartset.baseset(revs), differ
991 1005
992 1006
993 1007 def _graphnodeformatter(ui, displayer):
994 1008 spec = ui.config(b'ui', b'graphnodetemplate')
995 1009 if not spec:
996 1010 return templatekw.getgraphnode # fast path for "{graphnode}"
997 1011
998 1012 spec = templater.unquotestring(spec)
999 1013 if isinstance(displayer, changesettemplater):
1000 1014 # reuse cache of slow templates
1001 1015 tres = displayer._tresources
1002 1016 else:
1003 1017 tres = formatter.templateresources(ui)
1004 1018 templ = formatter.maketemplater(
1005 1019 ui, spec, defaults=templatekw.keywords, resources=tres
1006 1020 )
1007 1021
1008 1022 def formatnode(repo, ctx, cache):
1009 1023 props = {b'ctx': ctx, b'repo': repo}
1010 1024 return templ.renderdefault(props)
1011 1025
1012 1026 return formatnode
1013 1027
1014 1028
1015 1029 def displaygraph(ui, repo, dag, displayer, edgefn, getcopies=None, props=None):
1016 1030 props = props or {}
1017 1031 formatnode = _graphnodeformatter(ui, displayer)
1018 1032 state = graphmod.asciistate()
1019 1033 styles = state.styles
1020 1034
1021 1035 # only set graph styling if HGPLAIN is not set.
1022 1036 if ui.plain(b'graph'):
1023 1037 # set all edge styles to |, the default pre-3.8 behaviour
1024 1038 styles.update(dict.fromkeys(styles, b'|'))
1025 1039 else:
1026 1040 edgetypes = {
1027 1041 b'parent': graphmod.PARENT,
1028 1042 b'grandparent': graphmod.GRANDPARENT,
1029 1043 b'missing': graphmod.MISSINGPARENT,
1030 1044 }
1031 1045 for name, key in edgetypes.items():
1032 1046 # experimental config: experimental.graphstyle.*
1033 1047 styles[key] = ui.config(
1034 1048 b'experimental', b'graphstyle.%s' % name, styles[key]
1035 1049 )
1036 1050 if not styles[key]:
1037 1051 styles[key] = None
1038 1052
1039 1053 # experimental config: experimental.graphshorten
1040 1054 state.graphshorten = ui.configbool(b'experimental', b'graphshorten')
1041 1055
1042 1056 formatnode_cache = {}
1043 1057 for rev, type, ctx, parents in dag:
1044 1058 char = formatnode(repo, ctx, formatnode_cache)
1045 1059 copies = getcopies(ctx) if getcopies else None
1046 1060 edges = edgefn(type, char, state, rev, parents)
1047 1061 firstedge = next(edges)
1048 1062 width = firstedge[2]
1049 1063 displayer.show(
1050 1064 ctx, copies=copies, graphwidth=width, **pycompat.strkwargs(props)
1051 1065 )
1052 1066 lines = displayer.hunk.pop(rev).split(b'\n')
1053 1067 if not lines[-1]:
1054 1068 del lines[-1]
1055 1069 displayer.flush(ctx)
1056 1070 for type, char, width, coldata in itertools.chain([firstedge], edges):
1057 1071 graphmod.ascii(ui, state, type, char, lines, coldata)
1058 1072 lines = []
1059 1073 displayer.close()
1060 1074
1061 1075
1062 1076 def displaygraphrevs(ui, repo, revs, displayer, getrenamed):
1063 1077 revdag = graphmod.dagwalker(repo, revs)
1064 1078 displaygraph(ui, repo, revdag, displayer, graphmod.asciiedges, getrenamed)
1065 1079
1066 1080
1067 1081 def displayrevs(ui, repo, revs, displayer, getcopies):
1068 1082 for rev in revs:
1069 1083 ctx = repo[rev]
1070 1084 copies = getcopies(ctx) if getcopies else None
1071 1085 displayer.show(ctx, copies=copies)
1072 1086 displayer.flush(ctx)
1073 1087 displayer.close()
1074 1088
1075 1089
1076 1090 def checkunsupportedgraphflags(pats, opts):
1077 1091 for op in [b"newest_first"]:
1078 1092 if op in opts and opts[op]:
1079 1093 raise error.Abort(
1080 1094 _(b"-G/--graph option is incompatible with --%s")
1081 1095 % op.replace(b"_", b"-")
1082 1096 )
1083 1097
1084 1098
1085 1099 def graphrevs(repo, nodes, opts):
1086 1100 limit = getlimit(opts)
1087 1101 nodes.reverse()
1088 1102 if limit is not None:
1089 1103 nodes = nodes[:limit]
1090 1104 return graphmod.nodes(repo, nodes)
@@ -1,2855 +1,2899 b''
1 1 Log on empty repository: checking consistency
2 2
3 3 $ hg init empty
4 4 $ cd empty
5 5 $ hg log
6 6 $ hg log -r 1
7 7 abort: unknown revision '1'!
8 8 [255]
9 9 $ hg log -r -1:0
10 10 abort: unknown revision '-1'!
11 11 [255]
12 12 $ hg log -r 'branch(name)'
13 13 abort: unknown revision 'name'!
14 14 [255]
15 15 $ hg log -r null -q
16 16 -1:000000000000
17 17
18 18 $ cd ..
19 19
20 20 The g is crafted to have 2 filelog topological heads in a linear
21 21 changeset graph
22 22
23 23 $ hg init a
24 24 $ cd a
25 25 $ echo a > a
26 26 $ echo f > f
27 27 $ hg ci -Ama -d '1 0'
28 28 adding a
29 29 adding f
30 30
31 31 $ hg cp a b
32 32 $ hg cp f g
33 33 $ hg ci -mb -d '2 0'
34 34
35 35 $ mkdir dir
36 36 $ hg mv b dir
37 37 $ echo g >> g
38 38 $ echo f >> f
39 39 $ hg ci -mc -d '3 0'
40 40
41 41 $ hg mv a b
42 42 $ hg cp -f f g
43 43 $ echo a > d
44 44 $ hg add d
45 45 $ hg ci -md -d '4 0'
46 46
47 47 $ hg mv dir/b e
48 48 $ hg ci -me -d '5 0'
49 49
50 50 Make sure largefiles doesn't interfere with logging a regular file
51 51 $ hg --debug log a -T '{rev}: {desc}\n' --config extensions.largefiles=
52 52 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
53 53 updated patterns: .hglf/a, a
54 54 0: a
55 55 $ hg log a
56 56 changeset: 0:9161b9aeaf16
57 57 user: test
58 58 date: Thu Jan 01 00:00:01 1970 +0000
59 59 summary: a
60 60
61 61 $ hg log glob:a*
62 62 changeset: 3:2ca5ba701980
63 63 user: test
64 64 date: Thu Jan 01 00:00:04 1970 +0000
65 65 summary: d
66 66
67 67 changeset: 0:9161b9aeaf16
68 68 user: test
69 69 date: Thu Jan 01 00:00:01 1970 +0000
70 70 summary: a
71 71
72 72 $ hg --debug log glob:a* -T '{rev}: {desc}\n' --config extensions.largefiles=
73 73 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
74 74 updated patterns: glob:.hglf/a*, glob:a*
75 75 3: d
76 76 0: a
77 77
78 78 log on directory
79 79
80 80 $ hg log dir
81 81 changeset: 4:7e4639b4691b
82 82 tag: tip
83 83 user: test
84 84 date: Thu Jan 01 00:00:05 1970 +0000
85 85 summary: e
86 86
87 87 changeset: 2:f8954cd4dc1f
88 88 user: test
89 89 date: Thu Jan 01 00:00:03 1970 +0000
90 90 summary: c
91 91
92 92 $ hg log somethingthatdoesntexist dir
93 93 changeset: 4:7e4639b4691b
94 94 tag: tip
95 95 user: test
96 96 date: Thu Jan 01 00:00:05 1970 +0000
97 97 summary: e
98 98
99 99 changeset: 2:f8954cd4dc1f
100 100 user: test
101 101 date: Thu Jan 01 00:00:03 1970 +0000
102 102 summary: c
103 103
104 104
105 105 -X, with explicit path
106 106
107 107 $ hg log a -X a
108 108
109 109 -f, non-existent directory
110 110
111 111 $ hg log -f dir
112 112 abort: cannot follow file not in parent revision: "dir"
113 113 [255]
114 114
115 115 -f, directory
116 116
117 117 $ hg up -q 3
118 118 $ hg log -f dir
119 119 changeset: 2:f8954cd4dc1f
120 120 user: test
121 121 date: Thu Jan 01 00:00:03 1970 +0000
122 122 summary: c
123 123
124 124 -f, directory with --patch
125 125
126 126 $ hg log -f dir -p
127 127 changeset: 2:f8954cd4dc1f
128 128 user: test
129 129 date: Thu Jan 01 00:00:03 1970 +0000
130 130 summary: c
131 131
132 132 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
133 133 --- /dev/null* (glob)
134 134 +++ b/dir/b* (glob)
135 135 @@ -0,0 +1,1 @@
136 136 +a
137 137
138 138
139 139 -f, pattern
140 140
141 141 $ hg log -f -I 'dir**' -p
142 142 changeset: 2:f8954cd4dc1f
143 143 user: test
144 144 date: Thu Jan 01 00:00:03 1970 +0000
145 145 summary: c
146 146
147 147 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
148 148 --- /dev/null* (glob)
149 149 +++ b/dir/b* (glob)
150 150 @@ -0,0 +1,1 @@
151 151 +a
152 152
153 153 $ hg up -q 4
154 154
155 155 -f, a wrong style
156 156
157 157 $ hg log -f -l1 --style something
158 158 abort: style 'something' not found
159 159 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
160 160 [255]
161 161
162 162 -f, phases style
163 163
164 164
165 165 $ hg log -f -l1 --style phases
166 166 changeset: 4:7e4639b4691b
167 167 tag: tip
168 168 phase: draft
169 169 user: test
170 170 date: Thu Jan 01 00:00:05 1970 +0000
171 171 summary: e
172 172
173 173
174 174 $ hg log -f -l1 --style phases -q
175 175 4:7e4639b4691b
176 176
177 177 -f, but no args
178 178
179 179 $ hg log -f
180 180 changeset: 4:7e4639b4691b
181 181 tag: tip
182 182 user: test
183 183 date: Thu Jan 01 00:00:05 1970 +0000
184 184 summary: e
185 185
186 186 changeset: 3:2ca5ba701980
187 187 user: test
188 188 date: Thu Jan 01 00:00:04 1970 +0000
189 189 summary: d
190 190
191 191 changeset: 2:f8954cd4dc1f
192 192 user: test
193 193 date: Thu Jan 01 00:00:03 1970 +0000
194 194 summary: c
195 195
196 196 changeset: 1:d89b0a12d229
197 197 user: test
198 198 date: Thu Jan 01 00:00:02 1970 +0000
199 199 summary: b
200 200
201 201 changeset: 0:9161b9aeaf16
202 202 user: test
203 203 date: Thu Jan 01 00:00:01 1970 +0000
204 204 summary: a
205 205
206 206
207 207 one rename
208 208
209 209 $ hg up -q 2
210 210 $ hg log -vf a
211 211 changeset: 0:9161b9aeaf16
212 212 user: test
213 213 date: Thu Jan 01 00:00:01 1970 +0000
214 214 files: a f
215 215 description:
216 216 a
217 217
218 218
219 219
220 220 many renames
221 221
222 222 $ hg up -q tip
223 223 $ hg log -vf e
224 224 changeset: 4:7e4639b4691b
225 225 tag: tip
226 226 user: test
227 227 date: Thu Jan 01 00:00:05 1970 +0000
228 228 files: dir/b e
229 229 description:
230 230 e
231 231
232 232
233 233 changeset: 2:f8954cd4dc1f
234 234 user: test
235 235 date: Thu Jan 01 00:00:03 1970 +0000
236 236 files: b dir/b f g
237 237 description:
238 238 c
239 239
240 240
241 241 changeset: 1:d89b0a12d229
242 242 user: test
243 243 date: Thu Jan 01 00:00:02 1970 +0000
244 244 files: b g
245 245 description:
246 246 b
247 247
248 248
249 249 changeset: 0:9161b9aeaf16
250 250 user: test
251 251 date: Thu Jan 01 00:00:01 1970 +0000
252 252 files: a f
253 253 description:
254 254 a
255 255
256 256
257 257
258 258
259 259 log -pf dir/b
260 260
261 261 $ hg up -q 3
262 262 $ hg log -pf dir/b
263 263 changeset: 2:f8954cd4dc1f
264 264 user: test
265 265 date: Thu Jan 01 00:00:03 1970 +0000
266 266 summary: c
267 267
268 268 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
269 269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270 270 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
271 271 @@ -0,0 +1,1 @@
272 272 +a
273 273
274 274 changeset: 1:d89b0a12d229
275 275 user: test
276 276 date: Thu Jan 01 00:00:02 1970 +0000
277 277 summary: b
278 278
279 279 diff -r 9161b9aeaf16 -r d89b0a12d229 b
280 280 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
281 281 +++ b/b Thu Jan 01 00:00:02 1970 +0000
282 282 @@ -0,0 +1,1 @@
283 283 +a
284 284
285 285 changeset: 0:9161b9aeaf16
286 286 user: test
287 287 date: Thu Jan 01 00:00:01 1970 +0000
288 288 summary: a
289 289
290 290 diff -r 000000000000 -r 9161b9aeaf16 a
291 291 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
292 292 +++ b/a Thu Jan 01 00:00:01 1970 +0000
293 293 @@ -0,0 +1,1 @@
294 294 +a
295 295
296 296
297 297 log -pf b inside dir
298 298
299 299 $ hg --cwd=dir log -pf b
300 300 changeset: 2:f8954cd4dc1f
301 301 user: test
302 302 date: Thu Jan 01 00:00:03 1970 +0000
303 303 summary: c
304 304
305 305 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
306 306 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
307 307 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
308 308 @@ -0,0 +1,1 @@
309 309 +a
310 310
311 311 changeset: 1:d89b0a12d229
312 312 user: test
313 313 date: Thu Jan 01 00:00:02 1970 +0000
314 314 summary: b
315 315
316 316 diff -r 9161b9aeaf16 -r d89b0a12d229 b
317 317 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
318 318 +++ b/b Thu Jan 01 00:00:02 1970 +0000
319 319 @@ -0,0 +1,1 @@
320 320 +a
321 321
322 322 changeset: 0:9161b9aeaf16
323 323 user: test
324 324 date: Thu Jan 01 00:00:01 1970 +0000
325 325 summary: a
326 326
327 327 diff -r 000000000000 -r 9161b9aeaf16 a
328 328 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
329 329 +++ b/a Thu Jan 01 00:00:01 1970 +0000
330 330 @@ -0,0 +1,1 @@
331 331 +a
332 332
333 333
334 334 log -pf, but no args
335 335
336 336 $ hg log -pf
337 337 changeset: 3:2ca5ba701980
338 338 user: test
339 339 date: Thu Jan 01 00:00:04 1970 +0000
340 340 summary: d
341 341
342 342 diff -r f8954cd4dc1f -r 2ca5ba701980 a
343 343 --- a/a Thu Jan 01 00:00:03 1970 +0000
344 344 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
345 345 @@ -1,1 +0,0 @@
346 346 -a
347 347 diff -r f8954cd4dc1f -r 2ca5ba701980 b
348 348 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
349 349 +++ b/b Thu Jan 01 00:00:04 1970 +0000
350 350 @@ -0,0 +1,1 @@
351 351 +a
352 352 diff -r f8954cd4dc1f -r 2ca5ba701980 d
353 353 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
354 354 +++ b/d Thu Jan 01 00:00:04 1970 +0000
355 355 @@ -0,0 +1,1 @@
356 356 +a
357 357 diff -r f8954cd4dc1f -r 2ca5ba701980 g
358 358 --- a/g Thu Jan 01 00:00:03 1970 +0000
359 359 +++ b/g Thu Jan 01 00:00:04 1970 +0000
360 360 @@ -1,2 +1,2 @@
361 361 f
362 362 -g
363 363 +f
364 364
365 365 changeset: 2:f8954cd4dc1f
366 366 user: test
367 367 date: Thu Jan 01 00:00:03 1970 +0000
368 368 summary: c
369 369
370 370 diff -r d89b0a12d229 -r f8954cd4dc1f b
371 371 --- a/b Thu Jan 01 00:00:02 1970 +0000
372 372 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
373 373 @@ -1,1 +0,0 @@
374 374 -a
375 375 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
376 376 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
377 377 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
378 378 @@ -0,0 +1,1 @@
379 379 +a
380 380 diff -r d89b0a12d229 -r f8954cd4dc1f f
381 381 --- a/f Thu Jan 01 00:00:02 1970 +0000
382 382 +++ b/f Thu Jan 01 00:00:03 1970 +0000
383 383 @@ -1,1 +1,2 @@
384 384 f
385 385 +f
386 386 diff -r d89b0a12d229 -r f8954cd4dc1f g
387 387 --- a/g Thu Jan 01 00:00:02 1970 +0000
388 388 +++ b/g Thu Jan 01 00:00:03 1970 +0000
389 389 @@ -1,1 +1,2 @@
390 390 f
391 391 +g
392 392
393 393 changeset: 1:d89b0a12d229
394 394 user: test
395 395 date: Thu Jan 01 00:00:02 1970 +0000
396 396 summary: b
397 397
398 398 diff -r 9161b9aeaf16 -r d89b0a12d229 b
399 399 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
400 400 +++ b/b Thu Jan 01 00:00:02 1970 +0000
401 401 @@ -0,0 +1,1 @@
402 402 +a
403 403 diff -r 9161b9aeaf16 -r d89b0a12d229 g
404 404 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
405 405 +++ b/g Thu Jan 01 00:00:02 1970 +0000
406 406 @@ -0,0 +1,1 @@
407 407 +f
408 408
409 409 changeset: 0:9161b9aeaf16
410 410 user: test
411 411 date: Thu Jan 01 00:00:01 1970 +0000
412 412 summary: a
413 413
414 414 diff -r 000000000000 -r 9161b9aeaf16 a
415 415 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
416 416 +++ b/a Thu Jan 01 00:00:01 1970 +0000
417 417 @@ -0,0 +1,1 @@
418 418 +a
419 419 diff -r 000000000000 -r 9161b9aeaf16 f
420 420 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
421 421 +++ b/f Thu Jan 01 00:00:01 1970 +0000
422 422 @@ -0,0 +1,1 @@
423 423 +f
424 424
425 425
426 426 log -vf dir/b
427 427
428 428 $ hg log -vf dir/b
429 429 changeset: 2:f8954cd4dc1f
430 430 user: test
431 431 date: Thu Jan 01 00:00:03 1970 +0000
432 432 files: b dir/b f g
433 433 description:
434 434 c
435 435
436 436
437 437 changeset: 1:d89b0a12d229
438 438 user: test
439 439 date: Thu Jan 01 00:00:02 1970 +0000
440 440 files: b g
441 441 description:
442 442 b
443 443
444 444
445 445 changeset: 0:9161b9aeaf16
446 446 user: test
447 447 date: Thu Jan 01 00:00:01 1970 +0000
448 448 files: a f
449 449 description:
450 450 a
451 451
452 452
453 453
454 454
455 455 -f and multiple filelog heads
456 456
457 457 $ hg up -q 2
458 458 $ hg log -f g --template '{rev}\n'
459 459 2
460 460 1
461 461 0
462 462 $ hg up -q tip
463 463 $ hg log -f g --template '{rev}\n'
464 464 3
465 465 2
466 466 0
467 467
468 468 follow files from the specified revisions (issue4959)
469 469
470 470 $ hg log -G -T '{rev} {files},{file_copies % " {source}->{name}"}\n'
471 471 @ 4 dir/b e, dir/b->e
472 472 |
473 473 o 3 a b d g, a->b f->g
474 474 |
475 475 o 2 b dir/b f g, b->dir/b
476 476 |
477 477 o 1 b g, a->b f->g
478 478 |
479 479 o 0 a f,
480 480
481 481
482 482 $ hg log -T '{rev}\n' -fr 4 e
483 483 4
484 484 2
485 485 1
486 486 0
487 487 $ hg log -T '{rev}\n' -fr 2 g
488 488 2
489 489 1
490 490 0
491 491 $ hg log -T '{rev}\n' -fr '2+3' g
492 492 3
493 493 2
494 494 1
495 495 0
496 496
497 497 follow files from the specified revisions with glob patterns (issue5053)
498 498 (BROKEN: should follow copies from e@4)
499 499
500 500 $ hg log -T '{rev}\n' -fr4 e -X '[abcdfg]'
501 501 4
502 502 2 (false !)
503 503 1 (false !)
504 504 0 (false !)
505 505
506 506 follow files from the specified revisions with missing patterns
507 (BROKEN: should follow copies from e@4)
508 507
509 508 $ hg log -T '{rev}\n' -fr4 e x
510 4
511 2 (false !)
509 abort: cannot follow file not in any of the specified revisions: "x"
510 [255]
511
512 follow files from the specified revisions with directory patterns
513 (BROKEN: should follow copies from dir/b@2)
514
515 $ hg log -T '{rev}\n' -fr2 dir/b dir
516 2
512 517 1 (false !)
513 518 0 (false !)
514 519
520 follow files from multiple revisions, but the pattern is missing in
521 one of the specified revisions
522
523 $ hg log -T '{rev}\n' -fr'2+4' dir/b e
524 e: no such file in rev f8954cd4dc1f
525 dir/b: no such file in rev 7e4639b4691b
526 4
527 2
528 1
529 0
530
531 follow files from multiple revisions, and the pattern matches a file in
532 one revision but matches a directory in another:
533 (BROKEN: should follow copies from dir/b@2 and dir/b/g@5)
534 (BROKEN: the revision 4 should not be included since dir/b/g@5 is unchanged)
535
536 $ mkdir -p dir/b
537 $ hg mv g dir/b
538 $ hg ci -m 'make dir/b a directory'
539
540 $ hg log -T '{rev}\n' -fr'2+5' dir/b
541 5
542 4
543 3 (false !)
544 2
545 1 (false !)
546 0 (false !)
547
548 $ hg --config extensions.strip= strip -r. --no-backup
549 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
550
515 551 follow files from the specified revisions across copies with -p/--patch
516 552
517 553 $ hg log -T '== rev: {rev},{file_copies % " {source}->{name}"} ==\n' -fpr 4 e g
518 554 == rev: 4, dir/b->e ==
519 555 diff -r 2ca5ba701980 -r 7e4639b4691b e
520 556 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
521 557 +++ b/e Thu Jan 01 00:00:05 1970 +0000
522 558 @@ -0,0 +1,1 @@
523 559 +a
524 560
525 561 == rev: 3, a->b f->g ==
526 562 diff -r f8954cd4dc1f -r 2ca5ba701980 g
527 563 --- a/g Thu Jan 01 00:00:03 1970 +0000
528 564 +++ b/g Thu Jan 01 00:00:04 1970 +0000
529 565 @@ -1,2 +1,2 @@
530 566 f
531 567 -g
532 568 +f
533 569
534 570 == rev: 2, b->dir/b ==
535 571 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
536 572 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
537 573 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
538 574 @@ -0,0 +1,1 @@
539 575 +a
540 576 diff -r d89b0a12d229 -r f8954cd4dc1f f
541 577 --- a/f Thu Jan 01 00:00:02 1970 +0000
542 578 +++ b/f Thu Jan 01 00:00:03 1970 +0000
543 579 @@ -1,1 +1,2 @@
544 580 f
545 581 +f
546 582
547 583 == rev: 1, a->b f->g ==
548 584 diff -r 9161b9aeaf16 -r d89b0a12d229 b
549 585 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
550 586 +++ b/b Thu Jan 01 00:00:02 1970 +0000
551 587 @@ -0,0 +1,1 @@
552 588 +a
553 589
554 590 == rev: 0, ==
555 591 diff -r 000000000000 -r 9161b9aeaf16 a
556 592 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
557 593 +++ b/a Thu Jan 01 00:00:01 1970 +0000
558 594 @@ -0,0 +1,1 @@
559 595 +a
560 596 diff -r 000000000000 -r 9161b9aeaf16 f
561 597 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
562 598 +++ b/f Thu Jan 01 00:00:01 1970 +0000
563 599 @@ -0,0 +1,1 @@
564 600 +f
565 601
566 602
567 603 log copies with --copies
568 604
569 605 $ hg log -vC --template '{rev} {file_copies}\n'
570 606 4 e (dir/b)
571 607 3 b (a)g (f)
572 608 2 dir/b (b)
573 609 1 b (a)g (f)
574 610 0
575 611
576 612 log copies switch without --copies, with old filecopy template
577 613
578 614 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
579 615 4
580 616 3
581 617 2
582 618 1
583 619 0
584 620
585 621 log copies switch with --copies
586 622
587 623 $ hg log -vC --template '{rev} {file_copies_switch}\n'
588 624 4 e (dir/b)
589 625 3 b (a)g (f)
590 626 2 dir/b (b)
591 627 1 b (a)g (f)
592 628 0
593 629
594 630
595 631 log copies with hardcoded style and with --style=default
596 632
597 633 $ hg log -vC -r4
598 634 changeset: 4:7e4639b4691b
599 635 tag: tip
600 636 user: test
601 637 date: Thu Jan 01 00:00:05 1970 +0000
602 638 files: dir/b e
603 639 copies: e (dir/b)
604 640 description:
605 641 e
606 642
607 643
608 644 $ hg log -vC -r4 --style=default
609 645 changeset: 4:7e4639b4691b
610 646 tag: tip
611 647 user: test
612 648 date: Thu Jan 01 00:00:05 1970 +0000
613 649 files: dir/b e
614 650 copies: e (dir/b)
615 651 description:
616 652 e
617 653
618 654
619 655 $ hg log -vC -r4 -Tjson
620 656 [
621 657 {
622 658 "bookmarks": [],
623 659 "branch": "default",
624 660 "copies": {"e": "dir/b"},
625 661 "date": [5, 0],
626 662 "desc": "e",
627 663 "files": ["dir/b", "e"],
628 664 "node": "7e4639b4691b9f84b81036a8d4fb218ce3c5e3a3",
629 665 "parents": ["2ca5ba7019804f1f597249caddf22a64d34df0ba"],
630 666 "phase": "draft",
631 667 "rev": 4,
632 668 "tags": ["tip"],
633 669 "user": "test"
634 670 }
635 671 ]
636 672
637 673 log copies, non-linear manifest
638 674
639 675 $ hg up -C 3
640 676 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
641 677 $ hg mv dir/b e
642 678 $ echo foo > foo
643 679 $ hg ci -Ame2 -d '6 0'
644 680 adding foo
645 681 created new head
646 682 $ hg log -v --template '{rev} {file_copies}\n' -r 5
647 683 5 e (dir/b)
648 684
649 685
650 686 log copies, execute bit set
651 687
652 688 #if execbit
653 689 $ chmod +x e
654 690 $ hg ci -me3 -d '7 0'
655 691 $ hg log -v --template '{rev} {file_copies}\n' -r 6
656 692 6
657 693 #endif
658 694
659 695 log copies, empty set
660 696
661 697 $ hg log --copies -r '0 and not 0'
662 698
663 699 log -p d
664 700
665 701 $ hg log -pv d
666 702 changeset: 3:2ca5ba701980
667 703 user: test
668 704 date: Thu Jan 01 00:00:04 1970 +0000
669 705 files: a b d g
670 706 description:
671 707 d
672 708
673 709
674 710 diff -r f8954cd4dc1f -r 2ca5ba701980 d
675 711 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
676 712 +++ b/d Thu Jan 01 00:00:04 1970 +0000
677 713 @@ -0,0 +1,1 @@
678 714 +a
679 715
680 716
681 717
682 718 log --removed file
683 719
684 720 $ hg log --removed -v a
685 721 changeset: 3:2ca5ba701980
686 722 user: test
687 723 date: Thu Jan 01 00:00:04 1970 +0000
688 724 files: a b d g
689 725 description:
690 726 d
691 727
692 728
693 729 changeset: 0:9161b9aeaf16
694 730 user: test
695 731 date: Thu Jan 01 00:00:01 1970 +0000
696 732 files: a f
697 733 description:
698 734 a
699 735
700 736
701 737
702 738 log --removed revrange file
703 739
704 740 $ hg log --removed -v -r0:2 a
705 741 changeset: 0:9161b9aeaf16
706 742 user: test
707 743 date: Thu Jan 01 00:00:01 1970 +0000
708 744 files: a f
709 745 description:
710 746 a
711 747
712 748
713 749 $ cd ..
714 750
715 751 log --follow tests
716 752
717 753 $ hg init follow
718 754 $ cd follow
719 755
720 756 $ echo base > base
721 757 $ hg ci -Ambase -d '1 0'
722 758 adding base
723 759
724 760 $ echo r1 >> base
725 761 $ hg ci -Amr1 -d '1 0'
726 762 $ echo r2 >> base
727 763 $ hg ci -Amr2 -d '1 0'
728 764
729 765 $ hg up -C 1
730 766 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
731 767 $ echo b1 > b1
732 768
733 769 log -r "follow('set:clean()')"
734 770
735 771 $ hg log -r "follow('set:clean()')"
736 772 changeset: 0:67e992f2c4f3
737 773 user: test
738 774 date: Thu Jan 01 00:00:01 1970 +0000
739 775 summary: base
740 776
741 777 changeset: 1:3d5bf5654eda
742 778 user: test
743 779 date: Thu Jan 01 00:00:01 1970 +0000
744 780 summary: r1
745 781
746 782
747 783 $ hg ci -Amb1 -d '1 0'
748 784 adding b1
749 785 created new head
750 786
751 787
752 788 log -f
753 789
754 790 $ hg log -f
755 791 changeset: 3:e62f78d544b4
756 792 tag: tip
757 793 parent: 1:3d5bf5654eda
758 794 user: test
759 795 date: Thu Jan 01 00:00:01 1970 +0000
760 796 summary: b1
761 797
762 798 changeset: 1:3d5bf5654eda
763 799 user: test
764 800 date: Thu Jan 01 00:00:01 1970 +0000
765 801 summary: r1
766 802
767 803 changeset: 0:67e992f2c4f3
768 804 user: test
769 805 date: Thu Jan 01 00:00:01 1970 +0000
770 806 summary: base
771 807
772 808
773 809 log -r follow('glob:b*')
774 810
775 811 $ hg log -r "follow('glob:b*')"
776 812 changeset: 0:67e992f2c4f3
777 813 user: test
778 814 date: Thu Jan 01 00:00:01 1970 +0000
779 815 summary: base
780 816
781 817 changeset: 1:3d5bf5654eda
782 818 user: test
783 819 date: Thu Jan 01 00:00:01 1970 +0000
784 820 summary: r1
785 821
786 822 changeset: 3:e62f78d544b4
787 823 tag: tip
788 824 parent: 1:3d5bf5654eda
789 825 user: test
790 826 date: Thu Jan 01 00:00:01 1970 +0000
791 827 summary: b1
792 828
793 829 log -f -r '1 + 4'
794 830
795 831 $ hg up -C 0
796 832 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
797 833 $ echo b2 > b2
798 834 $ hg ci -Amb2 -d '1 0'
799 835 adding b2
800 836 created new head
801 837 $ hg log -f -r '1 + 4'
802 838 changeset: 4:ddb82e70d1a1
803 839 tag: tip
804 840 parent: 0:67e992f2c4f3
805 841 user: test
806 842 date: Thu Jan 01 00:00:01 1970 +0000
807 843 summary: b2
808 844
809 845 changeset: 1:3d5bf5654eda
810 846 user: test
811 847 date: Thu Jan 01 00:00:01 1970 +0000
812 848 summary: r1
813 849
814 850 changeset: 0:67e992f2c4f3
815 851 user: test
816 852 date: Thu Jan 01 00:00:01 1970 +0000
817 853 summary: base
818 854
819 855
820 856 log -fr with aliases: 'A' should be expanded, but 'reverse()' should have no
821 857 effect
822 858
823 859 $ hg log --config 'revsetalias.reverse(x)=x' --config 'revsetalias.A=1+4' -qfrA
824 860 4:ddb82e70d1a1
825 861 1:3d5bf5654eda
826 862 0:67e992f2c4f3
827 863
828 864 log -r "follow('set:grep(b2)')"
829 865
830 866 $ hg log -r "follow('set:grep(b2)')"
831 867 changeset: 4:ddb82e70d1a1
832 868 tag: tip
833 869 parent: 0:67e992f2c4f3
834 870 user: test
835 871 date: Thu Jan 01 00:00:01 1970 +0000
836 872 summary: b2
837 873
838 874 log -r "follow('set:grep(b2)', 4)"
839 875
840 876 $ hg up -qC 0
841 877 $ hg log -r "follow('set:grep(b2)', 4)"
842 878 changeset: 4:ddb82e70d1a1
843 879 tag: tip
844 880 parent: 0:67e992f2c4f3
845 881 user: test
846 882 date: Thu Jan 01 00:00:01 1970 +0000
847 883 summary: b2
848 884
849 885
850 886 follow files starting from multiple revisions:
851 887
852 888 $ hg log -T '{rev}: {files}\n' -r "follow('glob:b?', startrev=2+3+4)"
853 889 3: b1
854 890 4: b2
855 891
856 892 follow files starting from empty revision:
857 893
858 894 $ hg log -T '{rev}: {files}\n' -r "follow('glob:*', startrev=.-.)"
859 895
860 896 follow starting from revisions:
861 897
862 898 $ hg log -Gq -r "follow(startrev=2+4)"
863 899 o 4:ddb82e70d1a1
864 900 |
865 901 | o 2:60c670bf5b30
866 902 | |
867 903 | o 1:3d5bf5654eda
868 904 |/
869 905 @ 0:67e992f2c4f3
870 906
871 907
872 908 follow the current revision:
873 909
874 910 $ hg log -Gq -r "follow()"
875 911 @ 0:67e992f2c4f3
876 912
877 913
878 914 $ hg up -qC 4
879 915
880 916 log -f -r null
881 917
882 918 $ hg log -f -r null
883 919 changeset: -1:000000000000
884 920 user:
885 921 date: Thu Jan 01 00:00:00 1970 +0000
886 922
887 923 $ hg log -f -r null -G
888 924 o changeset: -1:000000000000
889 925 user:
890 926 date: Thu Jan 01 00:00:00 1970 +0000
891 927
892 928
893 929
894 930 log -f with null parent
895 931
896 932 $ hg up -C null
897 933 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
898 934 $ hg log -f
899 935
900 936
901 937 log -r . with two parents
902 938
903 939 $ hg up -C 3
904 940 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
905 941 $ hg merge tip
906 942 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
907 943 (branch merge, don't forget to commit)
908 944 $ hg log -r .
909 945 changeset: 3:e62f78d544b4
910 946 parent: 1:3d5bf5654eda
911 947 user: test
912 948 date: Thu Jan 01 00:00:01 1970 +0000
913 949 summary: b1
914 950
915 951
916 952
917 953 log -r . with one parent
918 954
919 955 $ hg ci -mm12 -d '1 0'
920 956 $ hg log -r .
921 957 changeset: 5:302e9dd6890d
922 958 tag: tip
923 959 parent: 3:e62f78d544b4
924 960 parent: 4:ddb82e70d1a1
925 961 user: test
926 962 date: Thu Jan 01 00:00:01 1970 +0000
927 963 summary: m12
928 964
929 965
930 966 $ echo postm >> b1
931 967 $ hg ci -Amb1.1 -d'1 0'
932 968
933 969
934 970 log --follow-first
935 971
936 972 $ hg log --follow-first
937 973 changeset: 6:2404bbcab562
938 974 tag: tip
939 975 user: test
940 976 date: Thu Jan 01 00:00:01 1970 +0000
941 977 summary: b1.1
942 978
943 979 changeset: 5:302e9dd6890d
944 980 parent: 3:e62f78d544b4
945 981 parent: 4:ddb82e70d1a1
946 982 user: test
947 983 date: Thu Jan 01 00:00:01 1970 +0000
948 984 summary: m12
949 985
950 986 changeset: 3:e62f78d544b4
951 987 parent: 1:3d5bf5654eda
952 988 user: test
953 989 date: Thu Jan 01 00:00:01 1970 +0000
954 990 summary: b1
955 991
956 992 changeset: 1:3d5bf5654eda
957 993 user: test
958 994 date: Thu Jan 01 00:00:01 1970 +0000
959 995 summary: r1
960 996
961 997 changeset: 0:67e992f2c4f3
962 998 user: test
963 999 date: Thu Jan 01 00:00:01 1970 +0000
964 1000 summary: base
965 1001
966 1002
967 1003
968 1004 log -P 2
969 1005
970 1006 $ hg log -P 2
971 1007 changeset: 6:2404bbcab562
972 1008 tag: tip
973 1009 user: test
974 1010 date: Thu Jan 01 00:00:01 1970 +0000
975 1011 summary: b1.1
976 1012
977 1013 changeset: 5:302e9dd6890d
978 1014 parent: 3:e62f78d544b4
979 1015 parent: 4:ddb82e70d1a1
980 1016 user: test
981 1017 date: Thu Jan 01 00:00:01 1970 +0000
982 1018 summary: m12
983 1019
984 1020 changeset: 4:ddb82e70d1a1
985 1021 parent: 0:67e992f2c4f3
986 1022 user: test
987 1023 date: Thu Jan 01 00:00:01 1970 +0000
988 1024 summary: b2
989 1025
990 1026 changeset: 3:e62f78d544b4
991 1027 parent: 1:3d5bf5654eda
992 1028 user: test
993 1029 date: Thu Jan 01 00:00:01 1970 +0000
994 1030 summary: b1
995 1031
996 1032
997 1033
998 1034 log -r tip -p --git
999 1035
1000 1036 $ hg log -r tip -p --git
1001 1037 changeset: 6:2404bbcab562
1002 1038 tag: tip
1003 1039 user: test
1004 1040 date: Thu Jan 01 00:00:01 1970 +0000
1005 1041 summary: b1.1
1006 1042
1007 1043 diff --git a/b1 b/b1
1008 1044 --- a/b1
1009 1045 +++ b/b1
1010 1046 @@ -1,1 +1,2 @@
1011 1047 b1
1012 1048 +postm
1013 1049
1014 1050
1015 1051
1016 1052 log -r ""
1017 1053
1018 1054 $ hg log -r ''
1019 1055 hg: parse error: empty query
1020 1056 [255]
1021 1057
1022 1058 log -r <some unknown node id>
1023 1059
1024 1060 $ hg log -r 1000000000000000000000000000000000000000
1025 1061 abort: unknown revision '1000000000000000000000000000000000000000'!
1026 1062 [255]
1027 1063
1028 1064 log -k r1
1029 1065
1030 1066 $ hg log -k r1
1031 1067 changeset: 1:3d5bf5654eda
1032 1068 user: test
1033 1069 date: Thu Jan 01 00:00:01 1970 +0000
1034 1070 summary: r1
1035 1071
1036 1072 log -p -l2 --color=always
1037 1073
1038 1074 $ hg --config extensions.color= --config color.mode=ansi \
1039 1075 > log -p -l2 --color=always
1040 1076 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
1041 1077 tag: tip
1042 1078 user: test
1043 1079 date: Thu Jan 01 00:00:01 1970 +0000
1044 1080 summary: b1.1
1045 1081
1046 1082 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
1047 1083 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1048 1084 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1049 1085 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
1050 1086 b1
1051 1087 \x1b[0;32m+postm\x1b[0m (esc)
1052 1088
1053 1089 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
1054 1090 parent: 3:e62f78d544b4
1055 1091 parent: 4:ddb82e70d1a1
1056 1092 user: test
1057 1093 date: Thu Jan 01 00:00:01 1970 +0000
1058 1094 summary: m12
1059 1095
1060 1096 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
1061 1097 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
1062 1098 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1063 1099 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
1064 1100 \x1b[0;32m+b2\x1b[0m (esc)
1065 1101
1066 1102
1067 1103
1068 1104 log -r tip --stat
1069 1105
1070 1106 $ hg log -r tip --stat
1071 1107 changeset: 6:2404bbcab562
1072 1108 tag: tip
1073 1109 user: test
1074 1110 date: Thu Jan 01 00:00:01 1970 +0000
1075 1111 summary: b1.1
1076 1112
1077 1113 b1 | 1 +
1078 1114 1 files changed, 1 insertions(+), 0 deletions(-)
1079 1115
1080 1116
1081 1117 $ cd ..
1082 1118
1083 1119 log --follow --patch FILE in repository where linkrev isn't trustworthy
1084 1120 (issue5376, issue6124)
1085 1121
1086 1122 $ hg init follow-dup
1087 1123 $ cd follow-dup
1088 1124 $ cat <<EOF >> .hg/hgrc
1089 1125 > [ui]
1090 1126 > logtemplate = '=== {rev}: {desc}\n'
1091 1127 > [diff]
1092 1128 > nodates = True
1093 1129 > EOF
1094 1130 $ echo 0 >> a
1095 1131 $ hg ci -qAm 'a0'
1096 1132 $ echo 1 >> a
1097 1133 $ hg ci -m 'a1'
1098 1134 $ hg up -q 0
1099 1135 $ echo 1 >> a
1100 1136 $ touch b
1101 1137 $ hg ci -qAm 'a1 with b'
1102 1138 $ echo 3 >> a
1103 1139 $ hg ci -m 'a3'
1104 1140
1105 1141 fctx.rev() == 2, but fctx.linkrev() == 1
1106 1142
1107 1143 $ hg log -pf a
1108 1144 === 3: a3
1109 1145 diff -r 4ea02ba94d66 -r e7a6331a34f0 a
1110 1146 --- a/a
1111 1147 +++ b/a
1112 1148 @@ -1,2 +1,3 @@
1113 1149 0
1114 1150 1
1115 1151 +3
1116 1152
1117 1153 === 2: a1 with b
1118 1154 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
1119 1155 --- a/a
1120 1156 +++ b/a
1121 1157 @@ -1,1 +1,2 @@
1122 1158 0
1123 1159 +1
1124 1160
1125 1161 === 0: a0
1126 1162 diff -r 000000000000 -r 49b5e81287e2 a
1127 1163 --- /dev/null
1128 1164 +++ b/a
1129 1165 @@ -0,0 +1,1 @@
1130 1166 +0
1131 1167
1132 1168 $ hg log -pr . a
1133 1169 === 3: a3
1134 1170 diff -r 4ea02ba94d66 -r e7a6331a34f0 a
1135 1171 --- a/a
1136 1172 +++ b/a
1137 1173 @@ -1,2 +1,3 @@
1138 1174 0
1139 1175 1
1140 1176 +3
1141 1177
1142 1178
1143 1179 fctx.introrev() == 2, but fctx.linkrev() == 1
1144 1180
1145 1181 $ hg up -q 2
1146 1182 $ hg log -pf a
1147 1183 === 2: a1 with b
1148 1184 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
1149 1185 --- a/a
1150 1186 +++ b/a
1151 1187 @@ -1,1 +1,2 @@
1152 1188 0
1153 1189 +1
1154 1190
1155 1191 === 0: a0
1156 1192 diff -r 000000000000 -r 49b5e81287e2 a
1157 1193 --- /dev/null
1158 1194 +++ b/a
1159 1195 @@ -0,0 +1,1 @@
1160 1196 +0
1161 1197
1162 1198
1163 1199 BROKEN: should show the same diff as for rev 2 above
1164 1200 $ hg log -pr . a
1165 1201
1166 1202 $ cd ..
1167 1203
1168 1204 Multiple copy sources of a file:
1169 1205
1170 1206 $ hg init follow-multi
1171 1207 $ cd follow-multi
1172 1208 $ echo 0 >> a
1173 1209 $ hg ci -qAm 'a'
1174 1210 $ hg cp a b
1175 1211 $ hg ci -m 'a->b'
1176 1212 $ echo 2 >> a
1177 1213 $ hg ci -m 'a'
1178 1214 $ echo 3 >> b
1179 1215 $ hg ci -m 'b'
1180 1216 $ echo 4 >> a
1181 1217 $ echo 4 >> b
1182 1218 $ hg ci -m 'a,b'
1183 1219 $ echo 5 >> a
1184 1220 $ hg ci -m 'a0'
1185 1221 $ echo 6 >> b
1186 1222 $ hg ci -m 'b0'
1187 1223 $ hg up -q 4
1188 1224 $ echo 7 >> b
1189 1225 $ hg ci -m 'b1'
1190 1226 created new head
1191 1227 $ echo 8 >> a
1192 1228 $ hg ci -m 'a1'
1193 1229 $ hg rm a
1194 1230 $ hg mv b a
1195 1231 $ hg ci -m 'b1->a1'
1196 1232 $ hg merge -qt :local
1197 1233 $ hg ci -m '(a0,b1->a1)->a'
1198 1234
1199 1235 $ hg log -GT '{rev}: {desc}\n'
1200 1236 @ 10: (a0,b1->a1)->a
1201 1237 |\
1202 1238 | o 9: b1->a1
1203 1239 | |
1204 1240 | o 8: a1
1205 1241 | |
1206 1242 | o 7: b1
1207 1243 | |
1208 1244 o | 6: b0
1209 1245 | |
1210 1246 o | 5: a0
1211 1247 |/
1212 1248 o 4: a,b
1213 1249 |
1214 1250 o 3: b
1215 1251 |
1216 1252 o 2: a
1217 1253 |
1218 1254 o 1: a->b
1219 1255 |
1220 1256 o 0: a
1221 1257
1222 1258
1223 1259 since file 'a' has multiple copy sources at the revision 4, ancestors can't
1224 1260 be indexed solely by fctx.linkrev().
1225 1261
1226 1262 $ hg log -T '{rev}: {desc}\n' -f a
1227 1263 10: (a0,b1->a1)->a
1228 1264 9: b1->a1
1229 1265 7: b1
1230 1266 5: a0
1231 1267 4: a,b
1232 1268 3: b
1233 1269 2: a
1234 1270 1: a->b
1235 1271 0: a
1236 1272
1237 1273 $ cd ..
1238 1274
1239 1275 Test that log should respect the order of -rREV even if multiple OR conditions
1240 1276 are specified (issue5100):
1241 1277
1242 1278 $ hg init revorder
1243 1279 $ cd revorder
1244 1280
1245 1281 $ hg branch -q b0
1246 1282 $ echo 0 >> f0
1247 1283 $ hg ci -qAm k0 -u u0
1248 1284 $ hg branch -q b1
1249 1285 $ echo 1 >> f1
1250 1286 $ hg ci -qAm k1 -u u1
1251 1287 $ hg branch -q b2
1252 1288 $ echo 2 >> f2
1253 1289 $ hg ci -qAm k2 -u u2
1254 1290
1255 1291 $ hg update -q b2
1256 1292 $ echo 3 >> f2
1257 1293 $ hg ci -qAm k2 -u u2
1258 1294 $ hg update -q b1
1259 1295 $ echo 4 >> f1
1260 1296 $ hg ci -qAm k1 -u u1
1261 1297 $ hg update -q b0
1262 1298 $ echo 5 >> f0
1263 1299 $ hg ci -qAm k0 -u u0
1264 1300
1265 1301 summary of revisions:
1266 1302
1267 1303 $ hg log -G -T '{rev} {branch} {author} {desc} {files}\n'
1268 1304 @ 5 b0 u0 k0 f0
1269 1305 |
1270 1306 | o 4 b1 u1 k1 f1
1271 1307 | |
1272 1308 | | o 3 b2 u2 k2 f2
1273 1309 | | |
1274 1310 | | o 2 b2 u2 k2 f2
1275 1311 | |/
1276 1312 | o 1 b1 u1 k1 f1
1277 1313 |/
1278 1314 o 0 b0 u0 k0 f0
1279 1315
1280 1316
1281 1317 log -b BRANCH in ascending order:
1282 1318
1283 1319 $ hg log -r0:tip -T '{rev} {branch}\n' -b b0 -b b1
1284 1320 0 b0
1285 1321 1 b1
1286 1322 4 b1
1287 1323 5 b0
1288 1324 $ hg log -r0:tip -T '{rev} {branch}\n' -b b1 -b b0
1289 1325 0 b0
1290 1326 1 b1
1291 1327 4 b1
1292 1328 5 b0
1293 1329
1294 1330 log --only-branch BRANCH in descending order:
1295 1331
1296 1332 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b1 --only-branch b2
1297 1333 4 b1
1298 1334 3 b2
1299 1335 2 b2
1300 1336 1 b1
1301 1337 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b2 --only-branch b1
1302 1338 4 b1
1303 1339 3 b2
1304 1340 2 b2
1305 1341 1 b1
1306 1342
1307 1343 log -u USER in ascending order, against compound set:
1308 1344
1309 1345 $ hg log -r'::head()' -T '{rev} {author}\n' -u u0 -u u2
1310 1346 0 u0
1311 1347 2 u2
1312 1348 3 u2
1313 1349 5 u0
1314 1350 $ hg log -r'::head()' -T '{rev} {author}\n' -u u2 -u u0
1315 1351 0 u0
1316 1352 2 u2
1317 1353 3 u2
1318 1354 5 u0
1319 1355
1320 1356 log -k TEXT in descending order, against compound set:
1321 1357
1322 1358 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k0 -k k1 -k k2
1323 1359 5 k0
1324 1360 3 k2
1325 1361 2 k2
1326 1362 1 k1
1327 1363 0 k0
1328 1364 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k2 -k k1 -k k0
1329 1365 5 k0
1330 1366 3 k2
1331 1367 2 k2
1332 1368 1 k1
1333 1369 0 k0
1334 1370
1335 1371 log FILE in ascending order, against dagrange:
1336 1372
1337 1373 $ hg log -r1:: -T '{rev} {files}\n' f1 f2
1338 1374 1 f1
1339 1375 2 f2
1340 1376 3 f2
1341 1377 4 f1
1342 1378 $ hg log -r1:: -T '{rev} {files}\n' f2 f1
1343 1379 1 f1
1344 1380 2 f2
1345 1381 3 f2
1346 1382 4 f1
1347 1383
1348 1384 $ cd ..
1349 1385
1350 1386 User
1351 1387
1352 1388 $ hg init usertest
1353 1389 $ cd usertest
1354 1390
1355 1391 $ echo a > a
1356 1392 $ hg ci -A -m "a" -u "User One <user1@example.org>"
1357 1393 adding a
1358 1394 $ echo b > b
1359 1395 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
1360 1396 adding b
1361 1397
1362 1398 $ hg log -u "User One <user1@example.org>"
1363 1399 changeset: 0:29a4c94f1924
1364 1400 user: User One <user1@example.org>
1365 1401 date: Thu Jan 01 00:00:00 1970 +0000
1366 1402 summary: a
1367 1403
1368 1404 $ hg log -u "user1" -u "user2"
1369 1405 changeset: 1:e834b5e69c0e
1370 1406 tag: tip
1371 1407 user: User Two <user2@example.org>
1372 1408 date: Thu Jan 01 00:00:00 1970 +0000
1373 1409 summary: b
1374 1410
1375 1411 changeset: 0:29a4c94f1924
1376 1412 user: User One <user1@example.org>
1377 1413 date: Thu Jan 01 00:00:00 1970 +0000
1378 1414 summary: a
1379 1415
1380 1416 $ hg log -u "user3"
1381 1417
1382 1418 "-u USER" shouldn't be overridden by "user(USER)" alias
1383 1419
1384 1420 $ hg log --config 'revsetalias.user(x)=branch(x)' -u default
1385 1421 $ hg log --config 'revsetalias.user(x)=branch(x)' -u user1
1386 1422 changeset: 0:29a4c94f1924
1387 1423 user: User One <user1@example.org>
1388 1424 date: Thu Jan 01 00:00:00 1970 +0000
1389 1425 summary: a
1390 1426
1391 1427
1392 1428 $ cd ..
1393 1429
1394 1430 $ hg init branches
1395 1431 $ cd branches
1396 1432
1397 1433 $ echo a > a
1398 1434 $ hg ci -A -m "commit on default"
1399 1435 adding a
1400 1436 $ hg branch test
1401 1437 marked working directory as branch test
1402 1438 (branches are permanent and global, did you want a bookmark?)
1403 1439 $ echo b > b
1404 1440 $ hg ci -A -m "commit on test"
1405 1441 adding b
1406 1442
1407 1443 $ hg up default
1408 1444 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1409 1445 $ echo c > c
1410 1446 $ hg ci -A -m "commit on default"
1411 1447 adding c
1412 1448 $ hg up test
1413 1449 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1414 1450 $ echo c > c
1415 1451 $ hg ci -A -m "commit on test"
1416 1452 adding c
1417 1453
1418 1454
1419 1455 log -b default
1420 1456
1421 1457 $ hg log -b default
1422 1458 changeset: 2:c3a4f03cc9a7
1423 1459 parent: 0:24427303d56f
1424 1460 user: test
1425 1461 date: Thu Jan 01 00:00:00 1970 +0000
1426 1462 summary: commit on default
1427 1463
1428 1464 changeset: 0:24427303d56f
1429 1465 user: test
1430 1466 date: Thu Jan 01 00:00:00 1970 +0000
1431 1467 summary: commit on default
1432 1468
1433 1469
1434 1470
1435 1471 log -b test
1436 1472
1437 1473 $ hg log -b test
1438 1474 changeset: 3:f5d8de11c2e2
1439 1475 branch: test
1440 1476 tag: tip
1441 1477 parent: 1:d32277701ccb
1442 1478 user: test
1443 1479 date: Thu Jan 01 00:00:00 1970 +0000
1444 1480 summary: commit on test
1445 1481
1446 1482 changeset: 1:d32277701ccb
1447 1483 branch: test
1448 1484 user: test
1449 1485 date: Thu Jan 01 00:00:00 1970 +0000
1450 1486 summary: commit on test
1451 1487
1452 1488
1453 1489
1454 1490 log -b dummy
1455 1491
1456 1492 $ hg log -b dummy
1457 1493 abort: unknown revision 'dummy'!
1458 1494 [255]
1459 1495
1460 1496
1461 1497 log -b .
1462 1498
1463 1499 $ hg log -b .
1464 1500 changeset: 3:f5d8de11c2e2
1465 1501 branch: test
1466 1502 tag: tip
1467 1503 parent: 1:d32277701ccb
1468 1504 user: test
1469 1505 date: Thu Jan 01 00:00:00 1970 +0000
1470 1506 summary: commit on test
1471 1507
1472 1508 changeset: 1:d32277701ccb
1473 1509 branch: test
1474 1510 user: test
1475 1511 date: Thu Jan 01 00:00:00 1970 +0000
1476 1512 summary: commit on test
1477 1513
1478 1514
1479 1515
1480 1516 log -b default -b test
1481 1517
1482 1518 $ hg log -b default -b test
1483 1519 changeset: 3:f5d8de11c2e2
1484 1520 branch: test
1485 1521 tag: tip
1486 1522 parent: 1:d32277701ccb
1487 1523 user: test
1488 1524 date: Thu Jan 01 00:00:00 1970 +0000
1489 1525 summary: commit on test
1490 1526
1491 1527 changeset: 2:c3a4f03cc9a7
1492 1528 parent: 0:24427303d56f
1493 1529 user: test
1494 1530 date: Thu Jan 01 00:00:00 1970 +0000
1495 1531 summary: commit on default
1496 1532
1497 1533 changeset: 1:d32277701ccb
1498 1534 branch: test
1499 1535 user: test
1500 1536 date: Thu Jan 01 00:00:00 1970 +0000
1501 1537 summary: commit on test
1502 1538
1503 1539 changeset: 0:24427303d56f
1504 1540 user: test
1505 1541 date: Thu Jan 01 00:00:00 1970 +0000
1506 1542 summary: commit on default
1507 1543
1508 1544
1509 1545
1510 1546 log -b default -b .
1511 1547
1512 1548 $ hg log -b default -b .
1513 1549 changeset: 3:f5d8de11c2e2
1514 1550 branch: test
1515 1551 tag: tip
1516 1552 parent: 1:d32277701ccb
1517 1553 user: test
1518 1554 date: Thu Jan 01 00:00:00 1970 +0000
1519 1555 summary: commit on test
1520 1556
1521 1557 changeset: 2:c3a4f03cc9a7
1522 1558 parent: 0:24427303d56f
1523 1559 user: test
1524 1560 date: Thu Jan 01 00:00:00 1970 +0000
1525 1561 summary: commit on default
1526 1562
1527 1563 changeset: 1:d32277701ccb
1528 1564 branch: test
1529 1565 user: test
1530 1566 date: Thu Jan 01 00:00:00 1970 +0000
1531 1567 summary: commit on test
1532 1568
1533 1569 changeset: 0:24427303d56f
1534 1570 user: test
1535 1571 date: Thu Jan 01 00:00:00 1970 +0000
1536 1572 summary: commit on default
1537 1573
1538 1574
1539 1575
1540 1576 log -b . -b test
1541 1577
1542 1578 $ hg log -b . -b test
1543 1579 changeset: 3:f5d8de11c2e2
1544 1580 branch: test
1545 1581 tag: tip
1546 1582 parent: 1:d32277701ccb
1547 1583 user: test
1548 1584 date: Thu Jan 01 00:00:00 1970 +0000
1549 1585 summary: commit on test
1550 1586
1551 1587 changeset: 1:d32277701ccb
1552 1588 branch: test
1553 1589 user: test
1554 1590 date: Thu Jan 01 00:00:00 1970 +0000
1555 1591 summary: commit on test
1556 1592
1557 1593
1558 1594
1559 1595 log -b 2
1560 1596
1561 1597 $ hg log -b 2
1562 1598 changeset: 2:c3a4f03cc9a7
1563 1599 parent: 0:24427303d56f
1564 1600 user: test
1565 1601 date: Thu Jan 01 00:00:00 1970 +0000
1566 1602 summary: commit on default
1567 1603
1568 1604 changeset: 0:24427303d56f
1569 1605 user: test
1570 1606 date: Thu Jan 01 00:00:00 1970 +0000
1571 1607 summary: commit on default
1572 1608
1573 1609 #if gettext
1574 1610
1575 1611 Test that all log names are translated (e.g. branches, bookmarks, tags):
1576 1612
1577 1613 $ hg bookmark babar -r tip
1578 1614
1579 1615 $ HGENCODING=UTF-8 LANGUAGE=de hg log -r tip
1580 1616 \xc3\x84nderung: 3:f5d8de11c2e2 (esc)
1581 1617 Zweig: test
1582 1618 Lesezeichen: babar
1583 1619 Marke: tip
1584 1620 Vorg\xc3\xa4nger: 1:d32277701ccb (esc)
1585 1621 Nutzer: test
1586 1622 Datum: Thu Jan 01 00:00:00 1970 +0000
1587 1623 Zusammenfassung: commit on test
1588 1624
1589 1625 $ hg bookmark -d babar
1590 1626
1591 1627 #endif
1592 1628
1593 1629 log -p --cwd dir (in subdir)
1594 1630
1595 1631 $ mkdir dir
1596 1632 $ hg log -p --cwd dir
1597 1633 changeset: 3:f5d8de11c2e2
1598 1634 branch: test
1599 1635 tag: tip
1600 1636 parent: 1:d32277701ccb
1601 1637 user: test
1602 1638 date: Thu Jan 01 00:00:00 1970 +0000
1603 1639 summary: commit on test
1604 1640
1605 1641 diff -r d32277701ccb -r f5d8de11c2e2 c
1606 1642 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1607 1643 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1608 1644 @@ -0,0 +1,1 @@
1609 1645 +c
1610 1646
1611 1647 changeset: 2:c3a4f03cc9a7
1612 1648 parent: 0:24427303d56f
1613 1649 user: test
1614 1650 date: Thu Jan 01 00:00:00 1970 +0000
1615 1651 summary: commit on default
1616 1652
1617 1653 diff -r 24427303d56f -r c3a4f03cc9a7 c
1618 1654 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1619 1655 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1620 1656 @@ -0,0 +1,1 @@
1621 1657 +c
1622 1658
1623 1659 changeset: 1:d32277701ccb
1624 1660 branch: test
1625 1661 user: test
1626 1662 date: Thu Jan 01 00:00:00 1970 +0000
1627 1663 summary: commit on test
1628 1664
1629 1665 diff -r 24427303d56f -r d32277701ccb b
1630 1666 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1631 1667 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1632 1668 @@ -0,0 +1,1 @@
1633 1669 +b
1634 1670
1635 1671 changeset: 0:24427303d56f
1636 1672 user: test
1637 1673 date: Thu Jan 01 00:00:00 1970 +0000
1638 1674 summary: commit on default
1639 1675
1640 1676 diff -r 000000000000 -r 24427303d56f a
1641 1677 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1642 1678 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1643 1679 @@ -0,0 +1,1 @@
1644 1680 +a
1645 1681
1646 1682
1647 1683
1648 1684 log -p -R repo
1649 1685
1650 1686 $ cd dir
1651 1687 $ hg log -p -R .. ../a
1652 1688 changeset: 0:24427303d56f
1653 1689 user: test
1654 1690 date: Thu Jan 01 00:00:00 1970 +0000
1655 1691 summary: commit on default
1656 1692
1657 1693 diff -r 000000000000 -r 24427303d56f a
1658 1694 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1659 1695 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1660 1696 @@ -0,0 +1,1 @@
1661 1697 +a
1662 1698
1663 1699
1664 1700 $ cd ../..
1665 1701
1666 1702 $ hg init follow2
1667 1703 $ cd follow2
1668 1704
1669 1705 # Build the following history:
1670 1706 # tip - o - x - o - x - x
1671 1707 # \ /
1672 1708 # o - o - o - x
1673 1709 # \ /
1674 1710 # o
1675 1711 #
1676 1712 # Where "o" is a revision containing "foo" and
1677 1713 # "x" is a revision without "foo"
1678 1714
1679 1715 $ touch init
1680 1716 $ hg ci -A -m "init, unrelated"
1681 1717 adding init
1682 1718 $ echo 'foo' > init
1683 1719 $ hg ci -m "change, unrelated"
1684 1720 $ echo 'foo' > foo
1685 1721 $ hg ci -A -m "add unrelated old foo"
1686 1722 adding foo
1687 1723 $ hg rm foo
1688 1724 $ hg ci -m "delete foo, unrelated"
1689 1725 $ echo 'related' > foo
1690 1726 $ hg ci -A -m "add foo, related"
1691 1727 adding foo
1692 1728
1693 1729 $ hg up 0
1694 1730 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1695 1731 $ touch branch
1696 1732 $ hg ci -A -m "first branch, unrelated"
1697 1733 adding branch
1698 1734 created new head
1699 1735 $ touch foo
1700 1736 $ hg ci -A -m "create foo, related"
1701 1737 adding foo
1702 1738 $ echo 'change' > foo
1703 1739 $ hg ci -m "change foo, related"
1704 1740
1705 1741 $ hg up 6
1706 1742 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1707 1743 $ echo 'change foo in branch' > foo
1708 1744 $ hg ci -m "change foo in branch, related"
1709 1745 created new head
1710 1746 $ hg merge 7
1711 1747 merging foo
1712 1748 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1713 1749 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1714 1750 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
1715 1751 [1]
1716 1752 $ echo 'merge 1' > foo
1717 1753 $ hg resolve -m foo
1718 1754 (no more unresolved files)
1719 1755 $ hg ci -m "First merge, related"
1720 1756
1721 1757 $ hg merge 4
1722 1758 merging foo
1723 1759 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1724 1760 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1725 1761 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
1726 1762 [1]
1727 1763 $ echo 'merge 2' > foo
1728 1764 $ hg resolve -m foo
1729 1765 (no more unresolved files)
1730 1766 $ hg ci -m "Last merge, related"
1731 1767
1732 1768 $ hg log --graph
1733 1769 @ changeset: 10:4dae8563d2c5
1734 1770 |\ tag: tip
1735 1771 | | parent: 9:7b35701b003e
1736 1772 | | parent: 4:88176d361b69
1737 1773 | | user: test
1738 1774 | | date: Thu Jan 01 00:00:00 1970 +0000
1739 1775 | | summary: Last merge, related
1740 1776 | |
1741 1777 | o changeset: 9:7b35701b003e
1742 1778 | |\ parent: 8:e5416ad8a855
1743 1779 | | | parent: 7:87fe3144dcfa
1744 1780 | | | user: test
1745 1781 | | | date: Thu Jan 01 00:00:00 1970 +0000
1746 1782 | | | summary: First merge, related
1747 1783 | | |
1748 1784 | | o changeset: 8:e5416ad8a855
1749 1785 | | | parent: 6:dc6c325fe5ee
1750 1786 | | | user: test
1751 1787 | | | date: Thu Jan 01 00:00:00 1970 +0000
1752 1788 | | | summary: change foo in branch, related
1753 1789 | | |
1754 1790 | o | changeset: 7:87fe3144dcfa
1755 1791 | |/ user: test
1756 1792 | | date: Thu Jan 01 00:00:00 1970 +0000
1757 1793 | | summary: change foo, related
1758 1794 | |
1759 1795 | o changeset: 6:dc6c325fe5ee
1760 1796 | | user: test
1761 1797 | | date: Thu Jan 01 00:00:00 1970 +0000
1762 1798 | | summary: create foo, related
1763 1799 | |
1764 1800 | o changeset: 5:73db34516eb9
1765 1801 | | parent: 0:e87515fd044a
1766 1802 | | user: test
1767 1803 | | date: Thu Jan 01 00:00:00 1970 +0000
1768 1804 | | summary: first branch, unrelated
1769 1805 | |
1770 1806 o | changeset: 4:88176d361b69
1771 1807 | | user: test
1772 1808 | | date: Thu Jan 01 00:00:00 1970 +0000
1773 1809 | | summary: add foo, related
1774 1810 | |
1775 1811 o | changeset: 3:dd78ae4afb56
1776 1812 | | user: test
1777 1813 | | date: Thu Jan 01 00:00:00 1970 +0000
1778 1814 | | summary: delete foo, unrelated
1779 1815 | |
1780 1816 o | changeset: 2:c4c64aedf0f7
1781 1817 | | user: test
1782 1818 | | date: Thu Jan 01 00:00:00 1970 +0000
1783 1819 | | summary: add unrelated old foo
1784 1820 | |
1785 1821 o | changeset: 1:e5faa7440653
1786 1822 |/ user: test
1787 1823 | date: Thu Jan 01 00:00:00 1970 +0000
1788 1824 | summary: change, unrelated
1789 1825 |
1790 1826 o changeset: 0:e87515fd044a
1791 1827 user: test
1792 1828 date: Thu Jan 01 00:00:00 1970 +0000
1793 1829 summary: init, unrelated
1794 1830
1795 1831
1796 1832 $ hg --traceback log -f foo
1797 1833 changeset: 10:4dae8563d2c5
1798 1834 tag: tip
1799 1835 parent: 9:7b35701b003e
1800 1836 parent: 4:88176d361b69
1801 1837 user: test
1802 1838 date: Thu Jan 01 00:00:00 1970 +0000
1803 1839 summary: Last merge, related
1804 1840
1805 1841 changeset: 9:7b35701b003e
1806 1842 parent: 8:e5416ad8a855
1807 1843 parent: 7:87fe3144dcfa
1808 1844 user: test
1809 1845 date: Thu Jan 01 00:00:00 1970 +0000
1810 1846 summary: First merge, related
1811 1847
1812 1848 changeset: 8:e5416ad8a855
1813 1849 parent: 6:dc6c325fe5ee
1814 1850 user: test
1815 1851 date: Thu Jan 01 00:00:00 1970 +0000
1816 1852 summary: change foo in branch, related
1817 1853
1818 1854 changeset: 7:87fe3144dcfa
1819 1855 user: test
1820 1856 date: Thu Jan 01 00:00:00 1970 +0000
1821 1857 summary: change foo, related
1822 1858
1823 1859 changeset: 6:dc6c325fe5ee
1824 1860 user: test
1825 1861 date: Thu Jan 01 00:00:00 1970 +0000
1826 1862 summary: create foo, related
1827 1863
1828 1864 changeset: 4:88176d361b69
1829 1865 user: test
1830 1866 date: Thu Jan 01 00:00:00 1970 +0000
1831 1867 summary: add foo, related
1832 1868
1833 1869
1834 1870 Also check when maxrev < lastrevfilelog
1835 1871
1836 1872 $ hg --traceback log -f -r4 foo
1837 1873 changeset: 4:88176d361b69
1838 1874 user: test
1839 1875 date: Thu Jan 01 00:00:00 1970 +0000
1840 1876 summary: add foo, related
1841 1877
1842 1878 $ cd ..
1843 1879
1844 1880 Issue2383: hg log showing _less_ differences than hg diff
1845 1881
1846 1882 $ hg init issue2383
1847 1883 $ cd issue2383
1848 1884
1849 1885 Create a test repo:
1850 1886
1851 1887 $ echo a > a
1852 1888 $ hg ci -Am0
1853 1889 adding a
1854 1890 $ echo b > b
1855 1891 $ hg ci -Am1
1856 1892 adding b
1857 1893 $ hg co 0
1858 1894 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1859 1895 $ echo b > a
1860 1896 $ hg ci -m2
1861 1897 created new head
1862 1898
1863 1899 Merge:
1864 1900
1865 1901 $ hg merge
1866 1902 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1867 1903 (branch merge, don't forget to commit)
1868 1904
1869 1905 Make sure there's a file listed in the merge to trigger the bug:
1870 1906
1871 1907 $ echo c > a
1872 1908 $ hg ci -m3
1873 1909
1874 1910 Two files shown here in diff:
1875 1911
1876 1912 $ hg diff --rev 2:3
1877 1913 diff -r b09be438c43a -r 8e07aafe1edc a
1878 1914 --- a/a Thu Jan 01 00:00:00 1970 +0000
1879 1915 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1880 1916 @@ -1,1 +1,1 @@
1881 1917 -b
1882 1918 +c
1883 1919 diff -r b09be438c43a -r 8e07aafe1edc b
1884 1920 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1885 1921 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1886 1922 @@ -0,0 +1,1 @@
1887 1923 +b
1888 1924
1889 1925 Diff here should be the same:
1890 1926
1891 1927 $ hg log -vpr 3
1892 1928 changeset: 3:8e07aafe1edc
1893 1929 tag: tip
1894 1930 parent: 2:b09be438c43a
1895 1931 parent: 1:925d80f479bb
1896 1932 user: test
1897 1933 date: Thu Jan 01 00:00:00 1970 +0000
1898 1934 files: a
1899 1935 description:
1900 1936 3
1901 1937
1902 1938
1903 1939 diff -r b09be438c43a -r 8e07aafe1edc a
1904 1940 --- a/a Thu Jan 01 00:00:00 1970 +0000
1905 1941 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1906 1942 @@ -1,1 +1,1 @@
1907 1943 -b
1908 1944 +c
1909 1945 diff -r b09be438c43a -r 8e07aafe1edc b
1910 1946 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1911 1947 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1912 1948 @@ -0,0 +1,1 @@
1913 1949 +b
1914 1950
1915 1951 $ cd ..
1916 1952
1917 1953 'hg log -r rev fn' when last(filelog(fn)) != rev
1918 1954
1919 1955 $ hg init simplelog
1920 1956 $ cd simplelog
1921 1957 $ echo f > a
1922 1958 $ hg ci -Am'a' -d '0 0'
1923 1959 adding a
1924 1960 $ echo f >> a
1925 1961 $ hg ci -Am'a bis' -d '1 0'
1926 1962
1927 1963 $ hg log -r0 a
1928 1964 changeset: 0:9f758d63dcde
1929 1965 user: test
1930 1966 date: Thu Jan 01 00:00:00 1970 +0000
1931 1967 summary: a
1932 1968
1933 1969 enable obsolete to test hidden feature
1934 1970
1935 1971 $ cat >> $HGRCPATH << EOF
1936 1972 > [experimental]
1937 1973 > evolution.createmarkers=True
1938 1974 > EOF
1939 1975
1940 1976 $ hg log --template='{rev}:{node}\n'
1941 1977 1:a765632148dc55d38c35c4f247c618701886cb2f
1942 1978 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1943 1979 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1944 1980 1 new obsolescence markers
1945 1981 obsoleted 1 changesets
1946 1982 $ hg up null -q
1947 1983 $ hg log --template='{rev}:{node}\n'
1948 1984 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1949 1985 $ hg log --template='{rev}:{node}\n' --hidden
1950 1986 1:a765632148dc55d38c35c4f247c618701886cb2f
1951 1987 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1952 1988 $ hg log -r a
1953 1989 abort: hidden revision 'a' is pruned!
1954 1990 (use --hidden to access hidden revisions)
1955 1991 [255]
1956 1992
1957 1993 test that parent prevent a changeset to be hidden
1958 1994
1959 1995 $ hg up 1 -q --hidden
1960 1996 updated to hidden changeset a765632148dc
1961 1997 (hidden revision 'a765632148dc' is pruned)
1962 1998 $ hg log --template='{rev}:{node}\n'
1963 1999 1:a765632148dc55d38c35c4f247c618701886cb2f
1964 2000 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1965 2001
1966 2002 test that second parent prevent a changeset to be hidden too
1967 2003
1968 2004 $ hg debugsetparents 0 1 # nothing suitable to merge here
1969 2005 $ hg log --template='{rev}:{node}\n'
1970 2006 1:a765632148dc55d38c35c4f247c618701886cb2f
1971 2007 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1972 2008 $ hg debugsetparents 1
1973 2009 $ hg up -q null
1974 2010
1975 2011 bookmarks prevent a changeset being hidden
1976 2012
1977 2013 $ hg bookmark --hidden -r 1 X
1978 2014 bookmarking hidden changeset a765632148dc
1979 2015 (hidden revision 'a765632148dc' is pruned)
1980 2016 $ hg log --template '{rev}:{node}\n'
1981 2017 1:a765632148dc55d38c35c4f247c618701886cb2f
1982 2018 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1983 2019 $ hg bookmark -d X
1984 2020
1985 2021 divergent bookmarks are not hidden
1986 2022
1987 2023 $ hg bookmark --hidden -r 1 X@foo
1988 2024 bookmarking hidden changeset a765632148dc
1989 2025 (hidden revision 'a765632148dc' is pruned)
1990 2026 $ hg log --template '{rev}:{node}\n'
1991 2027 1:a765632148dc55d38c35c4f247c618701886cb2f
1992 2028 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1993 2029
1994 2030 test hidden revision 0 (issue5385)
1995 2031
1996 2032 $ hg bookmark -d X@foo
1997 2033 $ hg up null -q
1998 2034 $ hg debugobsolete 9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1999 2035 1 new obsolescence markers
2000 2036 obsoleted 1 changesets
2001 2037 $ echo f > b
2002 2038 $ hg ci -Am'b' -d '2 0'
2003 2039 adding b
2004 2040 $ echo f >> b
2005 2041 $ hg ci -m'b bis' -d '3 0'
2006 2042 $ hg log -T'{rev}:{node}\n'
2007 2043 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2008 2044 2:94375ec45bddd2a824535fc04855bd058c926ec0
2009 2045
2010 2046 $ hg log -T'{rev}:{node}\n' -r:
2011 2047 2:94375ec45bddd2a824535fc04855bd058c926ec0
2012 2048 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2013 2049 $ hg log -T'{rev}:{node}\n' -r:tip
2014 2050 2:94375ec45bddd2a824535fc04855bd058c926ec0
2015 2051 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2016 2052 $ hg log -T'{rev}:{node}\n' -r:0
2017 2053 abort: hidden revision '0' is pruned!
2018 2054 (use --hidden to access hidden revisions)
2019 2055 [255]
2020 2056 $ hg log -T'{rev}:{node}\n' -f
2021 2057 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2022 2058 2:94375ec45bddd2a824535fc04855bd058c926ec0
2023 2059
2024 2060 clear extensions configuration
2025 2061 $ echo '[extensions]' >> $HGRCPATH
2026 2062 $ echo "obs=!" >> $HGRCPATH
2027 2063 $ cd ..
2028 2064
2029 2065 test -u/-k for problematic encoding
2030 2066 # unicode: cp932:
2031 2067 # u30A2 0x83 0x41(= 'A')
2032 2068 # u30C2 0x83 0x61(= 'a')
2033 2069
2034 2070 $ hg init problematicencoding
2035 2071 $ cd problematicencoding
2036 2072
2037 2073 >>> with open('setup.sh', 'wb') as f:
2038 2074 ... f.write(u'''
2039 2075 ... echo a > text
2040 2076 ... hg add text
2041 2077 ... hg --encoding utf-8 commit -u '\u30A2' -m none
2042 2078 ... echo b > text
2043 2079 ... hg --encoding utf-8 commit -u '\u30C2' -m none
2044 2080 ... echo c > text
2045 2081 ... hg --encoding utf-8 commit -u none -m '\u30A2'
2046 2082 ... echo d > text
2047 2083 ... hg --encoding utf-8 commit -u none -m '\u30C2'
2048 2084 ... '''.encode('utf-8')) and None
2049 2085 $ sh < setup.sh
2050 2086
2051 2087 test in problematic encoding
2052 2088 >>> with open('test.sh', 'wb') as f:
2053 2089 ... f.write(u'''
2054 2090 ... hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
2055 2091 ... echo ====
2056 2092 ... hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
2057 2093 ... echo ====
2058 2094 ... hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
2059 2095 ... echo ====
2060 2096 ... hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
2061 2097 ... '''.encode('cp932')) and None
2062 2098 $ sh < test.sh
2063 2099 0
2064 2100 ====
2065 2101 1
2066 2102 ====
2067 2103 2
2068 2104 0
2069 2105 ====
2070 2106 3
2071 2107 1
2072 2108
2073 2109 $ cd ..
2074 2110
2075 2111 test hg log on non-existent files and on directories
2076 2112 $ hg init issue1340
2077 2113 $ cd issue1340
2078 2114 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
2079 2115 $ echo 1 > d1/f1
2080 2116 $ echo 1 > D2/f1
2081 2117 $ echo 1 > D3.i/f1
2082 2118 $ echo 1 > d4.hg/f1
2083 2119 $ echo 1 > d5.d/f1
2084 2120 $ echo 1 > .d6/f1
2085 2121 $ hg -q add .
2086 2122 $ hg commit -m "a bunch of weird directories"
2087 2123 $ hg log -l1 d1/f1 | grep changeset
2088 2124 changeset: 0:65624cd9070a
2089 2125 $ hg log -l1 f1
2090 2126 $ hg log -l1 . | grep changeset
2091 2127 changeset: 0:65624cd9070a
2092 2128 $ hg log -l1 ./ | grep changeset
2093 2129 changeset: 0:65624cd9070a
2094 2130 $ hg log -l1 d1 | grep changeset
2095 2131 changeset: 0:65624cd9070a
2096 2132 $ hg log -l1 D2 | grep changeset
2097 2133 changeset: 0:65624cd9070a
2098 2134 $ hg log -l1 D2/f1 | grep changeset
2099 2135 changeset: 0:65624cd9070a
2100 2136 $ hg log -l1 D3.i | grep changeset
2101 2137 changeset: 0:65624cd9070a
2102 2138 $ hg log -l1 D3.i/f1 | grep changeset
2103 2139 changeset: 0:65624cd9070a
2104 2140 $ hg log -l1 d4.hg | grep changeset
2105 2141 changeset: 0:65624cd9070a
2106 2142 $ hg log -l1 d4.hg/f1 | grep changeset
2107 2143 changeset: 0:65624cd9070a
2108 2144 $ hg log -l1 d5.d | grep changeset
2109 2145 changeset: 0:65624cd9070a
2110 2146 $ hg log -l1 d5.d/f1 | grep changeset
2111 2147 changeset: 0:65624cd9070a
2112 2148 $ hg log -l1 .d6 | grep changeset
2113 2149 changeset: 0:65624cd9070a
2114 2150 $ hg log -l1 .d6/f1 | grep changeset
2115 2151 changeset: 0:65624cd9070a
2116 2152
2117 2153 issue3772: hg log -r :null showing revision 0 as well
2118 2154
2119 2155 $ hg log -r :null
2120 2156 changeset: 0:65624cd9070a
2121 2157 tag: tip
2122 2158 user: test
2123 2159 date: Thu Jan 01 00:00:00 1970 +0000
2124 2160 summary: a bunch of weird directories
2125 2161
2126 2162 changeset: -1:000000000000
2127 2163 user:
2128 2164 date: Thu Jan 01 00:00:00 1970 +0000
2129 2165
2130 2166 $ hg log -r null:null
2131 2167 changeset: -1:000000000000
2132 2168 user:
2133 2169 date: Thu Jan 01 00:00:00 1970 +0000
2134 2170
2135 2171 working-directory revision requires special treatment
2136 2172
2137 2173 clean:
2138 2174
2139 2175 $ hg log -r 'wdir()' --debug
2140 2176 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2141 2177 phase: draft
2142 2178 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
2143 2179 parent: -1:0000000000000000000000000000000000000000
2144 2180 manifest: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2145 2181 user: test
2146 2182 date: [A-Za-z0-9:+ ]+ (re)
2147 2183 extra: branch=default
2148 2184
2149 2185 $ hg log -r 'wdir()' -p --stat
2150 2186 changeset: 2147483647:ffffffffffff
2151 2187 parent: 0:65624cd9070a
2152 2188 user: test
2153 2189 date: [A-Za-z0-9:+ ]+ (re)
2154 2190
2155 2191
2156 2192
2157 2193
2158 2194 dirty:
2159 2195
2160 2196 $ echo 2 >> d1/f1
2161 2197 $ echo 2 > d1/f2
2162 2198 $ hg add d1/f2
2163 2199 $ hg remove .d6/f1
2164 2200 $ hg status
2165 2201 M d1/f1
2166 2202 A d1/f2
2167 2203 R .d6/f1
2168 2204
2169 2205 $ hg log -r 'wdir()'
2170 2206 changeset: 2147483647:ffffffffffff
2171 2207 parent: 0:65624cd9070a
2172 2208 user: test
2173 2209 date: [A-Za-z0-9:+ ]+ (re)
2174 2210
2175 2211 $ hg log -r 'wdir()' -q
2176 2212 2147483647:ffffffffffff
2177 2213
2178 2214 $ hg log -r 'wdir()' --debug
2179 2215 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2180 2216 phase: draft
2181 2217 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
2182 2218 parent: -1:0000000000000000000000000000000000000000
2183 2219 manifest: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2184 2220 user: test
2185 2221 date: [A-Za-z0-9:+ ]+ (re)
2186 2222 files: d1/f1
2187 2223 files+: d1/f2
2188 2224 files-: .d6/f1
2189 2225 extra: branch=default
2190 2226
2191 2227 $ hg log -r 'wdir()' -p --stat --git
2192 2228 changeset: 2147483647:ffffffffffff
2193 2229 parent: 0:65624cd9070a
2194 2230 user: test
2195 2231 date: [A-Za-z0-9:+ ]+ (re)
2196 2232
2197 2233 .d6/f1 | 1 -
2198 2234 d1/f1 | 1 +
2199 2235 d1/f2 | 1 +
2200 2236 3 files changed, 2 insertions(+), 1 deletions(-)
2201 2237
2202 2238 diff --git a/.d6/f1 b/.d6/f1
2203 2239 deleted file mode 100644
2204 2240 --- a/.d6/f1
2205 2241 +++ /dev/null
2206 2242 @@ -1,1 +0,0 @@
2207 2243 -1
2208 2244 diff --git a/d1/f1 b/d1/f1
2209 2245 --- a/d1/f1
2210 2246 +++ b/d1/f1
2211 2247 @@ -1,1 +1,2 @@
2212 2248 1
2213 2249 +2
2214 2250 diff --git a/d1/f2 b/d1/f2
2215 2251 new file mode 100644
2216 2252 --- /dev/null
2217 2253 +++ b/d1/f2
2218 2254 @@ -0,0 +1,1 @@
2219 2255 +2
2220 2256
2221 2257 $ hg log -r 'wdir()' -Tjson
2222 2258 [
2223 2259 {
2224 2260 "bookmarks": [],
2225 2261 "branch": "default",
2226 2262 "date": [*, 0], (glob)
2227 2263 "desc": "",
2228 2264 "node": "ffffffffffffffffffffffffffffffffffffffff",
2229 2265 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"],
2230 2266 "phase": "draft",
2231 2267 "rev": 2147483647,
2232 2268 "tags": [],
2233 2269 "user": "test"
2234 2270 }
2235 2271 ]
2236 2272
2237 2273 $ hg log -r 'wdir()' -Tjson -q
2238 2274 [
2239 2275 {
2240 2276 "node": "ffffffffffffffffffffffffffffffffffffffff",
2241 2277 "rev": 2147483647
2242 2278 }
2243 2279 ]
2244 2280
2245 2281 $ hg log -r 'wdir()' -Tjson --debug
2246 2282 [
2247 2283 {
2248 2284 "added": ["d1/f2"],
2249 2285 "bookmarks": [],
2250 2286 "branch": "default",
2251 2287 "date": [*, 0], (glob)
2252 2288 "desc": "",
2253 2289 "extra": {"branch": "default"},
2254 2290 "manifest": "ffffffffffffffffffffffffffffffffffffffff",
2255 2291 "modified": ["d1/f1"],
2256 2292 "node": "ffffffffffffffffffffffffffffffffffffffff",
2257 2293 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"],
2258 2294 "phase": "draft",
2259 2295 "removed": [".d6/f1"],
2260 2296 "rev": 2147483647,
2261 2297 "tags": [],
2262 2298 "user": "test"
2263 2299 }
2264 2300 ]
2265 2301
2266 2302 follow files from wdir
2267 2303
2268 2304 $ hg cp d1/f1 f1-copy
2269 2305 $ hg stat --all
2270 2306 M d1/f1
2271 2307 A d1/f2
2272 2308 A f1-copy
2273 2309 d1/f1
2274 2310 R .d6/f1
2275 2311 C D2/f1
2276 2312 C D3.i/f1
2277 2313 C d4.hg/f1
2278 2314 C d5.d/f1
2279 2315
2280 2316 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d5.d/f1
2281 2317 == 2147483647 ==
2282 2318
2283 2319 == 0 ==
2284 2320 d5.d/f1 | 1 +
2285 2321 1 files changed, 1 insertions(+), 0 deletions(-)
2286 2322
2287 2323
2288 2324 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d1/f1
2289 2325 == 2147483647 ==
2290 2326 d1/f1 | 1 +
2291 2327 1 files changed, 1 insertions(+), 0 deletions(-)
2292 2328
2293 2329 == 0 ==
2294 2330 d1/f1 | 1 +
2295 2331 1 files changed, 1 insertions(+), 0 deletions(-)
2296 2332
2297 2333
2298 2334 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d1/f2
2299 2335 == 2147483647 ==
2300 2336 d1/f2 | 1 +
2301 2337 1 files changed, 1 insertions(+), 0 deletions(-)
2302 2338
2303 2339
2304 2340 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat f1-copy
2305 2341 == 2147483647 ==
2306 2342 f1-copy | 1 +
2307 2343 1 files changed, 1 insertions(+), 0 deletions(-)
2308 2344
2309 2345 == 0 ==
2310 2346 d1/f1 | 1 +
2311 2347 1 files changed, 1 insertions(+), 0 deletions(-)
2312 2348
2313 2349
2314 2350 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat notfound
2315 notfound: $ENOENT$
2351 abort: cannot follow file not in any of the specified revisions: "notfound"
2352 [255]
2353
2354 follow files from wdir and non-wdir revision:
2355
2356 $ hg log -T '{rev}\n' -fr'wdir()+.' f1-copy
2357 f1-copy: no such file in rev 65624cd9070a
2358 2147483647
2359 0
2316 2360
2317 2361 follow added/removed files from wdir parent
2318 2362
2319 2363 $ hg log -T '{rev}\n' -f d1/f2
2320 2364 abort: cannot follow nonexistent file: "d1/f2"
2321 2365 [255]
2322 2366
2323 2367 $ hg log -T '{rev}\n' -f f1-copy
2324 2368 abort: cannot follow nonexistent file: "f1-copy"
2325 2369 [255]
2326 2370
2327 2371 $ hg log -T '{rev}\n' -f .d6/f1
2328 2372 abort: cannot follow file not in parent revision: ".d6/f1"
2329 2373 [255]
2330 2374
2331 2375 $ hg revert -aqC
2332 2376
2333 2377 Check that adding an arbitrary name shows up in log automatically
2334 2378
2335 2379 $ cat > ../names.py <<EOF
2336 2380 > """A small extension to test adding arbitrary names to a repo"""
2337 2381 > from __future__ import absolute_import
2338 2382 > from mercurial import namespaces
2339 2383 >
2340 2384 > def reposetup(ui, repo):
2341 2385 > if not repo.local():
2342 2386 > return
2343 2387 > foo = {b'foo': repo[0].node()}
2344 2388 > names = lambda r: foo.keys()
2345 2389 > namemap = lambda r, name: foo.get(name)
2346 2390 > nodemap = lambda r, node: [name for name, n in foo.items()
2347 2391 > if n == node]
2348 2392 > ns = namespaces.namespace(
2349 2393 > b"bars", templatename=b"bar", logname=b"barlog",
2350 2394 > colorname=b"barcolor", listnames=names, namemap=namemap,
2351 2395 > nodemap=nodemap)
2352 2396 >
2353 2397 > repo.names.addnamespace(ns)
2354 2398 > EOF
2355 2399
2356 2400 $ hg --config extensions.names=../names.py log -r 0
2357 2401 changeset: 0:65624cd9070a
2358 2402 tag: tip
2359 2403 barlog: foo
2360 2404 user: test
2361 2405 date: Thu Jan 01 00:00:00 1970 +0000
2362 2406 summary: a bunch of weird directories
2363 2407
2364 2408 $ hg --config extensions.names=../names.py \
2365 2409 > --config extensions.color= --config color.log.barcolor=red \
2366 2410 > --color=always log -r 0
2367 2411 \x1b[0;33mchangeset: 0:65624cd9070a\x1b[0m (esc)
2368 2412 tag: tip
2369 2413 \x1b[0;31mbarlog: foo\x1b[0m (esc)
2370 2414 user: test
2371 2415 date: Thu Jan 01 00:00:00 1970 +0000
2372 2416 summary: a bunch of weird directories
2373 2417
2374 2418 $ hg --config extensions.names=../names.py log -r 0 --template '{bars}\n'
2375 2419 foo
2376 2420
2377 2421 Templater parse errors:
2378 2422
2379 2423 simple error
2380 2424 $ hg log -r . -T '{shortest(node}'
2381 2425 hg: parse error at 14: unexpected token: end
2382 2426 ({shortest(node}
2383 2427 ^ here)
2384 2428 [255]
2385 2429
2386 2430 multi-line template with error
2387 2431 $ hg log -r . -T 'line 1
2388 2432 > line2
2389 2433 > {shortest(node}
2390 2434 > line4\nline5'
2391 2435 hg: parse error at 27: unexpected token: end
2392 2436 (line 1\nline2\n{shortest(node}\nline4\nline5
2393 2437 ^ here)
2394 2438 [255]
2395 2439
2396 2440 $ cd ..
2397 2441
2398 2442 New namespace is registered per repo instance, but the template keyword
2399 2443 is global. So we shouldn't expect the namespace always exists. Using
2400 2444 ssh:// makes sure a bundle repository is created from scratch. (issue6301)
2401 2445
2402 2446 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" \
2403 2447 > -qr0 "ssh://user@dummy/`pwd`/a" a-clone
2404 2448 $ hg incoming --config extensions.names=names.py -R a-clone \
2405 2449 > -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" -T '{bars}\n' -l1
2406 2450 comparing with ssh://user@dummy/$TESTTMP/a
2407 2451 searching for changes
2408 2452
2409 2453
2410 2454 hg log -f dir across branches
2411 2455
2412 2456 $ hg init acrossbranches
2413 2457 $ cd acrossbranches
2414 2458 $ mkdir d
2415 2459 $ echo a > d/a && hg ci -Aqm a
2416 2460 $ echo b > d/a && hg ci -Aqm b
2417 2461 $ hg up -q 0
2418 2462 $ echo b > d/a && hg ci -Aqm c
2419 2463 $ hg log -f d -T '{desc}' -G
2420 2464 @ c
2421 2465 |
2422 2466 o a
2423 2467
2424 2468 Ensure that largefiles doesn't interfere with following a normal file
2425 2469 $ hg --config extensions.largefiles= log -f d -T '{desc}' -G
2426 2470 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
2427 2471 @ c
2428 2472 |
2429 2473 o a
2430 2474
2431 2475 $ hg log -f d/a -T '{desc}' -G
2432 2476 @ c
2433 2477 |
2434 2478 o a
2435 2479
2436 2480 $ cd ..
2437 2481
2438 2482 hg log -f with linkrev pointing to another branch
2439 2483 -------------------------------------------------
2440 2484
2441 2485 create history with a filerev whose linkrev points to another branch
2442 2486
2443 2487 $ hg init branchedlinkrev
2444 2488 $ cd branchedlinkrev
2445 2489 $ echo 1 > a
2446 2490 $ hg commit -Am 'content1'
2447 2491 adding a
2448 2492 $ echo 2 > a
2449 2493 $ hg commit -m 'content2'
2450 2494 $ hg up --rev 'desc(content1)'
2451 2495 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2452 2496 $ echo unrelated > unrelated
2453 2497 $ hg commit -Am 'unrelated'
2454 2498 adding unrelated
2455 2499 created new head
2456 2500 $ hg graft -r 'desc(content2)'
2457 2501 grafting 1:2294ae80ad84 "content2"
2458 2502 $ echo 3 > a
2459 2503 $ hg commit -m 'content3'
2460 2504 $ hg log -G
2461 2505 @ changeset: 4:50b9b36e9c5d
2462 2506 | tag: tip
2463 2507 | user: test
2464 2508 | date: Thu Jan 01 00:00:00 1970 +0000
2465 2509 | summary: content3
2466 2510 |
2467 2511 o changeset: 3:15b2327059e5
2468 2512 | user: test
2469 2513 | date: Thu Jan 01 00:00:00 1970 +0000
2470 2514 | summary: content2
2471 2515 |
2472 2516 o changeset: 2:2029acd1168c
2473 2517 | parent: 0:ae0a3c9f9e95
2474 2518 | user: test
2475 2519 | date: Thu Jan 01 00:00:00 1970 +0000
2476 2520 | summary: unrelated
2477 2521 |
2478 2522 | o changeset: 1:2294ae80ad84
2479 2523 |/ user: test
2480 2524 | date: Thu Jan 01 00:00:00 1970 +0000
2481 2525 | summary: content2
2482 2526 |
2483 2527 o changeset: 0:ae0a3c9f9e95
2484 2528 user: test
2485 2529 date: Thu Jan 01 00:00:00 1970 +0000
2486 2530 summary: content1
2487 2531
2488 2532
2489 2533 log -f on the file should list the graft result.
2490 2534
2491 2535 $ hg log -Gf a
2492 2536 @ changeset: 4:50b9b36e9c5d
2493 2537 | tag: tip
2494 2538 | user: test
2495 2539 | date: Thu Jan 01 00:00:00 1970 +0000
2496 2540 | summary: content3
2497 2541 |
2498 2542 o changeset: 3:15b2327059e5
2499 2543 : user: test
2500 2544 : date: Thu Jan 01 00:00:00 1970 +0000
2501 2545 : summary: content2
2502 2546 :
2503 2547 o changeset: 0:ae0a3c9f9e95
2504 2548 user: test
2505 2549 date: Thu Jan 01 00:00:00 1970 +0000
2506 2550 summary: content1
2507 2551
2508 2552
2509 2553 plain log lists the original version
2510 2554 (XXX we should probably list both)
2511 2555
2512 2556 $ hg log -G a
2513 2557 @ changeset: 4:50b9b36e9c5d
2514 2558 : tag: tip
2515 2559 : user: test
2516 2560 : date: Thu Jan 01 00:00:00 1970 +0000
2517 2561 : summary: content3
2518 2562 :
2519 2563 : o changeset: 1:2294ae80ad84
2520 2564 :/ user: test
2521 2565 : date: Thu Jan 01 00:00:00 1970 +0000
2522 2566 : summary: content2
2523 2567 :
2524 2568 o changeset: 0:ae0a3c9f9e95
2525 2569 user: test
2526 2570 date: Thu Jan 01 00:00:00 1970 +0000
2527 2571 summary: content1
2528 2572
2529 2573
2530 2574 hg log -f from the grafted changeset
2531 2575 (The bootstrap should properly take the topology in account)
2532 2576
2533 2577 $ hg up 'desc(content3)^'
2534 2578 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2535 2579 $ hg log -Gf a
2536 2580 @ changeset: 3:15b2327059e5
2537 2581 : user: test
2538 2582 : date: Thu Jan 01 00:00:00 1970 +0000
2539 2583 : summary: content2
2540 2584 :
2541 2585 o changeset: 0:ae0a3c9f9e95
2542 2586 user: test
2543 2587 date: Thu Jan 01 00:00:00 1970 +0000
2544 2588 summary: content1
2545 2589
2546 2590
2547 2591 Test that we use the first non-hidden changeset in that case.
2548 2592
2549 2593 (hide the changeset)
2550 2594
2551 2595 $ hg log -T '{node}\n' -r 1
2552 2596 2294ae80ad8447bc78383182eeac50cb049df623
2553 2597 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
2554 2598 1 new obsolescence markers
2555 2599 obsoleted 1 changesets
2556 2600 $ hg log -G
2557 2601 o changeset: 4:50b9b36e9c5d
2558 2602 | tag: tip
2559 2603 | user: test
2560 2604 | date: Thu Jan 01 00:00:00 1970 +0000
2561 2605 | summary: content3
2562 2606 |
2563 2607 @ changeset: 3:15b2327059e5
2564 2608 | user: test
2565 2609 | date: Thu Jan 01 00:00:00 1970 +0000
2566 2610 | summary: content2
2567 2611 |
2568 2612 o changeset: 2:2029acd1168c
2569 2613 | parent: 0:ae0a3c9f9e95
2570 2614 | user: test
2571 2615 | date: Thu Jan 01 00:00:00 1970 +0000
2572 2616 | summary: unrelated
2573 2617 |
2574 2618 o changeset: 0:ae0a3c9f9e95
2575 2619 user: test
2576 2620 date: Thu Jan 01 00:00:00 1970 +0000
2577 2621 summary: content1
2578 2622
2579 2623
2580 2624 Check that log on the file does not drop the file revision.
2581 2625
2582 2626 $ hg log -G a
2583 2627 o changeset: 4:50b9b36e9c5d
2584 2628 | tag: tip
2585 2629 | user: test
2586 2630 | date: Thu Jan 01 00:00:00 1970 +0000
2587 2631 | summary: content3
2588 2632 |
2589 2633 @ changeset: 3:15b2327059e5
2590 2634 : user: test
2591 2635 : date: Thu Jan 01 00:00:00 1970 +0000
2592 2636 : summary: content2
2593 2637 :
2594 2638 o changeset: 0:ae0a3c9f9e95
2595 2639 user: test
2596 2640 date: Thu Jan 01 00:00:00 1970 +0000
2597 2641 summary: content1
2598 2642
2599 2643
2600 2644 Even when a head revision is linkrev-shadowed.
2601 2645
2602 2646 $ hg log -T '{node}\n' -r 4
2603 2647 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2604 2648 $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2605 2649 1 new obsolescence markers
2606 2650 obsoleted 1 changesets
2607 2651 $ hg log -G a
2608 2652 @ changeset: 3:15b2327059e5
2609 2653 : tag: tip
2610 2654 : user: test
2611 2655 : date: Thu Jan 01 00:00:00 1970 +0000
2612 2656 : summary: content2
2613 2657 :
2614 2658 o changeset: 0:ae0a3c9f9e95
2615 2659 user: test
2616 2660 date: Thu Jan 01 00:00:00 1970 +0000
2617 2661 summary: content1
2618 2662
2619 2663
2620 2664 $ cd ..
2621 2665
2622 2666 Even when the file revision is missing from some head:
2623 2667
2624 2668 $ hg init issue4490
2625 2669 $ cd issue4490
2626 2670 $ echo '[experimental]' >> .hg/hgrc
2627 2671 $ echo 'evolution.createmarkers=True' >> .hg/hgrc
2628 2672 $ echo a > a
2629 2673 $ hg ci -Am0
2630 2674 adding a
2631 2675 $ echo b > b
2632 2676 $ hg ci -Am1
2633 2677 adding b
2634 2678 $ echo B > b
2635 2679 $ hg ci --amend -m 1
2636 2680 $ hg up 0
2637 2681 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2638 2682 $ echo c > c
2639 2683 $ hg ci -Am2
2640 2684 adding c
2641 2685 created new head
2642 2686 $ hg up 'head() and not .'
2643 2687 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
2644 2688 $ hg log -G
2645 2689 o changeset: 3:db815d6d32e6
2646 2690 | tag: tip
2647 2691 | parent: 0:f7b1eb17ad24
2648 2692 | user: test
2649 2693 | date: Thu Jan 01 00:00:00 1970 +0000
2650 2694 | summary: 2
2651 2695 |
2652 2696 | @ changeset: 2:9bc8ce7f9356
2653 2697 |/ parent: 0:f7b1eb17ad24
2654 2698 | user: test
2655 2699 | date: Thu Jan 01 00:00:00 1970 +0000
2656 2700 | summary: 1
2657 2701 |
2658 2702 o changeset: 0:f7b1eb17ad24
2659 2703 user: test
2660 2704 date: Thu Jan 01 00:00:00 1970 +0000
2661 2705 summary: 0
2662 2706
2663 2707 $ hg log -f -G b
2664 2708 @ changeset: 2:9bc8ce7f9356
2665 2709 | parent: 0:f7b1eb17ad24
2666 2710 ~ user: test
2667 2711 date: Thu Jan 01 00:00:00 1970 +0000
2668 2712 summary: 1
2669 2713
2670 2714 $ hg log -G b
2671 2715 @ changeset: 2:9bc8ce7f9356
2672 2716 | parent: 0:f7b1eb17ad24
2673 2717 ~ user: test
2674 2718 date: Thu Jan 01 00:00:00 1970 +0000
2675 2719 summary: 1
2676 2720
2677 2721 $ cd ..
2678 2722
2679 2723 Check proper report when the manifest changes but not the file issue4499
2680 2724 ------------------------------------------------------------------------
2681 2725
2682 2726 $ hg init issue4499
2683 2727 $ cd issue4499
2684 2728 $ for f in A B C D F E G H I J K L M N O P Q R S T U; do
2685 2729 > echo 1 > $f;
2686 2730 > hg add $f;
2687 2731 > done
2688 2732 $ hg commit -m 'A1B1C1'
2689 2733 $ echo 2 > A
2690 2734 $ echo 2 > B
2691 2735 $ echo 2 > C
2692 2736 $ hg commit -m 'A2B2C2'
2693 2737 $ hg up 0
2694 2738 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2695 2739 $ echo 3 > A
2696 2740 $ echo 2 > B
2697 2741 $ echo 2 > C
2698 2742 $ hg commit -m 'A3B2C2'
2699 2743 created new head
2700 2744
2701 2745 $ hg log -G
2702 2746 @ changeset: 2:fe5fc3d0eb17
2703 2747 | tag: tip
2704 2748 | parent: 0:abf4f0e38563
2705 2749 | user: test
2706 2750 | date: Thu Jan 01 00:00:00 1970 +0000
2707 2751 | summary: A3B2C2
2708 2752 |
2709 2753 | o changeset: 1:07dcc6b312c0
2710 2754 |/ user: test
2711 2755 | date: Thu Jan 01 00:00:00 1970 +0000
2712 2756 | summary: A2B2C2
2713 2757 |
2714 2758 o changeset: 0:abf4f0e38563
2715 2759 user: test
2716 2760 date: Thu Jan 01 00:00:00 1970 +0000
2717 2761 summary: A1B1C1
2718 2762
2719 2763
2720 2764 Log -f on B should reports current changesets
2721 2765
2722 2766 $ hg log -fG B
2723 2767 @ changeset: 2:fe5fc3d0eb17
2724 2768 | tag: tip
2725 2769 | parent: 0:abf4f0e38563
2726 2770 | user: test
2727 2771 | date: Thu Jan 01 00:00:00 1970 +0000
2728 2772 | summary: A3B2C2
2729 2773 |
2730 2774 o changeset: 0:abf4f0e38563
2731 2775 user: test
2732 2776 date: Thu Jan 01 00:00:00 1970 +0000
2733 2777 summary: A1B1C1
2734 2778
2735 2779 $ cd ..
2736 2780
2737 2781 --- going to test line wrap fix on using both --stat and -G (issue5800)
2738 2782 $ hg init issue5800
2739 2783 $ cd issue5800
2740 2784 $ touch a
2741 2785 $ hg ci -Am 'add a'
2742 2786 adding a
2743 2787 ---- now we are going to add 300 lines to a
2744 2788 $ for i in `$TESTDIR/seq.py 1 300`; do echo $i >> a; done
2745 2789 $ hg ci -m 'modify a'
2746 2790 $ hg log
2747 2791 changeset: 1:a98683e6a834
2748 2792 tag: tip
2749 2793 user: test
2750 2794 date: Thu Jan 01 00:00:00 1970 +0000
2751 2795 summary: modify a
2752 2796
2753 2797 changeset: 0:ac82d8b1f7c4
2754 2798 user: test
2755 2799 date: Thu Jan 01 00:00:00 1970 +0000
2756 2800 summary: add a
2757 2801
2758 2802 ---- now visualise the changes we made without template
2759 2803 $ hg log -l1 -r a98683e6a834 --stat -G
2760 2804 @ changeset: 1:a98683e6a834
2761 2805 | tag: tip
2762 2806 ~ user: test
2763 2807 date: Thu Jan 01 00:00:00 1970 +0000
2764 2808 summary: modify a
2765 2809
2766 2810 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2767 2811 1 files changed, 300 insertions(+), 0 deletions(-)
2768 2812
2769 2813 ---- with template
2770 2814 $ hg log -l1 -r a98683e6a834 --stat -G -T bisect
2771 2815 @ changeset: 1:a98683e6a834
2772 2816 | bisect:
2773 2817 ~ tag: tip
2774 2818 user: test
2775 2819 date: Thu Jan 01 00:00:00 1970 +0000
2776 2820 summary: modify a
2777 2821
2778 2822 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2779 2823 1 files changed, 300 insertions(+), 0 deletions(-)
2780 2824
2781 2825 $ hg log -l1 -r a98683e6a834 --stat -G -T changelog
2782 2826 1970-01-01 test <test>
2783 2827
2784 2828 @ * a:
2785 2829 | modify a
2786 2830 ~ [a98683e6a834] [tip]
2787 2831
2788 2832 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2789 2833 1 files changed, 300 insertions(+), 0 deletions(-)
2790 2834
2791 2835 $ hg log -l1 -r a98683e6a834 --stat -G -T compact
2792 2836 @ 1[tip] a98683e6a834 1970-01-01 00:00 +0000 test
2793 2837 | modify a
2794 2838 ~
2795 2839 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2796 2840 1 files changed, 300 insertions(+), 0 deletions(-)
2797 2841
2798 2842 $ hg log -l1 -r a98683e6a834 --stat -G -T default
2799 2843 @ changeset: 1:a98683e6a834
2800 2844 | tag: tip
2801 2845 ~ user: test
2802 2846 date: Thu Jan 01 00:00:00 1970 +0000
2803 2847 summary: modify a
2804 2848
2805 2849 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2806 2850 1 files changed, 300 insertions(+), 0 deletions(-)
2807 2851
2808 2852 $ hg log -l1 -r a98683e6a834 --stat -G -T phases
2809 2853 @ changeset: 1:a98683e6a834
2810 2854 | tag: tip
2811 2855 ~ phase: draft
2812 2856 user: test
2813 2857 date: Thu Jan 01 00:00:00 1970 +0000
2814 2858 summary: modify a
2815 2859
2816 2860 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2817 2861 1 files changed, 300 insertions(+), 0 deletions(-)
2818 2862
2819 2863 $ hg log -l1 -r a98683e6a834 --stat -G -T show
2820 2864 @ changeset: 1:a98683e6a834
2821 2865 | tag: tip
2822 2866 ~ user: test
2823 2867 date: Thu Jan 01 00:00:00 1970 +0000
2824 2868 summary: modify a
2825 2869
2826 2870 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2827 2871 1 files changed, 300 insertions(+), 0 deletions(-)
2828 2872
2829 2873 $ hg log -l1 -r a98683e6a834 --stat -G -T status
2830 2874 @ changeset: 1:a98683e6a834
2831 2875 | tag: tip
2832 2876 ~ user: test
2833 2877 date: Thu Jan 01 00:00:00 1970 +0000
2834 2878 summary: modify a
2835 2879 files:
2836 2880 M a
2837 2881
2838 2882 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2839 2883 1 files changed, 300 insertions(+), 0 deletions(-)
2840 2884
2841 2885 $ hg log -l1 -r a98683e6a834 --stat -G -T xml
2842 2886 <?xml version="1.0"?>
2843 2887 <log>
2844 2888 @ <logentry revision="1" node="a98683e6a8340830a7683909768b62871e84bc9d">
2845 2889 | <tag>tip</tag>
2846 2890 ~ <author email="test">test</author>
2847 2891 <date>1970-01-01T00:00:00+00:00</date>
2848 2892 <msg xml:space="preserve">modify a</msg>
2849 2893 </logentry>
2850 2894 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2851 2895 1 files changed, 300 insertions(+), 0 deletions(-)
2852 2896
2853 2897 </log>
2854 2898
2855 2899 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now