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