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