##// END OF EJS Templates
templater: show the style list when I try to use a wrong one...
Iulian Stana -
r19125:6ba6e345 default
parent child Browse files
Show More
@@ -1,520 +1,531
1 # templater.py - template expansion for output
1 # templater.py - template expansion for output
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 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 i18n import _
8 from i18n import _
9 import sys, os, re
9 import sys, os, re
10 import util, config, templatefilters, parser, error
10 import util, config, templatefilters, parser, error
11 import types
11 import types
12 import minirst
12 import minirst
13
13
14 # template parsing
14 # template parsing
15
15
16 elements = {
16 elements = {
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
17 "(": (20, ("group", 1, ")"), ("func", 1, ")")),
18 ",": (2, None, ("list", 2)),
18 ",": (2, None, ("list", 2)),
19 "|": (5, None, ("|", 5)),
19 "|": (5, None, ("|", 5)),
20 "%": (6, None, ("%", 6)),
20 "%": (6, None, ("%", 6)),
21 ")": (0, None, None),
21 ")": (0, None, None),
22 "symbol": (0, ("symbol",), None),
22 "symbol": (0, ("symbol",), None),
23 "string": (0, ("string",), None),
23 "string": (0, ("string",), None),
24 "end": (0, None, None),
24 "end": (0, None, None),
25 }
25 }
26
26
27 def tokenizer(data):
27 def tokenizer(data):
28 program, start, end = data
28 program, start, end = data
29 pos = start
29 pos = start
30 while pos < end:
30 while pos < end:
31 c = program[pos]
31 c = program[pos]
32 if c.isspace(): # skip inter-token whitespace
32 if c.isspace(): # skip inter-token whitespace
33 pass
33 pass
34 elif c in "(,)%|": # handle simple operators
34 elif c in "(,)%|": # handle simple operators
35 yield (c, None, pos)
35 yield (c, None, pos)
36 elif (c in '"\'' or c == 'r' and
36 elif (c in '"\'' or c == 'r' and
37 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
37 program[pos:pos + 2] in ("r'", 'r"')): # handle quoted strings
38 if c == 'r':
38 if c == 'r':
39 pos += 1
39 pos += 1
40 c = program[pos]
40 c = program[pos]
41 decode = False
41 decode = False
42 else:
42 else:
43 decode = True
43 decode = True
44 pos += 1
44 pos += 1
45 s = pos
45 s = pos
46 while pos < end: # find closing quote
46 while pos < end: # find closing quote
47 d = program[pos]
47 d = program[pos]
48 if decode and d == '\\': # skip over escaped characters
48 if decode and d == '\\': # skip over escaped characters
49 pos += 2
49 pos += 2
50 continue
50 continue
51 if d == c:
51 if d == c:
52 if not decode:
52 if not decode:
53 yield ('string', program[s:pos].replace('\\', r'\\'), s)
53 yield ('string', program[s:pos].replace('\\', r'\\'), s)
54 break
54 break
55 yield ('string', program[s:pos].decode('string-escape'), s)
55 yield ('string', program[s:pos].decode('string-escape'), s)
56 break
56 break
57 pos += 1
57 pos += 1
58 else:
58 else:
59 raise error.ParseError(_("unterminated string"), s)
59 raise error.ParseError(_("unterminated string"), s)
60 elif c.isalnum() or c in '_':
60 elif c.isalnum() or c in '_':
61 s = pos
61 s = pos
62 pos += 1
62 pos += 1
63 while pos < end: # find end of symbol
63 while pos < end: # find end of symbol
64 d = program[pos]
64 d = program[pos]
65 if not (d.isalnum() or d == "_"):
65 if not (d.isalnum() or d == "_"):
66 break
66 break
67 pos += 1
67 pos += 1
68 sym = program[s:pos]
68 sym = program[s:pos]
69 yield ('symbol', sym, s)
69 yield ('symbol', sym, s)
70 pos -= 1
70 pos -= 1
71 elif c == '}':
71 elif c == '}':
72 pos += 1
72 pos += 1
73 break
73 break
74 else:
74 else:
75 raise error.ParseError(_("syntax error"), pos)
75 raise error.ParseError(_("syntax error"), pos)
76 pos += 1
76 pos += 1
77 yield ('end', None, pos)
77 yield ('end', None, pos)
78
78
79 def compiletemplate(tmpl, context):
79 def compiletemplate(tmpl, context):
80 parsed = []
80 parsed = []
81 pos, stop = 0, len(tmpl)
81 pos, stop = 0, len(tmpl)
82 p = parser.parser(tokenizer, elements)
82 p = parser.parser(tokenizer, elements)
83
83
84 while pos < stop:
84 while pos < stop:
85 n = tmpl.find('{', pos)
85 n = tmpl.find('{', pos)
86 if n < 0:
86 if n < 0:
87 parsed.append(("string", tmpl[pos:]))
87 parsed.append(("string", tmpl[pos:]))
88 break
88 break
89 if n > 0 and tmpl[n - 1] == '\\':
89 if n > 0 and tmpl[n - 1] == '\\':
90 # escaped
90 # escaped
91 parsed.append(("string", tmpl[pos:n - 1] + "{"))
91 parsed.append(("string", tmpl[pos:n - 1] + "{"))
92 pos = n + 1
92 pos = n + 1
93 continue
93 continue
94 if n > pos:
94 if n > pos:
95 parsed.append(("string", tmpl[pos:n]))
95 parsed.append(("string", tmpl[pos:n]))
96
96
97 pd = [tmpl, n + 1, stop]
97 pd = [tmpl, n + 1, stop]
98 parseres, pos = p.parse(pd)
98 parseres, pos = p.parse(pd)
99 parsed.append(parseres)
99 parsed.append(parseres)
100
100
101 return [compileexp(e, context) for e in parsed]
101 return [compileexp(e, context) for e in parsed]
102
102
103 def compileexp(exp, context):
103 def compileexp(exp, context):
104 t = exp[0]
104 t = exp[0]
105 if t in methods:
105 if t in methods:
106 return methods[t](exp, context)
106 return methods[t](exp, context)
107 raise error.ParseError(_("unknown method '%s'") % t)
107 raise error.ParseError(_("unknown method '%s'") % t)
108
108
109 # template evaluation
109 # template evaluation
110
110
111 def getsymbol(exp):
111 def getsymbol(exp):
112 if exp[0] == 'symbol':
112 if exp[0] == 'symbol':
113 return exp[1]
113 return exp[1]
114 raise error.ParseError(_("expected a symbol"))
114 raise error.ParseError(_("expected a symbol"))
115
115
116 def getlist(x):
116 def getlist(x):
117 if not x:
117 if not x:
118 return []
118 return []
119 if x[0] == 'list':
119 if x[0] == 'list':
120 return getlist(x[1]) + [x[2]]
120 return getlist(x[1]) + [x[2]]
121 return [x]
121 return [x]
122
122
123 def getfilter(exp, context):
123 def getfilter(exp, context):
124 f = getsymbol(exp)
124 f = getsymbol(exp)
125 if f not in context._filters:
125 if f not in context._filters:
126 raise error.ParseError(_("unknown function '%s'") % f)
126 raise error.ParseError(_("unknown function '%s'") % f)
127 return context._filters[f]
127 return context._filters[f]
128
128
129 def gettemplate(exp, context):
129 def gettemplate(exp, context):
130 if exp[0] == 'string':
130 if exp[0] == 'string':
131 return compiletemplate(exp[1], context)
131 return compiletemplate(exp[1], context)
132 if exp[0] == 'symbol':
132 if exp[0] == 'symbol':
133 return context._load(exp[1])
133 return context._load(exp[1])
134 raise error.ParseError(_("expected template specifier"))
134 raise error.ParseError(_("expected template specifier"))
135
135
136 def runstring(context, mapping, data):
136 def runstring(context, mapping, data):
137 return data
137 return data
138
138
139 def runsymbol(context, mapping, key):
139 def runsymbol(context, mapping, key):
140 v = mapping.get(key)
140 v = mapping.get(key)
141 if v is None:
141 if v is None:
142 v = context._defaults.get(key, '')
142 v = context._defaults.get(key, '')
143 if util.safehasattr(v, '__call__'):
143 if util.safehasattr(v, '__call__'):
144 return v(**mapping)
144 return v(**mapping)
145 if isinstance(v, types.GeneratorType):
145 if isinstance(v, types.GeneratorType):
146 v = list(v)
146 v = list(v)
147 mapping[key] = v
147 mapping[key] = v
148 return v
148 return v
149 return v
149 return v
150
150
151 def buildfilter(exp, context):
151 def buildfilter(exp, context):
152 func, data = compileexp(exp[1], context)
152 func, data = compileexp(exp[1], context)
153 filt = getfilter(exp[2], context)
153 filt = getfilter(exp[2], context)
154 return (runfilter, (func, data, filt))
154 return (runfilter, (func, data, filt))
155
155
156 def runfilter(context, mapping, data):
156 def runfilter(context, mapping, data):
157 func, data, filt = data
157 func, data, filt = data
158 try:
158 try:
159 return filt(func(context, mapping, data))
159 return filt(func(context, mapping, data))
160 except (ValueError, AttributeError, TypeError):
160 except (ValueError, AttributeError, TypeError):
161 if isinstance(data, tuple):
161 if isinstance(data, tuple):
162 dt = data[1]
162 dt = data[1]
163 else:
163 else:
164 dt = data
164 dt = data
165 raise util.Abort(_("template filter '%s' is not compatible with "
165 raise util.Abort(_("template filter '%s' is not compatible with "
166 "keyword '%s'") % (filt.func_name, dt))
166 "keyword '%s'") % (filt.func_name, dt))
167
167
168 def buildmap(exp, context):
168 def buildmap(exp, context):
169 func, data = compileexp(exp[1], context)
169 func, data = compileexp(exp[1], context)
170 ctmpl = gettemplate(exp[2], context)
170 ctmpl = gettemplate(exp[2], context)
171 return (runmap, (func, data, ctmpl))
171 return (runmap, (func, data, ctmpl))
172
172
173 def runtemplate(context, mapping, template):
173 def runtemplate(context, mapping, template):
174 for func, data in template:
174 for func, data in template:
175 yield func(context, mapping, data)
175 yield func(context, mapping, data)
176
176
177 def runmap(context, mapping, data):
177 def runmap(context, mapping, data):
178 func, data, ctmpl = data
178 func, data, ctmpl = data
179 d = func(context, mapping, data)
179 d = func(context, mapping, data)
180 if util.safehasattr(d, '__call__'):
180 if util.safehasattr(d, '__call__'):
181 d = d()
181 d = d()
182
182
183 lm = mapping.copy()
183 lm = mapping.copy()
184
184
185 for i in d:
185 for i in d:
186 if isinstance(i, dict):
186 if isinstance(i, dict):
187 lm.update(i)
187 lm.update(i)
188 lm['originalnode'] = mapping.get('node')
188 lm['originalnode'] = mapping.get('node')
189 yield runtemplate(context, lm, ctmpl)
189 yield runtemplate(context, lm, ctmpl)
190 else:
190 else:
191 # v is not an iterable of dicts, this happen when 'key'
191 # v is not an iterable of dicts, this happen when 'key'
192 # has been fully expanded already and format is useless.
192 # has been fully expanded already and format is useless.
193 # If so, return the expanded value.
193 # If so, return the expanded value.
194 yield i
194 yield i
195
195
196 def buildfunc(exp, context):
196 def buildfunc(exp, context):
197 n = getsymbol(exp[1])
197 n = getsymbol(exp[1])
198 args = [compileexp(x, context) for x in getlist(exp[2])]
198 args = [compileexp(x, context) for x in getlist(exp[2])]
199 if n in funcs:
199 if n in funcs:
200 f = funcs[n]
200 f = funcs[n]
201 return (f, args)
201 return (f, args)
202 if n in templatefilters.funcs:
202 if n in templatefilters.funcs:
203 f = templatefilters.funcs[n]
203 f = templatefilters.funcs[n]
204 return (f, args)
204 return (f, args)
205 if n in context._filters:
205 if n in context._filters:
206 if len(args) != 1:
206 if len(args) != 1:
207 raise error.ParseError(_("filter %s expects one argument") % n)
207 raise error.ParseError(_("filter %s expects one argument") % n)
208 f = context._filters[n]
208 f = context._filters[n]
209 return (runfilter, (args[0][0], args[0][1], f))
209 return (runfilter, (args[0][0], args[0][1], f))
210
210
211 def get(context, mapping, args):
211 def get(context, mapping, args):
212 if len(args) != 2:
212 if len(args) != 2:
213 # i18n: "get" is a keyword
213 # i18n: "get" is a keyword
214 raise error.ParseError(_("get() expects two arguments"))
214 raise error.ParseError(_("get() expects two arguments"))
215
215
216 dictarg = args[0][0](context, mapping, args[0][1])
216 dictarg = args[0][0](context, mapping, args[0][1])
217 if not util.safehasattr(dictarg, 'get'):
217 if not util.safehasattr(dictarg, 'get'):
218 # i18n: "get" is a keyword
218 # i18n: "get" is a keyword
219 raise error.ParseError(_("get() expects a dict as first argument"))
219 raise error.ParseError(_("get() expects a dict as first argument"))
220
220
221 key = args[1][0](context, mapping, args[1][1])
221 key = args[1][0](context, mapping, args[1][1])
222 yield dictarg.get(key)
222 yield dictarg.get(key)
223
223
224 def join(context, mapping, args):
224 def join(context, mapping, args):
225 if not (1 <= len(args) <= 2):
225 if not (1 <= len(args) <= 2):
226 # i18n: "join" is a keyword
226 # i18n: "join" is a keyword
227 raise error.ParseError(_("join expects one or two arguments"))
227 raise error.ParseError(_("join expects one or two arguments"))
228
228
229 joinset = args[0][0](context, mapping, args[0][1])
229 joinset = args[0][0](context, mapping, args[0][1])
230 if util.safehasattr(joinset, '__call__'):
230 if util.safehasattr(joinset, '__call__'):
231 jf = joinset.joinfmt
231 jf = joinset.joinfmt
232 joinset = [jf(x) for x in joinset()]
232 joinset = [jf(x) for x in joinset()]
233
233
234 joiner = " "
234 joiner = " "
235 if len(args) > 1:
235 if len(args) > 1:
236 joiner = args[1][0](context, mapping, args[1][1])
236 joiner = args[1][0](context, mapping, args[1][1])
237
237
238 first = True
238 first = True
239 for x in joinset:
239 for x in joinset:
240 if first:
240 if first:
241 first = False
241 first = False
242 else:
242 else:
243 yield joiner
243 yield joiner
244 yield x
244 yield x
245
245
246 def sub(context, mapping, args):
246 def sub(context, mapping, args):
247 if len(args) != 3:
247 if len(args) != 3:
248 # i18n: "sub" is a keyword
248 # i18n: "sub" is a keyword
249 raise error.ParseError(_("sub expects three arguments"))
249 raise error.ParseError(_("sub expects three arguments"))
250
250
251 pat = stringify(args[0][0](context, mapping, args[0][1]))
251 pat = stringify(args[0][0](context, mapping, args[0][1]))
252 rpl = stringify(args[1][0](context, mapping, args[1][1]))
252 rpl = stringify(args[1][0](context, mapping, args[1][1]))
253 src = stringify(args[2][0](context, mapping, args[2][1]))
253 src = stringify(args[2][0](context, mapping, args[2][1]))
254 src = stringify(runtemplate(context, mapping,
254 src = stringify(runtemplate(context, mapping,
255 compiletemplate(src, context)))
255 compiletemplate(src, context)))
256 yield re.sub(pat, rpl, src)
256 yield re.sub(pat, rpl, src)
257
257
258 def if_(context, mapping, args):
258 def if_(context, mapping, args):
259 if not (2 <= len(args) <= 3):
259 if not (2 <= len(args) <= 3):
260 # i18n: "if" is a keyword
260 # i18n: "if" is a keyword
261 raise error.ParseError(_("if expects two or three arguments"))
261 raise error.ParseError(_("if expects two or three arguments"))
262
262
263 test = stringify(args[0][0](context, mapping, args[0][1]))
263 test = stringify(args[0][0](context, mapping, args[0][1]))
264 if test:
264 if test:
265 t = stringify(args[1][0](context, mapping, args[1][1]))
265 t = stringify(args[1][0](context, mapping, args[1][1]))
266 yield runtemplate(context, mapping, compiletemplate(t, context))
266 yield runtemplate(context, mapping, compiletemplate(t, context))
267 elif len(args) == 3:
267 elif len(args) == 3:
268 t = stringify(args[2][0](context, mapping, args[2][1]))
268 t = stringify(args[2][0](context, mapping, args[2][1]))
269 yield runtemplate(context, mapping, compiletemplate(t, context))
269 yield runtemplate(context, mapping, compiletemplate(t, context))
270
270
271 def ifeq(context, mapping, args):
271 def ifeq(context, mapping, args):
272 if not (3 <= len(args) <= 4):
272 if not (3 <= len(args) <= 4):
273 # i18n: "ifeq" is a keyword
273 # i18n: "ifeq" is a keyword
274 raise error.ParseError(_("ifeq expects three or four arguments"))
274 raise error.ParseError(_("ifeq expects three or four arguments"))
275
275
276 test = stringify(args[0][0](context, mapping, args[0][1]))
276 test = stringify(args[0][0](context, mapping, args[0][1]))
277 match = stringify(args[1][0](context, mapping, args[1][1]))
277 match = stringify(args[1][0](context, mapping, args[1][1]))
278 if test == match:
278 if test == match:
279 t = stringify(args[2][0](context, mapping, args[2][1]))
279 t = stringify(args[2][0](context, mapping, args[2][1]))
280 yield runtemplate(context, mapping, compiletemplate(t, context))
280 yield runtemplate(context, mapping, compiletemplate(t, context))
281 elif len(args) == 4:
281 elif len(args) == 4:
282 t = stringify(args[3][0](context, mapping, args[3][1]))
282 t = stringify(args[3][0](context, mapping, args[3][1]))
283 yield runtemplate(context, mapping, compiletemplate(t, context))
283 yield runtemplate(context, mapping, compiletemplate(t, context))
284
284
285 def label(context, mapping, args):
285 def label(context, mapping, args):
286 if len(args) != 2:
286 if len(args) != 2:
287 # i18n: "label" is a keyword
287 # i18n: "label" is a keyword
288 raise error.ParseError(_("label expects two arguments"))
288 raise error.ParseError(_("label expects two arguments"))
289
289
290 # ignore args[0] (the label string) since this is supposed to be a a no-op
290 # ignore args[0] (the label string) since this is supposed to be a a no-op
291 t = stringify(args[1][0](context, mapping, args[1][1]))
291 t = stringify(args[1][0](context, mapping, args[1][1]))
292 yield runtemplate(context, mapping, compiletemplate(t, context))
292 yield runtemplate(context, mapping, compiletemplate(t, context))
293
293
294 def rstdoc(context, mapping, args):
294 def rstdoc(context, mapping, args):
295 if len(args) != 2:
295 if len(args) != 2:
296 # i18n: "rstdoc" is a keyword
296 # i18n: "rstdoc" is a keyword
297 raise error.ParseError(_("rstdoc expects two arguments"))
297 raise error.ParseError(_("rstdoc expects two arguments"))
298
298
299 text = stringify(args[0][0](context, mapping, args[0][1]))
299 text = stringify(args[0][0](context, mapping, args[0][1]))
300 style = stringify(args[1][0](context, mapping, args[1][1]))
300 style = stringify(args[1][0](context, mapping, args[1][1]))
301
301
302 return minirst.format(text, style=style, keep=['verbose'])
302 return minirst.format(text, style=style, keep=['verbose'])
303
303
304 methods = {
304 methods = {
305 "string": lambda e, c: (runstring, e[1]),
305 "string": lambda e, c: (runstring, e[1]),
306 "symbol": lambda e, c: (runsymbol, e[1]),
306 "symbol": lambda e, c: (runsymbol, e[1]),
307 "group": lambda e, c: compileexp(e[1], c),
307 "group": lambda e, c: compileexp(e[1], c),
308 # ".": buildmember,
308 # ".": buildmember,
309 "|": buildfilter,
309 "|": buildfilter,
310 "%": buildmap,
310 "%": buildmap,
311 "func": buildfunc,
311 "func": buildfunc,
312 }
312 }
313
313
314 funcs = {
314 funcs = {
315 "get": get,
315 "get": get,
316 "if": if_,
316 "if": if_,
317 "ifeq": ifeq,
317 "ifeq": ifeq,
318 "join": join,
318 "join": join,
319 "label": label,
319 "label": label,
320 "rstdoc": rstdoc,
320 "rstdoc": rstdoc,
321 "sub": sub,
321 "sub": sub,
322 }
322 }
323
323
324 # template engine
324 # template engine
325
325
326 path = ['templates', '../templates']
326 path = ['templates', '../templates']
327 stringify = templatefilters.stringify
327 stringify = templatefilters.stringify
328
328
329 def _flatten(thing):
329 def _flatten(thing):
330 '''yield a single stream from a possibly nested set of iterators'''
330 '''yield a single stream from a possibly nested set of iterators'''
331 if isinstance(thing, str):
331 if isinstance(thing, str):
332 yield thing
332 yield thing
333 elif not util.safehasattr(thing, '__iter__'):
333 elif not util.safehasattr(thing, '__iter__'):
334 if thing is not None:
334 if thing is not None:
335 yield str(thing)
335 yield str(thing)
336 else:
336 else:
337 for i in thing:
337 for i in thing:
338 if isinstance(i, str):
338 if isinstance(i, str):
339 yield i
339 yield i
340 elif not util.safehasattr(i, '__iter__'):
340 elif not util.safehasattr(i, '__iter__'):
341 if i is not None:
341 if i is not None:
342 yield str(i)
342 yield str(i)
343 elif i is not None:
343 elif i is not None:
344 for j in _flatten(i):
344 for j in _flatten(i):
345 yield j
345 yield j
346
346
347 def parsestring(s, quoted=True):
347 def parsestring(s, quoted=True):
348 '''parse a string using simple c-like syntax.
348 '''parse a string using simple c-like syntax.
349 string must be in quotes if quoted is True.'''
349 string must be in quotes if quoted is True.'''
350 if quoted:
350 if quoted:
351 if len(s) < 2 or s[0] != s[-1]:
351 if len(s) < 2 or s[0] != s[-1]:
352 raise SyntaxError(_('unmatched quotes'))
352 raise SyntaxError(_('unmatched quotes'))
353 return s[1:-1].decode('string_escape')
353 return s[1:-1].decode('string_escape')
354
354
355 return s.decode('string_escape')
355 return s.decode('string_escape')
356
356
357 class engine(object):
357 class engine(object):
358 '''template expansion engine.
358 '''template expansion engine.
359
359
360 template expansion works like this. a map file contains key=value
360 template expansion works like this. a map file contains key=value
361 pairs. if value is quoted, it is treated as string. otherwise, it
361 pairs. if value is quoted, it is treated as string. otherwise, it
362 is treated as name of template file.
362 is treated as name of template file.
363
363
364 templater is asked to expand a key in map. it looks up key, and
364 templater is asked to expand a key in map. it looks up key, and
365 looks for strings like this: {foo}. it expands {foo} by looking up
365 looks for strings like this: {foo}. it expands {foo} by looking up
366 foo in map, and substituting it. expansion is recursive: it stops
366 foo in map, and substituting it. expansion is recursive: it stops
367 when there is no more {foo} to replace.
367 when there is no more {foo} to replace.
368
368
369 expansion also allows formatting and filtering.
369 expansion also allows formatting and filtering.
370
370
371 format uses key to expand each item in list. syntax is
371 format uses key to expand each item in list. syntax is
372 {key%format}.
372 {key%format}.
373
373
374 filter uses function to transform value. syntax is
374 filter uses function to transform value. syntax is
375 {key|filter1|filter2|...}.'''
375 {key|filter1|filter2|...}.'''
376
376
377 def __init__(self, loader, filters={}, defaults={}):
377 def __init__(self, loader, filters={}, defaults={}):
378 self._loader = loader
378 self._loader = loader
379 self._filters = filters
379 self._filters = filters
380 self._defaults = defaults
380 self._defaults = defaults
381 self._cache = {}
381 self._cache = {}
382
382
383 def _load(self, t):
383 def _load(self, t):
384 '''load, parse, and cache a template'''
384 '''load, parse, and cache a template'''
385 if t not in self._cache:
385 if t not in self._cache:
386 self._cache[t] = compiletemplate(self._loader(t), self)
386 self._cache[t] = compiletemplate(self._loader(t), self)
387 return self._cache[t]
387 return self._cache[t]
388
388
389 def process(self, t, mapping):
389 def process(self, t, mapping):
390 '''Perform expansion. t is name of map element to expand.
390 '''Perform expansion. t is name of map element to expand.
391 mapping contains added elements for use during expansion. Is a
391 mapping contains added elements for use during expansion. Is a
392 generator.'''
392 generator.'''
393 return _flatten(runtemplate(self, mapping, self._load(t)))
393 return _flatten(runtemplate(self, mapping, self._load(t)))
394
394
395 engines = {'default': engine}
395 engines = {'default': engine}
396
396
397 def stylelist():
398 path = templatepath()[0]
399 dirlist = os.listdir(path)
400 stylelist = []
401 for file in dirlist:
402 split = file.split(".")
403 if split[0] == "map-cmdline":
404 stylelist.append(split[1])
405 return ", ".join(stylelist)
406
397 class templater(object):
407 class templater(object):
398
408
399 def __init__(self, mapfile, filters={}, defaults={}, cache={},
409 def __init__(self, mapfile, filters={}, defaults={}, cache={},
400 minchunk=1024, maxchunk=65536):
410 minchunk=1024, maxchunk=65536):
401 '''set up template engine.
411 '''set up template engine.
402 mapfile is name of file to read map definitions from.
412 mapfile is name of file to read map definitions from.
403 filters is dict of functions. each transforms a value into another.
413 filters is dict of functions. each transforms a value into another.
404 defaults is dict of default map definitions.'''
414 defaults is dict of default map definitions.'''
405 self.mapfile = mapfile or 'template'
415 self.mapfile = mapfile or 'template'
406 self.cache = cache.copy()
416 self.cache = cache.copy()
407 self.map = {}
417 self.map = {}
408 self.base = (mapfile and os.path.dirname(mapfile)) or ''
418 self.base = (mapfile and os.path.dirname(mapfile)) or ''
409 self.filters = templatefilters.filters.copy()
419 self.filters = templatefilters.filters.copy()
410 self.filters.update(filters)
420 self.filters.update(filters)
411 self.defaults = defaults
421 self.defaults = defaults
412 self.minchunk, self.maxchunk = minchunk, maxchunk
422 self.minchunk, self.maxchunk = minchunk, maxchunk
413 self.ecache = {}
423 self.ecache = {}
414
424
415 if not mapfile:
425 if not mapfile:
416 return
426 return
417 if not os.path.exists(mapfile):
427 if not os.path.exists(mapfile):
418 raise util.Abort(_('style not found: %s') % mapfile)
428 raise util.Abort(_("style '%s' not found") % mapfile,
429 hint=_("available styles: %s") % stylelist())
419
430
420 conf = config.config()
431 conf = config.config()
421 conf.read(mapfile)
432 conf.read(mapfile)
422
433
423 for key, val in conf[''].items():
434 for key, val in conf[''].items():
424 if not val:
435 if not val:
425 raise SyntaxError(_('%s: missing value') % conf.source('', key))
436 raise SyntaxError(_('%s: missing value') % conf.source('', key))
426 if val[0] in "'\"":
437 if val[0] in "'\"":
427 try:
438 try:
428 self.cache[key] = parsestring(val)
439 self.cache[key] = parsestring(val)
429 except SyntaxError, inst:
440 except SyntaxError, inst:
430 raise SyntaxError('%s: %s' %
441 raise SyntaxError('%s: %s' %
431 (conf.source('', key), inst.args[0]))
442 (conf.source('', key), inst.args[0]))
432 else:
443 else:
433 val = 'default', val
444 val = 'default', val
434 if ':' in val[1]:
445 if ':' in val[1]:
435 val = val[1].split(':', 1)
446 val = val[1].split(':', 1)
436 self.map[key] = val[0], os.path.join(self.base, val[1])
447 self.map[key] = val[0], os.path.join(self.base, val[1])
437
448
438 def __contains__(self, key):
449 def __contains__(self, key):
439 return key in self.cache or key in self.map
450 return key in self.cache or key in self.map
440
451
441 def load(self, t):
452 def load(self, t):
442 '''Get the template for the given template name. Use a local cache.'''
453 '''Get the template for the given template name. Use a local cache.'''
443 if t not in self.cache:
454 if t not in self.cache:
444 try:
455 try:
445 self.cache[t] = util.readfile(self.map[t][1])
456 self.cache[t] = util.readfile(self.map[t][1])
446 except KeyError, inst:
457 except KeyError, inst:
447 raise util.Abort(_('"%s" not in template map') % inst.args[0])
458 raise util.Abort(_('"%s" not in template map') % inst.args[0])
448 except IOError, inst:
459 except IOError, inst:
449 raise IOError(inst.args[0], _('template file %s: %s') %
460 raise IOError(inst.args[0], _('template file %s: %s') %
450 (self.map[t][1], inst.args[1]))
461 (self.map[t][1], inst.args[1]))
451 return self.cache[t]
462 return self.cache[t]
452
463
453 def __call__(self, t, **mapping):
464 def __call__(self, t, **mapping):
454 ttype = t in self.map and self.map[t][0] or 'default'
465 ttype = t in self.map and self.map[t][0] or 'default'
455 if ttype not in self.ecache:
466 if ttype not in self.ecache:
456 self.ecache[ttype] = engines[ttype](self.load,
467 self.ecache[ttype] = engines[ttype](self.load,
457 self.filters, self.defaults)
468 self.filters, self.defaults)
458 proc = self.ecache[ttype]
469 proc = self.ecache[ttype]
459
470
460 stream = proc.process(t, mapping)
471 stream = proc.process(t, mapping)
461 if self.minchunk:
472 if self.minchunk:
462 stream = util.increasingchunks(stream, min=self.minchunk,
473 stream = util.increasingchunks(stream, min=self.minchunk,
463 max=self.maxchunk)
474 max=self.maxchunk)
464 return stream
475 return stream
465
476
466 def templatepath(name=None):
477 def templatepath(name=None):
467 '''return location of template file or directory (if no name).
478 '''return location of template file or directory (if no name).
468 returns None if not found.'''
479 returns None if not found.'''
469 normpaths = []
480 normpaths = []
470
481
471 # executable version (py2exe) doesn't support __file__
482 # executable version (py2exe) doesn't support __file__
472 if util.mainfrozen():
483 if util.mainfrozen():
473 module = sys.executable
484 module = sys.executable
474 else:
485 else:
475 module = __file__
486 module = __file__
476 for f in path:
487 for f in path:
477 if f.startswith('/'):
488 if f.startswith('/'):
478 p = f
489 p = f
479 else:
490 else:
480 fl = f.split('/')
491 fl = f.split('/')
481 p = os.path.join(os.path.dirname(module), *fl)
492 p = os.path.join(os.path.dirname(module), *fl)
482 if name:
493 if name:
483 p = os.path.join(p, name)
494 p = os.path.join(p, name)
484 if name and os.path.exists(p):
495 if name and os.path.exists(p):
485 return os.path.normpath(p)
496 return os.path.normpath(p)
486 elif os.path.isdir(p):
497 elif os.path.isdir(p):
487 normpaths.append(os.path.normpath(p))
498 normpaths.append(os.path.normpath(p))
488
499
489 return normpaths
500 return normpaths
490
501
491 def stylemap(styles, paths=None):
502 def stylemap(styles, paths=None):
492 """Return path to mapfile for a given style.
503 """Return path to mapfile for a given style.
493
504
494 Searches mapfile in the following locations:
505 Searches mapfile in the following locations:
495 1. templatepath/style/map
506 1. templatepath/style/map
496 2. templatepath/map-style
507 2. templatepath/map-style
497 3. templatepath/map
508 3. templatepath/map
498 """
509 """
499
510
500 if paths is None:
511 if paths is None:
501 paths = templatepath()
512 paths = templatepath()
502 elif isinstance(paths, str):
513 elif isinstance(paths, str):
503 paths = [paths]
514 paths = [paths]
504
515
505 if isinstance(styles, str):
516 if isinstance(styles, str):
506 styles = [styles]
517 styles = [styles]
507
518
508 for style in styles:
519 for style in styles:
509 if not style:
520 if not style:
510 continue
521 continue
511 locations = [os.path.join(style, 'map'), 'map-' + style]
522 locations = [os.path.join(style, 'map'), 'map-' + style]
512 locations.append('map')
523 locations.append('map')
513
524
514 for path in paths:
525 for path in paths:
515 for location in locations:
526 for location in locations:
516 mapfile = os.path.join(path, location)
527 mapfile = os.path.join(path, location)
517 if os.path.isfile(mapfile):
528 if os.path.isfile(mapfile):
518 return style, mapfile
529 return style, mapfile
519
530
520 raise RuntimeError("No hgweb templates found in %r" % paths)
531 raise RuntimeError("No hgweb templates found in %r" % paths)
@@ -1,1347 +1,1355
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 The g is crafted to have 2 filelog topological heads in a linear
18 The g is crafted to have 2 filelog topological heads in a linear
19 changeset graph
19 changeset graph
20
20
21 $ hg init a
21 $ hg init a
22 $ cd a
22 $ cd a
23 $ echo a > a
23 $ echo a > a
24 $ echo f > f
24 $ echo f > f
25 $ hg ci -Ama -d '1 0'
25 $ hg ci -Ama -d '1 0'
26 adding a
26 adding a
27 adding f
27 adding f
28
28
29 $ hg cp a b
29 $ hg cp a b
30 $ hg cp f g
30 $ hg cp f g
31 $ hg ci -mb -d '2 0'
31 $ hg ci -mb -d '2 0'
32
32
33 $ mkdir dir
33 $ mkdir dir
34 $ hg mv b dir
34 $ hg mv b dir
35 $ echo g >> g
35 $ echo g >> g
36 $ echo f >> f
36 $ echo f >> f
37 $ hg ci -mc -d '3 0'
37 $ hg ci -mc -d '3 0'
38
38
39 $ hg mv a b
39 $ hg mv a b
40 $ hg cp -f f g
40 $ hg cp -f f g
41 $ echo a > d
41 $ echo a > d
42 $ hg add d
42 $ hg add d
43 $ hg ci -md -d '4 0'
43 $ hg ci -md -d '4 0'
44
44
45 $ hg mv dir/b e
45 $ hg mv dir/b e
46 $ hg ci -me -d '5 0'
46 $ hg ci -me -d '5 0'
47
47
48 $ hg log a
48 $ hg log a
49 changeset: 0:9161b9aeaf16
49 changeset: 0:9161b9aeaf16
50 user: test
50 user: test
51 date: Thu Jan 01 00:00:01 1970 +0000
51 date: Thu Jan 01 00:00:01 1970 +0000
52 summary: a
52 summary: a
53
53
54 log on directory
54 log on directory
55
55
56 $ hg log dir
56 $ hg log dir
57 changeset: 4:7e4639b4691b
57 changeset: 4:7e4639b4691b
58 tag: tip
58 tag: tip
59 user: test
59 user: test
60 date: Thu Jan 01 00:00:05 1970 +0000
60 date: Thu Jan 01 00:00:05 1970 +0000
61 summary: e
61 summary: e
62
62
63 changeset: 2:f8954cd4dc1f
63 changeset: 2:f8954cd4dc1f
64 user: test
64 user: test
65 date: Thu Jan 01 00:00:03 1970 +0000
65 date: Thu Jan 01 00:00:03 1970 +0000
66 summary: c
66 summary: c
67
67
68 $ hg log somethingthatdoesntexist dir
68 $ hg log somethingthatdoesntexist dir
69 changeset: 4:7e4639b4691b
69 changeset: 4:7e4639b4691b
70 tag: tip
70 tag: tip
71 user: test
71 user: test
72 date: Thu Jan 01 00:00:05 1970 +0000
72 date: Thu Jan 01 00:00:05 1970 +0000
73 summary: e
73 summary: e
74
74
75 changeset: 2:f8954cd4dc1f
75 changeset: 2:f8954cd4dc1f
76 user: test
76 user: test
77 date: Thu Jan 01 00:00:03 1970 +0000
77 date: Thu Jan 01 00:00:03 1970 +0000
78 summary: c
78 summary: c
79
79
80
80
81 -f, directory
81 -f, directory
82
82
83 $ hg log -f dir
83 $ hg log -f dir
84 abort: cannot follow file not in parent revision: "dir"
84 abort: cannot follow file not in parent revision: "dir"
85 [255]
85 [255]
86
86
87 -f, a wrong style
88
89 $ hg log -f -l1 --style something
90 abort: style 'something' not found
91 (available styles: changelog, bisect, default, xml, compact)
92 [255]
93
94
87 -f, but no args
95 -f, but no args
88
96
89 $ hg log -f
97 $ hg log -f
90 changeset: 4:7e4639b4691b
98 changeset: 4:7e4639b4691b
91 tag: tip
99 tag: tip
92 user: test
100 user: test
93 date: Thu Jan 01 00:00:05 1970 +0000
101 date: Thu Jan 01 00:00:05 1970 +0000
94 summary: e
102 summary: e
95
103
96 changeset: 3:2ca5ba701980
104 changeset: 3:2ca5ba701980
97 user: test
105 user: test
98 date: Thu Jan 01 00:00:04 1970 +0000
106 date: Thu Jan 01 00:00:04 1970 +0000
99 summary: d
107 summary: d
100
108
101 changeset: 2:f8954cd4dc1f
109 changeset: 2:f8954cd4dc1f
102 user: test
110 user: test
103 date: Thu Jan 01 00:00:03 1970 +0000
111 date: Thu Jan 01 00:00:03 1970 +0000
104 summary: c
112 summary: c
105
113
106 changeset: 1:d89b0a12d229
114 changeset: 1:d89b0a12d229
107 user: test
115 user: test
108 date: Thu Jan 01 00:00:02 1970 +0000
116 date: Thu Jan 01 00:00:02 1970 +0000
109 summary: b
117 summary: b
110
118
111 changeset: 0:9161b9aeaf16
119 changeset: 0:9161b9aeaf16
112 user: test
120 user: test
113 date: Thu Jan 01 00:00:01 1970 +0000
121 date: Thu Jan 01 00:00:01 1970 +0000
114 summary: a
122 summary: a
115
123
116
124
117 one rename
125 one rename
118
126
119 $ hg up -q 2
127 $ hg up -q 2
120 $ hg log -vf a
128 $ hg log -vf a
121 changeset: 0:9161b9aeaf16
129 changeset: 0:9161b9aeaf16
122 user: test
130 user: test
123 date: Thu Jan 01 00:00:01 1970 +0000
131 date: Thu Jan 01 00:00:01 1970 +0000
124 files: a f
132 files: a f
125 description:
133 description:
126 a
134 a
127
135
128
136
129
137
130 many renames
138 many renames
131
139
132 $ hg up -q tip
140 $ hg up -q tip
133 $ hg log -vf e
141 $ hg log -vf e
134 changeset: 4:7e4639b4691b
142 changeset: 4:7e4639b4691b
135 tag: tip
143 tag: tip
136 user: test
144 user: test
137 date: Thu Jan 01 00:00:05 1970 +0000
145 date: Thu Jan 01 00:00:05 1970 +0000
138 files: dir/b e
146 files: dir/b e
139 description:
147 description:
140 e
148 e
141
149
142
150
143 changeset: 2:f8954cd4dc1f
151 changeset: 2:f8954cd4dc1f
144 user: test
152 user: test
145 date: Thu Jan 01 00:00:03 1970 +0000
153 date: Thu Jan 01 00:00:03 1970 +0000
146 files: b dir/b f g
154 files: b dir/b f g
147 description:
155 description:
148 c
156 c
149
157
150
158
151 changeset: 1:d89b0a12d229
159 changeset: 1:d89b0a12d229
152 user: test
160 user: test
153 date: Thu Jan 01 00:00:02 1970 +0000
161 date: Thu Jan 01 00:00:02 1970 +0000
154 files: b g
162 files: b g
155 description:
163 description:
156 b
164 b
157
165
158
166
159 changeset: 0:9161b9aeaf16
167 changeset: 0:9161b9aeaf16
160 user: test
168 user: test
161 date: Thu Jan 01 00:00:01 1970 +0000
169 date: Thu Jan 01 00:00:01 1970 +0000
162 files: a f
170 files: a f
163 description:
171 description:
164 a
172 a
165
173
166
174
167
175
168
176
169 log -pf dir/b
177 log -pf dir/b
170
178
171 $ hg up -q 3
179 $ hg up -q 3
172 $ hg log -pf dir/b
180 $ hg log -pf dir/b
173 changeset: 2:f8954cd4dc1f
181 changeset: 2:f8954cd4dc1f
174 user: test
182 user: test
175 date: Thu Jan 01 00:00:03 1970 +0000
183 date: Thu Jan 01 00:00:03 1970 +0000
176 summary: c
184 summary: c
177
185
178 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
186 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
179 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
187 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
180 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
188 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
181 @@ -0,0 +1,1 @@
189 @@ -0,0 +1,1 @@
182 +a
190 +a
183
191
184 changeset: 1:d89b0a12d229
192 changeset: 1:d89b0a12d229
185 user: test
193 user: test
186 date: Thu Jan 01 00:00:02 1970 +0000
194 date: Thu Jan 01 00:00:02 1970 +0000
187 summary: b
195 summary: b
188
196
189 diff -r 9161b9aeaf16 -r d89b0a12d229 b
197 diff -r 9161b9aeaf16 -r d89b0a12d229 b
190 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
198 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
191 +++ b/b Thu Jan 01 00:00:02 1970 +0000
199 +++ b/b Thu Jan 01 00:00:02 1970 +0000
192 @@ -0,0 +1,1 @@
200 @@ -0,0 +1,1 @@
193 +a
201 +a
194
202
195 changeset: 0:9161b9aeaf16
203 changeset: 0:9161b9aeaf16
196 user: test
204 user: test
197 date: Thu Jan 01 00:00:01 1970 +0000
205 date: Thu Jan 01 00:00:01 1970 +0000
198 summary: a
206 summary: a
199
207
200 diff -r 000000000000 -r 9161b9aeaf16 a
208 diff -r 000000000000 -r 9161b9aeaf16 a
201 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
209 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
202 +++ b/a Thu Jan 01 00:00:01 1970 +0000
210 +++ b/a Thu Jan 01 00:00:01 1970 +0000
203 @@ -0,0 +1,1 @@
211 @@ -0,0 +1,1 @@
204 +a
212 +a
205
213
206
214
207 log -vf dir/b
215 log -vf dir/b
208
216
209 $ hg log -vf dir/b
217 $ hg log -vf dir/b
210 changeset: 2:f8954cd4dc1f
218 changeset: 2:f8954cd4dc1f
211 user: test
219 user: test
212 date: Thu Jan 01 00:00:03 1970 +0000
220 date: Thu Jan 01 00:00:03 1970 +0000
213 files: b dir/b f g
221 files: b dir/b f g
214 description:
222 description:
215 c
223 c
216
224
217
225
218 changeset: 1:d89b0a12d229
226 changeset: 1:d89b0a12d229
219 user: test
227 user: test
220 date: Thu Jan 01 00:00:02 1970 +0000
228 date: Thu Jan 01 00:00:02 1970 +0000
221 files: b g
229 files: b g
222 description:
230 description:
223 b
231 b
224
232
225
233
226 changeset: 0:9161b9aeaf16
234 changeset: 0:9161b9aeaf16
227 user: test
235 user: test
228 date: Thu Jan 01 00:00:01 1970 +0000
236 date: Thu Jan 01 00:00:01 1970 +0000
229 files: a f
237 files: a f
230 description:
238 description:
231 a
239 a
232
240
233
241
234
242
235
243
236 -f and multiple filelog heads
244 -f and multiple filelog heads
237
245
238 $ hg up -q 2
246 $ hg up -q 2
239 $ hg log -f g --template '{rev}\n'
247 $ hg log -f g --template '{rev}\n'
240 2
248 2
241 1
249 1
242 0
250 0
243 $ hg up -q tip
251 $ hg up -q tip
244 $ hg log -f g --template '{rev}\n'
252 $ hg log -f g --template '{rev}\n'
245 3
253 3
246 2
254 2
247 0
255 0
248
256
249
257
250 log copies with --copies
258 log copies with --copies
251
259
252 $ hg log -vC --template '{rev} {file_copies}\n'
260 $ hg log -vC --template '{rev} {file_copies}\n'
253 4 e (dir/b)
261 4 e (dir/b)
254 3 b (a)g (f)
262 3 b (a)g (f)
255 2 dir/b (b)
263 2 dir/b (b)
256 1 b (a)g (f)
264 1 b (a)g (f)
257 0
265 0
258
266
259 log copies switch without --copies, with old filecopy template
267 log copies switch without --copies, with old filecopy template
260
268
261 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
269 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
262 4
270 4
263 3
271 3
264 2
272 2
265 1
273 1
266 0
274 0
267
275
268 log copies switch with --copies
276 log copies switch with --copies
269
277
270 $ hg log -vC --template '{rev} {file_copies_switch}\n'
278 $ hg log -vC --template '{rev} {file_copies_switch}\n'
271 4 e (dir/b)
279 4 e (dir/b)
272 3 b (a)g (f)
280 3 b (a)g (f)
273 2 dir/b (b)
281 2 dir/b (b)
274 1 b (a)g (f)
282 1 b (a)g (f)
275 0
283 0
276
284
277
285
278 log copies with hardcoded style and with --style=default
286 log copies with hardcoded style and with --style=default
279
287
280 $ hg log -vC -r4
288 $ hg log -vC -r4
281 changeset: 4:7e4639b4691b
289 changeset: 4:7e4639b4691b
282 tag: tip
290 tag: tip
283 user: test
291 user: test
284 date: Thu Jan 01 00:00:05 1970 +0000
292 date: Thu Jan 01 00:00:05 1970 +0000
285 files: dir/b e
293 files: dir/b e
286 copies: e (dir/b)
294 copies: e (dir/b)
287 description:
295 description:
288 e
296 e
289
297
290
298
291 $ hg log -vC -r4 --style=default
299 $ hg log -vC -r4 --style=default
292 changeset: 4:7e4639b4691b
300 changeset: 4:7e4639b4691b
293 tag: tip
301 tag: tip
294 user: test
302 user: test
295 date: Thu Jan 01 00:00:05 1970 +0000
303 date: Thu Jan 01 00:00:05 1970 +0000
296 files: dir/b e
304 files: dir/b e
297 copies: e (dir/b)
305 copies: e (dir/b)
298 description:
306 description:
299 e
307 e
300
308
301
309
302
310
303
311
304 log copies, non-linear manifest
312 log copies, non-linear manifest
305
313
306 $ hg up -C 3
314 $ hg up -C 3
307 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
315 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
308 $ hg mv dir/b e
316 $ hg mv dir/b e
309 $ echo foo > foo
317 $ echo foo > foo
310 $ hg ci -Ame2 -d '6 0'
318 $ hg ci -Ame2 -d '6 0'
311 adding foo
319 adding foo
312 created new head
320 created new head
313 $ hg log -v --template '{rev} {file_copies}\n' -r 5
321 $ hg log -v --template '{rev} {file_copies}\n' -r 5
314 5 e (dir/b)
322 5 e (dir/b)
315
323
316
324
317 log copies, execute bit set
325 log copies, execute bit set
318
326
319 #if execbit
327 #if execbit
320 $ chmod +x e
328 $ chmod +x e
321 $ hg ci -me3 -d '7 0'
329 $ hg ci -me3 -d '7 0'
322 $ hg log -v --template '{rev} {file_copies}\n' -r 6
330 $ hg log -v --template '{rev} {file_copies}\n' -r 6
323 6
331 6
324 #endif
332 #endif
325
333
326
334
327 log -p d
335 log -p d
328
336
329 $ hg log -pv d
337 $ hg log -pv d
330 changeset: 3:2ca5ba701980
338 changeset: 3:2ca5ba701980
331 user: test
339 user: test
332 date: Thu Jan 01 00:00:04 1970 +0000
340 date: Thu Jan 01 00:00:04 1970 +0000
333 files: a b d g
341 files: a b d g
334 description:
342 description:
335 d
343 d
336
344
337
345
338 diff -r f8954cd4dc1f -r 2ca5ba701980 d
346 diff -r f8954cd4dc1f -r 2ca5ba701980 d
339 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
347 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
340 +++ b/d Thu Jan 01 00:00:04 1970 +0000
348 +++ b/d Thu Jan 01 00:00:04 1970 +0000
341 @@ -0,0 +1,1 @@
349 @@ -0,0 +1,1 @@
342 +a
350 +a
343
351
344
352
345
353
346 log --removed file
354 log --removed file
347
355
348 $ hg log --removed -v a
356 $ hg log --removed -v a
349 changeset: 3:2ca5ba701980
357 changeset: 3:2ca5ba701980
350 user: test
358 user: test
351 date: Thu Jan 01 00:00:04 1970 +0000
359 date: Thu Jan 01 00:00:04 1970 +0000
352 files: a b d g
360 files: a b d g
353 description:
361 description:
354 d
362 d
355
363
356
364
357 changeset: 0:9161b9aeaf16
365 changeset: 0:9161b9aeaf16
358 user: test
366 user: test
359 date: Thu Jan 01 00:00:01 1970 +0000
367 date: Thu Jan 01 00:00:01 1970 +0000
360 files: a f
368 files: a f
361 description:
369 description:
362 a
370 a
363
371
364
372
365
373
366 log --removed revrange file
374 log --removed revrange file
367
375
368 $ hg log --removed -v -r0:2 a
376 $ hg log --removed -v -r0:2 a
369 changeset: 0:9161b9aeaf16
377 changeset: 0:9161b9aeaf16
370 user: test
378 user: test
371 date: Thu Jan 01 00:00:01 1970 +0000
379 date: Thu Jan 01 00:00:01 1970 +0000
372 files: a f
380 files: a f
373 description:
381 description:
374 a
382 a
375
383
376
384
377 $ cd ..
385 $ cd ..
378
386
379 log --follow tests
387 log --follow tests
380
388
381 $ hg init follow
389 $ hg init follow
382 $ cd follow
390 $ cd follow
383
391
384 $ echo base > base
392 $ echo base > base
385 $ hg ci -Ambase -d '1 0'
393 $ hg ci -Ambase -d '1 0'
386 adding base
394 adding base
387
395
388 $ echo r1 >> base
396 $ echo r1 >> base
389 $ hg ci -Amr1 -d '1 0'
397 $ hg ci -Amr1 -d '1 0'
390 $ echo r2 >> base
398 $ echo r2 >> base
391 $ hg ci -Amr2 -d '1 0'
399 $ hg ci -Amr2 -d '1 0'
392
400
393 $ hg up -C 1
401 $ hg up -C 1
394 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
402 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 $ echo b1 > b1
403 $ echo b1 > b1
396 $ hg ci -Amb1 -d '1 0'
404 $ hg ci -Amb1 -d '1 0'
397 adding b1
405 adding b1
398 created new head
406 created new head
399
407
400
408
401 log -f
409 log -f
402
410
403 $ hg log -f
411 $ hg log -f
404 changeset: 3:e62f78d544b4
412 changeset: 3:e62f78d544b4
405 tag: tip
413 tag: tip
406 parent: 1:3d5bf5654eda
414 parent: 1:3d5bf5654eda
407 user: test
415 user: test
408 date: Thu Jan 01 00:00:01 1970 +0000
416 date: Thu Jan 01 00:00:01 1970 +0000
409 summary: b1
417 summary: b1
410
418
411 changeset: 1:3d5bf5654eda
419 changeset: 1:3d5bf5654eda
412 user: test
420 user: test
413 date: Thu Jan 01 00:00:01 1970 +0000
421 date: Thu Jan 01 00:00:01 1970 +0000
414 summary: r1
422 summary: r1
415
423
416 changeset: 0:67e992f2c4f3
424 changeset: 0:67e992f2c4f3
417 user: test
425 user: test
418 date: Thu Jan 01 00:00:01 1970 +0000
426 date: Thu Jan 01 00:00:01 1970 +0000
419 summary: base
427 summary: base
420
428
421
429
422
430
423 log -f -r 1:tip
431 log -f -r 1:tip
424
432
425 $ hg up -C 0
433 $ hg up -C 0
426 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
434 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
427 $ echo b2 > b2
435 $ echo b2 > b2
428 $ hg ci -Amb2 -d '1 0'
436 $ hg ci -Amb2 -d '1 0'
429 adding b2
437 adding b2
430 created new head
438 created new head
431 $ hg log -f -r 1:tip
439 $ hg log -f -r 1:tip
432 changeset: 1:3d5bf5654eda
440 changeset: 1:3d5bf5654eda
433 user: test
441 user: test
434 date: Thu Jan 01 00:00:01 1970 +0000
442 date: Thu Jan 01 00:00:01 1970 +0000
435 summary: r1
443 summary: r1
436
444
437 changeset: 2:60c670bf5b30
445 changeset: 2:60c670bf5b30
438 user: test
446 user: test
439 date: Thu Jan 01 00:00:01 1970 +0000
447 date: Thu Jan 01 00:00:01 1970 +0000
440 summary: r2
448 summary: r2
441
449
442 changeset: 3:e62f78d544b4
450 changeset: 3:e62f78d544b4
443 parent: 1:3d5bf5654eda
451 parent: 1:3d5bf5654eda
444 user: test
452 user: test
445 date: Thu Jan 01 00:00:01 1970 +0000
453 date: Thu Jan 01 00:00:01 1970 +0000
446 summary: b1
454 summary: b1
447
455
448
456
449
457
450 log -r . with two parents
458 log -r . with two parents
451
459
452 $ hg up -C 3
460 $ hg up -C 3
453 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
461 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
454 $ hg merge tip
462 $ hg merge tip
455 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
463 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
456 (branch merge, don't forget to commit)
464 (branch merge, don't forget to commit)
457 $ hg log -r .
465 $ hg log -r .
458 changeset: 3:e62f78d544b4
466 changeset: 3:e62f78d544b4
459 parent: 1:3d5bf5654eda
467 parent: 1:3d5bf5654eda
460 user: test
468 user: test
461 date: Thu Jan 01 00:00:01 1970 +0000
469 date: Thu Jan 01 00:00:01 1970 +0000
462 summary: b1
470 summary: b1
463
471
464
472
465
473
466 log -r . with one parent
474 log -r . with one parent
467
475
468 $ hg ci -mm12 -d '1 0'
476 $ hg ci -mm12 -d '1 0'
469 $ hg log -r .
477 $ hg log -r .
470 changeset: 5:302e9dd6890d
478 changeset: 5:302e9dd6890d
471 tag: tip
479 tag: tip
472 parent: 3:e62f78d544b4
480 parent: 3:e62f78d544b4
473 parent: 4:ddb82e70d1a1
481 parent: 4:ddb82e70d1a1
474 user: test
482 user: test
475 date: Thu Jan 01 00:00:01 1970 +0000
483 date: Thu Jan 01 00:00:01 1970 +0000
476 summary: m12
484 summary: m12
477
485
478
486
479 $ echo postm >> b1
487 $ echo postm >> b1
480 $ hg ci -Amb1.1 -d'1 0'
488 $ hg ci -Amb1.1 -d'1 0'
481
489
482
490
483 log --follow-first
491 log --follow-first
484
492
485 $ hg log --follow-first
493 $ hg log --follow-first
486 changeset: 6:2404bbcab562
494 changeset: 6:2404bbcab562
487 tag: tip
495 tag: tip
488 user: test
496 user: test
489 date: Thu Jan 01 00:00:01 1970 +0000
497 date: Thu Jan 01 00:00:01 1970 +0000
490 summary: b1.1
498 summary: b1.1
491
499
492 changeset: 5:302e9dd6890d
500 changeset: 5:302e9dd6890d
493 parent: 3:e62f78d544b4
501 parent: 3:e62f78d544b4
494 parent: 4:ddb82e70d1a1
502 parent: 4:ddb82e70d1a1
495 user: test
503 user: test
496 date: Thu Jan 01 00:00:01 1970 +0000
504 date: Thu Jan 01 00:00:01 1970 +0000
497 summary: m12
505 summary: m12
498
506
499 changeset: 3:e62f78d544b4
507 changeset: 3:e62f78d544b4
500 parent: 1:3d5bf5654eda
508 parent: 1:3d5bf5654eda
501 user: test
509 user: test
502 date: Thu Jan 01 00:00:01 1970 +0000
510 date: Thu Jan 01 00:00:01 1970 +0000
503 summary: b1
511 summary: b1
504
512
505 changeset: 1:3d5bf5654eda
513 changeset: 1:3d5bf5654eda
506 user: test
514 user: test
507 date: Thu Jan 01 00:00:01 1970 +0000
515 date: Thu Jan 01 00:00:01 1970 +0000
508 summary: r1
516 summary: r1
509
517
510 changeset: 0:67e992f2c4f3
518 changeset: 0:67e992f2c4f3
511 user: test
519 user: test
512 date: Thu Jan 01 00:00:01 1970 +0000
520 date: Thu Jan 01 00:00:01 1970 +0000
513 summary: base
521 summary: base
514
522
515
523
516
524
517 log -P 2
525 log -P 2
518
526
519 $ hg log -P 2
527 $ hg log -P 2
520 changeset: 6:2404bbcab562
528 changeset: 6:2404bbcab562
521 tag: tip
529 tag: tip
522 user: test
530 user: test
523 date: Thu Jan 01 00:00:01 1970 +0000
531 date: Thu Jan 01 00:00:01 1970 +0000
524 summary: b1.1
532 summary: b1.1
525
533
526 changeset: 5:302e9dd6890d
534 changeset: 5:302e9dd6890d
527 parent: 3:e62f78d544b4
535 parent: 3:e62f78d544b4
528 parent: 4:ddb82e70d1a1
536 parent: 4:ddb82e70d1a1
529 user: test
537 user: test
530 date: Thu Jan 01 00:00:01 1970 +0000
538 date: Thu Jan 01 00:00:01 1970 +0000
531 summary: m12
539 summary: m12
532
540
533 changeset: 4:ddb82e70d1a1
541 changeset: 4:ddb82e70d1a1
534 parent: 0:67e992f2c4f3
542 parent: 0:67e992f2c4f3
535 user: test
543 user: test
536 date: Thu Jan 01 00:00:01 1970 +0000
544 date: Thu Jan 01 00:00:01 1970 +0000
537 summary: b2
545 summary: b2
538
546
539 changeset: 3:e62f78d544b4
547 changeset: 3:e62f78d544b4
540 parent: 1:3d5bf5654eda
548 parent: 1:3d5bf5654eda
541 user: test
549 user: test
542 date: Thu Jan 01 00:00:01 1970 +0000
550 date: Thu Jan 01 00:00:01 1970 +0000
543 summary: b1
551 summary: b1
544
552
545
553
546
554
547 log -r tip -p --git
555 log -r tip -p --git
548
556
549 $ hg log -r tip -p --git
557 $ hg log -r tip -p --git
550 changeset: 6:2404bbcab562
558 changeset: 6:2404bbcab562
551 tag: tip
559 tag: tip
552 user: test
560 user: test
553 date: Thu Jan 01 00:00:01 1970 +0000
561 date: Thu Jan 01 00:00:01 1970 +0000
554 summary: b1.1
562 summary: b1.1
555
563
556 diff --git a/b1 b/b1
564 diff --git a/b1 b/b1
557 --- a/b1
565 --- a/b1
558 +++ b/b1
566 +++ b/b1
559 @@ -1,1 +1,2 @@
567 @@ -1,1 +1,2 @@
560 b1
568 b1
561 +postm
569 +postm
562
570
563
571
564
572
565 log -r ""
573 log -r ""
566
574
567 $ hg log -r ''
575 $ hg log -r ''
568 hg: parse error: empty query
576 hg: parse error: empty query
569 [255]
577 [255]
570
578
571 log -r <some unknown node id>
579 log -r <some unknown node id>
572
580
573 $ hg log -r 1000000000000000000000000000000000000000
581 $ hg log -r 1000000000000000000000000000000000000000
574 abort: unknown revision '1000000000000000000000000000000000000000'!
582 abort: unknown revision '1000000000000000000000000000000000000000'!
575 [255]
583 [255]
576
584
577 log -k r1
585 log -k r1
578
586
579 $ hg log -k r1
587 $ hg log -k r1
580 changeset: 1:3d5bf5654eda
588 changeset: 1:3d5bf5654eda
581 user: test
589 user: test
582 date: Thu Jan 01 00:00:01 1970 +0000
590 date: Thu Jan 01 00:00:01 1970 +0000
583 summary: r1
591 summary: r1
584
592
585 log -p -l2 --color=always
593 log -p -l2 --color=always
586
594
587 $ hg --config extensions.color= --config color.mode=ansi \
595 $ hg --config extensions.color= --config color.mode=ansi \
588 > log -p -l2 --color=always
596 > log -p -l2 --color=always
589 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
597 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
590 tag: tip
598 tag: tip
591 user: test
599 user: test
592 date: Thu Jan 01 00:00:01 1970 +0000
600 date: Thu Jan 01 00:00:01 1970 +0000
593 summary: b1.1
601 summary: b1.1
594
602
595 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
603 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
596 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
604 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
597 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
605 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
598 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
606 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
599 b1
607 b1
600 \x1b[0;32m+postm\x1b[0m (esc)
608 \x1b[0;32m+postm\x1b[0m (esc)
601
609
602 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
610 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
603 parent: 3:e62f78d544b4
611 parent: 3:e62f78d544b4
604 parent: 4:ddb82e70d1a1
612 parent: 4:ddb82e70d1a1
605 user: test
613 user: test
606 date: Thu Jan 01 00:00:01 1970 +0000
614 date: Thu Jan 01 00:00:01 1970 +0000
607 summary: m12
615 summary: m12
608
616
609 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
617 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
610 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
618 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
611 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
619 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
612 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
620 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
613 \x1b[0;32m+b2\x1b[0m (esc)
621 \x1b[0;32m+b2\x1b[0m (esc)
614
622
615
623
616
624
617 log -r tip --stat
625 log -r tip --stat
618
626
619 $ hg log -r tip --stat
627 $ hg log -r tip --stat
620 changeset: 6:2404bbcab562
628 changeset: 6:2404bbcab562
621 tag: tip
629 tag: tip
622 user: test
630 user: test
623 date: Thu Jan 01 00:00:01 1970 +0000
631 date: Thu Jan 01 00:00:01 1970 +0000
624 summary: b1.1
632 summary: b1.1
625
633
626 b1 | 1 +
634 b1 | 1 +
627 1 files changed, 1 insertions(+), 0 deletions(-)
635 1 files changed, 1 insertions(+), 0 deletions(-)
628
636
629
637
630 $ cd ..
638 $ cd ..
631
639
632
640
633 User
641 User
634
642
635 $ hg init usertest
643 $ hg init usertest
636 $ cd usertest
644 $ cd usertest
637
645
638 $ echo a > a
646 $ echo a > a
639 $ hg ci -A -m "a" -u "User One <user1@example.org>"
647 $ hg ci -A -m "a" -u "User One <user1@example.org>"
640 adding a
648 adding a
641 $ echo b > b
649 $ echo b > b
642 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
650 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
643 adding b
651 adding b
644
652
645 $ hg log -u "User One <user1@example.org>"
653 $ hg log -u "User One <user1@example.org>"
646 changeset: 0:29a4c94f1924
654 changeset: 0:29a4c94f1924
647 user: User One <user1@example.org>
655 user: User One <user1@example.org>
648 date: Thu Jan 01 00:00:00 1970 +0000
656 date: Thu Jan 01 00:00:00 1970 +0000
649 summary: a
657 summary: a
650
658
651 $ hg log -u "user1" -u "user2"
659 $ hg log -u "user1" -u "user2"
652 changeset: 1:e834b5e69c0e
660 changeset: 1:e834b5e69c0e
653 tag: tip
661 tag: tip
654 user: User Two <user2@example.org>
662 user: User Two <user2@example.org>
655 date: Thu Jan 01 00:00:00 1970 +0000
663 date: Thu Jan 01 00:00:00 1970 +0000
656 summary: b
664 summary: b
657
665
658 changeset: 0:29a4c94f1924
666 changeset: 0:29a4c94f1924
659 user: User One <user1@example.org>
667 user: User One <user1@example.org>
660 date: Thu Jan 01 00:00:00 1970 +0000
668 date: Thu Jan 01 00:00:00 1970 +0000
661 summary: a
669 summary: a
662
670
663 $ hg log -u "user3"
671 $ hg log -u "user3"
664
672
665 $ cd ..
673 $ cd ..
666
674
667 $ hg init branches
675 $ hg init branches
668 $ cd branches
676 $ cd branches
669
677
670 $ echo a > a
678 $ echo a > a
671 $ hg ci -A -m "commit on default"
679 $ hg ci -A -m "commit on default"
672 adding a
680 adding a
673 $ hg branch test
681 $ hg branch test
674 marked working directory as branch test
682 marked working directory as branch test
675 (branches are permanent and global, did you want a bookmark?)
683 (branches are permanent and global, did you want a bookmark?)
676 $ echo b > b
684 $ echo b > b
677 $ hg ci -A -m "commit on test"
685 $ hg ci -A -m "commit on test"
678 adding b
686 adding b
679
687
680 $ hg up default
688 $ hg up default
681 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
689 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
682 $ echo c > c
690 $ echo c > c
683 $ hg ci -A -m "commit on default"
691 $ hg ci -A -m "commit on default"
684 adding c
692 adding c
685 $ hg up test
693 $ hg up test
686 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
694 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
687 $ echo c > c
695 $ echo c > c
688 $ hg ci -A -m "commit on test"
696 $ hg ci -A -m "commit on test"
689 adding c
697 adding c
690
698
691
699
692 log -b default
700 log -b default
693
701
694 $ hg log -b default
702 $ hg log -b default
695 changeset: 2:c3a4f03cc9a7
703 changeset: 2:c3a4f03cc9a7
696 parent: 0:24427303d56f
704 parent: 0:24427303d56f
697 user: test
705 user: test
698 date: Thu Jan 01 00:00:00 1970 +0000
706 date: Thu Jan 01 00:00:00 1970 +0000
699 summary: commit on default
707 summary: commit on default
700
708
701 changeset: 0:24427303d56f
709 changeset: 0:24427303d56f
702 user: test
710 user: test
703 date: Thu Jan 01 00:00:00 1970 +0000
711 date: Thu Jan 01 00:00:00 1970 +0000
704 summary: commit on default
712 summary: commit on default
705
713
706
714
707
715
708 log -b test
716 log -b test
709
717
710 $ hg log -b test
718 $ hg log -b test
711 changeset: 3:f5d8de11c2e2
719 changeset: 3:f5d8de11c2e2
712 branch: test
720 branch: test
713 tag: tip
721 tag: tip
714 parent: 1:d32277701ccb
722 parent: 1:d32277701ccb
715 user: test
723 user: test
716 date: Thu Jan 01 00:00:00 1970 +0000
724 date: Thu Jan 01 00:00:00 1970 +0000
717 summary: commit on test
725 summary: commit on test
718
726
719 changeset: 1:d32277701ccb
727 changeset: 1:d32277701ccb
720 branch: test
728 branch: test
721 user: test
729 user: test
722 date: Thu Jan 01 00:00:00 1970 +0000
730 date: Thu Jan 01 00:00:00 1970 +0000
723 summary: commit on test
731 summary: commit on test
724
732
725
733
726
734
727 log -b dummy
735 log -b dummy
728
736
729 $ hg log -b dummy
737 $ hg log -b dummy
730 abort: unknown revision 'dummy'!
738 abort: unknown revision 'dummy'!
731 [255]
739 [255]
732
740
733
741
734 log -b .
742 log -b .
735
743
736 $ hg log -b .
744 $ hg log -b .
737 changeset: 3:f5d8de11c2e2
745 changeset: 3:f5d8de11c2e2
738 branch: test
746 branch: test
739 tag: tip
747 tag: tip
740 parent: 1:d32277701ccb
748 parent: 1:d32277701ccb
741 user: test
749 user: test
742 date: Thu Jan 01 00:00:00 1970 +0000
750 date: Thu Jan 01 00:00:00 1970 +0000
743 summary: commit on test
751 summary: commit on test
744
752
745 changeset: 1:d32277701ccb
753 changeset: 1:d32277701ccb
746 branch: test
754 branch: test
747 user: test
755 user: test
748 date: Thu Jan 01 00:00:00 1970 +0000
756 date: Thu Jan 01 00:00:00 1970 +0000
749 summary: commit on test
757 summary: commit on test
750
758
751
759
752
760
753 log -b default -b test
761 log -b default -b test
754
762
755 $ hg log -b default -b test
763 $ hg log -b default -b test
756 changeset: 3:f5d8de11c2e2
764 changeset: 3:f5d8de11c2e2
757 branch: test
765 branch: test
758 tag: tip
766 tag: tip
759 parent: 1:d32277701ccb
767 parent: 1:d32277701ccb
760 user: test
768 user: test
761 date: Thu Jan 01 00:00:00 1970 +0000
769 date: Thu Jan 01 00:00:00 1970 +0000
762 summary: commit on test
770 summary: commit on test
763
771
764 changeset: 2:c3a4f03cc9a7
772 changeset: 2:c3a4f03cc9a7
765 parent: 0:24427303d56f
773 parent: 0:24427303d56f
766 user: test
774 user: test
767 date: Thu Jan 01 00:00:00 1970 +0000
775 date: Thu Jan 01 00:00:00 1970 +0000
768 summary: commit on default
776 summary: commit on default
769
777
770 changeset: 1:d32277701ccb
778 changeset: 1:d32277701ccb
771 branch: test
779 branch: test
772 user: test
780 user: test
773 date: Thu Jan 01 00:00:00 1970 +0000
781 date: Thu Jan 01 00:00:00 1970 +0000
774 summary: commit on test
782 summary: commit on test
775
783
776 changeset: 0:24427303d56f
784 changeset: 0:24427303d56f
777 user: test
785 user: test
778 date: Thu Jan 01 00:00:00 1970 +0000
786 date: Thu Jan 01 00:00:00 1970 +0000
779 summary: commit on default
787 summary: commit on default
780
788
781
789
782
790
783 log -b default -b .
791 log -b default -b .
784
792
785 $ hg log -b default -b .
793 $ hg log -b default -b .
786 changeset: 3:f5d8de11c2e2
794 changeset: 3:f5d8de11c2e2
787 branch: test
795 branch: test
788 tag: tip
796 tag: tip
789 parent: 1:d32277701ccb
797 parent: 1:d32277701ccb
790 user: test
798 user: test
791 date: Thu Jan 01 00:00:00 1970 +0000
799 date: Thu Jan 01 00:00:00 1970 +0000
792 summary: commit on test
800 summary: commit on test
793
801
794 changeset: 2:c3a4f03cc9a7
802 changeset: 2:c3a4f03cc9a7
795 parent: 0:24427303d56f
803 parent: 0:24427303d56f
796 user: test
804 user: test
797 date: Thu Jan 01 00:00:00 1970 +0000
805 date: Thu Jan 01 00:00:00 1970 +0000
798 summary: commit on default
806 summary: commit on default
799
807
800 changeset: 1:d32277701ccb
808 changeset: 1:d32277701ccb
801 branch: test
809 branch: test
802 user: test
810 user: test
803 date: Thu Jan 01 00:00:00 1970 +0000
811 date: Thu Jan 01 00:00:00 1970 +0000
804 summary: commit on test
812 summary: commit on test
805
813
806 changeset: 0:24427303d56f
814 changeset: 0:24427303d56f
807 user: test
815 user: test
808 date: Thu Jan 01 00:00:00 1970 +0000
816 date: Thu Jan 01 00:00:00 1970 +0000
809 summary: commit on default
817 summary: commit on default
810
818
811
819
812
820
813 log -b . -b test
821 log -b . -b test
814
822
815 $ hg log -b . -b test
823 $ hg log -b . -b test
816 changeset: 3:f5d8de11c2e2
824 changeset: 3:f5d8de11c2e2
817 branch: test
825 branch: test
818 tag: tip
826 tag: tip
819 parent: 1:d32277701ccb
827 parent: 1:d32277701ccb
820 user: test
828 user: test
821 date: Thu Jan 01 00:00:00 1970 +0000
829 date: Thu Jan 01 00:00:00 1970 +0000
822 summary: commit on test
830 summary: commit on test
823
831
824 changeset: 1:d32277701ccb
832 changeset: 1:d32277701ccb
825 branch: test
833 branch: test
826 user: test
834 user: test
827 date: Thu Jan 01 00:00:00 1970 +0000
835 date: Thu Jan 01 00:00:00 1970 +0000
828 summary: commit on test
836 summary: commit on test
829
837
830
838
831
839
832 log -b 2
840 log -b 2
833
841
834 $ hg log -b 2
842 $ hg log -b 2
835 changeset: 2:c3a4f03cc9a7
843 changeset: 2:c3a4f03cc9a7
836 parent: 0:24427303d56f
844 parent: 0:24427303d56f
837 user: test
845 user: test
838 date: Thu Jan 01 00:00:00 1970 +0000
846 date: Thu Jan 01 00:00:00 1970 +0000
839 summary: commit on default
847 summary: commit on default
840
848
841 changeset: 0:24427303d56f
849 changeset: 0:24427303d56f
842 user: test
850 user: test
843 date: Thu Jan 01 00:00:00 1970 +0000
851 date: Thu Jan 01 00:00:00 1970 +0000
844 summary: commit on default
852 summary: commit on default
845
853
846
854
847
855
848 log -p --cwd dir (in subdir)
856 log -p --cwd dir (in subdir)
849
857
850 $ mkdir dir
858 $ mkdir dir
851 $ hg log -p --cwd dir
859 $ hg log -p --cwd dir
852 changeset: 3:f5d8de11c2e2
860 changeset: 3:f5d8de11c2e2
853 branch: test
861 branch: test
854 tag: tip
862 tag: tip
855 parent: 1:d32277701ccb
863 parent: 1:d32277701ccb
856 user: test
864 user: test
857 date: Thu Jan 01 00:00:00 1970 +0000
865 date: Thu Jan 01 00:00:00 1970 +0000
858 summary: commit on test
866 summary: commit on test
859
867
860 diff -r d32277701ccb -r f5d8de11c2e2 c
868 diff -r d32277701ccb -r f5d8de11c2e2 c
861 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
869 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
862 +++ b/c Thu Jan 01 00:00:00 1970 +0000
870 +++ b/c Thu Jan 01 00:00:00 1970 +0000
863 @@ -0,0 +1,1 @@
871 @@ -0,0 +1,1 @@
864 +c
872 +c
865
873
866 changeset: 2:c3a4f03cc9a7
874 changeset: 2:c3a4f03cc9a7
867 parent: 0:24427303d56f
875 parent: 0:24427303d56f
868 user: test
876 user: test
869 date: Thu Jan 01 00:00:00 1970 +0000
877 date: Thu Jan 01 00:00:00 1970 +0000
870 summary: commit on default
878 summary: commit on default
871
879
872 diff -r 24427303d56f -r c3a4f03cc9a7 c
880 diff -r 24427303d56f -r c3a4f03cc9a7 c
873 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
881 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
874 +++ b/c Thu Jan 01 00:00:00 1970 +0000
882 +++ b/c Thu Jan 01 00:00:00 1970 +0000
875 @@ -0,0 +1,1 @@
883 @@ -0,0 +1,1 @@
876 +c
884 +c
877
885
878 changeset: 1:d32277701ccb
886 changeset: 1:d32277701ccb
879 branch: test
887 branch: test
880 user: test
888 user: test
881 date: Thu Jan 01 00:00:00 1970 +0000
889 date: Thu Jan 01 00:00:00 1970 +0000
882 summary: commit on test
890 summary: commit on test
883
891
884 diff -r 24427303d56f -r d32277701ccb b
892 diff -r 24427303d56f -r d32277701ccb b
885 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
893 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
886 +++ b/b Thu Jan 01 00:00:00 1970 +0000
894 +++ b/b Thu Jan 01 00:00:00 1970 +0000
887 @@ -0,0 +1,1 @@
895 @@ -0,0 +1,1 @@
888 +b
896 +b
889
897
890 changeset: 0:24427303d56f
898 changeset: 0:24427303d56f
891 user: test
899 user: test
892 date: Thu Jan 01 00:00:00 1970 +0000
900 date: Thu Jan 01 00:00:00 1970 +0000
893 summary: commit on default
901 summary: commit on default
894
902
895 diff -r 000000000000 -r 24427303d56f a
903 diff -r 000000000000 -r 24427303d56f a
896 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
904 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
897 +++ b/a Thu Jan 01 00:00:00 1970 +0000
905 +++ b/a Thu Jan 01 00:00:00 1970 +0000
898 @@ -0,0 +1,1 @@
906 @@ -0,0 +1,1 @@
899 +a
907 +a
900
908
901
909
902
910
903 log -p -R repo
911 log -p -R repo
904
912
905 $ cd dir
913 $ cd dir
906 $ hg log -p -R .. ../a
914 $ hg log -p -R .. ../a
907 changeset: 0:24427303d56f
915 changeset: 0:24427303d56f
908 user: test
916 user: test
909 date: Thu Jan 01 00:00:00 1970 +0000
917 date: Thu Jan 01 00:00:00 1970 +0000
910 summary: commit on default
918 summary: commit on default
911
919
912 diff -r 000000000000 -r 24427303d56f a
920 diff -r 000000000000 -r 24427303d56f a
913 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
921 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
914 +++ b/a Thu Jan 01 00:00:00 1970 +0000
922 +++ b/a Thu Jan 01 00:00:00 1970 +0000
915 @@ -0,0 +1,1 @@
923 @@ -0,0 +1,1 @@
916 +a
924 +a
917
925
918
926
919 $ cd ../..
927 $ cd ../..
920
928
921 $ hg init follow2
929 $ hg init follow2
922 $ cd follow2
930 $ cd follow2
923
931
924 # Build the following history:
932 # Build the following history:
925 # tip - o - x - o - x - x
933 # tip - o - x - o - x - x
926 # \ /
934 # \ /
927 # o - o - o - x
935 # o - o - o - x
928 # \ /
936 # \ /
929 # o
937 # o
930 #
938 #
931 # Where "o" is a revision containing "foo" and
939 # Where "o" is a revision containing "foo" and
932 # "x" is a revision without "foo"
940 # "x" is a revision without "foo"
933
941
934 $ touch init
942 $ touch init
935 $ hg ci -A -m "init, unrelated"
943 $ hg ci -A -m "init, unrelated"
936 adding init
944 adding init
937 $ echo 'foo' > init
945 $ echo 'foo' > init
938 $ hg ci -m "change, unrelated"
946 $ hg ci -m "change, unrelated"
939 $ echo 'foo' > foo
947 $ echo 'foo' > foo
940 $ hg ci -A -m "add unrelated old foo"
948 $ hg ci -A -m "add unrelated old foo"
941 adding foo
949 adding foo
942 $ hg rm foo
950 $ hg rm foo
943 $ hg ci -m "delete foo, unrelated"
951 $ hg ci -m "delete foo, unrelated"
944 $ echo 'related' > foo
952 $ echo 'related' > foo
945 $ hg ci -A -m "add foo, related"
953 $ hg ci -A -m "add foo, related"
946 adding foo
954 adding foo
947
955
948 $ hg up 0
956 $ hg up 0
949 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
957 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
950 $ touch branch
958 $ touch branch
951 $ hg ci -A -m "first branch, unrelated"
959 $ hg ci -A -m "first branch, unrelated"
952 adding branch
960 adding branch
953 created new head
961 created new head
954 $ touch foo
962 $ touch foo
955 $ hg ci -A -m "create foo, related"
963 $ hg ci -A -m "create foo, related"
956 adding foo
964 adding foo
957 $ echo 'change' > foo
965 $ echo 'change' > foo
958 $ hg ci -m "change foo, related"
966 $ hg ci -m "change foo, related"
959
967
960 $ hg up 6
968 $ hg up 6
961 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
969 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
962 $ echo 'change foo in branch' > foo
970 $ echo 'change foo in branch' > foo
963 $ hg ci -m "change foo in branch, related"
971 $ hg ci -m "change foo in branch, related"
964 created new head
972 created new head
965 $ hg merge 7
973 $ hg merge 7
966 merging foo
974 merging foo
967 warning: conflicts during merge.
975 warning: conflicts during merge.
968 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
976 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
969 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
977 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
970 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
978 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
971 [1]
979 [1]
972 $ echo 'merge 1' > foo
980 $ echo 'merge 1' > foo
973 $ hg resolve -m foo
981 $ hg resolve -m foo
974 $ hg ci -m "First merge, related"
982 $ hg ci -m "First merge, related"
975
983
976 $ hg merge 4
984 $ hg merge 4
977 merging foo
985 merging foo
978 warning: conflicts during merge.
986 warning: conflicts during merge.
979 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
987 merging foo incomplete! (edit conflicts, then use 'hg resolve --mark')
980 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
988 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
981 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
989 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
982 [1]
990 [1]
983 $ echo 'merge 2' > foo
991 $ echo 'merge 2' > foo
984 $ hg resolve -m foo
992 $ hg resolve -m foo
985 $ hg ci -m "Last merge, related"
993 $ hg ci -m "Last merge, related"
986
994
987 $ hg log --graph
995 $ hg log --graph
988 @ changeset: 10:4dae8563d2c5
996 @ changeset: 10:4dae8563d2c5
989 |\ tag: tip
997 |\ tag: tip
990 | | parent: 9:7b35701b003e
998 | | parent: 9:7b35701b003e
991 | | parent: 4:88176d361b69
999 | | parent: 4:88176d361b69
992 | | user: test
1000 | | user: test
993 | | date: Thu Jan 01 00:00:00 1970 +0000
1001 | | date: Thu Jan 01 00:00:00 1970 +0000
994 | | summary: Last merge, related
1002 | | summary: Last merge, related
995 | |
1003 | |
996 | o changeset: 9:7b35701b003e
1004 | o changeset: 9:7b35701b003e
997 | |\ parent: 8:e5416ad8a855
1005 | |\ parent: 8:e5416ad8a855
998 | | | parent: 7:87fe3144dcfa
1006 | | | parent: 7:87fe3144dcfa
999 | | | user: test
1007 | | | user: test
1000 | | | date: Thu Jan 01 00:00:00 1970 +0000
1008 | | | date: Thu Jan 01 00:00:00 1970 +0000
1001 | | | summary: First merge, related
1009 | | | summary: First merge, related
1002 | | |
1010 | | |
1003 | | o changeset: 8:e5416ad8a855
1011 | | o changeset: 8:e5416ad8a855
1004 | | | parent: 6:dc6c325fe5ee
1012 | | | parent: 6:dc6c325fe5ee
1005 | | | user: test
1013 | | | user: test
1006 | | | date: Thu Jan 01 00:00:00 1970 +0000
1014 | | | date: Thu Jan 01 00:00:00 1970 +0000
1007 | | | summary: change foo in branch, related
1015 | | | summary: change foo in branch, related
1008 | | |
1016 | | |
1009 | o | changeset: 7:87fe3144dcfa
1017 | o | changeset: 7:87fe3144dcfa
1010 | |/ user: test
1018 | |/ user: test
1011 | | date: Thu Jan 01 00:00:00 1970 +0000
1019 | | date: Thu Jan 01 00:00:00 1970 +0000
1012 | | summary: change foo, related
1020 | | summary: change foo, related
1013 | |
1021 | |
1014 | o changeset: 6:dc6c325fe5ee
1022 | o changeset: 6:dc6c325fe5ee
1015 | | user: test
1023 | | user: test
1016 | | date: Thu Jan 01 00:00:00 1970 +0000
1024 | | date: Thu Jan 01 00:00:00 1970 +0000
1017 | | summary: create foo, related
1025 | | summary: create foo, related
1018 | |
1026 | |
1019 | o changeset: 5:73db34516eb9
1027 | o changeset: 5:73db34516eb9
1020 | | parent: 0:e87515fd044a
1028 | | parent: 0:e87515fd044a
1021 | | user: test
1029 | | user: test
1022 | | date: Thu Jan 01 00:00:00 1970 +0000
1030 | | date: Thu Jan 01 00:00:00 1970 +0000
1023 | | summary: first branch, unrelated
1031 | | summary: first branch, unrelated
1024 | |
1032 | |
1025 o | changeset: 4:88176d361b69
1033 o | changeset: 4:88176d361b69
1026 | | user: test
1034 | | user: test
1027 | | date: Thu Jan 01 00:00:00 1970 +0000
1035 | | date: Thu Jan 01 00:00:00 1970 +0000
1028 | | summary: add foo, related
1036 | | summary: add foo, related
1029 | |
1037 | |
1030 o | changeset: 3:dd78ae4afb56
1038 o | changeset: 3:dd78ae4afb56
1031 | | user: test
1039 | | user: test
1032 | | date: Thu Jan 01 00:00:00 1970 +0000
1040 | | date: Thu Jan 01 00:00:00 1970 +0000
1033 | | summary: delete foo, unrelated
1041 | | summary: delete foo, unrelated
1034 | |
1042 | |
1035 o | changeset: 2:c4c64aedf0f7
1043 o | changeset: 2:c4c64aedf0f7
1036 | | user: test
1044 | | user: test
1037 | | date: Thu Jan 01 00:00:00 1970 +0000
1045 | | date: Thu Jan 01 00:00:00 1970 +0000
1038 | | summary: add unrelated old foo
1046 | | summary: add unrelated old foo
1039 | |
1047 | |
1040 o | changeset: 1:e5faa7440653
1048 o | changeset: 1:e5faa7440653
1041 |/ user: test
1049 |/ user: test
1042 | date: Thu Jan 01 00:00:00 1970 +0000
1050 | date: Thu Jan 01 00:00:00 1970 +0000
1043 | summary: change, unrelated
1051 | summary: change, unrelated
1044 |
1052 |
1045 o changeset: 0:e87515fd044a
1053 o changeset: 0:e87515fd044a
1046 user: test
1054 user: test
1047 date: Thu Jan 01 00:00:00 1970 +0000
1055 date: Thu Jan 01 00:00:00 1970 +0000
1048 summary: init, unrelated
1056 summary: init, unrelated
1049
1057
1050
1058
1051 $ hg --traceback log -f foo
1059 $ hg --traceback log -f foo
1052 changeset: 10:4dae8563d2c5
1060 changeset: 10:4dae8563d2c5
1053 tag: tip
1061 tag: tip
1054 parent: 9:7b35701b003e
1062 parent: 9:7b35701b003e
1055 parent: 4:88176d361b69
1063 parent: 4:88176d361b69
1056 user: test
1064 user: test
1057 date: Thu Jan 01 00:00:00 1970 +0000
1065 date: Thu Jan 01 00:00:00 1970 +0000
1058 summary: Last merge, related
1066 summary: Last merge, related
1059
1067
1060 changeset: 9:7b35701b003e
1068 changeset: 9:7b35701b003e
1061 parent: 8:e5416ad8a855
1069 parent: 8:e5416ad8a855
1062 parent: 7:87fe3144dcfa
1070 parent: 7:87fe3144dcfa
1063 user: test
1071 user: test
1064 date: Thu Jan 01 00:00:00 1970 +0000
1072 date: Thu Jan 01 00:00:00 1970 +0000
1065 summary: First merge, related
1073 summary: First merge, related
1066
1074
1067 changeset: 8:e5416ad8a855
1075 changeset: 8:e5416ad8a855
1068 parent: 6:dc6c325fe5ee
1076 parent: 6:dc6c325fe5ee
1069 user: test
1077 user: test
1070 date: Thu Jan 01 00:00:00 1970 +0000
1078 date: Thu Jan 01 00:00:00 1970 +0000
1071 summary: change foo in branch, related
1079 summary: change foo in branch, related
1072
1080
1073 changeset: 7:87fe3144dcfa
1081 changeset: 7:87fe3144dcfa
1074 user: test
1082 user: test
1075 date: Thu Jan 01 00:00:00 1970 +0000
1083 date: Thu Jan 01 00:00:00 1970 +0000
1076 summary: change foo, related
1084 summary: change foo, related
1077
1085
1078 changeset: 6:dc6c325fe5ee
1086 changeset: 6:dc6c325fe5ee
1079 user: test
1087 user: test
1080 date: Thu Jan 01 00:00:00 1970 +0000
1088 date: Thu Jan 01 00:00:00 1970 +0000
1081 summary: create foo, related
1089 summary: create foo, related
1082
1090
1083 changeset: 4:88176d361b69
1091 changeset: 4:88176d361b69
1084 user: test
1092 user: test
1085 date: Thu Jan 01 00:00:00 1970 +0000
1093 date: Thu Jan 01 00:00:00 1970 +0000
1086 summary: add foo, related
1094 summary: add foo, related
1087
1095
1088
1096
1089 Also check when maxrev < lastrevfilelog
1097 Also check when maxrev < lastrevfilelog
1090
1098
1091 $ hg --traceback log -f -r4 foo
1099 $ hg --traceback log -f -r4 foo
1092 changeset: 4:88176d361b69
1100 changeset: 4:88176d361b69
1093 user: test
1101 user: test
1094 date: Thu Jan 01 00:00:00 1970 +0000
1102 date: Thu Jan 01 00:00:00 1970 +0000
1095 summary: add foo, related
1103 summary: add foo, related
1096
1104
1097 $ cd ..
1105 $ cd ..
1098
1106
1099 Issue2383: hg log showing _less_ differences than hg diff
1107 Issue2383: hg log showing _less_ differences than hg diff
1100
1108
1101 $ hg init issue2383
1109 $ hg init issue2383
1102 $ cd issue2383
1110 $ cd issue2383
1103
1111
1104 Create a test repo:
1112 Create a test repo:
1105
1113
1106 $ echo a > a
1114 $ echo a > a
1107 $ hg ci -Am0
1115 $ hg ci -Am0
1108 adding a
1116 adding a
1109 $ echo b > b
1117 $ echo b > b
1110 $ hg ci -Am1
1118 $ hg ci -Am1
1111 adding b
1119 adding b
1112 $ hg co 0
1120 $ hg co 0
1113 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1121 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1114 $ echo b > a
1122 $ echo b > a
1115 $ hg ci -m2
1123 $ hg ci -m2
1116 created new head
1124 created new head
1117
1125
1118 Merge:
1126 Merge:
1119
1127
1120 $ hg merge
1128 $ hg merge
1121 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1129 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1122 (branch merge, don't forget to commit)
1130 (branch merge, don't forget to commit)
1123
1131
1124 Make sure there's a file listed in the merge to trigger the bug:
1132 Make sure there's a file listed in the merge to trigger the bug:
1125
1133
1126 $ echo c > a
1134 $ echo c > a
1127 $ hg ci -m3
1135 $ hg ci -m3
1128
1136
1129 Two files shown here in diff:
1137 Two files shown here in diff:
1130
1138
1131 $ hg diff --rev 2:3
1139 $ hg diff --rev 2:3
1132 diff -r b09be438c43a -r 8e07aafe1edc a
1140 diff -r b09be438c43a -r 8e07aafe1edc a
1133 --- a/a Thu Jan 01 00:00:00 1970 +0000
1141 --- a/a Thu Jan 01 00:00:00 1970 +0000
1134 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1142 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1135 @@ -1,1 +1,1 @@
1143 @@ -1,1 +1,1 @@
1136 -b
1144 -b
1137 +c
1145 +c
1138 diff -r b09be438c43a -r 8e07aafe1edc b
1146 diff -r b09be438c43a -r 8e07aafe1edc b
1139 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1147 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1140 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1148 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1141 @@ -0,0 +1,1 @@
1149 @@ -0,0 +1,1 @@
1142 +b
1150 +b
1143
1151
1144 Diff here should be the same:
1152 Diff here should be the same:
1145
1153
1146 $ hg log -vpr 3
1154 $ hg log -vpr 3
1147 changeset: 3:8e07aafe1edc
1155 changeset: 3:8e07aafe1edc
1148 tag: tip
1156 tag: tip
1149 parent: 2:b09be438c43a
1157 parent: 2:b09be438c43a
1150 parent: 1:925d80f479bb
1158 parent: 1:925d80f479bb
1151 user: test
1159 user: test
1152 date: Thu Jan 01 00:00:00 1970 +0000
1160 date: Thu Jan 01 00:00:00 1970 +0000
1153 files: a
1161 files: a
1154 description:
1162 description:
1155 3
1163 3
1156
1164
1157
1165
1158 diff -r b09be438c43a -r 8e07aafe1edc a
1166 diff -r b09be438c43a -r 8e07aafe1edc a
1159 --- a/a Thu Jan 01 00:00:00 1970 +0000
1167 --- a/a Thu Jan 01 00:00:00 1970 +0000
1160 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1168 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1161 @@ -1,1 +1,1 @@
1169 @@ -1,1 +1,1 @@
1162 -b
1170 -b
1163 +c
1171 +c
1164 diff -r b09be438c43a -r 8e07aafe1edc b
1172 diff -r b09be438c43a -r 8e07aafe1edc b
1165 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1173 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1166 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1174 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1167 @@ -0,0 +1,1 @@
1175 @@ -0,0 +1,1 @@
1168 +b
1176 +b
1169
1177
1170 $ cd ..
1178 $ cd ..
1171
1179
1172 'hg log -r rev fn' when last(filelog(fn)) != rev
1180 'hg log -r rev fn' when last(filelog(fn)) != rev
1173
1181
1174 $ hg init simplelog
1182 $ hg init simplelog
1175 $ cd simplelog
1183 $ cd simplelog
1176 $ echo f > a
1184 $ echo f > a
1177 $ hg ci -Am'a' -d '0 0'
1185 $ hg ci -Am'a' -d '0 0'
1178 adding a
1186 adding a
1179 $ echo f >> a
1187 $ echo f >> a
1180 $ hg ci -Am'a bis' -d '1 0'
1188 $ hg ci -Am'a bis' -d '1 0'
1181
1189
1182 $ hg log -r0 a
1190 $ hg log -r0 a
1183 changeset: 0:9f758d63dcde
1191 changeset: 0:9f758d63dcde
1184 user: test
1192 user: test
1185 date: Thu Jan 01 00:00:00 1970 +0000
1193 date: Thu Jan 01 00:00:00 1970 +0000
1186 summary: a
1194 summary: a
1187
1195
1188 enable obsolete to test hidden feature
1196 enable obsolete to test hidden feature
1189
1197
1190 $ cat > ${TESTTMP}/obs.py << EOF
1198 $ cat > ${TESTTMP}/obs.py << EOF
1191 > import mercurial.obsolete
1199 > import mercurial.obsolete
1192 > mercurial.obsolete._enabled = True
1200 > mercurial.obsolete._enabled = True
1193 > EOF
1201 > EOF
1194 $ echo '[extensions]' >> $HGRCPATH
1202 $ echo '[extensions]' >> $HGRCPATH
1195 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
1203 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
1196
1204
1197 $ hg log --template='{rev}:{node}\n'
1205 $ hg log --template='{rev}:{node}\n'
1198 1:a765632148dc55d38c35c4f247c618701886cb2f
1206 1:a765632148dc55d38c35c4f247c618701886cb2f
1199 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1207 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1200 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1208 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1201 $ hg up null -q
1209 $ hg up null -q
1202 $ hg log --template='{rev}:{node}\n'
1210 $ hg log --template='{rev}:{node}\n'
1203 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1211 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1204 $ hg log --template='{rev}:{node}\n' --hidden
1212 $ hg log --template='{rev}:{node}\n' --hidden
1205 1:a765632148dc55d38c35c4f247c618701886cb2f
1213 1:a765632148dc55d38c35c4f247c618701886cb2f
1206 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1214 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1207
1215
1208 test that parent prevent a changeset to be hidden
1216 test that parent prevent a changeset to be hidden
1209
1217
1210 $ hg up 1 -q --hidden
1218 $ hg up 1 -q --hidden
1211 $ hg log --template='{rev}:{node}\n'
1219 $ hg log --template='{rev}:{node}\n'
1212 1:a765632148dc55d38c35c4f247c618701886cb2f
1220 1:a765632148dc55d38c35c4f247c618701886cb2f
1213 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1221 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1214
1222
1215 test that second parent prevent a changeset to be hidden too
1223 test that second parent prevent a changeset to be hidden too
1216
1224
1217 $ hg debugsetparents 0 1 # nothing suitable to merge here
1225 $ hg debugsetparents 0 1 # nothing suitable to merge here
1218 $ hg log --template='{rev}:{node}\n'
1226 $ hg log --template='{rev}:{node}\n'
1219 1:a765632148dc55d38c35c4f247c618701886cb2f
1227 1:a765632148dc55d38c35c4f247c618701886cb2f
1220 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1228 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1221 $ hg debugsetparents 1
1229 $ hg debugsetparents 1
1222 $ hg up -q null
1230 $ hg up -q null
1223
1231
1224 bookmarks prevent a changeset being hidden
1232 bookmarks prevent a changeset being hidden
1225
1233
1226 $ hg bookmark --hidden -r 1 X
1234 $ hg bookmark --hidden -r 1 X
1227 $ hg log --template '{rev}:{node}\n'
1235 $ hg log --template '{rev}:{node}\n'
1228 1:a765632148dc55d38c35c4f247c618701886cb2f
1236 1:a765632148dc55d38c35c4f247c618701886cb2f
1229 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1237 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1230 $ hg bookmark -d X
1238 $ hg bookmark -d X
1231
1239
1232 divergent bookmarks are not hidden
1240 divergent bookmarks are not hidden
1233
1241
1234 $ hg bookmark --hidden -r 1 X@foo
1242 $ hg bookmark --hidden -r 1 X@foo
1235 $ hg log --template '{rev}:{node}\n'
1243 $ hg log --template '{rev}:{node}\n'
1236 1:a765632148dc55d38c35c4f247c618701886cb2f
1244 1:a765632148dc55d38c35c4f247c618701886cb2f
1237 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1245 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1238
1246
1239 clear extensions configuration
1247 clear extensions configuration
1240 $ echo '[extensions]' >> $HGRCPATH
1248 $ echo '[extensions]' >> $HGRCPATH
1241 $ echo "obs=!" >> $HGRCPATH
1249 $ echo "obs=!" >> $HGRCPATH
1242 $ cd ..
1250 $ cd ..
1243
1251
1244 test -u/-k for problematic encoding
1252 test -u/-k for problematic encoding
1245 # unicode: cp932:
1253 # unicode: cp932:
1246 # u30A2 0x83 0x41(= 'A')
1254 # u30A2 0x83 0x41(= 'A')
1247 # u30C2 0x83 0x61(= 'a')
1255 # u30C2 0x83 0x61(= 'a')
1248
1256
1249 $ hg init problematicencoding
1257 $ hg init problematicencoding
1250 $ cd problematicencoding
1258 $ cd problematicencoding
1251
1259
1252 $ python > setup.sh <<EOF
1260 $ python > setup.sh <<EOF
1253 > print u'''
1261 > print u'''
1254 > echo a > text
1262 > echo a > text
1255 > hg add text
1263 > hg add text
1256 > hg --encoding utf-8 commit -u '\u30A2' -m none
1264 > hg --encoding utf-8 commit -u '\u30A2' -m none
1257 > echo b > text
1265 > echo b > text
1258 > hg --encoding utf-8 commit -u '\u30C2' -m none
1266 > hg --encoding utf-8 commit -u '\u30C2' -m none
1259 > echo c > text
1267 > echo c > text
1260 > hg --encoding utf-8 commit -u none -m '\u30A2'
1268 > hg --encoding utf-8 commit -u none -m '\u30A2'
1261 > echo d > text
1269 > echo d > text
1262 > hg --encoding utf-8 commit -u none -m '\u30C2'
1270 > hg --encoding utf-8 commit -u none -m '\u30C2'
1263 > '''.encode('utf-8')
1271 > '''.encode('utf-8')
1264 > EOF
1272 > EOF
1265 $ sh < setup.sh
1273 $ sh < setup.sh
1266
1274
1267 test in problematic encoding
1275 test in problematic encoding
1268 $ python > test.sh <<EOF
1276 $ python > test.sh <<EOF
1269 > print u'''
1277 > print u'''
1270 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1278 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1271 > echo ====
1279 > echo ====
1272 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1280 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1273 > echo ====
1281 > echo ====
1274 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1282 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1275 > echo ====
1283 > echo ====
1276 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1284 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1277 > '''.encode('cp932')
1285 > '''.encode('cp932')
1278 > EOF
1286 > EOF
1279 $ sh < test.sh
1287 $ sh < test.sh
1280 0
1288 0
1281 ====
1289 ====
1282 1
1290 1
1283 ====
1291 ====
1284 2
1292 2
1285 0
1293 0
1286 ====
1294 ====
1287 3
1295 3
1288 1
1296 1
1289
1297
1290 $ cd ..
1298 $ cd ..
1291
1299
1292 test hg log on non-existent files and on directories
1300 test hg log on non-existent files and on directories
1293 $ hg init issue1340
1301 $ hg init issue1340
1294 $ cd issue1340
1302 $ cd issue1340
1295 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1303 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1296 $ echo 1 > d1/f1
1304 $ echo 1 > d1/f1
1297 $ echo 1 > D2/f1
1305 $ echo 1 > D2/f1
1298 $ echo 1 > D3.i/f1
1306 $ echo 1 > D3.i/f1
1299 $ echo 1 > d4.hg/f1
1307 $ echo 1 > d4.hg/f1
1300 $ echo 1 > d5.d/f1
1308 $ echo 1 > d5.d/f1
1301 $ echo 1 > .d6/f1
1309 $ echo 1 > .d6/f1
1302 $ hg -q add .
1310 $ hg -q add .
1303 $ hg commit -m "a bunch of weird directories"
1311 $ hg commit -m "a bunch of weird directories"
1304 $ hg log -l1 d1/f1 | grep changeset
1312 $ hg log -l1 d1/f1 | grep changeset
1305 changeset: 0:65624cd9070a
1313 changeset: 0:65624cd9070a
1306 $ hg log -l1 f1
1314 $ hg log -l1 f1
1307 $ hg log -l1 . | grep changeset
1315 $ hg log -l1 . | grep changeset
1308 changeset: 0:65624cd9070a
1316 changeset: 0:65624cd9070a
1309 $ hg log -l1 ./ | grep changeset
1317 $ hg log -l1 ./ | grep changeset
1310 changeset: 0:65624cd9070a
1318 changeset: 0:65624cd9070a
1311 $ hg log -l1 d1 | grep changeset
1319 $ hg log -l1 d1 | grep changeset
1312 changeset: 0:65624cd9070a
1320 changeset: 0:65624cd9070a
1313 $ hg log -l1 D2 | grep changeset
1321 $ hg log -l1 D2 | grep changeset
1314 changeset: 0:65624cd9070a
1322 changeset: 0:65624cd9070a
1315 $ hg log -l1 D2/f1 | grep changeset
1323 $ hg log -l1 D2/f1 | grep changeset
1316 changeset: 0:65624cd9070a
1324 changeset: 0:65624cd9070a
1317 $ hg log -l1 D3.i | grep changeset
1325 $ hg log -l1 D3.i | grep changeset
1318 changeset: 0:65624cd9070a
1326 changeset: 0:65624cd9070a
1319 $ hg log -l1 D3.i/f1 | grep changeset
1327 $ hg log -l1 D3.i/f1 | grep changeset
1320 changeset: 0:65624cd9070a
1328 changeset: 0:65624cd9070a
1321 $ hg log -l1 d4.hg | grep changeset
1329 $ hg log -l1 d4.hg | grep changeset
1322 changeset: 0:65624cd9070a
1330 changeset: 0:65624cd9070a
1323 $ hg log -l1 d4.hg/f1 | grep changeset
1331 $ hg log -l1 d4.hg/f1 | grep changeset
1324 changeset: 0:65624cd9070a
1332 changeset: 0:65624cd9070a
1325 $ hg log -l1 d5.d | grep changeset
1333 $ hg log -l1 d5.d | grep changeset
1326 changeset: 0:65624cd9070a
1334 changeset: 0:65624cd9070a
1327 $ hg log -l1 d5.d/f1 | grep changeset
1335 $ hg log -l1 d5.d/f1 | grep changeset
1328 changeset: 0:65624cd9070a
1336 changeset: 0:65624cd9070a
1329 $ hg log -l1 .d6 | grep changeset
1337 $ hg log -l1 .d6 | grep changeset
1330 changeset: 0:65624cd9070a
1338 changeset: 0:65624cd9070a
1331 $ hg log -l1 .d6/f1 | grep changeset
1339 $ hg log -l1 .d6/f1 | grep changeset
1332 changeset: 0:65624cd9070a
1340 changeset: 0:65624cd9070a
1333
1341
1334 issue3772: hg log -r :null showing revision 0 as well
1342 issue3772: hg log -r :null showing revision 0 as well
1335
1343
1336 $ hg log -r :null
1344 $ hg log -r :null
1337 changeset: -1:000000000000
1345 changeset: -1:000000000000
1338 user:
1346 user:
1339 date: Thu Jan 01 00:00:00 1970 +0000
1347 date: Thu Jan 01 00:00:00 1970 +0000
1340
1348
1341 $ hg log -r null:null
1349 $ hg log -r null:null
1342 changeset: -1:000000000000
1350 changeset: -1:000000000000
1343 user:
1351 user:
1344 date: Thu Jan 01 00:00:00 1970 +0000
1352 date: Thu Jan 01 00:00:00 1970 +0000
1345
1353
1346
1354
1347 $ cd ..
1355 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now