##// END OF EJS Templates
py3: use dict.items() instead of dict.iteritems() in tests...
Pulkit Goyal -
r36345:58c1368a default
parent child Browse files
Show More
@@ -1,78 +1,78 b''
1 1 # extension to emulate invoking 'dirstate.write()' at the time
2 2 # specified by '[fakedirstatewritetime] fakenow', only when
3 3 # 'dirstate.write()' is invoked via functions below:
4 4 #
5 5 # - 'workingctx._poststatusfixup()' (= 'repo.status()')
6 6 # - 'committablectx.markcommitted()'
7 7
8 8 from __future__ import absolute_import
9 9
10 10 from mercurial import (
11 11 context,
12 12 dirstate,
13 13 extensions,
14 14 policy,
15 15 registrar,
16 16 util,
17 17 )
18 18
19 19 configtable = {}
20 20 configitem = registrar.configitem(configtable)
21 21
22 22 configitem(b'fakedirstatewritetime', b'fakenow',
23 23 default=None,
24 24 )
25 25
26 26 parsers = policy.importmod(r'parsers')
27 27
28 28 def pack_dirstate(fakenow, orig, dmap, copymap, pl, now):
29 29 # execute what original parsers.pack_dirstate should do actually
30 30 # for consistency
31 31 actualnow = int(now)
32 for f, e in dmap.iteritems():
32 for f, e in dmap.items():
33 33 if e[0] == 'n' and e[3] == actualnow:
34 34 e = parsers.dirstatetuple(e[0], e[1], e[2], -1)
35 35 dmap[f] = e
36 36
37 37 return orig(dmap, copymap, pl, fakenow)
38 38
39 39 def fakewrite(ui, func):
40 40 # fake "now" of 'pack_dirstate' only if it is invoked while 'func'
41 41
42 42 fakenow = ui.config(b'fakedirstatewritetime', b'fakenow')
43 43 if not fakenow:
44 44 # Execute original one, if fakenow isn't configured. This is
45 45 # useful to prevent subrepos from executing replaced one,
46 46 # because replacing 'parsers.pack_dirstate' is also effective
47 47 # in subrepos.
48 48 return func()
49 49
50 50 # parsing 'fakenow' in YYYYmmddHHMM format makes comparison between
51 51 # 'fakenow' value and 'touch -t YYYYmmddHHMM' argument easy
52 52 fakenow = util.parsedate(fakenow, [b'%Y%m%d%H%M'])[0]
53 53
54 54 orig_pack_dirstate = parsers.pack_dirstate
55 55 orig_dirstate_getfsnow = dirstate._getfsnow
56 56 wrapper = lambda *args: pack_dirstate(fakenow, orig_pack_dirstate, *args)
57 57
58 58 parsers.pack_dirstate = wrapper
59 59 dirstate._getfsnow = lambda *args: fakenow
60 60 try:
61 61 return func()
62 62 finally:
63 63 parsers.pack_dirstate = orig_pack_dirstate
64 64 dirstate._getfsnow = orig_dirstate_getfsnow
65 65
66 66 def _poststatusfixup(orig, workingctx, status, fixup):
67 67 ui = workingctx.repo().ui
68 68 return fakewrite(ui, lambda : orig(workingctx, status, fixup))
69 69
70 70 def markcommitted(orig, committablectx, node):
71 71 ui = committablectx.repo().ui
72 72 return fakewrite(ui, lambda : orig(committablectx, node))
73 73
74 74 def extsetup(ui):
75 75 extensions.wrapfunction(context.workingctx, '_poststatusfixup',
76 76 _poststatusfixup)
77 77 extensions.wrapfunction(context.committablectx, 'markcommitted',
78 78 markcommitted)
@@ -1,114 +1,114 b''
1 1 from __future__ import absolute_import, print_function
2 2
3 3 from mercurial import demandimport; demandimport.enable()
4 4 from mercurial import (
5 5 error,
6 6 ui as uimod,
7 7 url,
8 8 util,
9 9 )
10 10
11 11 urlerr = util.urlerr
12 12 urlreq = util.urlreq
13 13
14 14 class myui(uimod.ui):
15 15 def interactive(self):
16 16 return False
17 17
18 18 origui = myui.load()
19 19
20 20 def writeauth(items):
21 21 ui = origui.copy()
22 for name, value in items.iteritems():
22 for name, value in items.items():
23 23 ui.setconfig('auth', name, value)
24 24 return ui
25 25
26 26 def dumpdict(dict):
27 27 return '{' + ', '.join(['%s: %s' % (k, dict[k])
28 28 for k in sorted(dict)]) + '}'
29 29
30 30 def test(auth, urls=None):
31 31 print('CFG:', dumpdict(auth))
32 32 prefixes = set()
33 33 for k in auth:
34 34 prefixes.add(k.split('.', 1)[0])
35 35 for p in prefixes:
36 36 for name in ('.username', '.password'):
37 37 if (p + name) not in auth:
38 38 auth[p + name] = p
39 auth = dict((k, v) for k, v in auth.iteritems() if v is not None)
39 auth = dict((k, v) for k, v in auth.items() if v is not None)
40 40
41 41 ui = writeauth(auth)
42 42
43 43 def _test(uri):
44 44 print('URI:', uri)
45 45 try:
46 46 pm = url.passwordmgr(ui, urlreq.httppasswordmgrwithdefaultrealm())
47 47 u, authinfo = util.url(uri).authinfo()
48 48 if authinfo is not None:
49 49 pm.add_password(*authinfo)
50 50 print(' ', pm.find_user_password('test', u))
51 51 except error.Abort:
52 52 print(' ','abort')
53 53
54 54 if not urls:
55 55 urls = [
56 56 'http://example.org/foo',
57 57 'http://example.org/foo/bar',
58 58 'http://example.org/bar',
59 59 'https://example.org/foo',
60 60 'https://example.org/foo/bar',
61 61 'https://example.org/bar',
62 62 'https://x@example.org/bar',
63 63 'https://y@example.org/bar',
64 64 ]
65 65 for u in urls:
66 66 _test(u)
67 67
68 68
69 69 print('\n*** Test in-uri schemes\n')
70 70 test({'x.prefix': 'http://example.org'})
71 71 test({'x.prefix': 'https://example.org'})
72 72 test({'x.prefix': 'http://example.org', 'x.schemes': 'https'})
73 73 test({'x.prefix': 'https://example.org', 'x.schemes': 'http'})
74 74
75 75 print('\n*** Test separately configured schemes\n')
76 76 test({'x.prefix': 'example.org', 'x.schemes': 'http'})
77 77 test({'x.prefix': 'example.org', 'x.schemes': 'https'})
78 78 test({'x.prefix': 'example.org', 'x.schemes': 'http https'})
79 79
80 80 print('\n*** Test prefix matching\n')
81 81 test({'x.prefix': 'http://example.org/foo',
82 82 'y.prefix': 'http://example.org/bar'})
83 83 test({'x.prefix': 'http://example.org/foo',
84 84 'y.prefix': 'http://example.org/foo/bar'})
85 85 test({'x.prefix': '*', 'y.prefix': 'https://example.org/bar'})
86 86
87 87 print('\n*** Test user matching\n')
88 88 test({'x.prefix': 'http://example.org/foo',
89 89 'x.username': None,
90 90 'x.password': 'xpassword'},
91 91 urls=['http://y@example.org/foo'])
92 92 test({'x.prefix': 'http://example.org/foo',
93 93 'x.username': None,
94 94 'x.password': 'xpassword',
95 95 'y.prefix': 'http://example.org/foo',
96 96 'y.username': 'y',
97 97 'y.password': 'ypassword'},
98 98 urls=['http://y@example.org/foo'])
99 99 test({'x.prefix': 'http://example.org/foo/bar',
100 100 'x.username': None,
101 101 'x.password': 'xpassword',
102 102 'y.prefix': 'http://example.org/foo',
103 103 'y.username': 'y',
104 104 'y.password': 'ypassword'},
105 105 urls=['http://y@example.org/foo/bar'])
106 106
107 107 def testauthinfo(fullurl, authurl):
108 108 print('URIs:', fullurl, authurl)
109 109 pm = urlreq.httppasswordmgrwithdefaultrealm()
110 110 pm.add_password(*util.url(fullurl).authinfo()[1])
111 111 print(pm.find_user_password('test', authurl))
112 112
113 113 print('\n*** Test urllib2 and util.url\n')
114 114 testauthinfo('http://user@example.com:8080/foo', 'http://example.com:8080/foo')
@@ -1,2617 +1,2617 b''
1 1 Log on empty repository: checking consistency
2 2
3 3 $ hg init empty
4 4 $ cd empty
5 5 $ hg log
6 6 $ hg log -r 1
7 7 abort: unknown revision '1'!
8 8 [255]
9 9 $ hg log -r -1:0
10 10 abort: unknown revision '-1'!
11 11 [255]
12 12 $ hg log -r 'branch(name)'
13 13 abort: unknown revision 'name'!
14 14 [255]
15 15 $ hg log -r null -q
16 16 -1:000000000000
17 17
18 18 $ cd ..
19 19
20 20 The g is crafted to have 2 filelog topological heads in a linear
21 21 changeset graph
22 22
23 23 $ hg init a
24 24 $ cd a
25 25 $ echo a > a
26 26 $ echo f > f
27 27 $ hg ci -Ama -d '1 0'
28 28 adding a
29 29 adding f
30 30
31 31 $ hg cp a b
32 32 $ hg cp f g
33 33 $ hg ci -mb -d '2 0'
34 34
35 35 $ mkdir dir
36 36 $ hg mv b dir
37 37 $ echo g >> g
38 38 $ echo f >> f
39 39 $ hg ci -mc -d '3 0'
40 40
41 41 $ hg mv a b
42 42 $ hg cp -f f g
43 43 $ echo a > d
44 44 $ hg add d
45 45 $ hg ci -md -d '4 0'
46 46
47 47 $ hg mv dir/b e
48 48 $ hg ci -me -d '5 0'
49 49
50 50 Make sure largefiles doesn't interfere with logging a regular file
51 51 $ hg --debug log a -T '{rev}: {desc}\n' --config extensions.largefiles=
52 52 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
53 53 updated patterns: .hglf/a, a
54 54 0: a
55 55 $ hg log a
56 56 changeset: 0:9161b9aeaf16
57 57 user: test
58 58 date: Thu Jan 01 00:00:01 1970 +0000
59 59 summary: a
60 60
61 61 $ hg log glob:a*
62 62 changeset: 3:2ca5ba701980
63 63 user: test
64 64 date: Thu Jan 01 00:00:04 1970 +0000
65 65 summary: d
66 66
67 67 changeset: 0:9161b9aeaf16
68 68 user: test
69 69 date: Thu Jan 01 00:00:01 1970 +0000
70 70 summary: a
71 71
72 72 $ hg --debug log glob:a* -T '{rev}: {desc}\n' --config extensions.largefiles=
73 73 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
74 74 updated patterns: glob:.hglf/a*, glob:a*
75 75 3: d
76 76 0: a
77 77
78 78 log on directory
79 79
80 80 $ hg log dir
81 81 changeset: 4:7e4639b4691b
82 82 tag: tip
83 83 user: test
84 84 date: Thu Jan 01 00:00:05 1970 +0000
85 85 summary: e
86 86
87 87 changeset: 2:f8954cd4dc1f
88 88 user: test
89 89 date: Thu Jan 01 00:00:03 1970 +0000
90 90 summary: c
91 91
92 92 $ hg log somethingthatdoesntexist dir
93 93 changeset: 4:7e4639b4691b
94 94 tag: tip
95 95 user: test
96 96 date: Thu Jan 01 00:00:05 1970 +0000
97 97 summary: e
98 98
99 99 changeset: 2:f8954cd4dc1f
100 100 user: test
101 101 date: Thu Jan 01 00:00:03 1970 +0000
102 102 summary: c
103 103
104 104
105 105 -X, with explicit path
106 106
107 107 $ hg log a -X a
108 108
109 109 -f, non-existent directory
110 110
111 111 $ hg log -f dir
112 112 abort: cannot follow file not in parent revision: "dir"
113 113 [255]
114 114
115 115 -f, directory
116 116
117 117 $ hg up -q 3
118 118 $ hg log -f dir
119 119 changeset: 2:f8954cd4dc1f
120 120 user: test
121 121 date: Thu Jan 01 00:00:03 1970 +0000
122 122 summary: c
123 123
124 124 -f, directory with --patch
125 125
126 126 $ hg log -f dir -p
127 127 changeset: 2:f8954cd4dc1f
128 128 user: test
129 129 date: Thu Jan 01 00:00:03 1970 +0000
130 130 summary: c
131 131
132 132 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
133 133 --- /dev/null* (glob)
134 134 +++ b/dir/b* (glob)
135 135 @@ -0,0 +1,1 @@
136 136 +a
137 137
138 138
139 139 -f, pattern
140 140
141 141 $ hg log -f -I 'dir**' -p
142 142 changeset: 2:f8954cd4dc1f
143 143 user: test
144 144 date: Thu Jan 01 00:00:03 1970 +0000
145 145 summary: c
146 146
147 147 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
148 148 --- /dev/null* (glob)
149 149 +++ b/dir/b* (glob)
150 150 @@ -0,0 +1,1 @@
151 151 +a
152 152
153 153 $ hg up -q 4
154 154
155 155 -f, a wrong style
156 156
157 157 $ hg log -f -l1 --style something
158 158 abort: style 'something' not found
159 159 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
160 160 [255]
161 161
162 162 -f, phases style
163 163
164 164
165 165 $ hg log -f -l1 --style phases
166 166 changeset: 4:7e4639b4691b
167 167 tag: tip
168 168 phase: draft
169 169 user: test
170 170 date: Thu Jan 01 00:00:05 1970 +0000
171 171 summary: e
172 172
173 173
174 174 $ hg log -f -l1 --style phases -q
175 175 4:7e4639b4691b
176 176
177 177 -f, but no args
178 178
179 179 $ hg log -f
180 180 changeset: 4:7e4639b4691b
181 181 tag: tip
182 182 user: test
183 183 date: Thu Jan 01 00:00:05 1970 +0000
184 184 summary: e
185 185
186 186 changeset: 3:2ca5ba701980
187 187 user: test
188 188 date: Thu Jan 01 00:00:04 1970 +0000
189 189 summary: d
190 190
191 191 changeset: 2:f8954cd4dc1f
192 192 user: test
193 193 date: Thu Jan 01 00:00:03 1970 +0000
194 194 summary: c
195 195
196 196 changeset: 1:d89b0a12d229
197 197 user: test
198 198 date: Thu Jan 01 00:00:02 1970 +0000
199 199 summary: b
200 200
201 201 changeset: 0:9161b9aeaf16
202 202 user: test
203 203 date: Thu Jan 01 00:00:01 1970 +0000
204 204 summary: a
205 205
206 206
207 207 one rename
208 208
209 209 $ hg up -q 2
210 210 $ hg log -vf a
211 211 changeset: 0:9161b9aeaf16
212 212 user: test
213 213 date: Thu Jan 01 00:00:01 1970 +0000
214 214 files: a f
215 215 description:
216 216 a
217 217
218 218
219 219
220 220 many renames
221 221
222 222 $ hg up -q tip
223 223 $ hg log -vf e
224 224 changeset: 4:7e4639b4691b
225 225 tag: tip
226 226 user: test
227 227 date: Thu Jan 01 00:00:05 1970 +0000
228 228 files: dir/b e
229 229 description:
230 230 e
231 231
232 232
233 233 changeset: 2:f8954cd4dc1f
234 234 user: test
235 235 date: Thu Jan 01 00:00:03 1970 +0000
236 236 files: b dir/b f g
237 237 description:
238 238 c
239 239
240 240
241 241 changeset: 1:d89b0a12d229
242 242 user: test
243 243 date: Thu Jan 01 00:00:02 1970 +0000
244 244 files: b g
245 245 description:
246 246 b
247 247
248 248
249 249 changeset: 0:9161b9aeaf16
250 250 user: test
251 251 date: Thu Jan 01 00:00:01 1970 +0000
252 252 files: a f
253 253 description:
254 254 a
255 255
256 256
257 257
258 258
259 259 log -pf dir/b
260 260
261 261 $ hg up -q 3
262 262 $ hg log -pf dir/b
263 263 changeset: 2:f8954cd4dc1f
264 264 user: test
265 265 date: Thu Jan 01 00:00:03 1970 +0000
266 266 summary: c
267 267
268 268 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
269 269 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
270 270 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
271 271 @@ -0,0 +1,1 @@
272 272 +a
273 273
274 274 changeset: 1:d89b0a12d229
275 275 user: test
276 276 date: Thu Jan 01 00:00:02 1970 +0000
277 277 summary: b
278 278
279 279 diff -r 9161b9aeaf16 -r d89b0a12d229 b
280 280 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
281 281 +++ b/b Thu Jan 01 00:00:02 1970 +0000
282 282 @@ -0,0 +1,1 @@
283 283 +a
284 284
285 285 changeset: 0:9161b9aeaf16
286 286 user: test
287 287 date: Thu Jan 01 00:00:01 1970 +0000
288 288 summary: a
289 289
290 290 diff -r 000000000000 -r 9161b9aeaf16 a
291 291 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
292 292 +++ b/a Thu Jan 01 00:00:01 1970 +0000
293 293 @@ -0,0 +1,1 @@
294 294 +a
295 295
296 296
297 297 log -pf b inside dir
298 298
299 299 $ hg --cwd=dir log -pf b
300 300 changeset: 2:f8954cd4dc1f
301 301 user: test
302 302 date: Thu Jan 01 00:00:03 1970 +0000
303 303 summary: c
304 304
305 305 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
306 306 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
307 307 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
308 308 @@ -0,0 +1,1 @@
309 309 +a
310 310
311 311 changeset: 1:d89b0a12d229
312 312 user: test
313 313 date: Thu Jan 01 00:00:02 1970 +0000
314 314 summary: b
315 315
316 316 diff -r 9161b9aeaf16 -r d89b0a12d229 b
317 317 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
318 318 +++ b/b Thu Jan 01 00:00:02 1970 +0000
319 319 @@ -0,0 +1,1 @@
320 320 +a
321 321
322 322 changeset: 0:9161b9aeaf16
323 323 user: test
324 324 date: Thu Jan 01 00:00:01 1970 +0000
325 325 summary: a
326 326
327 327 diff -r 000000000000 -r 9161b9aeaf16 a
328 328 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
329 329 +++ b/a Thu Jan 01 00:00:01 1970 +0000
330 330 @@ -0,0 +1,1 @@
331 331 +a
332 332
333 333
334 334 log -pf, but no args
335 335
336 336 $ hg log -pf
337 337 changeset: 3:2ca5ba701980
338 338 user: test
339 339 date: Thu Jan 01 00:00:04 1970 +0000
340 340 summary: d
341 341
342 342 diff -r f8954cd4dc1f -r 2ca5ba701980 a
343 343 --- a/a Thu Jan 01 00:00:03 1970 +0000
344 344 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
345 345 @@ -1,1 +0,0 @@
346 346 -a
347 347 diff -r f8954cd4dc1f -r 2ca5ba701980 b
348 348 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
349 349 +++ b/b Thu Jan 01 00:00:04 1970 +0000
350 350 @@ -0,0 +1,1 @@
351 351 +a
352 352 diff -r f8954cd4dc1f -r 2ca5ba701980 d
353 353 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
354 354 +++ b/d Thu Jan 01 00:00:04 1970 +0000
355 355 @@ -0,0 +1,1 @@
356 356 +a
357 357 diff -r f8954cd4dc1f -r 2ca5ba701980 g
358 358 --- a/g Thu Jan 01 00:00:03 1970 +0000
359 359 +++ b/g Thu Jan 01 00:00:04 1970 +0000
360 360 @@ -1,2 +1,2 @@
361 361 f
362 362 -g
363 363 +f
364 364
365 365 changeset: 2:f8954cd4dc1f
366 366 user: test
367 367 date: Thu Jan 01 00:00:03 1970 +0000
368 368 summary: c
369 369
370 370 diff -r d89b0a12d229 -r f8954cd4dc1f b
371 371 --- a/b Thu Jan 01 00:00:02 1970 +0000
372 372 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
373 373 @@ -1,1 +0,0 @@
374 374 -a
375 375 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
376 376 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
377 377 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
378 378 @@ -0,0 +1,1 @@
379 379 +a
380 380 diff -r d89b0a12d229 -r f8954cd4dc1f f
381 381 --- a/f Thu Jan 01 00:00:02 1970 +0000
382 382 +++ b/f Thu Jan 01 00:00:03 1970 +0000
383 383 @@ -1,1 +1,2 @@
384 384 f
385 385 +f
386 386 diff -r d89b0a12d229 -r f8954cd4dc1f g
387 387 --- a/g Thu Jan 01 00:00:02 1970 +0000
388 388 +++ b/g Thu Jan 01 00:00:03 1970 +0000
389 389 @@ -1,1 +1,2 @@
390 390 f
391 391 +g
392 392
393 393 changeset: 1:d89b0a12d229
394 394 user: test
395 395 date: Thu Jan 01 00:00:02 1970 +0000
396 396 summary: b
397 397
398 398 diff -r 9161b9aeaf16 -r d89b0a12d229 b
399 399 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
400 400 +++ b/b Thu Jan 01 00:00:02 1970 +0000
401 401 @@ -0,0 +1,1 @@
402 402 +a
403 403 diff -r 9161b9aeaf16 -r d89b0a12d229 g
404 404 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
405 405 +++ b/g Thu Jan 01 00:00:02 1970 +0000
406 406 @@ -0,0 +1,1 @@
407 407 +f
408 408
409 409 changeset: 0:9161b9aeaf16
410 410 user: test
411 411 date: Thu Jan 01 00:00:01 1970 +0000
412 412 summary: a
413 413
414 414 diff -r 000000000000 -r 9161b9aeaf16 a
415 415 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
416 416 +++ b/a Thu Jan 01 00:00:01 1970 +0000
417 417 @@ -0,0 +1,1 @@
418 418 +a
419 419 diff -r 000000000000 -r 9161b9aeaf16 f
420 420 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
421 421 +++ b/f Thu Jan 01 00:00:01 1970 +0000
422 422 @@ -0,0 +1,1 @@
423 423 +f
424 424
425 425
426 426 log -vf dir/b
427 427
428 428 $ hg log -vf dir/b
429 429 changeset: 2:f8954cd4dc1f
430 430 user: test
431 431 date: Thu Jan 01 00:00:03 1970 +0000
432 432 files: b dir/b f g
433 433 description:
434 434 c
435 435
436 436
437 437 changeset: 1:d89b0a12d229
438 438 user: test
439 439 date: Thu Jan 01 00:00:02 1970 +0000
440 440 files: b g
441 441 description:
442 442 b
443 443
444 444
445 445 changeset: 0:9161b9aeaf16
446 446 user: test
447 447 date: Thu Jan 01 00:00:01 1970 +0000
448 448 files: a f
449 449 description:
450 450 a
451 451
452 452
453 453
454 454
455 455 -f and multiple filelog heads
456 456
457 457 $ hg up -q 2
458 458 $ hg log -f g --template '{rev}\n'
459 459 2
460 460 1
461 461 0
462 462 $ hg up -q tip
463 463 $ hg log -f g --template '{rev}\n'
464 464 3
465 465 2
466 466 0
467 467
468 468 follow files from the specified revisions (issue4959)
469 469
470 470 $ hg log -G -T '{rev} {files},{file_copies % " {source}->{name}"}\n'
471 471 @ 4 dir/b e, dir/b->e
472 472 |
473 473 o 3 a b d g, a->b f->g
474 474 |
475 475 o 2 b dir/b f g, b->dir/b
476 476 |
477 477 o 1 b g, a->b f->g
478 478 |
479 479 o 0 a f,
480 480
481 481
482 482 $ hg log -T '{rev}\n' -fr 4 e
483 483 4
484 484 2
485 485 1
486 486 0
487 487 $ hg log -T '{rev}\n' -fr 2 g
488 488 2
489 489 1
490 490 0
491 491 $ hg log -T '{rev}\n' -fr '2+3' g
492 492 3
493 493 2
494 494 1
495 495 0
496 496
497 497 follow files from the specified revisions with glob patterns (issue5053)
498 498 (BROKEN: should follow copies from e@4)
499 499
500 500 $ hg log -T '{rev}\n' -fr4 e -X '[abcdfg]'
501 501 4
502 502 2 (false !)
503 503 1 (false !)
504 504 0 (false !)
505 505
506 506 follow files from the specified revisions with missing patterns
507 507 (BROKEN: should follow copies from e@4)
508 508
509 509 $ hg log -T '{rev}\n' -fr4 e x
510 510 4
511 511 2 (false !)
512 512 1 (false !)
513 513 0 (false !)
514 514
515 515 follow files from the specified revisions across copies with -p/--patch
516 516
517 517 $ hg log -T '== rev: {rev},{file_copies % " {source}->{name}"} ==\n' -fpr 4 e g
518 518 == rev: 4, dir/b->e ==
519 519 diff -r 2ca5ba701980 -r 7e4639b4691b e
520 520 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
521 521 +++ b/e Thu Jan 01 00:00:05 1970 +0000
522 522 @@ -0,0 +1,1 @@
523 523 +a
524 524
525 525 == rev: 3, a->b f->g ==
526 526 diff -r f8954cd4dc1f -r 2ca5ba701980 g
527 527 --- a/g Thu Jan 01 00:00:03 1970 +0000
528 528 +++ b/g Thu Jan 01 00:00:04 1970 +0000
529 529 @@ -1,2 +1,2 @@
530 530 f
531 531 -g
532 532 +f
533 533
534 534 == rev: 2, b->dir/b ==
535 535 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
536 536 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
537 537 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
538 538 @@ -0,0 +1,1 @@
539 539 +a
540 540 diff -r d89b0a12d229 -r f8954cd4dc1f f
541 541 --- a/f Thu Jan 01 00:00:02 1970 +0000
542 542 +++ b/f Thu Jan 01 00:00:03 1970 +0000
543 543 @@ -1,1 +1,2 @@
544 544 f
545 545 +f
546 546
547 547 == rev: 1, a->b f->g ==
548 548 diff -r 9161b9aeaf16 -r d89b0a12d229 b
549 549 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
550 550 +++ b/b Thu Jan 01 00:00:02 1970 +0000
551 551 @@ -0,0 +1,1 @@
552 552 +a
553 553
554 554 == rev: 0, ==
555 555 diff -r 000000000000 -r 9161b9aeaf16 a
556 556 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
557 557 +++ b/a Thu Jan 01 00:00:01 1970 +0000
558 558 @@ -0,0 +1,1 @@
559 559 +a
560 560 diff -r 000000000000 -r 9161b9aeaf16 f
561 561 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
562 562 +++ b/f Thu Jan 01 00:00:01 1970 +0000
563 563 @@ -0,0 +1,1 @@
564 564 +f
565 565
566 566
567 567 log copies with --copies
568 568
569 569 $ hg log -vC --template '{rev} {file_copies}\n'
570 570 4 e (dir/b)
571 571 3 b (a)g (f)
572 572 2 dir/b (b)
573 573 1 b (a)g (f)
574 574 0
575 575
576 576 log copies switch without --copies, with old filecopy template
577 577
578 578 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
579 579 4
580 580 3
581 581 2
582 582 1
583 583 0
584 584
585 585 log copies switch with --copies
586 586
587 587 $ hg log -vC --template '{rev} {file_copies_switch}\n'
588 588 4 e (dir/b)
589 589 3 b (a)g (f)
590 590 2 dir/b (b)
591 591 1 b (a)g (f)
592 592 0
593 593
594 594
595 595 log copies with hardcoded style and with --style=default
596 596
597 597 $ hg log -vC -r4
598 598 changeset: 4:7e4639b4691b
599 599 tag: tip
600 600 user: test
601 601 date: Thu Jan 01 00:00:05 1970 +0000
602 602 files: dir/b e
603 603 copies: e (dir/b)
604 604 description:
605 605 e
606 606
607 607
608 608 $ hg log -vC -r4 --style=default
609 609 changeset: 4:7e4639b4691b
610 610 tag: tip
611 611 user: test
612 612 date: Thu Jan 01 00:00:05 1970 +0000
613 613 files: dir/b e
614 614 copies: e (dir/b)
615 615 description:
616 616 e
617 617
618 618
619 619 $ hg log -vC -r4 -Tjson
620 620 [
621 621 {
622 622 "rev": 4,
623 623 "node": "7e4639b4691b9f84b81036a8d4fb218ce3c5e3a3",
624 624 "branch": "default",
625 625 "phase": "draft",
626 626 "user": "test",
627 627 "date": [5, 0],
628 628 "desc": "e",
629 629 "bookmarks": [],
630 630 "tags": ["tip"],
631 631 "parents": ["2ca5ba7019804f1f597249caddf22a64d34df0ba"],
632 632 "files": ["dir/b", "e"],
633 633 "copies": {"e": "dir/b"}
634 634 }
635 635 ]
636 636
637 637 log copies, non-linear manifest
638 638
639 639 $ hg up -C 3
640 640 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
641 641 $ hg mv dir/b e
642 642 $ echo foo > foo
643 643 $ hg ci -Ame2 -d '6 0'
644 644 adding foo
645 645 created new head
646 646 $ hg log -v --template '{rev} {file_copies}\n' -r 5
647 647 5 e (dir/b)
648 648
649 649
650 650 log copies, execute bit set
651 651
652 652 #if execbit
653 653 $ chmod +x e
654 654 $ hg ci -me3 -d '7 0'
655 655 $ hg log -v --template '{rev} {file_copies}\n' -r 6
656 656 6
657 657 #endif
658 658
659 659
660 660 log -p d
661 661
662 662 $ hg log -pv d
663 663 changeset: 3:2ca5ba701980
664 664 user: test
665 665 date: Thu Jan 01 00:00:04 1970 +0000
666 666 files: a b d g
667 667 description:
668 668 d
669 669
670 670
671 671 diff -r f8954cd4dc1f -r 2ca5ba701980 d
672 672 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
673 673 +++ b/d Thu Jan 01 00:00:04 1970 +0000
674 674 @@ -0,0 +1,1 @@
675 675 +a
676 676
677 677
678 678
679 679 log --removed file
680 680
681 681 $ hg log --removed -v a
682 682 changeset: 3:2ca5ba701980
683 683 user: test
684 684 date: Thu Jan 01 00:00:04 1970 +0000
685 685 files: a b d g
686 686 description:
687 687 d
688 688
689 689
690 690 changeset: 0:9161b9aeaf16
691 691 user: test
692 692 date: Thu Jan 01 00:00:01 1970 +0000
693 693 files: a f
694 694 description:
695 695 a
696 696
697 697
698 698
699 699 log --removed revrange file
700 700
701 701 $ hg log --removed -v -r0:2 a
702 702 changeset: 0:9161b9aeaf16
703 703 user: test
704 704 date: Thu Jan 01 00:00:01 1970 +0000
705 705 files: a f
706 706 description:
707 707 a
708 708
709 709
710 710 $ cd ..
711 711
712 712 log --follow tests
713 713
714 714 $ hg init follow
715 715 $ cd follow
716 716
717 717 $ echo base > base
718 718 $ hg ci -Ambase -d '1 0'
719 719 adding base
720 720
721 721 $ echo r1 >> base
722 722 $ hg ci -Amr1 -d '1 0'
723 723 $ echo r2 >> base
724 724 $ hg ci -Amr2 -d '1 0'
725 725
726 726 $ hg up -C 1
727 727 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
728 728 $ echo b1 > b1
729 729
730 730 log -r "follow('set:clean()')"
731 731
732 732 $ hg log -r "follow('set:clean()')"
733 733 changeset: 0:67e992f2c4f3
734 734 user: test
735 735 date: Thu Jan 01 00:00:01 1970 +0000
736 736 summary: base
737 737
738 738 changeset: 1:3d5bf5654eda
739 739 user: test
740 740 date: Thu Jan 01 00:00:01 1970 +0000
741 741 summary: r1
742 742
743 743
744 744 $ hg ci -Amb1 -d '1 0'
745 745 adding b1
746 746 created new head
747 747
748 748
749 749 log -f
750 750
751 751 $ hg log -f
752 752 changeset: 3:e62f78d544b4
753 753 tag: tip
754 754 parent: 1:3d5bf5654eda
755 755 user: test
756 756 date: Thu Jan 01 00:00:01 1970 +0000
757 757 summary: b1
758 758
759 759 changeset: 1:3d5bf5654eda
760 760 user: test
761 761 date: Thu Jan 01 00:00:01 1970 +0000
762 762 summary: r1
763 763
764 764 changeset: 0:67e992f2c4f3
765 765 user: test
766 766 date: Thu Jan 01 00:00:01 1970 +0000
767 767 summary: base
768 768
769 769
770 770 log -r follow('glob:b*')
771 771
772 772 $ hg log -r "follow('glob:b*')"
773 773 changeset: 0:67e992f2c4f3
774 774 user: test
775 775 date: Thu Jan 01 00:00:01 1970 +0000
776 776 summary: base
777 777
778 778 changeset: 1:3d5bf5654eda
779 779 user: test
780 780 date: Thu Jan 01 00:00:01 1970 +0000
781 781 summary: r1
782 782
783 783 changeset: 3:e62f78d544b4
784 784 tag: tip
785 785 parent: 1:3d5bf5654eda
786 786 user: test
787 787 date: Thu Jan 01 00:00:01 1970 +0000
788 788 summary: b1
789 789
790 790 log -f -r '1 + 4'
791 791
792 792 $ hg up -C 0
793 793 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
794 794 $ echo b2 > b2
795 795 $ hg ci -Amb2 -d '1 0'
796 796 adding b2
797 797 created new head
798 798 $ hg log -f -r '1 + 4'
799 799 changeset: 4:ddb82e70d1a1
800 800 tag: tip
801 801 parent: 0:67e992f2c4f3
802 802 user: test
803 803 date: Thu Jan 01 00:00:01 1970 +0000
804 804 summary: b2
805 805
806 806 changeset: 1:3d5bf5654eda
807 807 user: test
808 808 date: Thu Jan 01 00:00:01 1970 +0000
809 809 summary: r1
810 810
811 811 changeset: 0:67e992f2c4f3
812 812 user: test
813 813 date: Thu Jan 01 00:00:01 1970 +0000
814 814 summary: base
815 815
816 816
817 817 log -fr with aliases: 'A' should be expanded, but 'reverse()' should have no
818 818 effect
819 819
820 820 $ hg log --config 'revsetalias.reverse(x)=x' --config 'revsetalias.A=1+4' -qfrA
821 821 4:ddb82e70d1a1
822 822 1:3d5bf5654eda
823 823 0:67e992f2c4f3
824 824
825 825 log -r "follow('set:grep(b2)')"
826 826
827 827 $ hg log -r "follow('set:grep(b2)')"
828 828 changeset: 4:ddb82e70d1a1
829 829 tag: tip
830 830 parent: 0:67e992f2c4f3
831 831 user: test
832 832 date: Thu Jan 01 00:00:01 1970 +0000
833 833 summary: b2
834 834
835 835 log -r "follow('set:grep(b2)', 4)"
836 836
837 837 $ hg up -qC 0
838 838 $ hg log -r "follow('set:grep(b2)', 4)"
839 839 changeset: 4:ddb82e70d1a1
840 840 tag: tip
841 841 parent: 0:67e992f2c4f3
842 842 user: test
843 843 date: Thu Jan 01 00:00:01 1970 +0000
844 844 summary: b2
845 845
846 846
847 847 follow files starting from multiple revisions:
848 848
849 849 $ hg log -T '{rev}: {files}\n' -r "follow('glob:b?', startrev=2+3+4)"
850 850 3: b1
851 851 4: b2
852 852
853 853 follow files starting from empty revision:
854 854
855 855 $ hg log -T '{rev}: {files}\n' -r "follow('glob:*', startrev=.-.)"
856 856
857 857 follow starting from revisions:
858 858
859 859 $ hg log -Gq -r "follow(startrev=2+4)"
860 860 o 4:ddb82e70d1a1
861 861 |
862 862 | o 2:60c670bf5b30
863 863 | |
864 864 | o 1:3d5bf5654eda
865 865 |/
866 866 @ 0:67e992f2c4f3
867 867
868 868
869 869 follow the current revision:
870 870
871 871 $ hg log -Gq -r "follow()"
872 872 @ 0:67e992f2c4f3
873 873
874 874
875 875 $ hg up -qC 4
876 876
877 877 log -f -r null
878 878
879 879 $ hg log -f -r null
880 880 changeset: -1:000000000000
881 881 user:
882 882 date: Thu Jan 01 00:00:00 1970 +0000
883 883
884 884 $ hg log -f -r null -G
885 885 o changeset: -1:000000000000
886 886 user:
887 887 date: Thu Jan 01 00:00:00 1970 +0000
888 888
889 889
890 890
891 891 log -f with null parent
892 892
893 893 $ hg up -C null
894 894 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
895 895 $ hg log -f
896 896
897 897
898 898 log -r . with two parents
899 899
900 900 $ hg up -C 3
901 901 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
902 902 $ hg merge tip
903 903 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
904 904 (branch merge, don't forget to commit)
905 905 $ hg log -r .
906 906 changeset: 3:e62f78d544b4
907 907 parent: 1:3d5bf5654eda
908 908 user: test
909 909 date: Thu Jan 01 00:00:01 1970 +0000
910 910 summary: b1
911 911
912 912
913 913
914 914 log -r . with one parent
915 915
916 916 $ hg ci -mm12 -d '1 0'
917 917 $ hg log -r .
918 918 changeset: 5:302e9dd6890d
919 919 tag: tip
920 920 parent: 3:e62f78d544b4
921 921 parent: 4:ddb82e70d1a1
922 922 user: test
923 923 date: Thu Jan 01 00:00:01 1970 +0000
924 924 summary: m12
925 925
926 926
927 927 $ echo postm >> b1
928 928 $ hg ci -Amb1.1 -d'1 0'
929 929
930 930
931 931 log --follow-first
932 932
933 933 $ hg log --follow-first
934 934 changeset: 6:2404bbcab562
935 935 tag: tip
936 936 user: test
937 937 date: Thu Jan 01 00:00:01 1970 +0000
938 938 summary: b1.1
939 939
940 940 changeset: 5:302e9dd6890d
941 941 parent: 3:e62f78d544b4
942 942 parent: 4:ddb82e70d1a1
943 943 user: test
944 944 date: Thu Jan 01 00:00:01 1970 +0000
945 945 summary: m12
946 946
947 947 changeset: 3:e62f78d544b4
948 948 parent: 1:3d5bf5654eda
949 949 user: test
950 950 date: Thu Jan 01 00:00:01 1970 +0000
951 951 summary: b1
952 952
953 953 changeset: 1:3d5bf5654eda
954 954 user: test
955 955 date: Thu Jan 01 00:00:01 1970 +0000
956 956 summary: r1
957 957
958 958 changeset: 0:67e992f2c4f3
959 959 user: test
960 960 date: Thu Jan 01 00:00:01 1970 +0000
961 961 summary: base
962 962
963 963
964 964
965 965 log -P 2
966 966
967 967 $ hg log -P 2
968 968 changeset: 6:2404bbcab562
969 969 tag: tip
970 970 user: test
971 971 date: Thu Jan 01 00:00:01 1970 +0000
972 972 summary: b1.1
973 973
974 974 changeset: 5:302e9dd6890d
975 975 parent: 3:e62f78d544b4
976 976 parent: 4:ddb82e70d1a1
977 977 user: test
978 978 date: Thu Jan 01 00:00:01 1970 +0000
979 979 summary: m12
980 980
981 981 changeset: 4:ddb82e70d1a1
982 982 parent: 0:67e992f2c4f3
983 983 user: test
984 984 date: Thu Jan 01 00:00:01 1970 +0000
985 985 summary: b2
986 986
987 987 changeset: 3:e62f78d544b4
988 988 parent: 1:3d5bf5654eda
989 989 user: test
990 990 date: Thu Jan 01 00:00:01 1970 +0000
991 991 summary: b1
992 992
993 993
994 994
995 995 log -r tip -p --git
996 996
997 997 $ hg log -r tip -p --git
998 998 changeset: 6:2404bbcab562
999 999 tag: tip
1000 1000 user: test
1001 1001 date: Thu Jan 01 00:00:01 1970 +0000
1002 1002 summary: b1.1
1003 1003
1004 1004 diff --git a/b1 b/b1
1005 1005 --- a/b1
1006 1006 +++ b/b1
1007 1007 @@ -1,1 +1,2 @@
1008 1008 b1
1009 1009 +postm
1010 1010
1011 1011
1012 1012
1013 1013 log -r ""
1014 1014
1015 1015 $ hg log -r ''
1016 1016 hg: parse error: empty query
1017 1017 [255]
1018 1018
1019 1019 log -r <some unknown node id>
1020 1020
1021 1021 $ hg log -r 1000000000000000000000000000000000000000
1022 1022 abort: unknown revision '1000000000000000000000000000000000000000'!
1023 1023 [255]
1024 1024
1025 1025 log -k r1
1026 1026
1027 1027 $ hg log -k r1
1028 1028 changeset: 1:3d5bf5654eda
1029 1029 user: test
1030 1030 date: Thu Jan 01 00:00:01 1970 +0000
1031 1031 summary: r1
1032 1032
1033 1033 log -p -l2 --color=always
1034 1034
1035 1035 $ hg --config extensions.color= --config color.mode=ansi \
1036 1036 > log -p -l2 --color=always
1037 1037 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
1038 1038 tag: tip
1039 1039 user: test
1040 1040 date: Thu Jan 01 00:00:01 1970 +0000
1041 1041 summary: b1.1
1042 1042
1043 1043 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
1044 1044 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1045 1045 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1046 1046 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
1047 1047 b1
1048 1048 \x1b[0;32m+postm\x1b[0m (esc)
1049 1049
1050 1050 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
1051 1051 parent: 3:e62f78d544b4
1052 1052 parent: 4:ddb82e70d1a1
1053 1053 user: test
1054 1054 date: Thu Jan 01 00:00:01 1970 +0000
1055 1055 summary: m12
1056 1056
1057 1057 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
1058 1058 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
1059 1059 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1060 1060 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
1061 1061 \x1b[0;32m+b2\x1b[0m (esc)
1062 1062
1063 1063
1064 1064
1065 1065 log -r tip --stat
1066 1066
1067 1067 $ hg log -r tip --stat
1068 1068 changeset: 6:2404bbcab562
1069 1069 tag: tip
1070 1070 user: test
1071 1071 date: Thu Jan 01 00:00:01 1970 +0000
1072 1072 summary: b1.1
1073 1073
1074 1074 b1 | 1 +
1075 1075 1 files changed, 1 insertions(+), 0 deletions(-)
1076 1076
1077 1077
1078 1078 $ cd ..
1079 1079
1080 1080 log --follow --patch FILE in repository where linkrev isn't trustworthy
1081 1081 (issue5376)
1082 1082
1083 1083 $ hg init follow-dup
1084 1084 $ cd follow-dup
1085 1085 $ cat <<EOF >> .hg/hgrc
1086 1086 > [ui]
1087 1087 > logtemplate = '=== {rev}: {desc}\n'
1088 1088 > [diff]
1089 1089 > nodates = True
1090 1090 > EOF
1091 1091 $ echo 0 >> a
1092 1092 $ hg ci -qAm 'a0'
1093 1093 $ echo 1 >> a
1094 1094 $ hg ci -m 'a1'
1095 1095 $ hg up -q 0
1096 1096 $ echo 1 >> a
1097 1097 $ touch b
1098 1098 $ hg ci -qAm 'a1 with b'
1099 1099 $ echo 3 >> a
1100 1100 $ hg ci -m 'a3'
1101 1101
1102 1102 fctx.rev() == 2, but fctx.linkrev() == 1
1103 1103
1104 1104 $ hg log -pf a
1105 1105 === 3: a3
1106 1106 diff -r 4ea02ba94d66 -r e7a6331a34f0 a
1107 1107 --- a/a
1108 1108 +++ b/a
1109 1109 @@ -1,2 +1,3 @@
1110 1110 0
1111 1111 1
1112 1112 +3
1113 1113
1114 1114 === 2: a1 with b
1115 1115 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
1116 1116 --- a/a
1117 1117 +++ b/a
1118 1118 @@ -1,1 +1,2 @@
1119 1119 0
1120 1120 +1
1121 1121
1122 1122 === 0: a0
1123 1123 diff -r 000000000000 -r 49b5e81287e2 a
1124 1124 --- /dev/null
1125 1125 +++ b/a
1126 1126 @@ -0,0 +1,1 @@
1127 1127 +0
1128 1128
1129 1129
1130 1130 fctx.introrev() == 2, but fctx.linkrev() == 1
1131 1131
1132 1132 $ hg up -q 2
1133 1133 $ hg log -pf a
1134 1134 === 2: a1 with b
1135 1135 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
1136 1136 --- a/a
1137 1137 +++ b/a
1138 1138 @@ -1,1 +1,2 @@
1139 1139 0
1140 1140 +1
1141 1141
1142 1142 === 0: a0
1143 1143 diff -r 000000000000 -r 49b5e81287e2 a
1144 1144 --- /dev/null
1145 1145 +++ b/a
1146 1146 @@ -0,0 +1,1 @@
1147 1147 +0
1148 1148
1149 1149
1150 1150 $ cd ..
1151 1151
1152 1152 Multiple copy sources of a file:
1153 1153
1154 1154 $ hg init follow-multi
1155 1155 $ cd follow-multi
1156 1156 $ echo 0 >> a
1157 1157 $ hg ci -qAm 'a'
1158 1158 $ hg cp a b
1159 1159 $ hg ci -m 'a->b'
1160 1160 $ echo 2 >> a
1161 1161 $ hg ci -m 'a'
1162 1162 $ echo 3 >> b
1163 1163 $ hg ci -m 'b'
1164 1164 $ echo 4 >> a
1165 1165 $ echo 4 >> b
1166 1166 $ hg ci -m 'a,b'
1167 1167 $ echo 5 >> a
1168 1168 $ hg ci -m 'a0'
1169 1169 $ echo 6 >> b
1170 1170 $ hg ci -m 'b0'
1171 1171 $ hg up -q 4
1172 1172 $ echo 7 >> b
1173 1173 $ hg ci -m 'b1'
1174 1174 created new head
1175 1175 $ echo 8 >> a
1176 1176 $ hg ci -m 'a1'
1177 1177 $ hg rm a
1178 1178 $ hg mv b a
1179 1179 $ hg ci -m 'b1->a1'
1180 1180 $ hg merge -qt :local
1181 1181 $ hg ci -m '(a0,b1->a1)->a'
1182 1182
1183 1183 $ hg log -GT '{rev}: {desc}\n'
1184 1184 @ 10: (a0,b1->a1)->a
1185 1185 |\
1186 1186 | o 9: b1->a1
1187 1187 | |
1188 1188 | o 8: a1
1189 1189 | |
1190 1190 | o 7: b1
1191 1191 | |
1192 1192 o | 6: b0
1193 1193 | |
1194 1194 o | 5: a0
1195 1195 |/
1196 1196 o 4: a,b
1197 1197 |
1198 1198 o 3: b
1199 1199 |
1200 1200 o 2: a
1201 1201 |
1202 1202 o 1: a->b
1203 1203 |
1204 1204 o 0: a
1205 1205
1206 1206
1207 1207 since file 'a' has multiple copy sources at the revision 4, ancestors can't
1208 1208 be indexed solely by fctx.linkrev().
1209 1209
1210 1210 $ hg log -T '{rev}: {desc}\n' -f a
1211 1211 10: (a0,b1->a1)->a
1212 1212 9: b1->a1
1213 1213 7: b1
1214 1214 5: a0
1215 1215 4: a,b
1216 1216 3: b
1217 1217 2: a
1218 1218 1: a->b
1219 1219 0: a
1220 1220
1221 1221 $ cd ..
1222 1222
1223 1223 Test that log should respect the order of -rREV even if multiple OR conditions
1224 1224 are specified (issue5100):
1225 1225
1226 1226 $ hg init revorder
1227 1227 $ cd revorder
1228 1228
1229 1229 $ hg branch -q b0
1230 1230 $ echo 0 >> f0
1231 1231 $ hg ci -qAm k0 -u u0
1232 1232 $ hg branch -q b1
1233 1233 $ echo 1 >> f1
1234 1234 $ hg ci -qAm k1 -u u1
1235 1235 $ hg branch -q b2
1236 1236 $ echo 2 >> f2
1237 1237 $ hg ci -qAm k2 -u u2
1238 1238
1239 1239 $ hg update -q b2
1240 1240 $ echo 3 >> f2
1241 1241 $ hg ci -qAm k2 -u u2
1242 1242 $ hg update -q b1
1243 1243 $ echo 4 >> f1
1244 1244 $ hg ci -qAm k1 -u u1
1245 1245 $ hg update -q b0
1246 1246 $ echo 5 >> f0
1247 1247 $ hg ci -qAm k0 -u u0
1248 1248
1249 1249 summary of revisions:
1250 1250
1251 1251 $ hg log -G -T '{rev} {branch} {author} {desc} {files}\n'
1252 1252 @ 5 b0 u0 k0 f0
1253 1253 |
1254 1254 | o 4 b1 u1 k1 f1
1255 1255 | |
1256 1256 | | o 3 b2 u2 k2 f2
1257 1257 | | |
1258 1258 | | o 2 b2 u2 k2 f2
1259 1259 | |/
1260 1260 | o 1 b1 u1 k1 f1
1261 1261 |/
1262 1262 o 0 b0 u0 k0 f0
1263 1263
1264 1264
1265 1265 log -b BRANCH in ascending order:
1266 1266
1267 1267 $ hg log -r0:tip -T '{rev} {branch}\n' -b b0 -b b1
1268 1268 0 b0
1269 1269 1 b1
1270 1270 4 b1
1271 1271 5 b0
1272 1272 $ hg log -r0:tip -T '{rev} {branch}\n' -b b1 -b b0
1273 1273 0 b0
1274 1274 1 b1
1275 1275 4 b1
1276 1276 5 b0
1277 1277
1278 1278 log --only-branch BRANCH in descending order:
1279 1279
1280 1280 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b1 --only-branch b2
1281 1281 4 b1
1282 1282 3 b2
1283 1283 2 b2
1284 1284 1 b1
1285 1285 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b2 --only-branch b1
1286 1286 4 b1
1287 1287 3 b2
1288 1288 2 b2
1289 1289 1 b1
1290 1290
1291 1291 log -u USER in ascending order, against compound set:
1292 1292
1293 1293 $ hg log -r'::head()' -T '{rev} {author}\n' -u u0 -u u2
1294 1294 0 u0
1295 1295 2 u2
1296 1296 3 u2
1297 1297 5 u0
1298 1298 $ hg log -r'::head()' -T '{rev} {author}\n' -u u2 -u u0
1299 1299 0 u0
1300 1300 2 u2
1301 1301 3 u2
1302 1302 5 u0
1303 1303
1304 1304 log -k TEXT in descending order, against compound set:
1305 1305
1306 1306 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k0 -k k1 -k k2
1307 1307 5 k0
1308 1308 3 k2
1309 1309 2 k2
1310 1310 1 k1
1311 1311 0 k0
1312 1312 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k2 -k k1 -k k0
1313 1313 5 k0
1314 1314 3 k2
1315 1315 2 k2
1316 1316 1 k1
1317 1317 0 k0
1318 1318
1319 1319 log FILE in ascending order, against dagrange:
1320 1320
1321 1321 $ hg log -r1:: -T '{rev} {files}\n' f1 f2
1322 1322 1 f1
1323 1323 2 f2
1324 1324 3 f2
1325 1325 4 f1
1326 1326 $ hg log -r1:: -T '{rev} {files}\n' f2 f1
1327 1327 1 f1
1328 1328 2 f2
1329 1329 3 f2
1330 1330 4 f1
1331 1331
1332 1332 $ cd ..
1333 1333
1334 1334 User
1335 1335
1336 1336 $ hg init usertest
1337 1337 $ cd usertest
1338 1338
1339 1339 $ echo a > a
1340 1340 $ hg ci -A -m "a" -u "User One <user1@example.org>"
1341 1341 adding a
1342 1342 $ echo b > b
1343 1343 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
1344 1344 adding b
1345 1345
1346 1346 $ hg log -u "User One <user1@example.org>"
1347 1347 changeset: 0:29a4c94f1924
1348 1348 user: User One <user1@example.org>
1349 1349 date: Thu Jan 01 00:00:00 1970 +0000
1350 1350 summary: a
1351 1351
1352 1352 $ hg log -u "user1" -u "user2"
1353 1353 changeset: 1:e834b5e69c0e
1354 1354 tag: tip
1355 1355 user: User Two <user2@example.org>
1356 1356 date: Thu Jan 01 00:00:00 1970 +0000
1357 1357 summary: b
1358 1358
1359 1359 changeset: 0:29a4c94f1924
1360 1360 user: User One <user1@example.org>
1361 1361 date: Thu Jan 01 00:00:00 1970 +0000
1362 1362 summary: a
1363 1363
1364 1364 $ hg log -u "user3"
1365 1365
1366 1366 "-u USER" shouldn't be overridden by "user(USER)" alias
1367 1367
1368 1368 $ hg log --config 'revsetalias.user(x)=branch(x)' -u default
1369 1369 $ hg log --config 'revsetalias.user(x)=branch(x)' -u user1
1370 1370 changeset: 0:29a4c94f1924
1371 1371 user: User One <user1@example.org>
1372 1372 date: Thu Jan 01 00:00:00 1970 +0000
1373 1373 summary: a
1374 1374
1375 1375
1376 1376 $ cd ..
1377 1377
1378 1378 $ hg init branches
1379 1379 $ cd branches
1380 1380
1381 1381 $ echo a > a
1382 1382 $ hg ci -A -m "commit on default"
1383 1383 adding a
1384 1384 $ hg branch test
1385 1385 marked working directory as branch test
1386 1386 (branches are permanent and global, did you want a bookmark?)
1387 1387 $ echo b > b
1388 1388 $ hg ci -A -m "commit on test"
1389 1389 adding b
1390 1390
1391 1391 $ hg up default
1392 1392 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1393 1393 $ echo c > c
1394 1394 $ hg ci -A -m "commit on default"
1395 1395 adding c
1396 1396 $ hg up test
1397 1397 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1398 1398 $ echo c > c
1399 1399 $ hg ci -A -m "commit on test"
1400 1400 adding c
1401 1401
1402 1402
1403 1403 log -b default
1404 1404
1405 1405 $ hg log -b default
1406 1406 changeset: 2:c3a4f03cc9a7
1407 1407 parent: 0:24427303d56f
1408 1408 user: test
1409 1409 date: Thu Jan 01 00:00:00 1970 +0000
1410 1410 summary: commit on default
1411 1411
1412 1412 changeset: 0:24427303d56f
1413 1413 user: test
1414 1414 date: Thu Jan 01 00:00:00 1970 +0000
1415 1415 summary: commit on default
1416 1416
1417 1417
1418 1418
1419 1419 log -b test
1420 1420
1421 1421 $ hg log -b test
1422 1422 changeset: 3:f5d8de11c2e2
1423 1423 branch: test
1424 1424 tag: tip
1425 1425 parent: 1:d32277701ccb
1426 1426 user: test
1427 1427 date: Thu Jan 01 00:00:00 1970 +0000
1428 1428 summary: commit on test
1429 1429
1430 1430 changeset: 1:d32277701ccb
1431 1431 branch: test
1432 1432 user: test
1433 1433 date: Thu Jan 01 00:00:00 1970 +0000
1434 1434 summary: commit on test
1435 1435
1436 1436
1437 1437
1438 1438 log -b dummy
1439 1439
1440 1440 $ hg log -b dummy
1441 1441 abort: unknown revision 'dummy'!
1442 1442 [255]
1443 1443
1444 1444
1445 1445 log -b .
1446 1446
1447 1447 $ hg log -b .
1448 1448 changeset: 3:f5d8de11c2e2
1449 1449 branch: test
1450 1450 tag: tip
1451 1451 parent: 1:d32277701ccb
1452 1452 user: test
1453 1453 date: Thu Jan 01 00:00:00 1970 +0000
1454 1454 summary: commit on test
1455 1455
1456 1456 changeset: 1:d32277701ccb
1457 1457 branch: test
1458 1458 user: test
1459 1459 date: Thu Jan 01 00:00:00 1970 +0000
1460 1460 summary: commit on test
1461 1461
1462 1462
1463 1463
1464 1464 log -b default -b test
1465 1465
1466 1466 $ hg log -b default -b test
1467 1467 changeset: 3:f5d8de11c2e2
1468 1468 branch: test
1469 1469 tag: tip
1470 1470 parent: 1:d32277701ccb
1471 1471 user: test
1472 1472 date: Thu Jan 01 00:00:00 1970 +0000
1473 1473 summary: commit on test
1474 1474
1475 1475 changeset: 2:c3a4f03cc9a7
1476 1476 parent: 0:24427303d56f
1477 1477 user: test
1478 1478 date: Thu Jan 01 00:00:00 1970 +0000
1479 1479 summary: commit on default
1480 1480
1481 1481 changeset: 1:d32277701ccb
1482 1482 branch: test
1483 1483 user: test
1484 1484 date: Thu Jan 01 00:00:00 1970 +0000
1485 1485 summary: commit on test
1486 1486
1487 1487 changeset: 0:24427303d56f
1488 1488 user: test
1489 1489 date: Thu Jan 01 00:00:00 1970 +0000
1490 1490 summary: commit on default
1491 1491
1492 1492
1493 1493
1494 1494 log -b default -b .
1495 1495
1496 1496 $ hg log -b default -b .
1497 1497 changeset: 3:f5d8de11c2e2
1498 1498 branch: test
1499 1499 tag: tip
1500 1500 parent: 1:d32277701ccb
1501 1501 user: test
1502 1502 date: Thu Jan 01 00:00:00 1970 +0000
1503 1503 summary: commit on test
1504 1504
1505 1505 changeset: 2:c3a4f03cc9a7
1506 1506 parent: 0:24427303d56f
1507 1507 user: test
1508 1508 date: Thu Jan 01 00:00:00 1970 +0000
1509 1509 summary: commit on default
1510 1510
1511 1511 changeset: 1:d32277701ccb
1512 1512 branch: test
1513 1513 user: test
1514 1514 date: Thu Jan 01 00:00:00 1970 +0000
1515 1515 summary: commit on test
1516 1516
1517 1517 changeset: 0:24427303d56f
1518 1518 user: test
1519 1519 date: Thu Jan 01 00:00:00 1970 +0000
1520 1520 summary: commit on default
1521 1521
1522 1522
1523 1523
1524 1524 log -b . -b test
1525 1525
1526 1526 $ hg log -b . -b test
1527 1527 changeset: 3:f5d8de11c2e2
1528 1528 branch: test
1529 1529 tag: tip
1530 1530 parent: 1:d32277701ccb
1531 1531 user: test
1532 1532 date: Thu Jan 01 00:00:00 1970 +0000
1533 1533 summary: commit on test
1534 1534
1535 1535 changeset: 1:d32277701ccb
1536 1536 branch: test
1537 1537 user: test
1538 1538 date: Thu Jan 01 00:00:00 1970 +0000
1539 1539 summary: commit on test
1540 1540
1541 1541
1542 1542
1543 1543 log -b 2
1544 1544
1545 1545 $ hg log -b 2
1546 1546 changeset: 2:c3a4f03cc9a7
1547 1547 parent: 0:24427303d56f
1548 1548 user: test
1549 1549 date: Thu Jan 01 00:00:00 1970 +0000
1550 1550 summary: commit on default
1551 1551
1552 1552 changeset: 0:24427303d56f
1553 1553 user: test
1554 1554 date: Thu Jan 01 00:00:00 1970 +0000
1555 1555 summary: commit on default
1556 1556
1557 1557 #if gettext
1558 1558
1559 1559 Test that all log names are translated (e.g. branches, bookmarks, tags):
1560 1560
1561 1561 $ hg bookmark babar -r tip
1562 1562
1563 1563 $ HGENCODING=UTF-8 LANGUAGE=de hg log -r tip
1564 1564 \xc3\x84nderung: 3:f5d8de11c2e2 (esc)
1565 1565 Zweig: test
1566 1566 Lesezeichen: babar
1567 1567 Marke: tip
1568 1568 Vorg\xc3\xa4nger: 1:d32277701ccb (esc)
1569 1569 Nutzer: test
1570 1570 Datum: Thu Jan 01 00:00:00 1970 +0000
1571 1571 Zusammenfassung: commit on test
1572 1572
1573 1573 $ hg bookmark -d babar
1574 1574
1575 1575 #endif
1576 1576
1577 1577 log -p --cwd dir (in subdir)
1578 1578
1579 1579 $ mkdir dir
1580 1580 $ hg log -p --cwd dir
1581 1581 changeset: 3:f5d8de11c2e2
1582 1582 branch: test
1583 1583 tag: tip
1584 1584 parent: 1:d32277701ccb
1585 1585 user: test
1586 1586 date: Thu Jan 01 00:00:00 1970 +0000
1587 1587 summary: commit on test
1588 1588
1589 1589 diff -r d32277701ccb -r f5d8de11c2e2 c
1590 1590 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1591 1591 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1592 1592 @@ -0,0 +1,1 @@
1593 1593 +c
1594 1594
1595 1595 changeset: 2:c3a4f03cc9a7
1596 1596 parent: 0:24427303d56f
1597 1597 user: test
1598 1598 date: Thu Jan 01 00:00:00 1970 +0000
1599 1599 summary: commit on default
1600 1600
1601 1601 diff -r 24427303d56f -r c3a4f03cc9a7 c
1602 1602 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1603 1603 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1604 1604 @@ -0,0 +1,1 @@
1605 1605 +c
1606 1606
1607 1607 changeset: 1:d32277701ccb
1608 1608 branch: test
1609 1609 user: test
1610 1610 date: Thu Jan 01 00:00:00 1970 +0000
1611 1611 summary: commit on test
1612 1612
1613 1613 diff -r 24427303d56f -r d32277701ccb b
1614 1614 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1615 1615 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1616 1616 @@ -0,0 +1,1 @@
1617 1617 +b
1618 1618
1619 1619 changeset: 0:24427303d56f
1620 1620 user: test
1621 1621 date: Thu Jan 01 00:00:00 1970 +0000
1622 1622 summary: commit on default
1623 1623
1624 1624 diff -r 000000000000 -r 24427303d56f a
1625 1625 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1626 1626 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1627 1627 @@ -0,0 +1,1 @@
1628 1628 +a
1629 1629
1630 1630
1631 1631
1632 1632 log -p -R repo
1633 1633
1634 1634 $ cd dir
1635 1635 $ hg log -p -R .. ../a
1636 1636 changeset: 0:24427303d56f
1637 1637 user: test
1638 1638 date: Thu Jan 01 00:00:00 1970 +0000
1639 1639 summary: commit on default
1640 1640
1641 1641 diff -r 000000000000 -r 24427303d56f a
1642 1642 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1643 1643 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1644 1644 @@ -0,0 +1,1 @@
1645 1645 +a
1646 1646
1647 1647
1648 1648 $ cd ../..
1649 1649
1650 1650 $ hg init follow2
1651 1651 $ cd follow2
1652 1652
1653 1653 # Build the following history:
1654 1654 # tip - o - x - o - x - x
1655 1655 # \ /
1656 1656 # o - o - o - x
1657 1657 # \ /
1658 1658 # o
1659 1659 #
1660 1660 # Where "o" is a revision containing "foo" and
1661 1661 # "x" is a revision without "foo"
1662 1662
1663 1663 $ touch init
1664 1664 $ hg ci -A -m "init, unrelated"
1665 1665 adding init
1666 1666 $ echo 'foo' > init
1667 1667 $ hg ci -m "change, unrelated"
1668 1668 $ echo 'foo' > foo
1669 1669 $ hg ci -A -m "add unrelated old foo"
1670 1670 adding foo
1671 1671 $ hg rm foo
1672 1672 $ hg ci -m "delete foo, unrelated"
1673 1673 $ echo 'related' > foo
1674 1674 $ hg ci -A -m "add foo, related"
1675 1675 adding foo
1676 1676
1677 1677 $ hg up 0
1678 1678 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1679 1679 $ touch branch
1680 1680 $ hg ci -A -m "first branch, unrelated"
1681 1681 adding branch
1682 1682 created new head
1683 1683 $ touch foo
1684 1684 $ hg ci -A -m "create foo, related"
1685 1685 adding foo
1686 1686 $ echo 'change' > foo
1687 1687 $ hg ci -m "change foo, related"
1688 1688
1689 1689 $ hg up 6
1690 1690 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1691 1691 $ echo 'change foo in branch' > foo
1692 1692 $ hg ci -m "change foo in branch, related"
1693 1693 created new head
1694 1694 $ hg merge 7
1695 1695 merging foo
1696 1696 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1697 1697 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1698 1698 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
1699 1699 [1]
1700 1700 $ echo 'merge 1' > foo
1701 1701 $ hg resolve -m foo
1702 1702 (no more unresolved files)
1703 1703 $ hg ci -m "First merge, related"
1704 1704
1705 1705 $ hg merge 4
1706 1706 merging foo
1707 1707 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1708 1708 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1709 1709 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
1710 1710 [1]
1711 1711 $ echo 'merge 2' > foo
1712 1712 $ hg resolve -m foo
1713 1713 (no more unresolved files)
1714 1714 $ hg ci -m "Last merge, related"
1715 1715
1716 1716 $ hg log --graph
1717 1717 @ changeset: 10:4dae8563d2c5
1718 1718 |\ tag: tip
1719 1719 | | parent: 9:7b35701b003e
1720 1720 | | parent: 4:88176d361b69
1721 1721 | | user: test
1722 1722 | | date: Thu Jan 01 00:00:00 1970 +0000
1723 1723 | | summary: Last merge, related
1724 1724 | |
1725 1725 | o changeset: 9:7b35701b003e
1726 1726 | |\ parent: 8:e5416ad8a855
1727 1727 | | | parent: 7:87fe3144dcfa
1728 1728 | | | user: test
1729 1729 | | | date: Thu Jan 01 00:00:00 1970 +0000
1730 1730 | | | summary: First merge, related
1731 1731 | | |
1732 1732 | | o changeset: 8:e5416ad8a855
1733 1733 | | | parent: 6:dc6c325fe5ee
1734 1734 | | | user: test
1735 1735 | | | date: Thu Jan 01 00:00:00 1970 +0000
1736 1736 | | | summary: change foo in branch, related
1737 1737 | | |
1738 1738 | o | changeset: 7:87fe3144dcfa
1739 1739 | |/ user: test
1740 1740 | | date: Thu Jan 01 00:00:00 1970 +0000
1741 1741 | | summary: change foo, related
1742 1742 | |
1743 1743 | o changeset: 6:dc6c325fe5ee
1744 1744 | | user: test
1745 1745 | | date: Thu Jan 01 00:00:00 1970 +0000
1746 1746 | | summary: create foo, related
1747 1747 | |
1748 1748 | o changeset: 5:73db34516eb9
1749 1749 | | parent: 0:e87515fd044a
1750 1750 | | user: test
1751 1751 | | date: Thu Jan 01 00:00:00 1970 +0000
1752 1752 | | summary: first branch, unrelated
1753 1753 | |
1754 1754 o | changeset: 4:88176d361b69
1755 1755 | | user: test
1756 1756 | | date: Thu Jan 01 00:00:00 1970 +0000
1757 1757 | | summary: add foo, related
1758 1758 | |
1759 1759 o | changeset: 3:dd78ae4afb56
1760 1760 | | user: test
1761 1761 | | date: Thu Jan 01 00:00:00 1970 +0000
1762 1762 | | summary: delete foo, unrelated
1763 1763 | |
1764 1764 o | changeset: 2:c4c64aedf0f7
1765 1765 | | user: test
1766 1766 | | date: Thu Jan 01 00:00:00 1970 +0000
1767 1767 | | summary: add unrelated old foo
1768 1768 | |
1769 1769 o | changeset: 1:e5faa7440653
1770 1770 |/ user: test
1771 1771 | date: Thu Jan 01 00:00:00 1970 +0000
1772 1772 | summary: change, unrelated
1773 1773 |
1774 1774 o changeset: 0:e87515fd044a
1775 1775 user: test
1776 1776 date: Thu Jan 01 00:00:00 1970 +0000
1777 1777 summary: init, unrelated
1778 1778
1779 1779
1780 1780 $ hg --traceback log -f foo
1781 1781 changeset: 10:4dae8563d2c5
1782 1782 tag: tip
1783 1783 parent: 9:7b35701b003e
1784 1784 parent: 4:88176d361b69
1785 1785 user: test
1786 1786 date: Thu Jan 01 00:00:00 1970 +0000
1787 1787 summary: Last merge, related
1788 1788
1789 1789 changeset: 9:7b35701b003e
1790 1790 parent: 8:e5416ad8a855
1791 1791 parent: 7:87fe3144dcfa
1792 1792 user: test
1793 1793 date: Thu Jan 01 00:00:00 1970 +0000
1794 1794 summary: First merge, related
1795 1795
1796 1796 changeset: 8:e5416ad8a855
1797 1797 parent: 6:dc6c325fe5ee
1798 1798 user: test
1799 1799 date: Thu Jan 01 00:00:00 1970 +0000
1800 1800 summary: change foo in branch, related
1801 1801
1802 1802 changeset: 7:87fe3144dcfa
1803 1803 user: test
1804 1804 date: Thu Jan 01 00:00:00 1970 +0000
1805 1805 summary: change foo, related
1806 1806
1807 1807 changeset: 6:dc6c325fe5ee
1808 1808 user: test
1809 1809 date: Thu Jan 01 00:00:00 1970 +0000
1810 1810 summary: create foo, related
1811 1811
1812 1812 changeset: 4:88176d361b69
1813 1813 user: test
1814 1814 date: Thu Jan 01 00:00:00 1970 +0000
1815 1815 summary: add foo, related
1816 1816
1817 1817
1818 1818 Also check when maxrev < lastrevfilelog
1819 1819
1820 1820 $ hg --traceback log -f -r4 foo
1821 1821 changeset: 4:88176d361b69
1822 1822 user: test
1823 1823 date: Thu Jan 01 00:00:00 1970 +0000
1824 1824 summary: add foo, related
1825 1825
1826 1826 $ cd ..
1827 1827
1828 1828 Issue2383: hg log showing _less_ differences than hg diff
1829 1829
1830 1830 $ hg init issue2383
1831 1831 $ cd issue2383
1832 1832
1833 1833 Create a test repo:
1834 1834
1835 1835 $ echo a > a
1836 1836 $ hg ci -Am0
1837 1837 adding a
1838 1838 $ echo b > b
1839 1839 $ hg ci -Am1
1840 1840 adding b
1841 1841 $ hg co 0
1842 1842 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1843 1843 $ echo b > a
1844 1844 $ hg ci -m2
1845 1845 created new head
1846 1846
1847 1847 Merge:
1848 1848
1849 1849 $ hg merge
1850 1850 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1851 1851 (branch merge, don't forget to commit)
1852 1852
1853 1853 Make sure there's a file listed in the merge to trigger the bug:
1854 1854
1855 1855 $ echo c > a
1856 1856 $ hg ci -m3
1857 1857
1858 1858 Two files shown here in diff:
1859 1859
1860 1860 $ hg diff --rev 2:3
1861 1861 diff -r b09be438c43a -r 8e07aafe1edc a
1862 1862 --- a/a Thu Jan 01 00:00:00 1970 +0000
1863 1863 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1864 1864 @@ -1,1 +1,1 @@
1865 1865 -b
1866 1866 +c
1867 1867 diff -r b09be438c43a -r 8e07aafe1edc b
1868 1868 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1869 1869 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1870 1870 @@ -0,0 +1,1 @@
1871 1871 +b
1872 1872
1873 1873 Diff here should be the same:
1874 1874
1875 1875 $ hg log -vpr 3
1876 1876 changeset: 3:8e07aafe1edc
1877 1877 tag: tip
1878 1878 parent: 2:b09be438c43a
1879 1879 parent: 1:925d80f479bb
1880 1880 user: test
1881 1881 date: Thu Jan 01 00:00:00 1970 +0000
1882 1882 files: a
1883 1883 description:
1884 1884 3
1885 1885
1886 1886
1887 1887 diff -r b09be438c43a -r 8e07aafe1edc a
1888 1888 --- a/a Thu Jan 01 00:00:00 1970 +0000
1889 1889 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1890 1890 @@ -1,1 +1,1 @@
1891 1891 -b
1892 1892 +c
1893 1893 diff -r b09be438c43a -r 8e07aafe1edc b
1894 1894 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1895 1895 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1896 1896 @@ -0,0 +1,1 @@
1897 1897 +b
1898 1898
1899 1899 $ cd ..
1900 1900
1901 1901 'hg log -r rev fn' when last(filelog(fn)) != rev
1902 1902
1903 1903 $ hg init simplelog
1904 1904 $ cd simplelog
1905 1905 $ echo f > a
1906 1906 $ hg ci -Am'a' -d '0 0'
1907 1907 adding a
1908 1908 $ echo f >> a
1909 1909 $ hg ci -Am'a bis' -d '1 0'
1910 1910
1911 1911 $ hg log -r0 a
1912 1912 changeset: 0:9f758d63dcde
1913 1913 user: test
1914 1914 date: Thu Jan 01 00:00:00 1970 +0000
1915 1915 summary: a
1916 1916
1917 1917 enable obsolete to test hidden feature
1918 1918
1919 1919 $ cat >> $HGRCPATH << EOF
1920 1920 > [experimental]
1921 1921 > evolution.createmarkers=True
1922 1922 > EOF
1923 1923
1924 1924 $ hg log --template='{rev}:{node}\n'
1925 1925 1:a765632148dc55d38c35c4f247c618701886cb2f
1926 1926 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1927 1927 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1928 1928 obsoleted 1 changesets
1929 1929 $ hg up null -q
1930 1930 $ hg log --template='{rev}:{node}\n'
1931 1931 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1932 1932 $ hg log --template='{rev}:{node}\n' --hidden
1933 1933 1:a765632148dc55d38c35c4f247c618701886cb2f
1934 1934 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1935 1935 $ hg log -r a
1936 1936 abort: hidden revision 'a' is pruned!
1937 1937 (use --hidden to access hidden revisions)
1938 1938 [255]
1939 1939
1940 1940 test that parent prevent a changeset to be hidden
1941 1941
1942 1942 $ hg up 1 -q --hidden
1943 1943 updating to a hidden changeset a765632148dc
1944 1944 (hidden revision 'a765632148dc' is pruned)
1945 1945 $ hg log --template='{rev}:{node}\n'
1946 1946 1:a765632148dc55d38c35c4f247c618701886cb2f
1947 1947 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1948 1948
1949 1949 test that second parent prevent a changeset to be hidden too
1950 1950
1951 1951 $ hg debugsetparents 0 1 # nothing suitable to merge here
1952 1952 $ hg log --template='{rev}:{node}\n'
1953 1953 1:a765632148dc55d38c35c4f247c618701886cb2f
1954 1954 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1955 1955 $ hg debugsetparents 1
1956 1956 $ hg up -q null
1957 1957
1958 1958 bookmarks prevent a changeset being hidden
1959 1959
1960 1960 $ hg bookmark --hidden -r 1 X
1961 1961 bookmarking hidden changeset a765632148dc
1962 1962 (hidden revision 'a765632148dc' is pruned)
1963 1963 $ hg log --template '{rev}:{node}\n'
1964 1964 1:a765632148dc55d38c35c4f247c618701886cb2f
1965 1965 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1966 1966 $ hg bookmark -d X
1967 1967
1968 1968 divergent bookmarks are not hidden
1969 1969
1970 1970 $ hg bookmark --hidden -r 1 X@foo
1971 1971 bookmarking hidden changeset a765632148dc
1972 1972 (hidden revision 'a765632148dc' is pruned)
1973 1973 $ hg log --template '{rev}:{node}\n'
1974 1974 1:a765632148dc55d38c35c4f247c618701886cb2f
1975 1975 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1976 1976
1977 1977 test hidden revision 0 (issue5385)
1978 1978
1979 1979 $ hg bookmark -d X@foo
1980 1980 $ hg up null -q
1981 1981 $ hg debugobsolete 9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1982 1982 obsoleted 1 changesets
1983 1983 $ echo f > b
1984 1984 $ hg ci -Am'b' -d '2 0'
1985 1985 adding b
1986 1986 $ echo f >> b
1987 1987 $ hg ci -m'b bis' -d '3 0'
1988 1988 $ hg log -T'{rev}:{node}\n'
1989 1989 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1990 1990 2:94375ec45bddd2a824535fc04855bd058c926ec0
1991 1991
1992 1992 $ hg log -T'{rev}:{node}\n' -r:
1993 1993 2:94375ec45bddd2a824535fc04855bd058c926ec0
1994 1994 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1995 1995 $ hg log -T'{rev}:{node}\n' -r:tip
1996 1996 2:94375ec45bddd2a824535fc04855bd058c926ec0
1997 1997 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1998 1998 $ hg log -T'{rev}:{node}\n' -r:0
1999 1999 abort: hidden revision '0' is pruned!
2000 2000 (use --hidden to access hidden revisions)
2001 2001 [255]
2002 2002 $ hg log -T'{rev}:{node}\n' -f
2003 2003 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2004 2004 2:94375ec45bddd2a824535fc04855bd058c926ec0
2005 2005
2006 2006 clear extensions configuration
2007 2007 $ echo '[extensions]' >> $HGRCPATH
2008 2008 $ echo "obs=!" >> $HGRCPATH
2009 2009 $ cd ..
2010 2010
2011 2011 test -u/-k for problematic encoding
2012 2012 # unicode: cp932:
2013 2013 # u30A2 0x83 0x41(= 'A')
2014 2014 # u30C2 0x83 0x61(= 'a')
2015 2015
2016 2016 $ hg init problematicencoding
2017 2017 $ cd problematicencoding
2018 2018
2019 2019 $ $PYTHON > setup.sh <<EOF
2020 2020 > print(u'''
2021 2021 > echo a > text
2022 2022 > hg add text
2023 2023 > hg --encoding utf-8 commit -u '\u30A2' -m none
2024 2024 > echo b > text
2025 2025 > hg --encoding utf-8 commit -u '\u30C2' -m none
2026 2026 > echo c > text
2027 2027 > hg --encoding utf-8 commit -u none -m '\u30A2'
2028 2028 > echo d > text
2029 2029 > hg --encoding utf-8 commit -u none -m '\u30C2'
2030 2030 > '''.encode('utf-8'))
2031 2031 > EOF
2032 2032 $ sh < setup.sh
2033 2033
2034 2034 test in problematic encoding
2035 2035 $ $PYTHON > test.sh <<EOF
2036 2036 > print(u'''
2037 2037 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
2038 2038 > echo ====
2039 2039 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
2040 2040 > echo ====
2041 2041 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
2042 2042 > echo ====
2043 2043 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
2044 2044 > '''.encode('cp932'))
2045 2045 > EOF
2046 2046 $ sh < test.sh
2047 2047 0
2048 2048 ====
2049 2049 1
2050 2050 ====
2051 2051 2
2052 2052 0
2053 2053 ====
2054 2054 3
2055 2055 1
2056 2056
2057 2057 $ cd ..
2058 2058
2059 2059 test hg log on non-existent files and on directories
2060 2060 $ hg init issue1340
2061 2061 $ cd issue1340
2062 2062 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
2063 2063 $ echo 1 > d1/f1
2064 2064 $ echo 1 > D2/f1
2065 2065 $ echo 1 > D3.i/f1
2066 2066 $ echo 1 > d4.hg/f1
2067 2067 $ echo 1 > d5.d/f1
2068 2068 $ echo 1 > .d6/f1
2069 2069 $ hg -q add .
2070 2070 $ hg commit -m "a bunch of weird directories"
2071 2071 $ hg log -l1 d1/f1 | grep changeset
2072 2072 changeset: 0:65624cd9070a
2073 2073 $ hg log -l1 f1
2074 2074 $ hg log -l1 . | grep changeset
2075 2075 changeset: 0:65624cd9070a
2076 2076 $ hg log -l1 ./ | grep changeset
2077 2077 changeset: 0:65624cd9070a
2078 2078 $ hg log -l1 d1 | grep changeset
2079 2079 changeset: 0:65624cd9070a
2080 2080 $ hg log -l1 D2 | grep changeset
2081 2081 changeset: 0:65624cd9070a
2082 2082 $ hg log -l1 D2/f1 | grep changeset
2083 2083 changeset: 0:65624cd9070a
2084 2084 $ hg log -l1 D3.i | grep changeset
2085 2085 changeset: 0:65624cd9070a
2086 2086 $ hg log -l1 D3.i/f1 | grep changeset
2087 2087 changeset: 0:65624cd9070a
2088 2088 $ hg log -l1 d4.hg | grep changeset
2089 2089 changeset: 0:65624cd9070a
2090 2090 $ hg log -l1 d4.hg/f1 | grep changeset
2091 2091 changeset: 0:65624cd9070a
2092 2092 $ hg log -l1 d5.d | grep changeset
2093 2093 changeset: 0:65624cd9070a
2094 2094 $ hg log -l1 d5.d/f1 | grep changeset
2095 2095 changeset: 0:65624cd9070a
2096 2096 $ hg log -l1 .d6 | grep changeset
2097 2097 changeset: 0:65624cd9070a
2098 2098 $ hg log -l1 .d6/f1 | grep changeset
2099 2099 changeset: 0:65624cd9070a
2100 2100
2101 2101 issue3772: hg log -r :null showing revision 0 as well
2102 2102
2103 2103 $ hg log -r :null
2104 2104 changeset: 0:65624cd9070a
2105 2105 tag: tip
2106 2106 user: test
2107 2107 date: Thu Jan 01 00:00:00 1970 +0000
2108 2108 summary: a bunch of weird directories
2109 2109
2110 2110 changeset: -1:000000000000
2111 2111 user:
2112 2112 date: Thu Jan 01 00:00:00 1970 +0000
2113 2113
2114 2114 $ hg log -r null:null
2115 2115 changeset: -1:000000000000
2116 2116 user:
2117 2117 date: Thu Jan 01 00:00:00 1970 +0000
2118 2118
2119 2119 working-directory revision requires special treatment
2120 2120
2121 2121 clean:
2122 2122
2123 2123 $ hg log -r 'wdir()' --debug
2124 2124 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2125 2125 phase: draft
2126 2126 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
2127 2127 parent: -1:0000000000000000000000000000000000000000
2128 2128 user: test
2129 2129 date: [A-Za-z0-9:+ ]+ (re)
2130 2130 extra: branch=default
2131 2131
2132 2132 $ hg log -r 'wdir()' -p --stat
2133 2133 changeset: 2147483647:ffffffffffff
2134 2134 parent: 0:65624cd9070a
2135 2135 user: test
2136 2136 date: [A-Za-z0-9:+ ]+ (re)
2137 2137
2138 2138
2139 2139
2140 2140
2141 2141 dirty:
2142 2142
2143 2143 $ echo 2 >> d1/f1
2144 2144 $ echo 2 > d1/f2
2145 2145 $ hg add d1/f2
2146 2146 $ hg remove .d6/f1
2147 2147 $ hg status
2148 2148 M d1/f1
2149 2149 A d1/f2
2150 2150 R .d6/f1
2151 2151
2152 2152 $ hg log -r 'wdir()'
2153 2153 changeset: 2147483647:ffffffffffff
2154 2154 parent: 0:65624cd9070a
2155 2155 user: test
2156 2156 date: [A-Za-z0-9:+ ]+ (re)
2157 2157
2158 2158 $ hg log -r 'wdir()' -q
2159 2159 2147483647:ffffffffffff
2160 2160
2161 2161 $ hg log -r 'wdir()' --debug
2162 2162 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2163 2163 phase: draft
2164 2164 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
2165 2165 parent: -1:0000000000000000000000000000000000000000
2166 2166 user: test
2167 2167 date: [A-Za-z0-9:+ ]+ (re)
2168 2168 files: d1/f1
2169 2169 files+: d1/f2
2170 2170 files-: .d6/f1
2171 2171 extra: branch=default
2172 2172
2173 2173 $ hg log -r 'wdir()' -p --stat --git
2174 2174 changeset: 2147483647:ffffffffffff
2175 2175 parent: 0:65624cd9070a
2176 2176 user: test
2177 2177 date: [A-Za-z0-9:+ ]+ (re)
2178 2178
2179 2179 .d6/f1 | 1 -
2180 2180 d1/f1 | 1 +
2181 2181 d1/f2 | 1 +
2182 2182 3 files changed, 2 insertions(+), 1 deletions(-)
2183 2183
2184 2184 diff --git a/.d6/f1 b/.d6/f1
2185 2185 deleted file mode 100644
2186 2186 --- a/.d6/f1
2187 2187 +++ /dev/null
2188 2188 @@ -1,1 +0,0 @@
2189 2189 -1
2190 2190 diff --git a/d1/f1 b/d1/f1
2191 2191 --- a/d1/f1
2192 2192 +++ b/d1/f1
2193 2193 @@ -1,1 +1,2 @@
2194 2194 1
2195 2195 +2
2196 2196 diff --git a/d1/f2 b/d1/f2
2197 2197 new file mode 100644
2198 2198 --- /dev/null
2199 2199 +++ b/d1/f2
2200 2200 @@ -0,0 +1,1 @@
2201 2201 +2
2202 2202
2203 2203 $ hg log -r 'wdir()' -Tjson
2204 2204 [
2205 2205 {
2206 2206 "rev": null,
2207 2207 "node": null,
2208 2208 "branch": "default",
2209 2209 "phase": "draft",
2210 2210 "user": "test",
2211 2211 "date": [*, 0], (glob)
2212 2212 "desc": "",
2213 2213 "bookmarks": [],
2214 2214 "tags": [],
2215 2215 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"]
2216 2216 }
2217 2217 ]
2218 2218
2219 2219 $ hg log -r 'wdir()' -Tjson -q
2220 2220 [
2221 2221 {
2222 2222 "rev": null,
2223 2223 "node": null
2224 2224 }
2225 2225 ]
2226 2226
2227 2227 $ hg log -r 'wdir()' -Tjson --debug
2228 2228 [
2229 2229 {
2230 2230 "rev": null,
2231 2231 "node": null,
2232 2232 "branch": "default",
2233 2233 "phase": "draft",
2234 2234 "user": "test",
2235 2235 "date": [*, 0], (glob)
2236 2236 "desc": "",
2237 2237 "bookmarks": [],
2238 2238 "tags": [],
2239 2239 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"],
2240 2240 "manifest": null,
2241 2241 "extra": {"branch": "default"},
2242 2242 "modified": ["d1/f1"],
2243 2243 "added": ["d1/f2"],
2244 2244 "removed": [".d6/f1"]
2245 2245 }
2246 2246 ]
2247 2247
2248 2248 $ hg revert -aqC
2249 2249
2250 2250 Check that adding an arbitrary name shows up in log automatically
2251 2251
2252 2252 $ cat > ../names.py <<EOF
2253 2253 > """A small extension to test adding arbitrary names to a repo"""
2254 2254 > from __future__ import absolute_import
2255 2255 > from mercurial import namespaces
2256 2256 >
2257 2257 > def reposetup(ui, repo):
2258 2258 > foo = {'foo': repo[0].node()}
2259 2259 > names = lambda r: foo.keys()
2260 2260 > namemap = lambda r, name: foo.get(name)
2261 > nodemap = lambda r, node: [name for name, n in foo.iteritems()
2261 > nodemap = lambda r, node: [name for name, n in foo.items()
2262 2262 > if n == node]
2263 2263 > ns = namespaces.namespace(
2264 2264 > "bars", templatename="bar", logname="barlog",
2265 2265 > colorname="barcolor", listnames=names, namemap=namemap,
2266 2266 > nodemap=nodemap)
2267 2267 >
2268 2268 > repo.names.addnamespace(ns)
2269 2269 > EOF
2270 2270
2271 2271 $ hg --config extensions.names=../names.py log -r 0
2272 2272 changeset: 0:65624cd9070a
2273 2273 tag: tip
2274 2274 barlog: foo
2275 2275 user: test
2276 2276 date: Thu Jan 01 00:00:00 1970 +0000
2277 2277 summary: a bunch of weird directories
2278 2278
2279 2279 $ hg --config extensions.names=../names.py \
2280 2280 > --config extensions.color= --config color.log.barcolor=red \
2281 2281 > --color=always log -r 0
2282 2282 \x1b[0;33mchangeset: 0:65624cd9070a\x1b[0m (esc)
2283 2283 tag: tip
2284 2284 \x1b[0;31mbarlog: foo\x1b[0m (esc)
2285 2285 user: test
2286 2286 date: Thu Jan 01 00:00:00 1970 +0000
2287 2287 summary: a bunch of weird directories
2288 2288
2289 2289 $ hg --config extensions.names=../names.py log -r 0 --template '{bars}\n'
2290 2290 foo
2291 2291
2292 2292 $ cd ..
2293 2293
2294 2294 hg log -f dir across branches
2295 2295
2296 2296 $ hg init acrossbranches
2297 2297 $ cd acrossbranches
2298 2298 $ mkdir d
2299 2299 $ echo a > d/a && hg ci -Aqm a
2300 2300 $ echo b > d/a && hg ci -Aqm b
2301 2301 $ hg up -q 0
2302 2302 $ echo b > d/a && hg ci -Aqm c
2303 2303 $ hg log -f d -T '{desc}' -G
2304 2304 @ c
2305 2305 |
2306 2306 o a
2307 2307
2308 2308 Ensure that largefiles doesn't interfere with following a normal file
2309 2309 $ hg --config extensions.largefiles= log -f d -T '{desc}' -G
2310 2310 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
2311 2311 @ c
2312 2312 |
2313 2313 o a
2314 2314
2315 2315 $ hg log -f d/a -T '{desc}' -G
2316 2316 @ c
2317 2317 |
2318 2318 o a
2319 2319
2320 2320 $ cd ..
2321 2321
2322 2322 hg log -f with linkrev pointing to another branch
2323 2323 -------------------------------------------------
2324 2324
2325 2325 create history with a filerev whose linkrev points to another branch
2326 2326
2327 2327 $ hg init branchedlinkrev
2328 2328 $ cd branchedlinkrev
2329 2329 $ echo 1 > a
2330 2330 $ hg commit -Am 'content1'
2331 2331 adding a
2332 2332 $ echo 2 > a
2333 2333 $ hg commit -m 'content2'
2334 2334 $ hg up --rev 'desc(content1)'
2335 2335 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2336 2336 $ echo unrelated > unrelated
2337 2337 $ hg commit -Am 'unrelated'
2338 2338 adding unrelated
2339 2339 created new head
2340 2340 $ hg graft -r 'desc(content2)'
2341 2341 grafting 1:2294ae80ad84 "content2"
2342 2342 $ echo 3 > a
2343 2343 $ hg commit -m 'content3'
2344 2344 $ hg log -G
2345 2345 @ changeset: 4:50b9b36e9c5d
2346 2346 | tag: tip
2347 2347 | user: test
2348 2348 | date: Thu Jan 01 00:00:00 1970 +0000
2349 2349 | summary: content3
2350 2350 |
2351 2351 o changeset: 3:15b2327059e5
2352 2352 | user: test
2353 2353 | date: Thu Jan 01 00:00:00 1970 +0000
2354 2354 | summary: content2
2355 2355 |
2356 2356 o changeset: 2:2029acd1168c
2357 2357 | parent: 0:ae0a3c9f9e95
2358 2358 | user: test
2359 2359 | date: Thu Jan 01 00:00:00 1970 +0000
2360 2360 | summary: unrelated
2361 2361 |
2362 2362 | o changeset: 1:2294ae80ad84
2363 2363 |/ user: test
2364 2364 | date: Thu Jan 01 00:00:00 1970 +0000
2365 2365 | summary: content2
2366 2366 |
2367 2367 o changeset: 0:ae0a3c9f9e95
2368 2368 user: test
2369 2369 date: Thu Jan 01 00:00:00 1970 +0000
2370 2370 summary: content1
2371 2371
2372 2372
2373 2373 log -f on the file should list the graft result.
2374 2374
2375 2375 $ hg log -Gf a
2376 2376 @ changeset: 4:50b9b36e9c5d
2377 2377 | tag: tip
2378 2378 | user: test
2379 2379 | date: Thu Jan 01 00:00:00 1970 +0000
2380 2380 | summary: content3
2381 2381 |
2382 2382 o changeset: 3:15b2327059e5
2383 2383 : user: test
2384 2384 : date: Thu Jan 01 00:00:00 1970 +0000
2385 2385 : summary: content2
2386 2386 :
2387 2387 o changeset: 0:ae0a3c9f9e95
2388 2388 user: test
2389 2389 date: Thu Jan 01 00:00:00 1970 +0000
2390 2390 summary: content1
2391 2391
2392 2392
2393 2393 plain log lists the original version
2394 2394 (XXX we should probably list both)
2395 2395
2396 2396 $ hg log -G a
2397 2397 @ changeset: 4:50b9b36e9c5d
2398 2398 : tag: tip
2399 2399 : user: test
2400 2400 : date: Thu Jan 01 00:00:00 1970 +0000
2401 2401 : summary: content3
2402 2402 :
2403 2403 : o changeset: 1:2294ae80ad84
2404 2404 :/ user: test
2405 2405 : date: Thu Jan 01 00:00:00 1970 +0000
2406 2406 : summary: content2
2407 2407 :
2408 2408 o changeset: 0:ae0a3c9f9e95
2409 2409 user: test
2410 2410 date: Thu Jan 01 00:00:00 1970 +0000
2411 2411 summary: content1
2412 2412
2413 2413
2414 2414 hg log -f from the grafted changeset
2415 2415 (The bootstrap should properly take the topology in account)
2416 2416
2417 2417 $ hg up 'desc(content3)^'
2418 2418 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2419 2419 $ hg log -Gf a
2420 2420 @ changeset: 3:15b2327059e5
2421 2421 : user: test
2422 2422 : date: Thu Jan 01 00:00:00 1970 +0000
2423 2423 : summary: content2
2424 2424 :
2425 2425 o changeset: 0:ae0a3c9f9e95
2426 2426 user: test
2427 2427 date: Thu Jan 01 00:00:00 1970 +0000
2428 2428 summary: content1
2429 2429
2430 2430
2431 2431 Test that we use the first non-hidden changeset in that case.
2432 2432
2433 2433 (hide the changeset)
2434 2434
2435 2435 $ hg log -T '{node}\n' -r 1
2436 2436 2294ae80ad8447bc78383182eeac50cb049df623
2437 2437 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
2438 2438 obsoleted 1 changesets
2439 2439 $ hg log -G
2440 2440 o changeset: 4:50b9b36e9c5d
2441 2441 | tag: tip
2442 2442 | user: test
2443 2443 | date: Thu Jan 01 00:00:00 1970 +0000
2444 2444 | summary: content3
2445 2445 |
2446 2446 @ changeset: 3:15b2327059e5
2447 2447 | user: test
2448 2448 | date: Thu Jan 01 00:00:00 1970 +0000
2449 2449 | summary: content2
2450 2450 |
2451 2451 o changeset: 2:2029acd1168c
2452 2452 | parent: 0:ae0a3c9f9e95
2453 2453 | user: test
2454 2454 | date: Thu Jan 01 00:00:00 1970 +0000
2455 2455 | summary: unrelated
2456 2456 |
2457 2457 o changeset: 0:ae0a3c9f9e95
2458 2458 user: test
2459 2459 date: Thu Jan 01 00:00:00 1970 +0000
2460 2460 summary: content1
2461 2461
2462 2462
2463 2463 Check that log on the file does not drop the file revision.
2464 2464
2465 2465 $ hg log -G a
2466 2466 o changeset: 4:50b9b36e9c5d
2467 2467 | tag: tip
2468 2468 | user: test
2469 2469 | date: Thu Jan 01 00:00:00 1970 +0000
2470 2470 | summary: content3
2471 2471 |
2472 2472 @ changeset: 3:15b2327059e5
2473 2473 : user: test
2474 2474 : date: Thu Jan 01 00:00:00 1970 +0000
2475 2475 : summary: content2
2476 2476 :
2477 2477 o changeset: 0:ae0a3c9f9e95
2478 2478 user: test
2479 2479 date: Thu Jan 01 00:00:00 1970 +0000
2480 2480 summary: content1
2481 2481
2482 2482
2483 2483 Even when a head revision is linkrev-shadowed.
2484 2484
2485 2485 $ hg log -T '{node}\n' -r 4
2486 2486 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2487 2487 $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2488 2488 obsoleted 1 changesets
2489 2489 $ hg log -G a
2490 2490 @ changeset: 3:15b2327059e5
2491 2491 : tag: tip
2492 2492 : user: test
2493 2493 : date: Thu Jan 01 00:00:00 1970 +0000
2494 2494 : summary: content2
2495 2495 :
2496 2496 o changeset: 0:ae0a3c9f9e95
2497 2497 user: test
2498 2498 date: Thu Jan 01 00:00:00 1970 +0000
2499 2499 summary: content1
2500 2500
2501 2501
2502 2502 $ cd ..
2503 2503
2504 2504 Even when the file revision is missing from some head:
2505 2505
2506 2506 $ hg init issue4490
2507 2507 $ cd issue4490
2508 2508 $ echo '[experimental]' >> .hg/hgrc
2509 2509 $ echo 'evolution.createmarkers=True' >> .hg/hgrc
2510 2510 $ echo a > a
2511 2511 $ hg ci -Am0
2512 2512 adding a
2513 2513 $ echo b > b
2514 2514 $ hg ci -Am1
2515 2515 adding b
2516 2516 $ echo B > b
2517 2517 $ hg ci --amend -m 1
2518 2518 $ hg up 0
2519 2519 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2520 2520 $ echo c > c
2521 2521 $ hg ci -Am2
2522 2522 adding c
2523 2523 created new head
2524 2524 $ hg up 'head() and not .'
2525 2525 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
2526 2526 $ hg log -G
2527 2527 o changeset: 3:db815d6d32e6
2528 2528 | tag: tip
2529 2529 | parent: 0:f7b1eb17ad24
2530 2530 | user: test
2531 2531 | date: Thu Jan 01 00:00:00 1970 +0000
2532 2532 | summary: 2
2533 2533 |
2534 2534 | @ changeset: 2:9bc8ce7f9356
2535 2535 |/ parent: 0:f7b1eb17ad24
2536 2536 | user: test
2537 2537 | date: Thu Jan 01 00:00:00 1970 +0000
2538 2538 | summary: 1
2539 2539 |
2540 2540 o changeset: 0:f7b1eb17ad24
2541 2541 user: test
2542 2542 date: Thu Jan 01 00:00:00 1970 +0000
2543 2543 summary: 0
2544 2544
2545 2545 $ hg log -f -G b
2546 2546 @ changeset: 2:9bc8ce7f9356
2547 2547 | parent: 0:f7b1eb17ad24
2548 2548 ~ user: test
2549 2549 date: Thu Jan 01 00:00:00 1970 +0000
2550 2550 summary: 1
2551 2551
2552 2552 $ hg log -G b
2553 2553 @ changeset: 2:9bc8ce7f9356
2554 2554 | parent: 0:f7b1eb17ad24
2555 2555 ~ user: test
2556 2556 date: Thu Jan 01 00:00:00 1970 +0000
2557 2557 summary: 1
2558 2558
2559 2559 $ cd ..
2560 2560
2561 2561 Check proper report when the manifest changes but not the file issue4499
2562 2562 ------------------------------------------------------------------------
2563 2563
2564 2564 $ hg init issue4499
2565 2565 $ cd issue4499
2566 2566 $ 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
2567 2567 > echo 1 > $f;
2568 2568 > hg add $f;
2569 2569 > done
2570 2570 $ hg commit -m 'A1B1C1'
2571 2571 $ echo 2 > A
2572 2572 $ echo 2 > B
2573 2573 $ echo 2 > C
2574 2574 $ hg commit -m 'A2B2C2'
2575 2575 $ hg up 0
2576 2576 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2577 2577 $ echo 3 > A
2578 2578 $ echo 2 > B
2579 2579 $ echo 2 > C
2580 2580 $ hg commit -m 'A3B2C2'
2581 2581 created new head
2582 2582
2583 2583 $ hg log -G
2584 2584 @ changeset: 2:fe5fc3d0eb17
2585 2585 | tag: tip
2586 2586 | parent: 0:abf4f0e38563
2587 2587 | user: test
2588 2588 | date: Thu Jan 01 00:00:00 1970 +0000
2589 2589 | summary: A3B2C2
2590 2590 |
2591 2591 | o changeset: 1:07dcc6b312c0
2592 2592 |/ user: test
2593 2593 | date: Thu Jan 01 00:00:00 1970 +0000
2594 2594 | summary: A2B2C2
2595 2595 |
2596 2596 o changeset: 0:abf4f0e38563
2597 2597 user: test
2598 2598 date: Thu Jan 01 00:00:00 1970 +0000
2599 2599 summary: A1B1C1
2600 2600
2601 2601
2602 2602 Log -f on B should reports current changesets
2603 2603
2604 2604 $ hg log -fG B
2605 2605 @ changeset: 2:fe5fc3d0eb17
2606 2606 | tag: tip
2607 2607 | parent: 0:abf4f0e38563
2608 2608 | user: test
2609 2609 | date: Thu Jan 01 00:00:00 1970 +0000
2610 2610 | summary: A3B2C2
2611 2611 |
2612 2612 o changeset: 0:abf4f0e38563
2613 2613 user: test
2614 2614 date: Thu Jan 01 00:00:00 1970 +0000
2615 2615 summary: A1B1C1
2616 2616
2617 2617 $ cd ..
@@ -1,489 +1,489 b''
1 1 from __future__ import absolute_import
2 2
3 3 import binascii
4 4 import itertools
5 5 import silenttestrunner
6 6 import unittest
7 7
8 8 from mercurial import (
9 9 manifest as manifestmod,
10 10 match as matchmod,
11 11 )
12 12
13 13 EMTPY_MANIFEST = b''
14 14 EMTPY_MANIFEST_V2 = b'\0\n'
15 15
16 16 HASH_1 = b'1' * 40
17 17 BIN_HASH_1 = binascii.unhexlify(HASH_1)
18 18 HASH_2 = b'f' * 40
19 19 BIN_HASH_2 = binascii.unhexlify(HASH_2)
20 20 HASH_3 = b'1234567890abcdef0987654321deadbeef0fcafe'
21 21 BIN_HASH_3 = binascii.unhexlify(HASH_3)
22 22 A_SHORT_MANIFEST = (
23 23 b'bar/baz/qux.py\0%(hash2)s%(flag2)s\n'
24 24 b'foo\0%(hash1)s%(flag1)s\n'
25 25 ) % {b'hash1': HASH_1,
26 26 b'flag1': b'',
27 27 b'hash2': HASH_2,
28 28 b'flag2': b'l',
29 29 }
30 30
31 31 # Same data as A_SHORT_MANIFEST
32 32 A_SHORT_MANIFEST_V2 = (
33 33 b'\0\n'
34 34 b'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
35 35 b'\x00foo\0%(flag1)s\n%(hash1)s\n'
36 36 ) % {b'hash1': BIN_HASH_1,
37 37 b'flag1': b'',
38 38 b'hash2': BIN_HASH_2,
39 39 b'flag2': b'l',
40 40 }
41 41
42 42 # Same data as A_SHORT_MANIFEST
43 43 A_METADATA_MANIFEST = (
44 44 b'\0foo\0bar\n'
45 45 b'\x00bar/baz/qux.py\0%(flag2)s\0foo\0bar\n%(hash2)s\n' # flag and metadata
46 46 b'\x00foo\0%(flag1)s\0foo\n%(hash1)s\n' # no flag, but metadata
47 47 ) % {b'hash1': BIN_HASH_1,
48 48 b'flag1': b'',
49 49 b'hash2': BIN_HASH_2,
50 50 b'flag2': b'l',
51 51 }
52 52
53 53 A_STEM_COMPRESSED_MANIFEST = (
54 54 b'\0\n'
55 55 b'\x00bar/baz/qux.py\0%(flag2)s\n%(hash2)s\n'
56 56 b'\x04qux/foo.py\0%(flag1)s\n%(hash1)s\n' # simple case of 4 stem chars
57 57 b'\x0az.py\0%(flag1)s\n%(hash1)s\n' # tricky newline = 10 stem characters
58 58 b'\x00%(verylongdir)sx/x\0\n%(hash1)s\n'
59 59 b'\xffx/y\0\n%(hash2)s\n' # more than 255 stem chars
60 60 ) % {b'hash1': BIN_HASH_1,
61 61 b'flag1': b'',
62 62 b'hash2': BIN_HASH_2,
63 63 b'flag2': b'l',
64 64 b'verylongdir': 255 * b'x',
65 65 }
66 66
67 67 A_DEEPER_MANIFEST = (
68 68 b'a/b/c/bar.py\0%(hash3)s%(flag1)s\n'
69 69 b'a/b/c/bar.txt\0%(hash1)s%(flag1)s\n'
70 70 b'a/b/c/foo.py\0%(hash3)s%(flag1)s\n'
71 71 b'a/b/c/foo.txt\0%(hash2)s%(flag2)s\n'
72 72 b'a/b/d/baz.py\0%(hash3)s%(flag1)s\n'
73 73 b'a/b/d/qux.py\0%(hash1)s%(flag2)s\n'
74 74 b'a/b/d/ten.txt\0%(hash3)s%(flag2)s\n'
75 75 b'a/b/dog.py\0%(hash3)s%(flag1)s\n'
76 76 b'a/b/fish.py\0%(hash2)s%(flag1)s\n'
77 77 b'a/c/london.py\0%(hash3)s%(flag2)s\n'
78 78 b'a/c/paper.txt\0%(hash2)s%(flag2)s\n'
79 79 b'a/c/paris.py\0%(hash2)s%(flag1)s\n'
80 80 b'a/d/apple.py\0%(hash3)s%(flag1)s\n'
81 81 b'a/d/pizza.py\0%(hash3)s%(flag2)s\n'
82 82 b'a/green.py\0%(hash1)s%(flag2)s\n'
83 83 b'a/purple.py\0%(hash2)s%(flag1)s\n'
84 84 b'app.py\0%(hash3)s%(flag1)s\n'
85 85 b'readme.txt\0%(hash2)s%(flag1)s\n'
86 86 ) % {b'hash1': HASH_1,
87 87 b'flag1': b'',
88 88 b'hash2': HASH_2,
89 89 b'flag2': b'l',
90 90 b'hash3': HASH_3,
91 91 }
92 92
93 93 HUGE_MANIFEST_ENTRIES = 200001
94 94
95 95 izip = getattr(itertools, 'izip', zip)
96 96 if 'xrange' not in globals():
97 97 xrange = range
98 98
99 99 A_HUGE_MANIFEST = b''.join(sorted(
100 100 b'file%d\0%s%s\n' % (i, h, f) for i, h, f in
101 101 izip(xrange(200001),
102 102 itertools.cycle((HASH_1, HASH_2)),
103 103 itertools.cycle((b'', b'x', b'l')))))
104 104
105 105 class basemanifesttests(object):
106 106 def parsemanifest(self, text):
107 107 raise NotImplementedError('parsemanifest not implemented by test case')
108 108
109 109 def testEmptyManifest(self):
110 110 m = self.parsemanifest(EMTPY_MANIFEST)
111 111 self.assertEqual(0, len(m))
112 112 self.assertEqual([], list(m))
113 113
114 114 def testEmptyManifestv2(self):
115 115 m = self.parsemanifest(EMTPY_MANIFEST_V2)
116 116 self.assertEqual(0, len(m))
117 117 self.assertEqual([], list(m))
118 118
119 119 def testManifest(self):
120 120 m = self.parsemanifest(A_SHORT_MANIFEST)
121 121 self.assertEqual([b'bar/baz/qux.py', b'foo'], list(m))
122 122 self.assertEqual(BIN_HASH_2, m[b'bar/baz/qux.py'])
123 123 self.assertEqual(b'l', m.flags(b'bar/baz/qux.py'))
124 124 self.assertEqual(BIN_HASH_1, m[b'foo'])
125 125 self.assertEqual(b'', m.flags(b'foo'))
126 126 with self.assertRaises(KeyError):
127 127 m[b'wat']
128 128
129 129 def testParseManifestV2(self):
130 130 m1 = self.parsemanifest(A_SHORT_MANIFEST)
131 131 m2 = self.parsemanifest(A_SHORT_MANIFEST_V2)
132 132 # Should have same content as A_SHORT_MANIFEST
133 133 self.assertEqual(m1.text(), m2.text())
134 134
135 135 def testParseManifestMetadata(self):
136 136 # Metadata is for future-proofing and should be accepted but ignored
137 137 m = self.parsemanifest(A_METADATA_MANIFEST)
138 138 self.assertEqual(A_SHORT_MANIFEST, m.text())
139 139
140 140 def testParseManifestStemCompression(self):
141 141 m = self.parsemanifest(A_STEM_COMPRESSED_MANIFEST)
142 142 self.assertIn(b'bar/baz/qux.py', m)
143 143 self.assertIn(b'bar/qux/foo.py', m)
144 144 self.assertIn(b'bar/qux/foz.py', m)
145 145 self.assertIn(256 * b'x' + b'/x', m)
146 146 self.assertIn(256 * b'x' + b'/y', m)
147 147 self.assertEqual(A_STEM_COMPRESSED_MANIFEST, m.text(usemanifestv2=True))
148 148
149 149 def testTextV2(self):
150 150 m1 = self.parsemanifest(A_SHORT_MANIFEST)
151 151 v2text = m1.text(usemanifestv2=True)
152 152 self.assertEqual(A_SHORT_MANIFEST_V2, v2text)
153 153
154 154 def testSetItem(self):
155 155 want = BIN_HASH_1
156 156
157 157 m = self.parsemanifest(EMTPY_MANIFEST)
158 158 m[b'a'] = want
159 159 self.assertIn(b'a', m)
160 160 self.assertEqual(want, m[b'a'])
161 161 self.assertEqual(b'a\0' + HASH_1 + b'\n', m.text())
162 162
163 163 m = self.parsemanifest(A_SHORT_MANIFEST)
164 164 m[b'a'] = want
165 165 self.assertEqual(want, m[b'a'])
166 166 self.assertEqual(b'a\0' + HASH_1 + b'\n' + A_SHORT_MANIFEST,
167 167 m.text())
168 168
169 169 def testSetFlag(self):
170 170 want = b'x'
171 171
172 172 m = self.parsemanifest(EMTPY_MANIFEST)
173 173 # first add a file; a file-less flag makes no sense
174 174 m[b'a'] = BIN_HASH_1
175 175 m.setflag(b'a', want)
176 176 self.assertEqual(want, m.flags(b'a'))
177 177 self.assertEqual(b'a\0' + HASH_1 + want + b'\n', m.text())
178 178
179 179 m = self.parsemanifest(A_SHORT_MANIFEST)
180 180 # first add a file; a file-less flag makes no sense
181 181 m[b'a'] = BIN_HASH_1
182 182 m.setflag(b'a', want)
183 183 self.assertEqual(want, m.flags(b'a'))
184 184 self.assertEqual(b'a\0' + HASH_1 + want + b'\n' + A_SHORT_MANIFEST,
185 185 m.text())
186 186
187 187 def testCopy(self):
188 188 m = self.parsemanifest(A_SHORT_MANIFEST)
189 189 m[b'a'] = BIN_HASH_1
190 190 m2 = m.copy()
191 191 del m
192 192 del m2 # make sure we don't double free() anything
193 193
194 194 def testCompaction(self):
195 195 unhex = binascii.unhexlify
196 196 h1, h2 = unhex(HASH_1), unhex(HASH_2)
197 197 m = self.parsemanifest(A_SHORT_MANIFEST)
198 198 m[b'alpha'] = h1
199 199 m[b'beta'] = h2
200 200 del m[b'foo']
201 201 want = b'alpha\0%s\nbar/baz/qux.py\0%sl\nbeta\0%s\n' % (
202 202 HASH_1, HASH_2, HASH_2)
203 203 self.assertEqual(want, m.text())
204 204 self.assertEqual(3, len(m))
205 205 self.assertEqual([b'alpha', b'bar/baz/qux.py', b'beta'], list(m))
206 206 self.assertEqual(h1, m[b'alpha'])
207 207 self.assertEqual(h2, m[b'bar/baz/qux.py'])
208 208 self.assertEqual(h2, m[b'beta'])
209 209 self.assertEqual(b'', m.flags(b'alpha'))
210 210 self.assertEqual(b'l', m.flags(b'bar/baz/qux.py'))
211 211 self.assertEqual(b'', m.flags(b'beta'))
212 212 with self.assertRaises(KeyError):
213 213 m[b'foo']
214 214
215 215 def testSetGetNodeSuffix(self):
216 216 clean = self.parsemanifest(A_SHORT_MANIFEST)
217 217 m = self.parsemanifest(A_SHORT_MANIFEST)
218 218 h = m[b'foo']
219 219 f = m.flags(b'foo')
220 220 want = h + b'a'
221 221 # Merge code wants to set 21-byte fake hashes at times
222 222 m[b'foo'] = want
223 223 self.assertEqual(want, m[b'foo'])
224 224 self.assertEqual([(b'bar/baz/qux.py', BIN_HASH_2),
225 225 (b'foo', BIN_HASH_1 + b'a')],
226 list(m.iteritems()))
226 list(m.items()))
227 227 # Sometimes it even tries a 22-byte fake hash, but we can
228 228 # return 21 and it'll work out
229 229 m[b'foo'] = want + b'+'
230 230 self.assertEqual(want, m[b'foo'])
231 231 # make sure the suffix survives a copy
232 232 match = matchmod.match(b'', b'', [b're:foo'])
233 233 m2 = m.matches(match)
234 234 self.assertEqual(want, m2[b'foo'])
235 235 self.assertEqual(1, len(m2))
236 236 m2 = m.copy()
237 237 self.assertEqual(want, m2[b'foo'])
238 238 # suffix with iteration
239 239 self.assertEqual([(b'bar/baz/qux.py', BIN_HASH_2),
240 240 (b'foo', want)],
241 list(m.iteritems()))
241 list(m.items()))
242 242
243 243 # shows up in diff
244 244 self.assertEqual({b'foo': ((want, f), (h, b''))}, m.diff(clean))
245 245 self.assertEqual({b'foo': ((h, b''), (want, f))}, clean.diff(m))
246 246
247 247 def testMatchException(self):
248 248 m = self.parsemanifest(A_SHORT_MANIFEST)
249 249 match = matchmod.match(b'', b'', [b're:.*'])
250 250 def filt(path):
251 251 if path == b'foo':
252 252 assert False
253 253 return True
254 254 match.matchfn = filt
255 255 with self.assertRaises(AssertionError):
256 256 m.matches(match)
257 257
258 258 def testRemoveItem(self):
259 259 m = self.parsemanifest(A_SHORT_MANIFEST)
260 260 del m[b'foo']
261 261 with self.assertRaises(KeyError):
262 262 m[b'foo']
263 263 self.assertEqual(1, len(m))
264 264 self.assertEqual(1, len(list(m)))
265 265 # now restore and make sure everything works right
266 266 m[b'foo'] = b'a' * 20
267 267 self.assertEqual(2, len(m))
268 268 self.assertEqual(2, len(list(m)))
269 269
270 270 def testManifestDiff(self):
271 271 MISSING = (None, b'')
272 272 addl = b'z-only-in-left\0' + HASH_1 + b'\n'
273 273 addr = b'z-only-in-right\0' + HASH_2 + b'x\n'
274 274 left = self.parsemanifest(
275 275 A_SHORT_MANIFEST.replace(HASH_1, HASH_3 + b'x') + addl)
276 276 right = self.parsemanifest(A_SHORT_MANIFEST + addr)
277 277 want = {
278 278 b'foo': ((BIN_HASH_3, b'x'),
279 279 (BIN_HASH_1, b'')),
280 280 b'z-only-in-left': ((BIN_HASH_1, b''), MISSING),
281 281 b'z-only-in-right': (MISSING, (BIN_HASH_2, b'x')),
282 282 }
283 283 self.assertEqual(want, left.diff(right))
284 284
285 285 want = {
286 286 b'bar/baz/qux.py': (MISSING, (BIN_HASH_2, b'l')),
287 287 b'foo': (MISSING, (BIN_HASH_3, b'x')),
288 288 b'z-only-in-left': (MISSING, (BIN_HASH_1, b'')),
289 289 }
290 290 self.assertEqual(want, self.parsemanifest(EMTPY_MANIFEST).diff(left))
291 291
292 292 want = {
293 293 b'bar/baz/qux.py': ((BIN_HASH_2, b'l'), MISSING),
294 294 b'foo': ((BIN_HASH_3, b'x'), MISSING),
295 295 b'z-only-in-left': ((BIN_HASH_1, b''), MISSING),
296 296 }
297 297 self.assertEqual(want, left.diff(self.parsemanifest(EMTPY_MANIFEST)))
298 298 copy = right.copy()
299 299 del copy[b'z-only-in-right']
300 300 del right[b'foo']
301 301 want = {
302 302 b'foo': (MISSING, (BIN_HASH_1, b'')),
303 303 b'z-only-in-right': ((BIN_HASH_2, b'x'), MISSING),
304 304 }
305 305 self.assertEqual(want, right.diff(copy))
306 306
307 307 short = self.parsemanifest(A_SHORT_MANIFEST)
308 308 pruned = short.copy()
309 309 del pruned[b'foo']
310 310 want = {
311 311 b'foo': ((BIN_HASH_1, b''), MISSING),
312 312 }
313 313 self.assertEqual(want, short.diff(pruned))
314 314 want = {
315 315 b'foo': (MISSING, (BIN_HASH_1, b'')),
316 316 }
317 317 self.assertEqual(want, pruned.diff(short))
318 318 want = {
319 319 b'bar/baz/qux.py': None,
320 320 b'foo': (MISSING, (BIN_HASH_1, b'')),
321 321 }
322 322 self.assertEqual(want, pruned.diff(short, clean=True))
323 323
324 324 def testReversedLines(self):
325 325 backwards = b''.join(
326 326 l + b'\n' for l in reversed(A_SHORT_MANIFEST.split(b'\n')) if l)
327 327 try:
328 328 self.parsemanifest(backwards)
329 329 self.fail('Should have raised ValueError')
330 330 except ValueError as v:
331 331 self.assertIn('Manifest lines not in sorted order.', str(v))
332 332
333 333 def testNoTerminalNewline(self):
334 334 try:
335 335 self.parsemanifest(A_SHORT_MANIFEST + b'wat')
336 336 self.fail('Should have raised ValueError')
337 337 except ValueError as v:
338 338 self.assertIn('Manifest did not end in a newline.', str(v))
339 339
340 340 def testNoNewLineAtAll(self):
341 341 try:
342 342 self.parsemanifest(b'wat')
343 343 self.fail('Should have raised ValueError')
344 344 except ValueError as v:
345 345 self.assertIn('Manifest did not end in a newline.', str(v))
346 346
347 347 def testHugeManifest(self):
348 348 m = self.parsemanifest(A_HUGE_MANIFEST)
349 349 self.assertEqual(HUGE_MANIFEST_ENTRIES, len(m))
350 350 self.assertEqual(len(m), len(list(m)))
351 351
352 352 def testMatchesMetadata(self):
353 353 '''Tests matches() for a few specific files to make sure that both
354 354 the set of files as well as their flags and nodeids are correct in
355 355 the resulting manifest.'''
356 356 m = self.parsemanifest(A_HUGE_MANIFEST)
357 357
358 358 match = matchmod.match(b'/', b'',
359 359 [b'file1', b'file200', b'file300'], exact=True)
360 360 m2 = m.matches(match)
361 361
362 362 w = (b'file1\0%sx\n'
363 363 b'file200\0%sl\n'
364 364 b'file300\0%s\n') % (HASH_2, HASH_1, HASH_1)
365 365 self.assertEqual(w, m2.text())
366 366
367 367 def testMatchesNonexistentFile(self):
368 368 '''Tests matches() for a small set of specific files, including one
369 369 nonexistent file to make sure in only matches against existing files.
370 370 '''
371 371 m = self.parsemanifest(A_DEEPER_MANIFEST)
372 372
373 373 match = matchmod.match(b'/', b'',
374 374 [b'a/b/c/bar.txt', b'a/b/d/qux.py',
375 375 b'readme.txt', b'nonexistent'],
376 376 exact=True)
377 377 m2 = m.matches(match)
378 378
379 379 self.assertEqual(
380 380 [b'a/b/c/bar.txt', b'a/b/d/qux.py', b'readme.txt'],
381 381 m2.keys())
382 382
383 383 def testMatchesNonexistentDirectory(self):
384 384 '''Tests matches() for a relpath match on a directory that doesn't
385 385 actually exist.'''
386 386 m = self.parsemanifest(A_DEEPER_MANIFEST)
387 387
388 388 match = matchmod.match(b'/', b'', [b'a/f'], default=b'relpath')
389 389 m2 = m.matches(match)
390 390
391 391 self.assertEqual([], m2.keys())
392 392
393 393 def testMatchesExactLarge(self):
394 394 '''Tests matches() for files matching a large list of exact files.
395 395 '''
396 396 m = self.parsemanifest(A_HUGE_MANIFEST)
397 397
398 398 flist = m.keys()[80:300]
399 399 match = matchmod.match(b'/', b'', flist, exact=True)
400 400 m2 = m.matches(match)
401 401
402 402 self.assertEqual(flist, m2.keys())
403 403
404 404 def testMatchesFull(self):
405 405 '''Tests matches() for what should be a full match.'''
406 406 m = self.parsemanifest(A_DEEPER_MANIFEST)
407 407
408 408 match = matchmod.match(b'/', b'', [b''])
409 409 m2 = m.matches(match)
410 410
411 411 self.assertEqual(m.keys(), m2.keys())
412 412
413 413 def testMatchesDirectory(self):
414 414 '''Tests matches() on a relpath match on a directory, which should
415 415 match against all files within said directory.'''
416 416 m = self.parsemanifest(A_DEEPER_MANIFEST)
417 417
418 418 match = matchmod.match(b'/', b'', [b'a/b'], default=b'relpath')
419 419 m2 = m.matches(match)
420 420
421 421 self.assertEqual([
422 422 b'a/b/c/bar.py', b'a/b/c/bar.txt', b'a/b/c/foo.py',
423 423 b'a/b/c/foo.txt',
424 424 b'a/b/d/baz.py', b'a/b/d/qux.py', b'a/b/d/ten.txt', b'a/b/dog.py',
425 425 b'a/b/fish.py'], m2.keys())
426 426
427 427 def testMatchesExactPath(self):
428 428 '''Tests matches() on an exact match on a directory, which should
429 429 result in an empty manifest because you can't perform an exact match
430 430 against a directory.'''
431 431 m = self.parsemanifest(A_DEEPER_MANIFEST)
432 432
433 433 match = matchmod.match(b'/', b'', [b'a/b'], exact=True)
434 434 m2 = m.matches(match)
435 435
436 436 self.assertEqual([], m2.keys())
437 437
438 438 def testMatchesCwd(self):
439 439 '''Tests matches() on a relpath match with the current directory ('.')
440 440 when not in the root directory.'''
441 441 m = self.parsemanifest(A_DEEPER_MANIFEST)
442 442
443 443 match = matchmod.match(b'/', b'a/b', [b'.'], default=b'relpath')
444 444 m2 = m.matches(match)
445 445
446 446 self.assertEqual([
447 447 b'a/b/c/bar.py', b'a/b/c/bar.txt', b'a/b/c/foo.py',
448 448 b'a/b/c/foo.txt', b'a/b/d/baz.py', b'a/b/d/qux.py',
449 449 b'a/b/d/ten.txt', b'a/b/dog.py', b'a/b/fish.py'], m2.keys())
450 450
451 451 def testMatchesWithPattern(self):
452 452 '''Tests matches() for files matching a pattern that reside
453 453 deeper than the specified directory.'''
454 454 m = self.parsemanifest(A_DEEPER_MANIFEST)
455 455
456 456 match = matchmod.match(b'/', b'', [b'a/b/*/*.txt'])
457 457 m2 = m.matches(match)
458 458
459 459 self.assertEqual(
460 460 [b'a/b/c/bar.txt', b'a/b/c/foo.txt', b'a/b/d/ten.txt'],
461 461 m2.keys())
462 462
463 463 class testmanifestdict(unittest.TestCase, basemanifesttests):
464 464 def parsemanifest(self, text):
465 465 return manifestmod.manifestdict(text)
466 466
467 467 class testtreemanifest(unittest.TestCase, basemanifesttests):
468 468 def parsemanifest(self, text):
469 469 return manifestmod.treemanifest(b'', text)
470 470
471 471 def testWalkSubtrees(self):
472 472 m = self.parsemanifest(A_DEEPER_MANIFEST)
473 473
474 474 dirs = [s._dir for s in m.walksubtrees()]
475 475 self.assertEqual(
476 476 sorted([
477 477 b'', b'a/', b'a/c/', b'a/d/', b'a/b/', b'a/b/c/', b'a/b/d/']),
478 478 sorted(dirs)
479 479 )
480 480
481 481 match = matchmod.match(b'/', b'', [b'path:a/b/'])
482 482 dirs = [s._dir for s in m.walksubtrees(matcher=match)]
483 483 self.assertEqual(
484 484 sorted([b'a/b/', b'a/b/c/', b'a/b/d/']),
485 485 sorted(dirs)
486 486 )
487 487
488 488 if __name__ == '__main__':
489 489 silenttestrunner.main(__name__)
@@ -1,24 +1,24 b''
1 1 from __future__ import absolute_import
2 2 from __future__ import print_function
3 3
4 4 import unittest
5 5
6 6 from mercurial import (
7 7 mdiff,
8 8 )
9 9
10 10 class splitnewlinesTests(unittest.TestCase):
11 11
12 12 def test_splitnewlines(self):
13 13 cases = {'a\nb\nc\n': ['a\n', 'b\n', 'c\n'],
14 14 'a\nb\nc': ['a\n', 'b\n', 'c'],
15 15 'a\nb\nc\n\n': ['a\n', 'b\n', 'c\n', '\n'],
16 16 '': [],
17 17 'abcabc': ['abcabc'],
18 18 }
19 for inp, want in cases.iteritems():
19 for inp, want in cases.items():
20 20 self.assertEqual(mdiff.splitnewlines(inp), want)
21 21
22 22 if __name__ == '__main__':
23 23 import silenttestrunner
24 24 silenttestrunner.main(__name__)
@@ -1,209 +1,209 b''
1 1 # This is a randomized test that generates different pathnames every
2 2 # time it is invoked, and tests the encoding of those pathnames.
3 3 #
4 4 # It uses a simple probabilistic model to generate valid pathnames
5 5 # that have proven likely to expose bugs and divergent behavior in
6 6 # different encoding implementations.
7 7
8 8 from __future__ import absolute_import, print_function
9 9
10 10 import binascii
11 11 import collections
12 12 import itertools
13 13 import math
14 14 import os
15 15 import random
16 16 import sys
17 17 import time
18 18 from mercurial import (
19 19 store,
20 20 )
21 21
22 22 try:
23 23 xrange
24 24 except NameError:
25 25 xrange = range
26 26
27 27 validchars = set(map(chr, range(0, 256)))
28 28 alphanum = range(ord('A'), ord('Z'))
29 29
30 30 for c in '\0/':
31 31 validchars.remove(c)
32 32
33 33 winreserved = ('aux con prn nul'.split() +
34 34 ['com%d' % i for i in xrange(1, 10)] +
35 35 ['lpt%d' % i for i in xrange(1, 10)])
36 36
37 37 def casecombinations(names):
38 38 '''Build all case-diddled combinations of names.'''
39 39
40 40 combos = set()
41 41
42 42 for r in names:
43 43 for i in xrange(len(r) + 1):
44 44 for c in itertools.combinations(xrange(len(r)), i):
45 45 d = r
46 46 for j in c:
47 47 d = ''.join((d[:j], d[j].upper(), d[j + 1:]))
48 48 combos.add(d)
49 49 return sorted(combos)
50 50
51 51 def buildprobtable(fp, cmd='hg manifest tip'):
52 52 '''Construct and print a table of probabilities for path name
53 53 components. The numbers are percentages.'''
54 54
55 55 counts = collections.defaultdict(lambda: 0)
56 56 for line in os.popen(cmd).read().splitlines():
57 57 if line[-2:] in ('.i', '.d'):
58 58 line = line[:-2]
59 59 if line.startswith('data/'):
60 60 line = line[5:]
61 61 for c in line:
62 62 counts[c] += 1
63 63 for c in '\r/\n':
64 64 counts.pop(c, None)
65 65 t = sum(counts.itervalues()) / 100.0
66 66 fp.write('probtable = (')
67 for i, (k, v) in enumerate(sorted(counts.iteritems(), key=lambda x: x[1],
67 for i, (k, v) in enumerate(sorted(counts.items(), key=lambda x: x[1],
68 68 reverse=True)):
69 69 if (i % 5) == 0:
70 70 fp.write('\n ')
71 71 vt = v / t
72 72 if vt < 0.0005:
73 73 break
74 74 fp.write('(%r, %.03f), ' % (k, vt))
75 75 fp.write('\n )\n')
76 76
77 77 # A table of character frequencies (as percentages), gleaned by
78 78 # looking at filelog names from a real-world, very large repo.
79 79
80 80 probtable = (
81 81 ('t', 9.828), ('e', 9.042), ('s', 8.011), ('a', 6.801), ('i', 6.618),
82 82 ('g', 5.053), ('r', 5.030), ('o', 4.887), ('p', 4.363), ('n', 4.258),
83 83 ('l', 3.830), ('h', 3.693), ('_', 3.659), ('.', 3.377), ('m', 3.194),
84 84 ('u', 2.364), ('d', 2.296), ('c', 2.163), ('b', 1.739), ('f', 1.625),
85 85 ('6', 0.666), ('j', 0.610), ('y', 0.554), ('x', 0.487), ('w', 0.477),
86 86 ('k', 0.476), ('v', 0.473), ('3', 0.336), ('1', 0.335), ('2', 0.326),
87 87 ('4', 0.310), ('5', 0.305), ('9', 0.302), ('8', 0.300), ('7', 0.299),
88 88 ('q', 0.298), ('0', 0.250), ('z', 0.223), ('-', 0.118), ('C', 0.095),
89 89 ('T', 0.087), ('F', 0.085), ('B', 0.077), ('S', 0.076), ('P', 0.076),
90 90 ('L', 0.059), ('A', 0.058), ('N', 0.051), ('D', 0.049), ('M', 0.046),
91 91 ('E', 0.039), ('I', 0.035), ('R', 0.035), ('G', 0.028), ('U', 0.026),
92 92 ('W', 0.025), ('O', 0.017), ('V', 0.015), ('H', 0.013), ('Q', 0.011),
93 93 ('J', 0.007), ('K', 0.005), ('+', 0.004), ('X', 0.003), ('Y', 0.001),
94 94 )
95 95
96 96 for c, _ in probtable:
97 97 validchars.remove(c)
98 98 validchars = list(validchars)
99 99
100 100 def pickfrom(rng, table):
101 101 c = 0
102 102 r = rng.random() * sum(i[1] for i in table)
103 103 for i, p in table:
104 104 c += p
105 105 if c >= r:
106 106 return i
107 107
108 108 reservedcombos = casecombinations(winreserved)
109 109
110 110 # The first component of a name following a slash.
111 111
112 112 firsttable = (
113 113 (lambda rng: pickfrom(rng, probtable), 90),
114 114 (lambda rng: rng.choice(validchars), 5),
115 115 (lambda rng: rng.choice(reservedcombos), 5),
116 116 )
117 117
118 118 # Components of a name following the first.
119 119
120 120 resttable = firsttable[:-1]
121 121
122 122 # Special suffixes.
123 123
124 124 internalsuffixcombos = casecombinations('.hg .i .d'.split())
125 125
126 126 # The last component of a path, before a slash or at the end of a name.
127 127
128 128 lasttable = resttable + (
129 129 (lambda rng: '', 95),
130 130 (lambda rng: rng.choice(internalsuffixcombos), 5),
131 131 )
132 132
133 133 def makepart(rng, k):
134 134 '''Construct a part of a pathname, without slashes.'''
135 135
136 136 p = pickfrom(rng, firsttable)(rng)
137 137 l = len(p)
138 138 ps = [p]
139 139 maxl = rng.randint(1, k)
140 140 while l < maxl:
141 141 p = pickfrom(rng, resttable)(rng)
142 142 l += len(p)
143 143 ps.append(p)
144 144 ps.append(pickfrom(rng, lasttable)(rng))
145 145 return ''.join(ps)
146 146
147 147 def makepath(rng, j, k):
148 148 '''Construct a complete pathname.'''
149 149
150 150 return ('data/' + '/'.join(makepart(rng, k) for _ in xrange(j)) +
151 151 rng.choice(['.d', '.i']))
152 152
153 153 def genpath(rng, count):
154 154 '''Generate random pathnames with gradually increasing lengths.'''
155 155
156 156 mink, maxk = 1, 4096
157 157 def steps():
158 158 for i in xrange(count):
159 159 yield mink + int(round(math.sqrt((maxk - mink) * float(i) / count)))
160 160 for k in steps():
161 161 x = rng.randint(1, k)
162 162 y = rng.randint(1, k)
163 163 yield makepath(rng, x, y)
164 164
165 165 def runtests(rng, seed, count):
166 166 nerrs = 0
167 167 for p in genpath(rng, count):
168 168 h = store._pathencode(p) # uses C implementation, if available
169 169 r = store._hybridencode(p, True) # reference implementation in Python
170 170 if h != r:
171 171 if nerrs == 0:
172 172 print('seed:', hex(seed)[:-1], file=sys.stderr)
173 173 print("\np: '%s'" % p.encode("string_escape"), file=sys.stderr)
174 174 print("h: '%s'" % h.encode("string_escape"), file=sys.stderr)
175 175 print("r: '%s'" % r.encode("string_escape"), file=sys.stderr)
176 176 nerrs += 1
177 177 return nerrs
178 178
179 179 def main():
180 180 import getopt
181 181
182 182 # Empirically observed to take about a second to run
183 183 count = 100
184 184 seed = None
185 185 opts, args = getopt.getopt(sys.argv[1:], 'c:s:',
186 186 ['build', 'count=', 'seed='])
187 187 for o, a in opts:
188 188 if o in ('-c', '--count'):
189 189 count = int(a)
190 190 elif o in ('-s', '--seed'):
191 191 seed = int(a, base=0) # accepts base 10 or 16 strings
192 192 elif o == '--build':
193 193 buildprobtable(sys.stdout,
194 194 'find .hg/store/data -type f && '
195 195 'cat .hg/store/fncache 2>/dev/null')
196 196 sys.exit(0)
197 197
198 198 if seed is None:
199 199 try:
200 200 seed = int(binascii.hexlify(os.urandom(16)), 16)
201 201 except AttributeError:
202 202 seed = int(time.time() * 1000)
203 203
204 204 rng = random.Random(seed)
205 205 if runtests(rng, seed, count):
206 206 sys.exit(1)
207 207
208 208 if __name__ == '__main__':
209 209 main()
@@ -1,60 +1,60 b''
1 1
2 2 $ cat > engine.py << EOF
3 3 >
4 4 > from mercurial import templater
5 5 >
6 6 > class mytemplater(object):
7 7 > def __init__(self, loader, filters, defaults, resources, aliases):
8 8 > self.loader = loader
9 9 > self._defaults = defaults
10 10 > self._resources = resources
11 11 >
12 12 > def process(self, t, map):
13 13 > tmpl = self.loader(t)
14 14 > props = self._defaults.copy()
15 15 > props.update(map)
16 > for k, v in props.iteritems():
16 > for k, v in props.items():
17 17 > if k in ('templ', 'ctx', 'repo', 'revcache', 'cache', 'troubles'):
18 18 > continue
19 19 > if hasattr(v, '__call__'):
20 20 > props = self._resources.copy()
21 21 > props.update(map)
22 22 > v = v(**props)
23 23 > v = templater.stringify(v)
24 24 > tmpl = tmpl.replace('{{%s}}' % k, v)
25 25 > yield tmpl
26 26 >
27 27 > templater.engines['my'] = mytemplater
28 28 > EOF
29 29 $ hg init test
30 30 $ echo '[extensions]' > test/.hg/hgrc
31 31 $ echo "engine = `pwd`/engine.py" >> test/.hg/hgrc
32 32 $ cd test
33 33 $ cat > mymap << EOF
34 34 > changeset = my:changeset.txt
35 35 > EOF
36 36 $ cat > changeset.txt << EOF
37 37 > {{rev}} {{node}} {{author}}
38 38 > EOF
39 39 $ hg ci -Ama
40 40 adding changeset.txt
41 41 adding mymap
42 42 $ hg log --style=./mymap
43 43 0 97e5f848f0936960273bbf75be6388cd0350a32b test
44 44
45 45 $ cat > changeset.txt << EOF
46 46 > {{p1rev}} {{p1node}} {{p2rev}} {{p2node}}
47 47 > EOF
48 48 $ hg ci -Ama
49 49 $ hg log --style=./mymap
50 50 0 97e5f848f0936960273bbf75be6388cd0350a32b -1 0000000000000000000000000000000000000000
51 51 -1 0000000000000000000000000000000000000000 -1 0000000000000000000000000000000000000000
52 52
53 53 invalid engine type:
54 54
55 55 $ echo 'changeset = unknown:changeset.txt' > unknownenginemap
56 56 $ hg log --style=./unknownenginemap
57 57 abort: invalid template engine: unknown
58 58 [255]
59 59
60 60 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now