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