##// END OF EJS Templates
py3: explicitly convert a list to bytes to pass in ui.debug...
Pulkit Goyal -
r32308:e8569cc1 default
parent child Browse files
Show More
@@ -1,1466 +1,1466
1 1 # Copyright 2009-2010 Gregory P. Ward
2 2 # Copyright 2009-2010 Intelerad Medical Systems Incorporated
3 3 # Copyright 2010-2011 Fog Creek Software
4 4 # Copyright 2010-2011 Unity Technologies
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 '''Overridden Mercurial commands and functions for the largefiles extension'''
10 10 from __future__ import absolute_import
11 11
12 12 import copy
13 13 import os
14 14
15 15 from mercurial.i18n import _
16 16
17 17 from mercurial import (
18 18 archival,
19 19 cmdutil,
20 20 error,
21 21 hg,
22 22 match as matchmod,
23 23 pathutil,
24 24 registrar,
25 25 scmutil,
26 26 smartset,
27 27 util,
28 28 )
29 29
30 30 from . import (
31 31 lfcommands,
32 32 lfutil,
33 33 storefactory,
34 34 )
35 35
36 36 # -- Utility functions: commonly/repeatedly needed functionality ---------------
37 37
38 38 def composelargefilematcher(match, manifest):
39 39 '''create a matcher that matches only the largefiles in the original
40 40 matcher'''
41 41 m = copy.copy(match)
42 42 lfile = lambda f: lfutil.standin(f) in manifest
43 43 m._files = filter(lfile, m._files)
44 44 m._fileroots = set(m._files)
45 45 m._always = False
46 46 origmatchfn = m.matchfn
47 47 m.matchfn = lambda f: lfile(f) and origmatchfn(f)
48 48 return m
49 49
50 50 def composenormalfilematcher(match, manifest, exclude=None):
51 51 excluded = set()
52 52 if exclude is not None:
53 53 excluded.update(exclude)
54 54
55 55 m = copy.copy(match)
56 56 notlfile = lambda f: not (lfutil.isstandin(f) or lfutil.standin(f) in
57 57 manifest or f in excluded)
58 58 m._files = filter(notlfile, m._files)
59 59 m._fileroots = set(m._files)
60 60 m._always = False
61 61 origmatchfn = m.matchfn
62 62 m.matchfn = lambda f: notlfile(f) and origmatchfn(f)
63 63 return m
64 64
65 65 def installnormalfilesmatchfn(manifest):
66 66 '''installmatchfn with a matchfn that ignores all largefiles'''
67 67 def overridematch(ctx, pats=(), opts=None, globbed=False,
68 68 default='relpath', badfn=None):
69 69 if opts is None:
70 70 opts = {}
71 71 match = oldmatch(ctx, pats, opts, globbed, default, badfn=badfn)
72 72 return composenormalfilematcher(match, manifest)
73 73 oldmatch = installmatchfn(overridematch)
74 74
75 75 def installmatchfn(f):
76 76 '''monkey patch the scmutil module with a custom match function.
77 77 Warning: it is monkey patching the _module_ on runtime! Not thread safe!'''
78 78 oldmatch = scmutil.match
79 79 setattr(f, 'oldmatch', oldmatch)
80 80 scmutil.match = f
81 81 return oldmatch
82 82
83 83 def restorematchfn():
84 84 '''restores scmutil.match to what it was before installmatchfn
85 85 was called. no-op if scmutil.match is its original function.
86 86
87 87 Note that n calls to installmatchfn will require n calls to
88 88 restore the original matchfn.'''
89 89 scmutil.match = getattr(scmutil.match, 'oldmatch')
90 90
91 91 def installmatchandpatsfn(f):
92 92 oldmatchandpats = scmutil.matchandpats
93 93 setattr(f, 'oldmatchandpats', oldmatchandpats)
94 94 scmutil.matchandpats = f
95 95 return oldmatchandpats
96 96
97 97 def restorematchandpatsfn():
98 98 '''restores scmutil.matchandpats to what it was before
99 99 installmatchandpatsfn was called. No-op if scmutil.matchandpats
100 100 is its original function.
101 101
102 102 Note that n calls to installmatchandpatsfn will require n calls
103 103 to restore the original matchfn.'''
104 104 scmutil.matchandpats = getattr(scmutil.matchandpats, 'oldmatchandpats',
105 105 scmutil.matchandpats)
106 106
107 107 def addlargefiles(ui, repo, isaddremove, matcher, **opts):
108 108 large = opts.get(r'large')
109 109 lfsize = lfutil.getminsize(
110 110 ui, lfutil.islfilesrepo(repo), opts.get(r'lfsize'))
111 111
112 112 lfmatcher = None
113 113 if lfutil.islfilesrepo(repo):
114 114 lfpats = ui.configlist(lfutil.longname, 'patterns', default=[])
115 115 if lfpats:
116 116 lfmatcher = matchmod.match(repo.root, '', list(lfpats))
117 117
118 118 lfnames = []
119 119 m = matcher
120 120
121 121 wctx = repo[None]
122 122 for f in repo.walk(matchmod.badmatch(m, lambda x, y: None)):
123 123 exact = m.exact(f)
124 124 lfile = lfutil.standin(f) in wctx
125 125 nfile = f in wctx
126 126 exists = lfile or nfile
127 127
128 128 # addremove in core gets fancy with the name, add doesn't
129 129 if isaddremove:
130 130 name = m.uipath(f)
131 131 else:
132 132 name = m.rel(f)
133 133
134 134 # Don't warn the user when they attempt to add a normal tracked file.
135 135 # The normal add code will do that for us.
136 136 if exact and exists:
137 137 if lfile:
138 138 ui.warn(_('%s already a largefile\n') % name)
139 139 continue
140 140
141 141 if (exact or not exists) and not lfutil.isstandin(f):
142 142 # In case the file was removed previously, but not committed
143 143 # (issue3507)
144 144 if not repo.wvfs.exists(f):
145 145 continue
146 146
147 147 abovemin = (lfsize and
148 148 repo.wvfs.lstat(f).st_size >= lfsize * 1024 * 1024)
149 149 if large or abovemin or (lfmatcher and lfmatcher(f)):
150 150 lfnames.append(f)
151 151 if ui.verbose or not exact:
152 152 ui.status(_('adding %s as a largefile\n') % name)
153 153
154 154 bad = []
155 155
156 156 # Need to lock, otherwise there could be a race condition between
157 157 # when standins are created and added to the repo.
158 158 with repo.wlock():
159 159 if not opts.get('dry_run'):
160 160 standins = []
161 161 lfdirstate = lfutil.openlfdirstate(ui, repo)
162 162 for f in lfnames:
163 163 standinname = lfutil.standin(f)
164 164 lfutil.writestandin(repo, standinname, hash='',
165 165 executable=lfutil.getexecutable(repo.wjoin(f)))
166 166 standins.append(standinname)
167 167 if lfdirstate[f] == 'r':
168 168 lfdirstate.normallookup(f)
169 169 else:
170 170 lfdirstate.add(f)
171 171 lfdirstate.write()
172 172 bad += [lfutil.splitstandin(f)
173 173 for f in repo[None].add(standins)
174 174 if f in m.files()]
175 175
176 176 added = [f for f in lfnames if f not in bad]
177 177 return added, bad
178 178
179 179 def removelargefiles(ui, repo, isaddremove, matcher, **opts):
180 180 after = opts.get('after')
181 181 m = composelargefilematcher(matcher, repo[None].manifest())
182 182 try:
183 183 repo.lfstatus = True
184 184 s = repo.status(match=m, clean=not isaddremove)
185 185 finally:
186 186 repo.lfstatus = False
187 187 manifest = repo[None].manifest()
188 188 modified, added, deleted, clean = [[f for f in list
189 189 if lfutil.standin(f) in manifest]
190 190 for list in (s.modified, s.added,
191 191 s.deleted, s.clean)]
192 192
193 193 def warn(files, msg):
194 194 for f in files:
195 195 ui.warn(msg % m.rel(f))
196 196 return int(len(files) > 0)
197 197
198 198 result = 0
199 199
200 200 if after:
201 201 remove = deleted
202 202 result = warn(modified + added + clean,
203 203 _('not removing %s: file still exists\n'))
204 204 else:
205 205 remove = deleted + clean
206 206 result = warn(modified, _('not removing %s: file is modified (use -f'
207 207 ' to force removal)\n'))
208 208 result = warn(added, _('not removing %s: file has been marked for add'
209 209 ' (use forget to undo)\n')) or result
210 210
211 211 # Need to lock because standin files are deleted then removed from the
212 212 # repository and we could race in-between.
213 213 with repo.wlock():
214 214 lfdirstate = lfutil.openlfdirstate(ui, repo)
215 215 for f in sorted(remove):
216 216 if ui.verbose or not m.exact(f):
217 217 # addremove in core gets fancy with the name, remove doesn't
218 218 if isaddremove:
219 219 name = m.uipath(f)
220 220 else:
221 221 name = m.rel(f)
222 222 ui.status(_('removing %s\n') % name)
223 223
224 224 if not opts.get('dry_run'):
225 225 if not after:
226 226 repo.wvfs.unlinkpath(f, ignoremissing=True)
227 227
228 228 if opts.get('dry_run'):
229 229 return result
230 230
231 231 remove = [lfutil.standin(f) for f in remove]
232 232 # If this is being called by addremove, let the original addremove
233 233 # function handle this.
234 234 if not isaddremove:
235 235 for f in remove:
236 236 repo.wvfs.unlinkpath(f, ignoremissing=True)
237 237 repo[None].forget(remove)
238 238
239 239 for f in remove:
240 240 lfutil.synclfdirstate(repo, lfdirstate, lfutil.splitstandin(f),
241 241 False)
242 242
243 243 lfdirstate.write()
244 244
245 245 return result
246 246
247 247 # For overriding mercurial.hgweb.webcommands so that largefiles will
248 248 # appear at their right place in the manifests.
249 249 def decodepath(orig, path):
250 250 return lfutil.splitstandin(path) or path
251 251
252 252 # -- Wrappers: modify existing commands --------------------------------
253 253
254 254 def overrideadd(orig, ui, repo, *pats, **opts):
255 255 if opts.get('normal') and opts.get('large'):
256 256 raise error.Abort(_('--normal cannot be used with --large'))
257 257 return orig(ui, repo, *pats, **opts)
258 258
259 259 def cmdutiladd(orig, ui, repo, matcher, prefix, explicitonly, **opts):
260 260 # The --normal flag short circuits this override
261 261 if opts.get(r'normal'):
262 262 return orig(ui, repo, matcher, prefix, explicitonly, **opts)
263 263
264 264 ladded, lbad = addlargefiles(ui, repo, False, matcher, **opts)
265 265 normalmatcher = composenormalfilematcher(matcher, repo[None].manifest(),
266 266 ladded)
267 267 bad = orig(ui, repo, normalmatcher, prefix, explicitonly, **opts)
268 268
269 269 bad.extend(f for f in lbad)
270 270 return bad
271 271
272 272 def cmdutilremove(orig, ui, repo, matcher, prefix, after, force, subrepos):
273 273 normalmatcher = composenormalfilematcher(matcher, repo[None].manifest())
274 274 result = orig(ui, repo, normalmatcher, prefix, after, force, subrepos)
275 275 return removelargefiles(ui, repo, False, matcher, after=after,
276 276 force=force) or result
277 277
278 278 def overridestatusfn(orig, repo, rev2, **opts):
279 279 try:
280 280 repo._repo.lfstatus = True
281 281 return orig(repo, rev2, **opts)
282 282 finally:
283 283 repo._repo.lfstatus = False
284 284
285 285 def overridestatus(orig, ui, repo, *pats, **opts):
286 286 try:
287 287 repo.lfstatus = True
288 288 return orig(ui, repo, *pats, **opts)
289 289 finally:
290 290 repo.lfstatus = False
291 291
292 292 def overridedirty(orig, repo, ignoreupdate=False):
293 293 try:
294 294 repo._repo.lfstatus = True
295 295 return orig(repo, ignoreupdate)
296 296 finally:
297 297 repo._repo.lfstatus = False
298 298
299 299 def overridelog(orig, ui, repo, *pats, **opts):
300 300 def overridematchandpats(ctx, pats=(), opts=None, globbed=False,
301 301 default='relpath', badfn=None):
302 302 """Matcher that merges root directory with .hglf, suitable for log.
303 303 It is still possible to match .hglf directly.
304 304 For any listed files run log on the standin too.
305 305 matchfn tries both the given filename and with .hglf stripped.
306 306 """
307 307 if opts is None:
308 308 opts = {}
309 309 matchandpats = oldmatchandpats(ctx, pats, opts, globbed, default,
310 310 badfn=badfn)
311 311 m, p = copy.copy(matchandpats)
312 312
313 313 if m.always():
314 314 # We want to match everything anyway, so there's no benefit trying
315 315 # to add standins.
316 316 return matchandpats
317 317
318 318 pats = set(p)
319 319
320 320 def fixpats(pat, tostandin=lfutil.standin):
321 321 if pat.startswith('set:'):
322 322 return pat
323 323
324 324 kindpat = matchmod._patsplit(pat, None)
325 325
326 326 if kindpat[0] is not None:
327 327 return kindpat[0] + ':' + tostandin(kindpat[1])
328 328 return tostandin(kindpat[1])
329 329
330 330 if m._cwd:
331 331 hglf = lfutil.shortname
332 332 back = util.pconvert(m.rel(hglf)[:-len(hglf)])
333 333
334 334 def tostandin(f):
335 335 # The file may already be a standin, so truncate the back
336 336 # prefix and test before mangling it. This avoids turning
337 337 # 'glob:../.hglf/foo*' into 'glob:../.hglf/../.hglf/foo*'.
338 338 if f.startswith(back) and lfutil.splitstandin(f[len(back):]):
339 339 return f
340 340
341 341 # An absolute path is from outside the repo, so truncate the
342 342 # path to the root before building the standin. Otherwise cwd
343 343 # is somewhere in the repo, relative to root, and needs to be
344 344 # prepended before building the standin.
345 345 if os.path.isabs(m._cwd):
346 346 f = f[len(back):]
347 347 else:
348 348 f = m._cwd + '/' + f
349 349 return back + lfutil.standin(f)
350 350 else:
351 351 def tostandin(f):
352 352 if lfutil.isstandin(f):
353 353 return f
354 354 return lfutil.standin(f)
355 355 pats.update(fixpats(f, tostandin) for f in p)
356 356
357 357 for i in range(0, len(m._files)):
358 358 # Don't add '.hglf' to m.files, since that is already covered by '.'
359 359 if m._files[i] == '.':
360 360 continue
361 361 standin = lfutil.standin(m._files[i])
362 362 # If the "standin" is a directory, append instead of replace to
363 363 # support naming a directory on the command line with only
364 364 # largefiles. The original directory is kept to support normal
365 365 # files.
366 366 if standin in ctx:
367 367 m._files[i] = standin
368 368 elif m._files[i] not in ctx and repo.wvfs.isdir(standin):
369 369 m._files.append(standin)
370 370
371 371 m._fileroots = set(m._files)
372 372 m._always = False
373 373 origmatchfn = m.matchfn
374 374 def lfmatchfn(f):
375 375 lf = lfutil.splitstandin(f)
376 376 if lf is not None and origmatchfn(lf):
377 377 return True
378 378 r = origmatchfn(f)
379 379 return r
380 380 m.matchfn = lfmatchfn
381 381
382 ui.debug('updated patterns: %s\n' % sorted(pats))
382 ui.debug('updated patterns: %s\n' % ', '.join(sorted(pats)))
383 383 return m, pats
384 384
385 385 # For hg log --patch, the match object is used in two different senses:
386 386 # (1) to determine what revisions should be printed out, and
387 387 # (2) to determine what files to print out diffs for.
388 388 # The magic matchandpats override should be used for case (1) but not for
389 389 # case (2).
390 390 def overridemakelogfilematcher(repo, pats, opts, badfn=None):
391 391 wctx = repo[None]
392 392 match, pats = oldmatchandpats(wctx, pats, opts, badfn=badfn)
393 393 return lambda rev: match
394 394
395 395 oldmatchandpats = installmatchandpatsfn(overridematchandpats)
396 396 oldmakelogfilematcher = cmdutil._makenofollowlogfilematcher
397 397 setattr(cmdutil, '_makenofollowlogfilematcher', overridemakelogfilematcher)
398 398
399 399 try:
400 400 return orig(ui, repo, *pats, **opts)
401 401 finally:
402 402 restorematchandpatsfn()
403 403 setattr(cmdutil, '_makenofollowlogfilematcher', oldmakelogfilematcher)
404 404
405 405 def overrideverify(orig, ui, repo, *pats, **opts):
406 406 large = opts.pop('large', False)
407 407 all = opts.pop('lfa', False)
408 408 contents = opts.pop('lfc', False)
409 409
410 410 result = orig(ui, repo, *pats, **opts)
411 411 if large or all or contents:
412 412 result = result or lfcommands.verifylfiles(ui, repo, all, contents)
413 413 return result
414 414
415 415 def overridedebugstate(orig, ui, repo, *pats, **opts):
416 416 large = opts.pop('large', False)
417 417 if large:
418 418 class fakerepo(object):
419 419 dirstate = lfutil.openlfdirstate(ui, repo)
420 420 orig(ui, fakerepo, *pats, **opts)
421 421 else:
422 422 orig(ui, repo, *pats, **opts)
423 423
424 424 # Before starting the manifest merge, merge.updates will call
425 425 # _checkunknownfile to check if there are any files in the merged-in
426 426 # changeset that collide with unknown files in the working copy.
427 427 #
428 428 # The largefiles are seen as unknown, so this prevents us from merging
429 429 # in a file 'foo' if we already have a largefile with the same name.
430 430 #
431 431 # The overridden function filters the unknown files by removing any
432 432 # largefiles. This makes the merge proceed and we can then handle this
433 433 # case further in the overridden calculateupdates function below.
434 434 def overridecheckunknownfile(origfn, repo, wctx, mctx, f, f2=None):
435 435 if lfutil.standin(repo.dirstate.normalize(f)) in wctx:
436 436 return False
437 437 return origfn(repo, wctx, mctx, f, f2)
438 438
439 439 # The manifest merge handles conflicts on the manifest level. We want
440 440 # to handle changes in largefile-ness of files at this level too.
441 441 #
442 442 # The strategy is to run the original calculateupdates and then process
443 443 # the action list it outputs. There are two cases we need to deal with:
444 444 #
445 445 # 1. Normal file in p1, largefile in p2. Here the largefile is
446 446 # detected via its standin file, which will enter the working copy
447 447 # with a "get" action. It is not "merge" since the standin is all
448 448 # Mercurial is concerned with at this level -- the link to the
449 449 # existing normal file is not relevant here.
450 450 #
451 451 # 2. Largefile in p1, normal file in p2. Here we get a "merge" action
452 452 # since the largefile will be present in the working copy and
453 453 # different from the normal file in p2. Mercurial therefore
454 454 # triggers a merge action.
455 455 #
456 456 # In both cases, we prompt the user and emit new actions to either
457 457 # remove the standin (if the normal file was kept) or to remove the
458 458 # normal file and get the standin (if the largefile was kept). The
459 459 # default prompt answer is to use the largefile version since it was
460 460 # presumably changed on purpose.
461 461 #
462 462 # Finally, the merge.applyupdates function will then take care of
463 463 # writing the files into the working copy and lfcommands.updatelfiles
464 464 # will update the largefiles.
465 465 def overridecalculateupdates(origfn, repo, p1, p2, pas, branchmerge, force,
466 466 acceptremote, *args, **kwargs):
467 467 overwrite = force and not branchmerge
468 468 actions, diverge, renamedelete = origfn(
469 469 repo, p1, p2, pas, branchmerge, force, acceptremote, *args, **kwargs)
470 470
471 471 if overwrite:
472 472 return actions, diverge, renamedelete
473 473
474 474 # Convert to dictionary with filename as key and action as value.
475 475 lfiles = set()
476 476 for f in actions:
477 477 splitstandin = lfutil.splitstandin(f)
478 478 if splitstandin in p1:
479 479 lfiles.add(splitstandin)
480 480 elif lfutil.standin(f) in p1:
481 481 lfiles.add(f)
482 482
483 483 for lfile in sorted(lfiles):
484 484 standin = lfutil.standin(lfile)
485 485 (lm, largs, lmsg) = actions.get(lfile, (None, None, None))
486 486 (sm, sargs, smsg) = actions.get(standin, (None, None, None))
487 487 if sm in ('g', 'dc') and lm != 'r':
488 488 if sm == 'dc':
489 489 f1, f2, fa, move, anc = sargs
490 490 sargs = (p2[f2].flags(), False)
491 491 # Case 1: normal file in the working copy, largefile in
492 492 # the second parent
493 493 usermsg = _('remote turned local normal file %s into a largefile\n'
494 494 'use (l)argefile or keep (n)ormal file?'
495 495 '$$ &Largefile $$ &Normal file') % lfile
496 496 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
497 497 actions[lfile] = ('r', None, 'replaced by standin')
498 498 actions[standin] = ('g', sargs, 'replaces standin')
499 499 else: # keep local normal file
500 500 actions[lfile] = ('k', None, 'replaces standin')
501 501 if branchmerge:
502 502 actions[standin] = ('k', None, 'replaced by non-standin')
503 503 else:
504 504 actions[standin] = ('r', None, 'replaced by non-standin')
505 505 elif lm in ('g', 'dc') and sm != 'r':
506 506 if lm == 'dc':
507 507 f1, f2, fa, move, anc = largs
508 508 largs = (p2[f2].flags(), False)
509 509 # Case 2: largefile in the working copy, normal file in
510 510 # the second parent
511 511 usermsg = _('remote turned local largefile %s into a normal file\n'
512 512 'keep (l)argefile or use (n)ormal file?'
513 513 '$$ &Largefile $$ &Normal file') % lfile
514 514 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
515 515 if branchmerge:
516 516 # largefile can be restored from standin safely
517 517 actions[lfile] = ('k', None, 'replaced by standin')
518 518 actions[standin] = ('k', None, 'replaces standin')
519 519 else:
520 520 # "lfile" should be marked as "removed" without
521 521 # removal of itself
522 522 actions[lfile] = ('lfmr', None,
523 523 'forget non-standin largefile')
524 524
525 525 # linear-merge should treat this largefile as 're-added'
526 526 actions[standin] = ('a', None, 'keep standin')
527 527 else: # pick remote normal file
528 528 actions[lfile] = ('g', largs, 'replaces standin')
529 529 actions[standin] = ('r', None, 'replaced by non-standin')
530 530
531 531 return actions, diverge, renamedelete
532 532
533 533 def mergerecordupdates(orig, repo, actions, branchmerge):
534 534 if 'lfmr' in actions:
535 535 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
536 536 for lfile, args, msg in actions['lfmr']:
537 537 # this should be executed before 'orig', to execute 'remove'
538 538 # before all other actions
539 539 repo.dirstate.remove(lfile)
540 540 # make sure lfile doesn't get synclfdirstate'd as normal
541 541 lfdirstate.add(lfile)
542 542 lfdirstate.write()
543 543
544 544 return orig(repo, actions, branchmerge)
545 545
546 546 # Override filemerge to prompt the user about how they wish to merge
547 547 # largefiles. This will handle identical edits without prompting the user.
548 548 def overridefilemerge(origfn, premerge, repo, mynode, orig, fcd, fco, fca,
549 549 labels=None):
550 550 if not lfutil.isstandin(orig) or fcd.isabsent() or fco.isabsent():
551 551 return origfn(premerge, repo, mynode, orig, fcd, fco, fca,
552 552 labels=labels)
553 553
554 554 ahash = lfutil.readasstandin(fca).lower()
555 555 dhash = lfutil.readasstandin(fcd).lower()
556 556 ohash = lfutil.readasstandin(fco).lower()
557 557 if (ohash != ahash and
558 558 ohash != dhash and
559 559 (dhash == ahash or
560 560 repo.ui.promptchoice(
561 561 _('largefile %s has a merge conflict\nancestor was %s\n'
562 562 'keep (l)ocal %s or\ntake (o)ther %s?'
563 563 '$$ &Local $$ &Other') %
564 564 (lfutil.splitstandin(orig), ahash, dhash, ohash),
565 565 0) == 1)):
566 566 repo.wwrite(fcd.path(), fco.data(), fco.flags())
567 567 return True, 0, False
568 568
569 569 def copiespathcopies(orig, ctx1, ctx2, match=None):
570 570 copies = orig(ctx1, ctx2, match=match)
571 571 updated = {}
572 572
573 573 for k, v in copies.iteritems():
574 574 updated[lfutil.splitstandin(k) or k] = lfutil.splitstandin(v) or v
575 575
576 576 return updated
577 577
578 578 # Copy first changes the matchers to match standins instead of
579 579 # largefiles. Then it overrides util.copyfile in that function it
580 580 # checks if the destination largefile already exists. It also keeps a
581 581 # list of copied files so that the largefiles can be copied and the
582 582 # dirstate updated.
583 583 def overridecopy(orig, ui, repo, pats, opts, rename=False):
584 584 # doesn't remove largefile on rename
585 585 if len(pats) < 2:
586 586 # this isn't legal, let the original function deal with it
587 587 return orig(ui, repo, pats, opts, rename)
588 588
589 589 # This could copy both lfiles and normal files in one command,
590 590 # but we don't want to do that. First replace their matcher to
591 591 # only match normal files and run it, then replace it to just
592 592 # match largefiles and run it again.
593 593 nonormalfiles = False
594 594 nolfiles = False
595 595 installnormalfilesmatchfn(repo[None].manifest())
596 596 try:
597 597 result = orig(ui, repo, pats, opts, rename)
598 598 except error.Abort as e:
599 599 if str(e) != _('no files to copy'):
600 600 raise e
601 601 else:
602 602 nonormalfiles = True
603 603 result = 0
604 604 finally:
605 605 restorematchfn()
606 606
607 607 # The first rename can cause our current working directory to be removed.
608 608 # In that case there is nothing left to copy/rename so just quit.
609 609 try:
610 610 repo.getcwd()
611 611 except OSError:
612 612 return result
613 613
614 614 def makestandin(relpath):
615 615 path = pathutil.canonpath(repo.root, repo.getcwd(), relpath)
616 616 return repo.wvfs.join(lfutil.standin(path))
617 617
618 618 fullpats = scmutil.expandpats(pats)
619 619 dest = fullpats[-1]
620 620
621 621 if os.path.isdir(dest):
622 622 if not os.path.isdir(makestandin(dest)):
623 623 os.makedirs(makestandin(dest))
624 624
625 625 try:
626 626 # When we call orig below it creates the standins but we don't add
627 627 # them to the dir state until later so lock during that time.
628 628 wlock = repo.wlock()
629 629
630 630 manifest = repo[None].manifest()
631 631 def overridematch(ctx, pats=(), opts=None, globbed=False,
632 632 default='relpath', badfn=None):
633 633 if opts is None:
634 634 opts = {}
635 635 newpats = []
636 636 # The patterns were previously mangled to add the standin
637 637 # directory; we need to remove that now
638 638 for pat in pats:
639 639 if matchmod.patkind(pat) is None and lfutil.shortname in pat:
640 640 newpats.append(pat.replace(lfutil.shortname, ''))
641 641 else:
642 642 newpats.append(pat)
643 643 match = oldmatch(ctx, newpats, opts, globbed, default, badfn=badfn)
644 644 m = copy.copy(match)
645 645 lfile = lambda f: lfutil.standin(f) in manifest
646 646 m._files = [lfutil.standin(f) for f in m._files if lfile(f)]
647 647 m._fileroots = set(m._files)
648 648 origmatchfn = m.matchfn
649 649 def matchfn(f):
650 650 lfile = lfutil.splitstandin(f)
651 651 return (lfile is not None and
652 652 (f in manifest) and
653 653 origmatchfn(lfile) or
654 654 None)
655 655 m.matchfn = matchfn
656 656 return m
657 657 oldmatch = installmatchfn(overridematch)
658 658 listpats = []
659 659 for pat in pats:
660 660 if matchmod.patkind(pat) is not None:
661 661 listpats.append(pat)
662 662 else:
663 663 listpats.append(makestandin(pat))
664 664
665 665 try:
666 666 origcopyfile = util.copyfile
667 667 copiedfiles = []
668 668 def overridecopyfile(src, dest):
669 669 if (lfutil.shortname in src and
670 670 dest.startswith(repo.wjoin(lfutil.shortname))):
671 671 destlfile = dest.replace(lfutil.shortname, '')
672 672 if not opts['force'] and os.path.exists(destlfile):
673 673 raise IOError('',
674 674 _('destination largefile already exists'))
675 675 copiedfiles.append((src, dest))
676 676 origcopyfile(src, dest)
677 677
678 678 util.copyfile = overridecopyfile
679 679 result += orig(ui, repo, listpats, opts, rename)
680 680 finally:
681 681 util.copyfile = origcopyfile
682 682
683 683 lfdirstate = lfutil.openlfdirstate(ui, repo)
684 684 for (src, dest) in copiedfiles:
685 685 if (lfutil.shortname in src and
686 686 dest.startswith(repo.wjoin(lfutil.shortname))):
687 687 srclfile = src.replace(repo.wjoin(lfutil.standin('')), '')
688 688 destlfile = dest.replace(repo.wjoin(lfutil.standin('')), '')
689 689 destlfiledir = repo.wvfs.dirname(repo.wjoin(destlfile)) or '.'
690 690 if not os.path.isdir(destlfiledir):
691 691 os.makedirs(destlfiledir)
692 692 if rename:
693 693 os.rename(repo.wjoin(srclfile), repo.wjoin(destlfile))
694 694
695 695 # The file is gone, but this deletes any empty parent
696 696 # directories as a side-effect.
697 697 repo.wvfs.unlinkpath(srclfile, ignoremissing=True)
698 698 lfdirstate.remove(srclfile)
699 699 else:
700 700 util.copyfile(repo.wjoin(srclfile),
701 701 repo.wjoin(destlfile))
702 702
703 703 lfdirstate.add(destlfile)
704 704 lfdirstate.write()
705 705 except error.Abort as e:
706 706 if str(e) != _('no files to copy'):
707 707 raise e
708 708 else:
709 709 nolfiles = True
710 710 finally:
711 711 restorematchfn()
712 712 wlock.release()
713 713
714 714 if nolfiles and nonormalfiles:
715 715 raise error.Abort(_('no files to copy'))
716 716
717 717 return result
718 718
719 719 # When the user calls revert, we have to be careful to not revert any
720 720 # changes to other largefiles accidentally. This means we have to keep
721 721 # track of the largefiles that are being reverted so we only pull down
722 722 # the necessary largefiles.
723 723 #
724 724 # Standins are only updated (to match the hash of largefiles) before
725 725 # commits. Update the standins then run the original revert, changing
726 726 # the matcher to hit standins instead of largefiles. Based on the
727 727 # resulting standins update the largefiles.
728 728 def overriderevert(orig, ui, repo, ctx, parents, *pats, **opts):
729 729 # Because we put the standins in a bad state (by updating them)
730 730 # and then return them to a correct state we need to lock to
731 731 # prevent others from changing them in their incorrect state.
732 732 with repo.wlock():
733 733 lfdirstate = lfutil.openlfdirstate(ui, repo)
734 734 s = lfutil.lfdirstatestatus(lfdirstate, repo)
735 735 lfdirstate.write()
736 736 for lfile in s.modified:
737 737 lfutil.updatestandin(repo, lfile, lfutil.standin(lfile))
738 738 for lfile in s.deleted:
739 739 fstandin = lfutil.standin(lfile)
740 740 if (repo.wvfs.exists(fstandin)):
741 741 repo.wvfs.unlink(fstandin)
742 742
743 743 oldstandins = lfutil.getstandinsstate(repo)
744 744
745 745 def overridematch(mctx, pats=(), opts=None, globbed=False,
746 746 default='relpath', badfn=None):
747 747 if opts is None:
748 748 opts = {}
749 749 match = oldmatch(mctx, pats, opts, globbed, default, badfn=badfn)
750 750 m = copy.copy(match)
751 751
752 752 # revert supports recursing into subrepos, and though largefiles
753 753 # currently doesn't work correctly in that case, this match is
754 754 # called, so the lfdirstate above may not be the correct one for
755 755 # this invocation of match.
756 756 lfdirstate = lfutil.openlfdirstate(mctx.repo().ui, mctx.repo(),
757 757 False)
758 758
759 759 wctx = repo[None]
760 760 matchfiles = []
761 761 for f in m._files:
762 762 standin = lfutil.standin(f)
763 763 if standin in ctx or standin in mctx:
764 764 matchfiles.append(standin)
765 765 elif standin in wctx or lfdirstate[f] == 'r':
766 766 continue
767 767 else:
768 768 matchfiles.append(f)
769 769 m._files = matchfiles
770 770 m._fileroots = set(m._files)
771 771 origmatchfn = m.matchfn
772 772 def matchfn(f):
773 773 lfile = lfutil.splitstandin(f)
774 774 if lfile is not None:
775 775 return (origmatchfn(lfile) and
776 776 (f in ctx or f in mctx))
777 777 return origmatchfn(f)
778 778 m.matchfn = matchfn
779 779 return m
780 780 oldmatch = installmatchfn(overridematch)
781 781 try:
782 782 orig(ui, repo, ctx, parents, *pats, **opts)
783 783 finally:
784 784 restorematchfn()
785 785
786 786 newstandins = lfutil.getstandinsstate(repo)
787 787 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
788 788 # lfdirstate should be 'normallookup'-ed for updated files,
789 789 # because reverting doesn't touch dirstate for 'normal' files
790 790 # when target revision is explicitly specified: in such case,
791 791 # 'n' and valid timestamp in dirstate doesn't ensure 'clean'
792 792 # of target (standin) file.
793 793 lfcommands.updatelfiles(ui, repo, filelist, printmessage=False,
794 794 normallookup=True)
795 795
796 796 # after pulling changesets, we need to take some extra care to get
797 797 # largefiles updated remotely
798 798 def overridepull(orig, ui, repo, source=None, **opts):
799 799 revsprepull = len(repo)
800 800 if not source:
801 801 source = 'default'
802 802 repo.lfpullsource = source
803 803 result = orig(ui, repo, source, **opts)
804 804 revspostpull = len(repo)
805 805 lfrevs = opts.get('lfrev', [])
806 806 if opts.get('all_largefiles'):
807 807 lfrevs.append('pulled()')
808 808 if lfrevs and revspostpull > revsprepull:
809 809 numcached = 0
810 810 repo.firstpulled = revsprepull # for pulled() revset expression
811 811 try:
812 812 for rev in scmutil.revrange(repo, lfrevs):
813 813 ui.note(_('pulling largefiles for revision %s\n') % rev)
814 814 (cached, missing) = lfcommands.cachelfiles(ui, repo, rev)
815 815 numcached += len(cached)
816 816 finally:
817 817 del repo.firstpulled
818 818 ui.status(_("%d largefiles cached\n") % numcached)
819 819 return result
820 820
821 821 def overridepush(orig, ui, repo, *args, **kwargs):
822 822 """Override push command and store --lfrev parameters in opargs"""
823 823 lfrevs = kwargs.pop('lfrev', None)
824 824 if lfrevs:
825 825 opargs = kwargs.setdefault('opargs', {})
826 826 opargs['lfrevs'] = scmutil.revrange(repo, lfrevs)
827 827 return orig(ui, repo, *args, **kwargs)
828 828
829 829 def exchangepushoperation(orig, *args, **kwargs):
830 830 """Override pushoperation constructor and store lfrevs parameter"""
831 831 lfrevs = kwargs.pop('lfrevs', None)
832 832 pushop = orig(*args, **kwargs)
833 833 pushop.lfrevs = lfrevs
834 834 return pushop
835 835
836 836 revsetpredicate = registrar.revsetpredicate()
837 837
838 838 @revsetpredicate('pulled()')
839 839 def pulledrevsetsymbol(repo, subset, x):
840 840 """Changesets that just has been pulled.
841 841
842 842 Only available with largefiles from pull --lfrev expressions.
843 843
844 844 .. container:: verbose
845 845
846 846 Some examples:
847 847
848 848 - pull largefiles for all new changesets::
849 849
850 850 hg pull -lfrev "pulled()"
851 851
852 852 - pull largefiles for all new branch heads::
853 853
854 854 hg pull -lfrev "head(pulled()) and not closed()"
855 855
856 856 """
857 857
858 858 try:
859 859 firstpulled = repo.firstpulled
860 860 except AttributeError:
861 861 raise error.Abort(_("pulled() only available in --lfrev"))
862 862 return smartset.baseset([r for r in subset if r >= firstpulled])
863 863
864 864 def overrideclone(orig, ui, source, dest=None, **opts):
865 865 d = dest
866 866 if d is None:
867 867 d = hg.defaultdest(source)
868 868 if opts.get('all_largefiles') and not hg.islocal(d):
869 869 raise error.Abort(_(
870 870 '--all-largefiles is incompatible with non-local destination %s') %
871 871 d)
872 872
873 873 return orig(ui, source, dest, **opts)
874 874
875 875 def hgclone(orig, ui, opts, *args, **kwargs):
876 876 result = orig(ui, opts, *args, **kwargs)
877 877
878 878 if result is not None:
879 879 sourcerepo, destrepo = result
880 880 repo = destrepo.local()
881 881
882 882 # When cloning to a remote repo (like through SSH), no repo is available
883 883 # from the peer. Therefore the largefiles can't be downloaded and the
884 884 # hgrc can't be updated.
885 885 if not repo:
886 886 return result
887 887
888 888 # If largefiles is required for this repo, permanently enable it locally
889 889 if 'largefiles' in repo.requirements:
890 890 with repo.vfs('hgrc', 'a', text=True) as fp:
891 891 fp.write('\n[extensions]\nlargefiles=\n')
892 892
893 893 # Caching is implicitly limited to 'rev' option, since the dest repo was
894 894 # truncated at that point. The user may expect a download count with
895 895 # this option, so attempt whether or not this is a largefile repo.
896 896 if opts.get('all_largefiles'):
897 897 success, missing = lfcommands.downloadlfiles(ui, repo, None)
898 898
899 899 if missing != 0:
900 900 return None
901 901
902 902 return result
903 903
904 904 def hgpostshare(orig, sourcerepo, destrepo, bookmarks=True, defaultpath=None):
905 905 orig(sourcerepo, destrepo, bookmarks, defaultpath)
906 906
907 907 # If largefiles is required for this repo, permanently enable it locally
908 908 if 'largefiles' in destrepo.requirements:
909 909 with destrepo.vfs('hgrc', 'a+', text=True) as fp:
910 910 fp.write('\n[extensions]\nlargefiles=\n')
911 911
912 912 def overriderebase(orig, ui, repo, **opts):
913 913 if not util.safehasattr(repo, '_largefilesenabled'):
914 914 return orig(ui, repo, **opts)
915 915
916 916 resuming = opts.get('continue')
917 917 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
918 918 repo._lfstatuswriters.append(lambda *msg, **opts: None)
919 919 try:
920 920 return orig(ui, repo, **opts)
921 921 finally:
922 922 repo._lfstatuswriters.pop()
923 923 repo._lfcommithooks.pop()
924 924
925 925 def overridearchivecmd(orig, ui, repo, dest, **opts):
926 926 repo.unfiltered().lfstatus = True
927 927
928 928 try:
929 929 return orig(ui, repo.unfiltered(), dest, **opts)
930 930 finally:
931 931 repo.unfiltered().lfstatus = False
932 932
933 933 def hgwebarchive(orig, web, req, tmpl):
934 934 web.repo.lfstatus = True
935 935
936 936 try:
937 937 return orig(web, req, tmpl)
938 938 finally:
939 939 web.repo.lfstatus = False
940 940
941 941 def overridearchive(orig, repo, dest, node, kind, decode=True, matchfn=None,
942 942 prefix='', mtime=None, subrepos=None):
943 943 # For some reason setting repo.lfstatus in hgwebarchive only changes the
944 944 # unfiltered repo's attr, so check that as well.
945 945 if not repo.lfstatus and not repo.unfiltered().lfstatus:
946 946 return orig(repo, dest, node, kind, decode, matchfn, prefix, mtime,
947 947 subrepos)
948 948
949 949 # No need to lock because we are only reading history and
950 950 # largefile caches, neither of which are modified.
951 951 if node is not None:
952 952 lfcommands.cachelfiles(repo.ui, repo, node)
953 953
954 954 if kind not in archival.archivers:
955 955 raise error.Abort(_("unknown archive type '%s'") % kind)
956 956
957 957 ctx = repo[node]
958 958
959 959 if kind == 'files':
960 960 if prefix:
961 961 raise error.Abort(
962 962 _('cannot give prefix when archiving to files'))
963 963 else:
964 964 prefix = archival.tidyprefix(dest, kind, prefix)
965 965
966 966 def write(name, mode, islink, getdata):
967 967 if matchfn and not matchfn(name):
968 968 return
969 969 data = getdata()
970 970 if decode:
971 971 data = repo.wwritedata(name, data)
972 972 archiver.addfile(prefix + name, mode, islink, data)
973 973
974 974 archiver = archival.archivers[kind](dest, mtime or ctx.date()[0])
975 975
976 976 if repo.ui.configbool("ui", "archivemeta", True):
977 977 write('.hg_archival.txt', 0o644, False,
978 978 lambda: archival.buildmetadata(ctx))
979 979
980 980 for f in ctx:
981 981 ff = ctx.flags(f)
982 982 getdata = ctx[f].data
983 983 lfile = lfutil.splitstandin(f)
984 984 if lfile is not None:
985 985 if node is not None:
986 986 path = lfutil.findfile(repo, getdata().strip())
987 987
988 988 if path is None:
989 989 raise error.Abort(
990 990 _('largefile %s not found in repo store or system cache')
991 991 % lfile)
992 992 else:
993 993 path = lfile
994 994
995 995 f = lfile
996 996
997 997 getdata = lambda: util.readfile(path)
998 998 write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, getdata)
999 999
1000 1000 if subrepos:
1001 1001 for subpath in sorted(ctx.substate):
1002 1002 sub = ctx.workingsub(subpath)
1003 1003 submatch = matchmod.subdirmatcher(subpath, matchfn)
1004 1004 sub._repo.lfstatus = True
1005 1005 sub.archive(archiver, prefix, submatch)
1006 1006
1007 1007 archiver.done()
1008 1008
1009 1009 def hgsubrepoarchive(orig, repo, archiver, prefix, match=None, decode=True):
1010 1010 if not repo._repo.lfstatus:
1011 1011 return orig(repo, archiver, prefix, match, decode)
1012 1012
1013 1013 repo._get(repo._state + ('hg',))
1014 1014 rev = repo._state[1]
1015 1015 ctx = repo._repo[rev]
1016 1016
1017 1017 if ctx.node() is not None:
1018 1018 lfcommands.cachelfiles(repo.ui, repo._repo, ctx.node())
1019 1019
1020 1020 def write(name, mode, islink, getdata):
1021 1021 # At this point, the standin has been replaced with the largefile name,
1022 1022 # so the normal matcher works here without the lfutil variants.
1023 1023 if match and not match(f):
1024 1024 return
1025 1025 data = getdata()
1026 1026 if decode:
1027 1027 data = repo._repo.wwritedata(name, data)
1028 1028
1029 1029 archiver.addfile(prefix + repo._path + '/' + name, mode, islink, data)
1030 1030
1031 1031 for f in ctx:
1032 1032 ff = ctx.flags(f)
1033 1033 getdata = ctx[f].data
1034 1034 lfile = lfutil.splitstandin(f)
1035 1035 if lfile is not None:
1036 1036 if ctx.node() is not None:
1037 1037 path = lfutil.findfile(repo._repo, getdata().strip())
1038 1038
1039 1039 if path is None:
1040 1040 raise error.Abort(
1041 1041 _('largefile %s not found in repo store or system cache')
1042 1042 % lfile)
1043 1043 else:
1044 1044 path = lfile
1045 1045
1046 1046 f = lfile
1047 1047
1048 1048 getdata = lambda: util.readfile(os.path.join(prefix, path))
1049 1049
1050 1050 write(f, 'x' in ff and 0o755 or 0o644, 'l' in ff, getdata)
1051 1051
1052 1052 for subpath in sorted(ctx.substate):
1053 1053 sub = ctx.workingsub(subpath)
1054 1054 submatch = matchmod.subdirmatcher(subpath, match)
1055 1055 sub._repo.lfstatus = True
1056 1056 sub.archive(archiver, prefix + repo._path + '/', submatch, decode)
1057 1057
1058 1058 # If a largefile is modified, the change is not reflected in its
1059 1059 # standin until a commit. cmdutil.bailifchanged() raises an exception
1060 1060 # if the repo has uncommitted changes. Wrap it to also check if
1061 1061 # largefiles were changed. This is used by bisect, backout and fetch.
1062 1062 def overridebailifchanged(orig, repo, *args, **kwargs):
1063 1063 orig(repo, *args, **kwargs)
1064 1064 repo.lfstatus = True
1065 1065 s = repo.status()
1066 1066 repo.lfstatus = False
1067 1067 if s.modified or s.added or s.removed or s.deleted:
1068 1068 raise error.Abort(_('uncommitted changes'))
1069 1069
1070 1070 def postcommitstatus(orig, repo, *args, **kwargs):
1071 1071 repo.lfstatus = True
1072 1072 try:
1073 1073 return orig(repo, *args, **kwargs)
1074 1074 finally:
1075 1075 repo.lfstatus = False
1076 1076
1077 1077 def cmdutilforget(orig, ui, repo, match, prefix, explicitonly):
1078 1078 normalmatcher = composenormalfilematcher(match, repo[None].manifest())
1079 1079 bad, forgot = orig(ui, repo, normalmatcher, prefix, explicitonly)
1080 1080 m = composelargefilematcher(match, repo[None].manifest())
1081 1081
1082 1082 try:
1083 1083 repo.lfstatus = True
1084 1084 s = repo.status(match=m, clean=True)
1085 1085 finally:
1086 1086 repo.lfstatus = False
1087 1087 manifest = repo[None].manifest()
1088 1088 forget = sorted(s.modified + s.added + s.deleted + s.clean)
1089 1089 forget = [f for f in forget if lfutil.standin(f) in manifest]
1090 1090
1091 1091 for f in forget:
1092 1092 fstandin = lfutil.standin(f)
1093 1093 if fstandin not in repo.dirstate and not repo.wvfs.isdir(fstandin):
1094 1094 ui.warn(_('not removing %s: file is already untracked\n')
1095 1095 % m.rel(f))
1096 1096 bad.append(f)
1097 1097
1098 1098 for f in forget:
1099 1099 if ui.verbose or not m.exact(f):
1100 1100 ui.status(_('removing %s\n') % m.rel(f))
1101 1101
1102 1102 # Need to lock because standin files are deleted then removed from the
1103 1103 # repository and we could race in-between.
1104 1104 with repo.wlock():
1105 1105 lfdirstate = lfutil.openlfdirstate(ui, repo)
1106 1106 for f in forget:
1107 1107 if lfdirstate[f] == 'a':
1108 1108 lfdirstate.drop(f)
1109 1109 else:
1110 1110 lfdirstate.remove(f)
1111 1111 lfdirstate.write()
1112 1112 standins = [lfutil.standin(f) for f in forget]
1113 1113 for f in standins:
1114 1114 repo.wvfs.unlinkpath(f, ignoremissing=True)
1115 1115 rejected = repo[None].forget(standins)
1116 1116
1117 1117 bad.extend(f for f in rejected if f in m.files())
1118 1118 forgot.extend(f for f in forget if f not in rejected)
1119 1119 return bad, forgot
1120 1120
1121 1121 def _getoutgoings(repo, other, missing, addfunc):
1122 1122 """get pairs of filename and largefile hash in outgoing revisions
1123 1123 in 'missing'.
1124 1124
1125 1125 largefiles already existing on 'other' repository are ignored.
1126 1126
1127 1127 'addfunc' is invoked with each unique pairs of filename and
1128 1128 largefile hash value.
1129 1129 """
1130 1130 knowns = set()
1131 1131 lfhashes = set()
1132 1132 def dedup(fn, lfhash):
1133 1133 k = (fn, lfhash)
1134 1134 if k not in knowns:
1135 1135 knowns.add(k)
1136 1136 lfhashes.add(lfhash)
1137 1137 lfutil.getlfilestoupload(repo, missing, dedup)
1138 1138 if lfhashes:
1139 1139 lfexists = storefactory.openstore(repo, other).exists(lfhashes)
1140 1140 for fn, lfhash in knowns:
1141 1141 if not lfexists[lfhash]: # lfhash doesn't exist on "other"
1142 1142 addfunc(fn, lfhash)
1143 1143
1144 1144 def outgoinghook(ui, repo, other, opts, missing):
1145 1145 if opts.pop('large', None):
1146 1146 lfhashes = set()
1147 1147 if ui.debugflag:
1148 1148 toupload = {}
1149 1149 def addfunc(fn, lfhash):
1150 1150 if fn not in toupload:
1151 1151 toupload[fn] = []
1152 1152 toupload[fn].append(lfhash)
1153 1153 lfhashes.add(lfhash)
1154 1154 def showhashes(fn):
1155 1155 for lfhash in sorted(toupload[fn]):
1156 1156 ui.debug(' %s\n' % (lfhash))
1157 1157 else:
1158 1158 toupload = set()
1159 1159 def addfunc(fn, lfhash):
1160 1160 toupload.add(fn)
1161 1161 lfhashes.add(lfhash)
1162 1162 def showhashes(fn):
1163 1163 pass
1164 1164 _getoutgoings(repo, other, missing, addfunc)
1165 1165
1166 1166 if not toupload:
1167 1167 ui.status(_('largefiles: no files to upload\n'))
1168 1168 else:
1169 1169 ui.status(_('largefiles to upload (%d entities):\n')
1170 1170 % (len(lfhashes)))
1171 1171 for file in sorted(toupload):
1172 1172 ui.status(lfutil.splitstandin(file) + '\n')
1173 1173 showhashes(file)
1174 1174 ui.status('\n')
1175 1175
1176 1176 def summaryremotehook(ui, repo, opts, changes):
1177 1177 largeopt = opts.get('large', False)
1178 1178 if changes is None:
1179 1179 if largeopt:
1180 1180 return (False, True) # only outgoing check is needed
1181 1181 else:
1182 1182 return (False, False)
1183 1183 elif largeopt:
1184 1184 url, branch, peer, outgoing = changes[1]
1185 1185 if peer is None:
1186 1186 # i18n: column positioning for "hg summary"
1187 1187 ui.status(_('largefiles: (no remote repo)\n'))
1188 1188 return
1189 1189
1190 1190 toupload = set()
1191 1191 lfhashes = set()
1192 1192 def addfunc(fn, lfhash):
1193 1193 toupload.add(fn)
1194 1194 lfhashes.add(lfhash)
1195 1195 _getoutgoings(repo, peer, outgoing.missing, addfunc)
1196 1196
1197 1197 if not toupload:
1198 1198 # i18n: column positioning for "hg summary"
1199 1199 ui.status(_('largefiles: (no files to upload)\n'))
1200 1200 else:
1201 1201 # i18n: column positioning for "hg summary"
1202 1202 ui.status(_('largefiles: %d entities for %d files to upload\n')
1203 1203 % (len(lfhashes), len(toupload)))
1204 1204
1205 1205 def overridesummary(orig, ui, repo, *pats, **opts):
1206 1206 try:
1207 1207 repo.lfstatus = True
1208 1208 orig(ui, repo, *pats, **opts)
1209 1209 finally:
1210 1210 repo.lfstatus = False
1211 1211
1212 1212 def scmutiladdremove(orig, repo, matcher, prefix, opts=None, dry_run=None,
1213 1213 similarity=None):
1214 1214 if opts is None:
1215 1215 opts = {}
1216 1216 if not lfutil.islfilesrepo(repo):
1217 1217 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1218 1218 # Get the list of missing largefiles so we can remove them
1219 1219 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1220 1220 unsure, s = lfdirstate.status(matchmod.always(repo.root, repo.getcwd()), [],
1221 1221 False, False, False)
1222 1222
1223 1223 # Call into the normal remove code, but the removing of the standin, we want
1224 1224 # to have handled by original addremove. Monkey patching here makes sure
1225 1225 # we don't remove the standin in the largefiles code, preventing a very
1226 1226 # confused state later.
1227 1227 if s.deleted:
1228 1228 m = copy.copy(matcher)
1229 1229
1230 1230 # The m._files and m._map attributes are not changed to the deleted list
1231 1231 # because that affects the m.exact() test, which in turn governs whether
1232 1232 # or not the file name is printed, and how. Simply limit the original
1233 1233 # matches to those in the deleted status list.
1234 1234 matchfn = m.matchfn
1235 1235 m.matchfn = lambda f: f in s.deleted and matchfn(f)
1236 1236
1237 1237 removelargefiles(repo.ui, repo, True, m, **opts)
1238 1238 # Call into the normal add code, and any files that *should* be added as
1239 1239 # largefiles will be
1240 1240 added, bad = addlargefiles(repo.ui, repo, True, matcher, **opts)
1241 1241 # Now that we've handled largefiles, hand off to the original addremove
1242 1242 # function to take care of the rest. Make sure it doesn't do anything with
1243 1243 # largefiles by passing a matcher that will ignore them.
1244 1244 matcher = composenormalfilematcher(matcher, repo[None].manifest(), added)
1245 1245 return orig(repo, matcher, prefix, opts, dry_run, similarity)
1246 1246
1247 1247 # Calling purge with --all will cause the largefiles to be deleted.
1248 1248 # Override repo.status to prevent this from happening.
1249 1249 def overridepurge(orig, ui, repo, *dirs, **opts):
1250 1250 # XXX Monkey patching a repoview will not work. The assigned attribute will
1251 1251 # be set on the unfiltered repo, but we will only lookup attributes in the
1252 1252 # unfiltered repo if the lookup in the repoview object itself fails. As the
1253 1253 # monkey patched method exists on the repoview class the lookup will not
1254 1254 # fail. As a result, the original version will shadow the monkey patched
1255 1255 # one, defeating the monkey patch.
1256 1256 #
1257 1257 # As a work around we use an unfiltered repo here. We should do something
1258 1258 # cleaner instead.
1259 1259 repo = repo.unfiltered()
1260 1260 oldstatus = repo.status
1261 1261 def overridestatus(node1='.', node2=None, match=None, ignored=False,
1262 1262 clean=False, unknown=False, listsubrepos=False):
1263 1263 r = oldstatus(node1, node2, match, ignored, clean, unknown,
1264 1264 listsubrepos)
1265 1265 lfdirstate = lfutil.openlfdirstate(ui, repo)
1266 1266 unknown = [f for f in r.unknown if lfdirstate[f] == '?']
1267 1267 ignored = [f for f in r.ignored if lfdirstate[f] == '?']
1268 1268 return scmutil.status(r.modified, r.added, r.removed, r.deleted,
1269 1269 unknown, ignored, r.clean)
1270 1270 repo.status = overridestatus
1271 1271 orig(ui, repo, *dirs, **opts)
1272 1272 repo.status = oldstatus
1273 1273 def overriderollback(orig, ui, repo, **opts):
1274 1274 with repo.wlock():
1275 1275 before = repo.dirstate.parents()
1276 1276 orphans = set(f for f in repo.dirstate
1277 1277 if lfutil.isstandin(f) and repo.dirstate[f] != 'r')
1278 1278 result = orig(ui, repo, **opts)
1279 1279 after = repo.dirstate.parents()
1280 1280 if before == after:
1281 1281 return result # no need to restore standins
1282 1282
1283 1283 pctx = repo['.']
1284 1284 for f in repo.dirstate:
1285 1285 if lfutil.isstandin(f):
1286 1286 orphans.discard(f)
1287 1287 if repo.dirstate[f] == 'r':
1288 1288 repo.wvfs.unlinkpath(f, ignoremissing=True)
1289 1289 elif f in pctx:
1290 1290 fctx = pctx[f]
1291 1291 repo.wwrite(f, fctx.data(), fctx.flags())
1292 1292 else:
1293 1293 # content of standin is not so important in 'a',
1294 1294 # 'm' or 'n' (coming from the 2nd parent) cases
1295 1295 lfutil.writestandin(repo, f, '', False)
1296 1296 for standin in orphans:
1297 1297 repo.wvfs.unlinkpath(standin, ignoremissing=True)
1298 1298
1299 1299 lfdirstate = lfutil.openlfdirstate(ui, repo)
1300 1300 orphans = set(lfdirstate)
1301 1301 lfiles = lfutil.listlfiles(repo)
1302 1302 for file in lfiles:
1303 1303 lfutil.synclfdirstate(repo, lfdirstate, file, True)
1304 1304 orphans.discard(file)
1305 1305 for lfile in orphans:
1306 1306 lfdirstate.drop(lfile)
1307 1307 lfdirstate.write()
1308 1308 return result
1309 1309
1310 1310 def overridetransplant(orig, ui, repo, *revs, **opts):
1311 1311 resuming = opts.get('continue')
1312 1312 repo._lfcommithooks.append(lfutil.automatedcommithook(resuming))
1313 1313 repo._lfstatuswriters.append(lambda *msg, **opts: None)
1314 1314 try:
1315 1315 result = orig(ui, repo, *revs, **opts)
1316 1316 finally:
1317 1317 repo._lfstatuswriters.pop()
1318 1318 repo._lfcommithooks.pop()
1319 1319 return result
1320 1320
1321 1321 def overridecat(orig, ui, repo, file1, *pats, **opts):
1322 1322 ctx = scmutil.revsingle(repo, opts.get('rev'))
1323 1323 err = 1
1324 1324 notbad = set()
1325 1325 m = scmutil.match(ctx, (file1,) + pats, opts)
1326 1326 origmatchfn = m.matchfn
1327 1327 def lfmatchfn(f):
1328 1328 if origmatchfn(f):
1329 1329 return True
1330 1330 lf = lfutil.splitstandin(f)
1331 1331 if lf is None:
1332 1332 return False
1333 1333 notbad.add(lf)
1334 1334 return origmatchfn(lf)
1335 1335 m.matchfn = lfmatchfn
1336 1336 origbadfn = m.bad
1337 1337 def lfbadfn(f, msg):
1338 1338 if not f in notbad:
1339 1339 origbadfn(f, msg)
1340 1340 m.bad = lfbadfn
1341 1341
1342 1342 origvisitdirfn = m.visitdir
1343 1343 def lfvisitdirfn(dir):
1344 1344 if dir == lfutil.shortname:
1345 1345 return True
1346 1346 ret = origvisitdirfn(dir)
1347 1347 if ret:
1348 1348 return ret
1349 1349 lf = lfutil.splitstandin(dir)
1350 1350 if lf is None:
1351 1351 return False
1352 1352 return origvisitdirfn(lf)
1353 1353 m.visitdir = lfvisitdirfn
1354 1354
1355 1355 for f in ctx.walk(m):
1356 1356 with cmdutil.makefileobj(repo, opts.get('output'), ctx.node(),
1357 1357 pathname=f) as fp:
1358 1358 lf = lfutil.splitstandin(f)
1359 1359 if lf is None or origmatchfn(f):
1360 1360 # duplicating unreachable code from commands.cat
1361 1361 data = ctx[f].data()
1362 1362 if opts.get('decode'):
1363 1363 data = repo.wwritedata(f, data)
1364 1364 fp.write(data)
1365 1365 else:
1366 1366 hash = lfutil.readasstandin(ctx[f])
1367 1367 if not lfutil.inusercache(repo.ui, hash):
1368 1368 store = storefactory.openstore(repo)
1369 1369 success, missing = store.get([(lf, hash)])
1370 1370 if len(success) != 1:
1371 1371 raise error.Abort(
1372 1372 _('largefile %s is not in cache and could not be '
1373 1373 'downloaded') % lf)
1374 1374 path = lfutil.usercachepath(repo.ui, hash)
1375 1375 with open(path, "rb") as fpin:
1376 1376 for chunk in util.filechunkiter(fpin):
1377 1377 fp.write(chunk)
1378 1378 err = 0
1379 1379 return err
1380 1380
1381 1381 def mergeupdate(orig, repo, node, branchmerge, force,
1382 1382 *args, **kwargs):
1383 1383 matcher = kwargs.get('matcher', None)
1384 1384 # note if this is a partial update
1385 1385 partial = matcher and not matcher.always()
1386 1386 with repo.wlock():
1387 1387 # branch | | |
1388 1388 # merge | force | partial | action
1389 1389 # -------+-------+---------+--------------
1390 1390 # x | x | x | linear-merge
1391 1391 # o | x | x | branch-merge
1392 1392 # x | o | x | overwrite (as clean update)
1393 1393 # o | o | x | force-branch-merge (*1)
1394 1394 # x | x | o | (*)
1395 1395 # o | x | o | (*)
1396 1396 # x | o | o | overwrite (as revert)
1397 1397 # o | o | o | (*)
1398 1398 #
1399 1399 # (*) don't care
1400 1400 # (*1) deprecated, but used internally (e.g: "rebase --collapse")
1401 1401
1402 1402 lfdirstate = lfutil.openlfdirstate(repo.ui, repo)
1403 1403 unsure, s = lfdirstate.status(matchmod.always(repo.root,
1404 1404 repo.getcwd()),
1405 1405 [], False, True, False)
1406 1406 oldclean = set(s.clean)
1407 1407 pctx = repo['.']
1408 1408 dctx = repo[node]
1409 1409 for lfile in unsure + s.modified:
1410 1410 lfileabs = repo.wvfs.join(lfile)
1411 1411 if not repo.wvfs.exists(lfileabs):
1412 1412 continue
1413 1413 lfhash = lfutil.hashfile(lfileabs)
1414 1414 standin = lfutil.standin(lfile)
1415 1415 lfutil.writestandin(repo, standin, lfhash,
1416 1416 lfutil.getexecutable(lfileabs))
1417 1417 if (standin in pctx and
1418 1418 lfhash == lfutil.readasstandin(pctx[standin])):
1419 1419 oldclean.add(lfile)
1420 1420 for lfile in s.added:
1421 1421 fstandin = lfutil.standin(lfile)
1422 1422 if fstandin not in dctx:
1423 1423 # in this case, content of standin file is meaningless
1424 1424 # (in dctx, lfile is unknown, or normal file)
1425 1425 continue
1426 1426 lfutil.updatestandin(repo, lfile, fstandin)
1427 1427 # mark all clean largefiles as dirty, just in case the update gets
1428 1428 # interrupted before largefiles and lfdirstate are synchronized
1429 1429 for lfile in oldclean:
1430 1430 lfdirstate.normallookup(lfile)
1431 1431 lfdirstate.write()
1432 1432
1433 1433 oldstandins = lfutil.getstandinsstate(repo)
1434 1434
1435 1435 result = orig(repo, node, branchmerge, force, *args, **kwargs)
1436 1436
1437 1437 newstandins = lfutil.getstandinsstate(repo)
1438 1438 filelist = lfutil.getlfilestoupdate(oldstandins, newstandins)
1439 1439
1440 1440 # to avoid leaving all largefiles as dirty and thus rehash them, mark
1441 1441 # all the ones that didn't change as clean
1442 1442 for lfile in oldclean.difference(filelist):
1443 1443 lfdirstate.normal(lfile)
1444 1444 lfdirstate.write()
1445 1445
1446 1446 if branchmerge or force or partial:
1447 1447 filelist.extend(s.deleted + s.removed)
1448 1448
1449 1449 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1450 1450 normallookup=partial)
1451 1451
1452 1452 return result
1453 1453
1454 1454 def scmutilmarktouched(orig, repo, files, *args, **kwargs):
1455 1455 result = orig(repo, files, *args, **kwargs)
1456 1456
1457 1457 filelist = []
1458 1458 for f in files:
1459 1459 lf = lfutil.splitstandin(f)
1460 1460 if lf is not None:
1461 1461 filelist.append(lf)
1462 1462 if filelist:
1463 1463 lfcommands.updatelfiles(repo.ui, repo, filelist=filelist,
1464 1464 printmessage=False, normallookup=True)
1465 1465
1466 1466 return result
@@ -1,1115 +1,1115
1 1 This file contains testcases that tend to be related to special cases or less
2 2 common commands affecting largefile.
3 3
4 4 Each sections should be independent of each others.
5 5
6 6 $ USERCACHE="$TESTTMP/cache"; export USERCACHE
7 7 $ mkdir "${USERCACHE}"
8 8 $ cat >> $HGRCPATH <<EOF
9 9 > [extensions]
10 10 > largefiles=
11 11 > purge=
12 12 > rebase=
13 13 > transplant=
14 14 > [phases]
15 15 > publish=False
16 16 > [largefiles]
17 17 > minsize=2
18 18 > patterns=glob:**.dat
19 19 > usercache=${USERCACHE}
20 20 > [hooks]
21 21 > precommit=sh -c "echo \\"Invoking status precommit hook\\"; hg status"
22 22 > EOF
23 23
24 24
25 25
26 26 Test copies and moves from a directory other than root (issue3516)
27 27 =========================================================================
28 28
29 29 $ hg init lf_cpmv
30 30 $ cd lf_cpmv
31 31 $ mkdir dira
32 32 $ mkdir dira/dirb
33 33 $ touch dira/dirb/largefile
34 34 $ hg add --large dira/dirb/largefile
35 35 $ hg commit -m "added"
36 36 Invoking status precommit hook
37 37 A dira/dirb/largefile
38 38 $ cd dira
39 39 $ hg cp dirb/largefile foo/largefile
40 40
41 41 TODO: Ideally, this should mention the largefile, not the standin
42 42 $ hg log -T '{rev}\n' --stat 'set:clean()'
43 43 0
44 44 .hglf/dira/dirb/largefile | 1 +
45 45 1 files changed, 1 insertions(+), 0 deletions(-)
46 46
47 47 $ hg ci -m "deep copy"
48 48 Invoking status precommit hook
49 49 A dira/foo/largefile
50 50 $ find . | sort
51 51 .
52 52 ./dirb
53 53 ./dirb/largefile
54 54 ./foo
55 55 ./foo/largefile
56 56 $ hg mv foo/largefile baz/largefile
57 57 $ hg ci -m "moved"
58 58 Invoking status precommit hook
59 59 A dira/baz/largefile
60 60 R dira/foo/largefile
61 61 $ find . | sort
62 62 .
63 63 ./baz
64 64 ./baz/largefile
65 65 ./dirb
66 66 ./dirb/largefile
67 67 $ cd ..
68 68 $ hg mv dira dirc
69 69 moving .hglf/dira/baz/largefile to .hglf/dirc/baz/largefile (glob)
70 70 moving .hglf/dira/dirb/largefile to .hglf/dirc/dirb/largefile (glob)
71 71 $ find * | sort
72 72 dirc
73 73 dirc/baz
74 74 dirc/baz/largefile
75 75 dirc/dirb
76 76 dirc/dirb/largefile
77 77
78 78 $ hg clone -q . ../fetch
79 79 $ hg --config extensions.fetch= fetch ../fetch
80 80 abort: uncommitted changes
81 81 [255]
82 82 $ hg up -qC
83 83 $ cd ..
84 84
85 85 Clone a local repository owned by another user
86 86 ===================================================
87 87
88 88 #if unix-permissions
89 89
90 90 We have to simulate that here by setting $HOME and removing write permissions
91 91 $ ORIGHOME="$HOME"
92 92 $ mkdir alice
93 93 $ HOME="`pwd`/alice"
94 94 $ cd alice
95 95 $ hg init pubrepo
96 96 $ cd pubrepo
97 97 $ dd if=/dev/zero bs=1k count=11k > a-large-file 2> /dev/null
98 98 $ hg add --large a-large-file
99 99 $ hg commit -m "Add a large file"
100 100 Invoking status precommit hook
101 101 A a-large-file
102 102 $ cd ..
103 103 $ chmod -R a-w pubrepo
104 104 $ cd ..
105 105 $ mkdir bob
106 106 $ HOME="`pwd`/bob"
107 107 $ cd bob
108 108 $ hg clone --pull ../alice/pubrepo pubrepo
109 109 requesting all changes
110 110 adding changesets
111 111 adding manifests
112 112 adding file changes
113 113 added 1 changesets with 1 changes to 1 files
114 114 updating to branch default
115 115 getting changed largefiles
116 116 1 largefiles updated, 0 removed
117 117 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 118 $ cd ..
119 119 $ chmod -R u+w alice/pubrepo
120 120 $ HOME="$ORIGHOME"
121 121
122 122 #endif
123 123
124 124
125 125 Symlink to a large largefile should behave the same as a symlink to a normal file
126 126 =====================================================================================
127 127
128 128 #if symlink
129 129
130 130 $ hg init largesymlink
131 131 $ cd largesymlink
132 132 $ dd if=/dev/zero bs=1k count=10k of=largefile 2>/dev/null
133 133 $ hg add --large largefile
134 134 $ hg commit -m "commit a large file"
135 135 Invoking status precommit hook
136 136 A largefile
137 137 $ ln -s largefile largelink
138 138 $ hg add largelink
139 139 $ hg commit -m "commit a large symlink"
140 140 Invoking status precommit hook
141 141 A largelink
142 142 $ rm -f largelink
143 143 $ hg up >/dev/null
144 144 $ test -f largelink
145 145 [1]
146 146 $ test -L largelink
147 147 [1]
148 148 $ rm -f largelink # make next part of the test independent of the previous
149 149 $ hg up -C >/dev/null
150 150 $ test -f largelink
151 151 $ test -L largelink
152 152 $ cd ..
153 153
154 154 #endif
155 155
156 156
157 157 test for pattern matching on 'hg status':
158 158 ==============================================
159 159
160 160
161 161 to boost performance, largefiles checks whether specified patterns are
162 162 related to largefiles in working directory (NOT to STANDIN) or not.
163 163
164 164 $ hg init statusmatch
165 165 $ cd statusmatch
166 166
167 167 $ mkdir -p a/b/c/d
168 168 $ echo normal > a/b/c/d/e.normal.txt
169 169 $ hg add a/b/c/d/e.normal.txt
170 170 $ echo large > a/b/c/d/e.large.txt
171 171 $ hg add --large a/b/c/d/e.large.txt
172 172 $ mkdir -p a/b/c/x
173 173 $ echo normal > a/b/c/x/y.normal.txt
174 174 $ hg add a/b/c/x/y.normal.txt
175 175 $ hg commit -m 'add files'
176 176 Invoking status precommit hook
177 177 A a/b/c/d/e.large.txt
178 178 A a/b/c/d/e.normal.txt
179 179 A a/b/c/x/y.normal.txt
180 180
181 181 (1) no pattern: no performance boost
182 182 $ hg status -A
183 183 C a/b/c/d/e.large.txt
184 184 C a/b/c/d/e.normal.txt
185 185 C a/b/c/x/y.normal.txt
186 186
187 187 (2) pattern not related to largefiles: performance boost
188 188 $ hg status -A a/b/c/x
189 189 C a/b/c/x/y.normal.txt
190 190
191 191 (3) pattern related to largefiles: no performance boost
192 192 $ hg status -A a/b/c/d
193 193 C a/b/c/d/e.large.txt
194 194 C a/b/c/d/e.normal.txt
195 195
196 196 (4) pattern related to STANDIN (not to largefiles): performance boost
197 197 $ hg status -A .hglf/a
198 198 C .hglf/a/b/c/d/e.large.txt
199 199
200 200 (5) mixed case: no performance boost
201 201 $ hg status -A a/b/c/x a/b/c/d
202 202 C a/b/c/d/e.large.txt
203 203 C a/b/c/d/e.normal.txt
204 204 C a/b/c/x/y.normal.txt
205 205
206 206 verify that largefiles doesn't break filesets
207 207
208 208 $ hg log --rev . --exclude "set:binary()"
209 209 changeset: 0:41bd42f10efa
210 210 tag: tip
211 211 user: test
212 212 date: Thu Jan 01 00:00:00 1970 +0000
213 213 summary: add files
214 214
215 215 sharing a largefile repo automatically enables largefiles on the share
216 216
217 217 $ hg share --config extensions.share= . ../shared_lfrepo
218 218 updating working directory
219 219 getting changed largefiles
220 220 1 largefiles updated, 0 removed
221 221 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
222 222 $ cat ../shared_lfrepo/.hg/hgrc
223 223
224 224 [extensions]
225 225 largefiles=
226 226
227 227 verify that large files in subrepos handled properly
228 228 $ hg init subrepo
229 229 $ echo "subrepo = subrepo" > .hgsub
230 230 $ hg add .hgsub
231 231 $ hg ci -m "add subrepo"
232 232 Invoking status precommit hook
233 233 A .hgsub
234 234 ? .hgsubstate
235 235 $ echo "rev 1" > subrepo/large.txt
236 236 $ hg add --large subrepo/large.txt
237 237 $ hg sum
238 238 parent: 1:8ee150ea2e9c tip
239 239 add subrepo
240 240 branch: default
241 241 commit: 1 subrepos
242 242 update: (current)
243 243 phases: 2 draft
244 244 $ hg st
245 245 $ hg st -S
246 246 A subrepo/large.txt
247 247 $ hg ci -S -m "commit top repo"
248 248 committing subrepository subrepo
249 249 Invoking status precommit hook
250 250 A large.txt
251 251 Invoking status precommit hook
252 252 M .hgsubstate
253 253 # No differences
254 254 $ hg st -S
255 255 $ hg sum
256 256 parent: 2:ce4cd0c527a6 tip
257 257 commit top repo
258 258 branch: default
259 259 commit: (clean)
260 260 update: (current)
261 261 phases: 3 draft
262 262 $ echo "rev 2" > subrepo/large.txt
263 263 $ hg st -S
264 264 M subrepo/large.txt
265 265 $ hg sum
266 266 parent: 2:ce4cd0c527a6 tip
267 267 commit top repo
268 268 branch: default
269 269 commit: 1 subrepos
270 270 update: (current)
271 271 phases: 3 draft
272 272 $ hg ci -m "this commit should fail without -S"
273 273 abort: uncommitted changes in subrepository 'subrepo'
274 274 (use --subrepos for recursive commit)
275 275 [255]
276 276
277 277 Add a normal file to the subrepo, then test archiving
278 278
279 279 $ echo 'normal file' > subrepo/normal.txt
280 280 $ touch large.dat
281 281 $ mv subrepo/large.txt subrepo/renamed-large.txt
282 282 $ hg addremove -S --dry-run
283 283 adding large.dat as a largefile
284 284 removing subrepo/large.txt
285 285 adding subrepo/normal.txt
286 286 adding subrepo/renamed-large.txt
287 287 $ hg status -S
288 288 ! subrepo/large.txt
289 289 ? large.dat
290 290 ? subrepo/normal.txt
291 291 ? subrepo/renamed-large.txt
292 292
293 293 $ hg addremove --dry-run subrepo
294 294 removing subrepo/large.txt (glob)
295 295 adding subrepo/normal.txt (glob)
296 296 adding subrepo/renamed-large.txt (glob)
297 297 $ hg status -S
298 298 ! subrepo/large.txt
299 299 ? large.dat
300 300 ? subrepo/normal.txt
301 301 ? subrepo/renamed-large.txt
302 302 $ cd ..
303 303
304 304 $ hg -R statusmatch addremove --dry-run statusmatch/subrepo
305 305 removing statusmatch/subrepo/large.txt (glob)
306 306 adding statusmatch/subrepo/normal.txt (glob)
307 307 adding statusmatch/subrepo/renamed-large.txt (glob)
308 308 $ hg -R statusmatch status -S
309 309 ! subrepo/large.txt
310 310 ? large.dat
311 311 ? subrepo/normal.txt
312 312 ? subrepo/renamed-large.txt
313 313
314 314 $ hg -R statusmatch addremove --dry-run -S
315 315 adding large.dat as a largefile
316 316 removing subrepo/large.txt
317 317 adding subrepo/normal.txt
318 318 adding subrepo/renamed-large.txt
319 319 $ cd statusmatch
320 320
321 321 $ mv subrepo/renamed-large.txt subrepo/large.txt
322 322 $ hg addremove subrepo
323 323 adding subrepo/normal.txt (glob)
324 324 $ hg forget subrepo/normal.txt
325 325
326 326 $ hg addremove -S
327 327 adding large.dat as a largefile
328 328 adding subrepo/normal.txt
329 329 $ rm large.dat
330 330
331 331 $ hg addremove subrepo
332 332 $ hg addremove -S
333 333 removing large.dat
334 334
335 335 Lock in subrepo, otherwise the change isn't archived
336 336
337 337 $ hg ci -S -m "add normal file to top level"
338 338 committing subrepository subrepo
339 339 Invoking status precommit hook
340 340 M large.txt
341 341 A normal.txt
342 342 Invoking status precommit hook
343 343 M .hgsubstate
344 344 $ hg archive -S ../lf_subrepo_archive
345 345 $ find ../lf_subrepo_archive | sort
346 346 ../lf_subrepo_archive
347 347 ../lf_subrepo_archive/.hg_archival.txt
348 348 ../lf_subrepo_archive/.hgsub
349 349 ../lf_subrepo_archive/.hgsubstate
350 350 ../lf_subrepo_archive/a
351 351 ../lf_subrepo_archive/a/b
352 352 ../lf_subrepo_archive/a/b/c
353 353 ../lf_subrepo_archive/a/b/c/d
354 354 ../lf_subrepo_archive/a/b/c/d/e.large.txt
355 355 ../lf_subrepo_archive/a/b/c/d/e.normal.txt
356 356 ../lf_subrepo_archive/a/b/c/x
357 357 ../lf_subrepo_archive/a/b/c/x/y.normal.txt
358 358 ../lf_subrepo_archive/subrepo
359 359 ../lf_subrepo_archive/subrepo/large.txt
360 360 ../lf_subrepo_archive/subrepo/normal.txt
361 361 $ cat ../lf_subrepo_archive/.hg_archival.txt
362 362 repo: 41bd42f10efa43698cc02052ea0977771cba506d
363 363 node: d56a95e6522858bc08a724c4fe2bdee066d1c30b
364 364 branch: default
365 365 latesttag: null
366 366 latesttagdistance: 4
367 367 changessincelatesttag: 4
368 368
369 369 Test update with subrepos.
370 370
371 371 $ hg update 0
372 372 getting changed largefiles
373 373 0 largefiles updated, 1 removed
374 374 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
375 375 $ hg status -S
376 376 $ hg update tip
377 377 getting changed largefiles
378 378 1 largefiles updated, 0 removed
379 379 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
380 380 $ hg status -S
381 381 # modify a large file
382 382 $ echo "modified" > subrepo/large.txt
383 383 $ hg st -S
384 384 M subrepo/large.txt
385 385 # update -C should revert the change.
386 386 $ hg update -C
387 387 getting changed largefiles
388 388 1 largefiles updated, 0 removed
389 389 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
390 390 $ hg status -S
391 391
392 392 $ hg forget -v subrepo/large.txt
393 393 removing subrepo/large.txt (glob)
394 394
395 395 Test reverting a forgotten file
396 396 $ hg revert -R subrepo subrepo/large.txt
397 397 $ hg status -SA subrepo/large.txt
398 398 C subrepo/large.txt
399 399
400 400 $ hg rm -v subrepo/large.txt
401 401 removing subrepo/large.txt (glob)
402 402 $ hg revert -R subrepo subrepo/large.txt
403 403 $ rm subrepo/large.txt
404 404 $ hg addremove -S
405 405 removing subrepo/large.txt
406 406 $ hg st -S
407 407 R subrepo/large.txt
408 408
409 409 Test archiving a revision that references a subrepo that is not yet
410 410 cloned (see test-subrepo-recursion.t):
411 411
412 412 $ hg clone -U . ../empty
413 413 $ cd ../empty
414 414 $ hg archive --subrepos -r tip ../archive.tar.gz
415 415 cloning subrepo subrepo from $TESTTMP/statusmatch/subrepo
416 416 $ cd ..
417 417
418 418
419 419
420 420
421 421
422 422
423 423 Test addremove, forget and others
424 424 ==============================================
425 425
426 426 Test that addremove picks up largefiles prior to the initial commit (issue3541)
427 427
428 428 $ hg init addrm2
429 429 $ cd addrm2
430 430 $ touch large.dat
431 431 $ touch large2.dat
432 432 $ touch normal
433 433 $ hg add --large large.dat
434 434 $ hg addremove -v
435 435 adding large2.dat as a largefile
436 436 adding normal
437 437
438 438 Test that forgetting all largefiles reverts to islfilesrepo() == False
439 439 (addremove will add *.dat as normal files now)
440 440 $ hg forget large.dat
441 441 $ hg forget large2.dat
442 442 $ hg addremove -v
443 443 adding large.dat
444 444 adding large2.dat
445 445
446 446 Test commit's addremove option prior to the first commit
447 447 $ hg forget large.dat
448 448 $ hg forget large2.dat
449 449 $ hg add --large large.dat
450 450 $ hg ci -Am "commit"
451 451 adding large2.dat as a largefile
452 452 Invoking status precommit hook
453 453 A large.dat
454 454 A large2.dat
455 455 A normal
456 456 $ find .hglf | sort
457 457 .hglf
458 458 .hglf/large.dat
459 459 .hglf/large2.dat
460 460
461 461 Test actions on largefiles using relative paths from subdir
462 462
463 463 $ mkdir sub
464 464 $ cd sub
465 465 $ echo anotherlarge > anotherlarge
466 466 $ hg add --large anotherlarge
467 467 $ hg st
468 468 A sub/anotherlarge
469 469 $ hg st anotherlarge
470 470 A anotherlarge
471 471 $ hg commit -m anotherlarge anotherlarge
472 472 Invoking status precommit hook
473 473 A sub/anotherlarge
474 474 $ hg log anotherlarge
475 475 changeset: 1:9627a577c5e9
476 476 tag: tip
477 477 user: test
478 478 date: Thu Jan 01 00:00:00 1970 +0000
479 479 summary: anotherlarge
480 480
481 481 $ hg --debug log -T '{rev}: {desc}\n' ../sub/anotherlarge
482 updated patterns: ['../.hglf/sub/../sub/anotherlarge', '../sub/anotherlarge']
482 updated patterns: ../.hglf/sub/../sub/anotherlarge, ../sub/anotherlarge
483 483 1: anotherlarge
484 484
485 485 $ hg log -G anotherlarge
486 486 @ changeset: 1:9627a577c5e9
487 487 | tag: tip
488 488 ~ user: test
489 489 date: Thu Jan 01 00:00:00 1970 +0000
490 490 summary: anotherlarge
491 491
492 492
493 493 $ hg log glob:another*
494 494 changeset: 1:9627a577c5e9
495 495 tag: tip
496 496 user: test
497 497 date: Thu Jan 01 00:00:00 1970 +0000
498 498 summary: anotherlarge
499 499
500 500 $ hg --debug log -T '{rev}: {desc}\n' -G glob:another*
501 updated patterns: ['glob:../.hglf/sub/another*', 'glob:another*']
501 updated patterns: glob:../.hglf/sub/another*, glob:another*
502 502 @ 1: anotherlarge
503 503 |
504 504 ~
505 505
506 506 #if no-msys
507 507 $ hg --debug log -T '{rev}: {desc}\n' 'glob:../.hglf/sub/another*' # no-msys
508 updated patterns: ['glob:../.hglf/sub/another*']
508 updated patterns: glob:../.hglf/sub/another*
509 509 1: anotherlarge
510 510
511 511 $ hg --debug log -G -T '{rev}: {desc}\n' 'glob:../.hglf/sub/another*' # no-msys
512 updated patterns: ['glob:../.hglf/sub/another*']
512 updated patterns: glob:../.hglf/sub/another*
513 513 @ 1: anotherlarge
514 514 |
515 515 ~
516 516 #endif
517 517
518 518 $ echo more >> anotherlarge
519 519 $ hg st .
520 520 M anotherlarge
521 521 $ hg cat anotherlarge
522 522 anotherlarge
523 523 $ hg revert anotherlarge
524 524 $ hg st
525 525 ? sub/anotherlarge.orig
526 526
527 527 Test orig files go where we want them
528 528 $ echo moremore >> anotherlarge
529 529 $ hg revert anotherlarge -v --config 'ui.origbackuppath=.hg/origbackups'
530 530 creating directory: $TESTTMP/addrm2/.hg/origbackups/.hglf/sub (glob)
531 531 saving current version of ../.hglf/sub/anotherlarge as $TESTTMP/addrm2/.hg/origbackups/.hglf/sub/anotherlarge.orig (glob)
532 532 reverting ../.hglf/sub/anotherlarge (glob)
533 533 creating directory: $TESTTMP/addrm2/.hg/origbackups/sub (glob)
534 534 found 90c622cf65cebe75c5842f9136c459333faf392e in store
535 535 found 90c622cf65cebe75c5842f9136c459333faf392e in store
536 536 $ ls ../.hg/origbackups/sub
537 537 anotherlarge.orig
538 538 $ cd ..
539 539
540 540 Test glob logging from the root dir
541 541 $ hg log glob:**another*
542 542 changeset: 1:9627a577c5e9
543 543 tag: tip
544 544 user: test
545 545 date: Thu Jan 01 00:00:00 1970 +0000
546 546 summary: anotherlarge
547 547
548 548 $ hg log -G glob:**another*
549 549 @ changeset: 1:9627a577c5e9
550 550 | tag: tip
551 551 ~ user: test
552 552 date: Thu Jan 01 00:00:00 1970 +0000
553 553 summary: anotherlarge
554 554
555 555
556 556 $ cd ..
557 557
558 558 Log from outer space
559 559 $ hg --debug log -R addrm2 -T '{rev}: {desc}\n' 'addrm2/sub/anotherlarge'
560 updated patterns: ['addrm2/.hglf/sub/anotherlarge', 'addrm2/sub/anotherlarge']
560 updated patterns: addrm2/.hglf/sub/anotherlarge, addrm2/sub/anotherlarge
561 561 1: anotherlarge
562 562 $ hg --debug log -R addrm2 -T '{rev}: {desc}\n' 'addrm2/.hglf/sub/anotherlarge'
563 updated patterns: ['addrm2/.hglf/sub/anotherlarge']
563 updated patterns: addrm2/.hglf/sub/anotherlarge
564 564 1: anotherlarge
565 565
566 566
567 567 Check error message while exchange
568 568 =========================================================
569 569
570 570 issue3651: summary/outgoing with largefiles shows "no remote repo"
571 571 unexpectedly
572 572
573 573 $ mkdir issue3651
574 574 $ cd issue3651
575 575
576 576 $ hg init src
577 577 $ echo a > src/a
578 578 $ hg -R src add --large src/a
579 579 $ hg -R src commit -m '#0'
580 580 Invoking status precommit hook
581 581 A a
582 582
583 583 check messages when no remote repository is specified:
584 584 "no remote repo" route for "hg outgoing --large" is not tested here,
585 585 because it can't be reproduced easily.
586 586
587 587 $ hg init clone1
588 588 $ hg -R clone1 -q pull src
589 589 $ hg -R clone1 -q update
590 590 $ hg -R clone1 paths | grep default
591 591 [1]
592 592
593 593 $ hg -R clone1 summary --large
594 594 parent: 0:fc0bd45326d3 tip
595 595 #0
596 596 branch: default
597 597 commit: (clean)
598 598 update: (current)
599 599 phases: 1 draft
600 600 largefiles: (no remote repo)
601 601
602 602 check messages when there is no files to upload:
603 603
604 604 $ hg -q clone src clone2
605 605 $ hg -R clone2 paths | grep default
606 606 default = $TESTTMP/issue3651/src (glob)
607 607
608 608 $ hg -R clone2 summary --large
609 609 parent: 0:fc0bd45326d3 tip
610 610 #0
611 611 branch: default
612 612 commit: (clean)
613 613 update: (current)
614 614 phases: 1 draft
615 615 largefiles: (no files to upload)
616 616 $ hg -R clone2 outgoing --large
617 617 comparing with $TESTTMP/issue3651/src (glob)
618 618 searching for changes
619 619 no changes found
620 620 largefiles: no files to upload
621 621 [1]
622 622
623 623 $ hg -R clone2 outgoing --large --graph --template "{rev}"
624 624 comparing with $TESTTMP/issue3651/src (glob)
625 625 searching for changes
626 626 no changes found
627 627 largefiles: no files to upload
628 628
629 629 check messages when there are files to upload:
630 630
631 631 $ echo b > clone2/b
632 632 $ hg -R clone2 add --large clone2/b
633 633 $ hg -R clone2 commit -m '#1'
634 634 Invoking status precommit hook
635 635 A b
636 636 $ hg -R clone2 summary --large
637 637 parent: 1:1acbe71ce432 tip
638 638 #1
639 639 branch: default
640 640 commit: (clean)
641 641 update: (current)
642 642 phases: 2 draft
643 643 largefiles: 1 entities for 1 files to upload
644 644 $ hg -R clone2 outgoing --large
645 645 comparing with $TESTTMP/issue3651/src (glob)
646 646 searching for changes
647 647 changeset: 1:1acbe71ce432
648 648 tag: tip
649 649 user: test
650 650 date: Thu Jan 01 00:00:00 1970 +0000
651 651 summary: #1
652 652
653 653 largefiles to upload (1 entities):
654 654 b
655 655
656 656 $ hg -R clone2 outgoing --large --graph --template "{rev}"
657 657 comparing with $TESTTMP/issue3651/src (glob)
658 658 searching for changes
659 659 @ 1
660 660
661 661 largefiles to upload (1 entities):
662 662 b
663 663
664 664
665 665 $ cp clone2/b clone2/b1
666 666 $ cp clone2/b clone2/b2
667 667 $ hg -R clone2 add --large clone2/b1 clone2/b2
668 668 $ hg -R clone2 commit -m '#2: add largefiles referring same entity'
669 669 Invoking status precommit hook
670 670 A b1
671 671 A b2
672 672 $ hg -R clone2 summary --large
673 673 parent: 2:6095d0695d70 tip
674 674 #2: add largefiles referring same entity
675 675 branch: default
676 676 commit: (clean)
677 677 update: (current)
678 678 phases: 3 draft
679 679 largefiles: 1 entities for 3 files to upload
680 680 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
681 681 comparing with $TESTTMP/issue3651/src (glob)
682 682 searching for changes
683 683 1:1acbe71ce432
684 684 2:6095d0695d70
685 685 largefiles to upload (1 entities):
686 686 b
687 687 b1
688 688 b2
689 689
690 690 $ hg -R clone2 cat -r 1 clone2/.hglf/b
691 691 89e6c98d92887913cadf06b2adb97f26cde4849b
692 692 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
693 693 comparing with $TESTTMP/issue3651/src (glob)
694 694 query 1; heads
695 695 searching for changes
696 696 all remote heads known locally
697 697 1:1acbe71ce432
698 698 2:6095d0695d70
699 699 finding outgoing largefiles: 0/2 revisions (0.00%)
700 700 finding outgoing largefiles: 1/2 revisions (50.00%)
701 701 largefiles to upload (1 entities):
702 702 b
703 703 89e6c98d92887913cadf06b2adb97f26cde4849b
704 704 b1
705 705 89e6c98d92887913cadf06b2adb97f26cde4849b
706 706 b2
707 707 89e6c98d92887913cadf06b2adb97f26cde4849b
708 708
709 709
710 710 $ echo bbb > clone2/b
711 711 $ hg -R clone2 commit -m '#3: add new largefile entity as existing file'
712 712 Invoking status precommit hook
713 713 M b
714 714 $ echo bbbb > clone2/b
715 715 $ hg -R clone2 commit -m '#4: add new largefile entity as existing file'
716 716 Invoking status precommit hook
717 717 M b
718 718 $ cp clone2/b1 clone2/b
719 719 $ hg -R clone2 commit -m '#5: refer existing largefile entity again'
720 720 Invoking status precommit hook
721 721 M b
722 722 $ hg -R clone2 summary --large
723 723 parent: 5:036794ea641c tip
724 724 #5: refer existing largefile entity again
725 725 branch: default
726 726 commit: (clean)
727 727 update: (current)
728 728 phases: 6 draft
729 729 largefiles: 3 entities for 3 files to upload
730 730 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
731 731 comparing with $TESTTMP/issue3651/src (glob)
732 732 searching for changes
733 733 1:1acbe71ce432
734 734 2:6095d0695d70
735 735 3:7983dce246cc
736 736 4:233f12ada4ae
737 737 5:036794ea641c
738 738 largefiles to upload (3 entities):
739 739 b
740 740 b1
741 741 b2
742 742
743 743 $ hg -R clone2 cat -r 3 clone2/.hglf/b
744 744 c801c9cfe94400963fcb683246217d5db77f9a9a
745 745 $ hg -R clone2 cat -r 4 clone2/.hglf/b
746 746 13f9ed0898e315bf59dc2973fec52037b6f441a2
747 747 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
748 748 comparing with $TESTTMP/issue3651/src (glob)
749 749 query 1; heads
750 750 searching for changes
751 751 all remote heads known locally
752 752 1:1acbe71ce432
753 753 2:6095d0695d70
754 754 3:7983dce246cc
755 755 4:233f12ada4ae
756 756 5:036794ea641c
757 757 finding outgoing largefiles: 0/5 revisions (0.00%)
758 758 finding outgoing largefiles: 1/5 revisions (20.00%)
759 759 finding outgoing largefiles: 2/5 revisions (40.00%)
760 760 finding outgoing largefiles: 3/5 revisions (60.00%)
761 761 finding outgoing largefiles: 4/5 revisions (80.00%)
762 762 largefiles to upload (3 entities):
763 763 b
764 764 13f9ed0898e315bf59dc2973fec52037b6f441a2
765 765 89e6c98d92887913cadf06b2adb97f26cde4849b
766 766 c801c9cfe94400963fcb683246217d5db77f9a9a
767 767 b1
768 768 89e6c98d92887913cadf06b2adb97f26cde4849b
769 769 b2
770 770 89e6c98d92887913cadf06b2adb97f26cde4849b
771 771
772 772
773 773 Pushing revision #1 causes uploading entity 89e6c98d9288, which is
774 774 shared also by largefiles b1, b2 in revision #2 and b in revision #5.
775 775
776 776 Then, entity 89e6c98d9288 is not treated as "outgoing entity" at "hg
777 777 summary" and "hg outgoing", even though files in outgoing revision #2
778 778 and #5 refer it.
779 779
780 780 $ hg -R clone2 push -r 1 -q
781 781 $ hg -R clone2 summary --large
782 782 parent: 5:036794ea641c tip
783 783 #5: refer existing largefile entity again
784 784 branch: default
785 785 commit: (clean)
786 786 update: (current)
787 787 phases: 6 draft
788 788 largefiles: 2 entities for 1 files to upload
789 789 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n"
790 790 comparing with $TESTTMP/issue3651/src (glob)
791 791 searching for changes
792 792 2:6095d0695d70
793 793 3:7983dce246cc
794 794 4:233f12ada4ae
795 795 5:036794ea641c
796 796 largefiles to upload (2 entities):
797 797 b
798 798
799 799 $ hg -R clone2 outgoing --large -T "{rev}:{node|short}\n" --debug --config progress.debug=true
800 800 comparing with $TESTTMP/issue3651/src (glob)
801 801 query 1; heads
802 802 searching for changes
803 803 all remote heads known locally
804 804 2:6095d0695d70
805 805 3:7983dce246cc
806 806 4:233f12ada4ae
807 807 5:036794ea641c
808 808 finding outgoing largefiles: 0/4 revisions (0.00%)
809 809 finding outgoing largefiles: 1/4 revisions (25.00%)
810 810 finding outgoing largefiles: 2/4 revisions (50.00%)
811 811 finding outgoing largefiles: 3/4 revisions (75.00%)
812 812 largefiles to upload (2 entities):
813 813 b
814 814 13f9ed0898e315bf59dc2973fec52037b6f441a2
815 815 c801c9cfe94400963fcb683246217d5db77f9a9a
816 816
817 817
818 818 $ cd ..
819 819
820 820 merge action 'd' for 'local renamed directory to d2/g' which has no filename
821 821 ==================================================================================
822 822
823 823 $ hg init merge-action
824 824 $ cd merge-action
825 825 $ touch l
826 826 $ hg add --large l
827 827 $ mkdir d1
828 828 $ touch d1/f
829 829 $ hg ci -Aqm0
830 830 Invoking status precommit hook
831 831 A d1/f
832 832 A l
833 833 $ echo > d1/f
834 834 $ touch d1/g
835 835 $ hg ci -Aqm1
836 836 Invoking status precommit hook
837 837 M d1/f
838 838 A d1/g
839 839 $ hg up -qr0
840 840 $ hg mv d1 d2
841 841 moving d1/f to d2/f (glob)
842 842 $ hg ci -qm2
843 843 Invoking status precommit hook
844 844 A d2/f
845 845 R d1/f
846 846 $ hg merge
847 847 merging d2/f and d1/f to d2/f
848 848 1 files updated, 1 files merged, 0 files removed, 0 files unresolved
849 849 (branch merge, don't forget to commit)
850 850 $ cd ..
851 851
852 852
853 853 Merge conflicts:
854 854 =====================
855 855
856 856 $ hg init merge
857 857 $ cd merge
858 858 $ echo 0 > f-different
859 859 $ echo 0 > f-same
860 860 $ echo 0 > f-unchanged-1
861 861 $ echo 0 > f-unchanged-2
862 862 $ hg add --large *
863 863 $ hg ci -m0
864 864 Invoking status precommit hook
865 865 A f-different
866 866 A f-same
867 867 A f-unchanged-1
868 868 A f-unchanged-2
869 869 $ echo tmp1 > f-unchanged-1
870 870 $ echo tmp1 > f-unchanged-2
871 871 $ echo tmp1 > f-same
872 872 $ hg ci -m1
873 873 Invoking status precommit hook
874 874 M f-same
875 875 M f-unchanged-1
876 876 M f-unchanged-2
877 877 $ echo 2 > f-different
878 878 $ echo 0 > f-unchanged-1
879 879 $ echo 1 > f-unchanged-2
880 880 $ echo 1 > f-same
881 881 $ hg ci -m2
882 882 Invoking status precommit hook
883 883 M f-different
884 884 M f-same
885 885 M f-unchanged-1
886 886 M f-unchanged-2
887 887 $ hg up -qr0
888 888 $ echo tmp2 > f-unchanged-1
889 889 $ echo tmp2 > f-unchanged-2
890 890 $ echo tmp2 > f-same
891 891 $ hg ci -m3
892 892 Invoking status precommit hook
893 893 M f-same
894 894 M f-unchanged-1
895 895 M f-unchanged-2
896 896 created new head
897 897 $ echo 1 > f-different
898 898 $ echo 1 > f-unchanged-1
899 899 $ echo 0 > f-unchanged-2
900 900 $ echo 1 > f-same
901 901 $ hg ci -m4
902 902 Invoking status precommit hook
903 903 M f-different
904 904 M f-same
905 905 M f-unchanged-1
906 906 M f-unchanged-2
907 907 $ hg merge
908 908 largefile f-different has a merge conflict
909 909 ancestor was 09d2af8dd22201dd8d48e5dcfcaed281ff9422c7
910 910 keep (l)ocal e5fa44f2b31c1fb553b6021e7360d07d5d91ff5e or
911 911 take (o)ther 7448d8798a4380162d4b56f9b452e2f6f9e24e7a? l
912 912 getting changed largefiles
913 913 1 largefiles updated, 0 removed
914 914 0 files updated, 4 files merged, 0 files removed, 0 files unresolved
915 915 (branch merge, don't forget to commit)
916 916 $ cat f-different
917 917 1
918 918 $ cat f-same
919 919 1
920 920 $ cat f-unchanged-1
921 921 1
922 922 $ cat f-unchanged-2
923 923 1
924 924 $ cd ..
925 925
926 926 Test largefile insulation (do not enabled a side effect
927 927 ========================================================
928 928
929 929 Check whether "largefiles" feature is supported only in repositories
930 930 enabling largefiles extension.
931 931
932 932 $ mkdir individualenabling
933 933 $ cd individualenabling
934 934
935 935 $ hg init enabledlocally
936 936 $ echo large > enabledlocally/large
937 937 $ hg -R enabledlocally add --large enabledlocally/large
938 938 $ hg -R enabledlocally commit -m '#0'
939 939 Invoking status precommit hook
940 940 A large
941 941
942 942 $ hg init notenabledlocally
943 943 $ echo large > notenabledlocally/large
944 944 $ hg -R notenabledlocally add --large notenabledlocally/large
945 945 $ hg -R notenabledlocally commit -m '#0'
946 946 Invoking status precommit hook
947 947 A large
948 948
949 949 $ cat >> $HGRCPATH <<EOF
950 950 > [extensions]
951 951 > # disable globally
952 952 > largefiles=!
953 953 > EOF
954 954 $ cat >> enabledlocally/.hg/hgrc <<EOF
955 955 > [extensions]
956 956 > # enable locally
957 957 > largefiles=
958 958 > EOF
959 959 $ hg -R enabledlocally root
960 960 $TESTTMP/individualenabling/enabledlocally (glob)
961 961 $ hg -R notenabledlocally root
962 962 abort: repository requires features unknown to this Mercurial: largefiles!
963 963 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
964 964 [255]
965 965
966 966 $ hg init push-dst
967 967 $ hg -R enabledlocally push push-dst
968 968 pushing to push-dst
969 969 abort: required features are not supported in the destination: largefiles
970 970 [255]
971 971
972 972 $ hg init pull-src
973 973 $ hg -R pull-src pull enabledlocally
974 974 pulling from enabledlocally
975 975 abort: required features are not supported in the destination: largefiles
976 976 [255]
977 977
978 978 $ hg clone enabledlocally clone-dst
979 979 abort: repository requires features unknown to this Mercurial: largefiles!
980 980 (see https://mercurial-scm.org/wiki/MissingRequirement for more information)
981 981 [255]
982 982 $ test -d clone-dst
983 983 [1]
984 984 $ hg clone --pull enabledlocally clone-pull-dst
985 985 abort: required features are not supported in the destination: largefiles
986 986 [255]
987 987 $ test -d clone-pull-dst
988 988 [1]
989 989
990 990 #if serve
991 991
992 992 Test largefiles specific peer setup, when largefiles is enabled
993 993 locally (issue4109)
994 994
995 995 $ hg showconfig extensions | grep largefiles
996 996 extensions.largefiles=!
997 997 $ mkdir -p $TESTTMP/individualenabling/usercache
998 998
999 999 $ hg serve -R enabledlocally -d -p $HGPORT --pid-file hg.pid
1000 1000 $ cat hg.pid >> $DAEMON_PIDS
1001 1001
1002 1002 $ hg init pull-dst
1003 1003 $ cat > pull-dst/.hg/hgrc <<EOF
1004 1004 > [extensions]
1005 1005 > # enable locally
1006 1006 > largefiles=
1007 1007 > [largefiles]
1008 1008 > # ignore system cache to force largefiles specific wire proto access
1009 1009 > usercache=$TESTTMP/individualenabling/usercache
1010 1010 > EOF
1011 1011 $ hg -R pull-dst -q pull -u http://localhost:$HGPORT
1012 1012
1013 1013 $ killdaemons.py
1014 1014 #endif
1015 1015
1016 1016 Test overridden functions work correctly even for repos disabling
1017 1017 largefiles (issue4547)
1018 1018
1019 1019 $ hg showconfig extensions | grep largefiles
1020 1020 extensions.largefiles=!
1021 1021
1022 1022 (test updating implied by clone)
1023 1023
1024 1024 $ hg init enabled-but-no-largefiles
1025 1025 $ echo normal1 > enabled-but-no-largefiles/normal1
1026 1026 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal1
1027 1027 $ hg -R enabled-but-no-largefiles commit -m '#0@enabled-but-no-largefiles'
1028 1028 Invoking status precommit hook
1029 1029 A normal1
1030 1030 $ cat >> enabled-but-no-largefiles/.hg/hgrc <<EOF
1031 1031 > [extensions]
1032 1032 > # enable locally
1033 1033 > largefiles=
1034 1034 > EOF
1035 1035 $ hg clone -q enabled-but-no-largefiles no-largefiles
1036 1036
1037 1037 $ echo normal2 > enabled-but-no-largefiles/normal2
1038 1038 $ hg -R enabled-but-no-largefiles add enabled-but-no-largefiles/normal2
1039 1039 $ hg -R enabled-but-no-largefiles commit -m '#1@enabled-but-no-largefiles'
1040 1040 Invoking status precommit hook
1041 1041 A normal2
1042 1042
1043 1043 $ echo normal3 > no-largefiles/normal3
1044 1044 $ hg -R no-largefiles add no-largefiles/normal3
1045 1045 $ hg -R no-largefiles commit -m '#1@no-largefiles'
1046 1046 Invoking status precommit hook
1047 1047 A normal3
1048 1048
1049 1049 $ hg -R no-largefiles -q pull --rebase
1050 1050 Invoking status precommit hook
1051 1051 A normal3
1052 1052
1053 1053 (test reverting)
1054 1054
1055 1055 $ hg init subrepo-root
1056 1056 $ cat >> subrepo-root/.hg/hgrc <<EOF
1057 1057 > [extensions]
1058 1058 > # enable locally
1059 1059 > largefiles=
1060 1060 > EOF
1061 1061 $ echo large > subrepo-root/large
1062 1062 $ hg -R subrepo-root add --large subrepo-root/large
1063 1063 $ hg clone -q no-largefiles subrepo-root/no-largefiles
1064 1064 $ cat > subrepo-root/.hgsub <<EOF
1065 1065 > no-largefiles = no-largefiles
1066 1066 > EOF
1067 1067 $ hg -R subrepo-root add subrepo-root/.hgsub
1068 1068 $ hg -R subrepo-root commit -m '#0'
1069 1069 Invoking status precommit hook
1070 1070 A .hgsub
1071 1071 A large
1072 1072 ? .hgsubstate
1073 1073 $ echo dirty >> subrepo-root/large
1074 1074 $ echo dirty >> subrepo-root/no-largefiles/normal1
1075 1075 $ hg -R subrepo-root status -S
1076 1076 M large
1077 1077 M no-largefiles/normal1
1078 1078 $ hg -R subrepo-root revert --all
1079 1079 reverting subrepo-root/.hglf/large (glob)
1080 1080 reverting subrepo no-largefiles
1081 1081 reverting subrepo-root/no-largefiles/normal1 (glob)
1082 1082
1083 1083 $ cd ..
1084 1084
1085 1085
1086 1086 Test "pull --rebase" when rebase is enabled before largefiles (issue3861)
1087 1087 =========================================================================
1088 1088
1089 1089 $ hg showconfig extensions | grep largefiles
1090 1090 extensions.largefiles=!
1091 1091
1092 1092 $ mkdir issue3861
1093 1093 $ cd issue3861
1094 1094 $ hg init src
1095 1095 $ hg clone -q src dst
1096 1096 $ echo a > src/a
1097 1097 $ hg -R src commit -Aqm "#0"
1098 1098 Invoking status precommit hook
1099 1099 A a
1100 1100
1101 1101 $ cat >> dst/.hg/hgrc <<EOF
1102 1102 > [extensions]
1103 1103 > largefiles=
1104 1104 > EOF
1105 1105 $ hg -R dst pull --rebase
1106 1106 pulling from $TESTTMP/issue3861/src (glob)
1107 1107 requesting all changes
1108 1108 adding changesets
1109 1109 adding manifests
1110 1110 adding file changes
1111 1111 added 1 changesets with 1 changes to 1 files
1112 1112 nothing to rebase - updating instead
1113 1113 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1114 1114
1115 1115 $ cd ..
@@ -1,2384 +1,2384
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 The g is crafted to have 2 filelog topological heads in a linear
19 19 changeset graph
20 20
21 21 $ hg init a
22 22 $ cd a
23 23 $ echo a > a
24 24 $ echo f > f
25 25 $ hg ci -Ama -d '1 0'
26 26 adding a
27 27 adding f
28 28
29 29 $ hg cp a b
30 30 $ hg cp f g
31 31 $ hg ci -mb -d '2 0'
32 32
33 33 $ mkdir dir
34 34 $ hg mv b dir
35 35 $ echo g >> g
36 36 $ echo f >> f
37 37 $ hg ci -mc -d '3 0'
38 38
39 39 $ hg mv a b
40 40 $ hg cp -f f g
41 41 $ echo a > d
42 42 $ hg add d
43 43 $ hg ci -md -d '4 0'
44 44
45 45 $ hg mv dir/b e
46 46 $ hg ci -me -d '5 0'
47 47
48 48 Make sure largefiles doesn't interfere with logging a regular file
49 49 $ hg --debug log a -T '{rev}: {desc}\n' --config extensions.largefiles=
50 updated patterns: ['.hglf/a', 'a']
50 updated patterns: .hglf/a, a
51 51 0: a
52 52 $ hg log a
53 53 changeset: 0:9161b9aeaf16
54 54 user: test
55 55 date: Thu Jan 01 00:00:01 1970 +0000
56 56 summary: a
57 57
58 58 $ hg log glob:a*
59 59 changeset: 3:2ca5ba701980
60 60 user: test
61 61 date: Thu Jan 01 00:00:04 1970 +0000
62 62 summary: d
63 63
64 64 changeset: 0:9161b9aeaf16
65 65 user: test
66 66 date: Thu Jan 01 00:00:01 1970 +0000
67 67 summary: a
68 68
69 69 $ hg --debug log glob:a* -T '{rev}: {desc}\n' --config extensions.largefiles=
70 updated patterns: ['glob:.hglf/a*', 'glob:a*']
70 updated patterns: glob:.hglf/a*, glob:a*
71 71 3: d
72 72 0: a
73 73
74 74 log on directory
75 75
76 76 $ hg log dir
77 77 changeset: 4:7e4639b4691b
78 78 tag: tip
79 79 user: test
80 80 date: Thu Jan 01 00:00:05 1970 +0000
81 81 summary: e
82 82
83 83 changeset: 2:f8954cd4dc1f
84 84 user: test
85 85 date: Thu Jan 01 00:00:03 1970 +0000
86 86 summary: c
87 87
88 88 $ hg log somethingthatdoesntexist dir
89 89 changeset: 4:7e4639b4691b
90 90 tag: tip
91 91 user: test
92 92 date: Thu Jan 01 00:00:05 1970 +0000
93 93 summary: e
94 94
95 95 changeset: 2:f8954cd4dc1f
96 96 user: test
97 97 date: Thu Jan 01 00:00:03 1970 +0000
98 98 summary: c
99 99
100 100
101 101 -f, non-existent directory
102 102
103 103 $ hg log -f dir
104 104 abort: cannot follow file not in parent revision: "dir"
105 105 [255]
106 106
107 107 -f, directory
108 108
109 109 $ hg up -q 3
110 110 $ hg log -f dir
111 111 changeset: 2:f8954cd4dc1f
112 112 user: test
113 113 date: Thu Jan 01 00:00:03 1970 +0000
114 114 summary: c
115 115
116 116 -f, directory with --patch
117 117
118 118 $ hg log -f dir -p
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 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
125 125 --- /dev/null* (glob)
126 126 +++ b/dir/b* (glob)
127 127 @@ -0,0 +1,1 @@
128 128 +a
129 129
130 130
131 131 -f, pattern
132 132
133 133 $ hg log -f -I 'dir**' -p
134 134 changeset: 2:f8954cd4dc1f
135 135 user: test
136 136 date: Thu Jan 01 00:00:03 1970 +0000
137 137 summary: c
138 138
139 139 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
140 140 --- /dev/null* (glob)
141 141 +++ b/dir/b* (glob)
142 142 @@ -0,0 +1,1 @@
143 143 +a
144 144
145 145 $ hg up -q 4
146 146
147 147 -f, a wrong style
148 148
149 149 $ hg log -f -l1 --style something
150 150 abort: style 'something' not found
151 151 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
152 152 [255]
153 153
154 154 -f, phases style
155 155
156 156
157 157 $ hg log -f -l1 --style phases
158 158 changeset: 4:7e4639b4691b
159 159 tag: tip
160 160 phase: draft
161 161 user: test
162 162 date: Thu Jan 01 00:00:05 1970 +0000
163 163 summary: e
164 164
165 165
166 166 $ hg log -f -l1 --style phases -q
167 167 4:7e4639b4691b
168 168
169 169 -f, but no args
170 170
171 171 $ hg log -f
172 172 changeset: 4:7e4639b4691b
173 173 tag: tip
174 174 user: test
175 175 date: Thu Jan 01 00:00:05 1970 +0000
176 176 summary: e
177 177
178 178 changeset: 3:2ca5ba701980
179 179 user: test
180 180 date: Thu Jan 01 00:00:04 1970 +0000
181 181 summary: d
182 182
183 183 changeset: 2:f8954cd4dc1f
184 184 user: test
185 185 date: Thu Jan 01 00:00:03 1970 +0000
186 186 summary: c
187 187
188 188 changeset: 1:d89b0a12d229
189 189 user: test
190 190 date: Thu Jan 01 00:00:02 1970 +0000
191 191 summary: b
192 192
193 193 changeset: 0:9161b9aeaf16
194 194 user: test
195 195 date: Thu Jan 01 00:00:01 1970 +0000
196 196 summary: a
197 197
198 198
199 199 one rename
200 200
201 201 $ hg up -q 2
202 202 $ hg log -vf a
203 203 changeset: 0:9161b9aeaf16
204 204 user: test
205 205 date: Thu Jan 01 00:00:01 1970 +0000
206 206 files: a f
207 207 description:
208 208 a
209 209
210 210
211 211
212 212 many renames
213 213
214 214 $ hg up -q tip
215 215 $ hg log -vf e
216 216 changeset: 4:7e4639b4691b
217 217 tag: tip
218 218 user: test
219 219 date: Thu Jan 01 00:00:05 1970 +0000
220 220 files: dir/b e
221 221 description:
222 222 e
223 223
224 224
225 225 changeset: 2:f8954cd4dc1f
226 226 user: test
227 227 date: Thu Jan 01 00:00:03 1970 +0000
228 228 files: b dir/b f g
229 229 description:
230 230 c
231 231
232 232
233 233 changeset: 1:d89b0a12d229
234 234 user: test
235 235 date: Thu Jan 01 00:00:02 1970 +0000
236 236 files: b g
237 237 description:
238 238 b
239 239
240 240
241 241 changeset: 0:9161b9aeaf16
242 242 user: test
243 243 date: Thu Jan 01 00:00:01 1970 +0000
244 244 files: a f
245 245 description:
246 246 a
247 247
248 248
249 249
250 250
251 251 log -pf dir/b
252 252
253 253 $ hg up -q 3
254 254 $ hg log -pf dir/b
255 255 changeset: 2:f8954cd4dc1f
256 256 user: test
257 257 date: Thu Jan 01 00:00:03 1970 +0000
258 258 summary: c
259 259
260 260 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
261 261 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
262 262 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
263 263 @@ -0,0 +1,1 @@
264 264 +a
265 265
266 266 changeset: 1:d89b0a12d229
267 267 user: test
268 268 date: Thu Jan 01 00:00:02 1970 +0000
269 269 summary: b
270 270
271 271 diff -r 9161b9aeaf16 -r d89b0a12d229 b
272 272 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
273 273 +++ b/b Thu Jan 01 00:00:02 1970 +0000
274 274 @@ -0,0 +1,1 @@
275 275 +a
276 276
277 277 changeset: 0:9161b9aeaf16
278 278 user: test
279 279 date: Thu Jan 01 00:00:01 1970 +0000
280 280 summary: a
281 281
282 282 diff -r 000000000000 -r 9161b9aeaf16 a
283 283 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
284 284 +++ b/a Thu Jan 01 00:00:01 1970 +0000
285 285 @@ -0,0 +1,1 @@
286 286 +a
287 287
288 288
289 289 log -pf b inside dir
290 290
291 291 $ hg --cwd=dir log -pf b
292 292 changeset: 2:f8954cd4dc1f
293 293 user: test
294 294 date: Thu Jan 01 00:00:03 1970 +0000
295 295 summary: c
296 296
297 297 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
298 298 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
299 299 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
300 300 @@ -0,0 +1,1 @@
301 301 +a
302 302
303 303 changeset: 1:d89b0a12d229
304 304 user: test
305 305 date: Thu Jan 01 00:00:02 1970 +0000
306 306 summary: b
307 307
308 308 diff -r 9161b9aeaf16 -r d89b0a12d229 b
309 309 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
310 310 +++ b/b Thu Jan 01 00:00:02 1970 +0000
311 311 @@ -0,0 +1,1 @@
312 312 +a
313 313
314 314 changeset: 0:9161b9aeaf16
315 315 user: test
316 316 date: Thu Jan 01 00:00:01 1970 +0000
317 317 summary: a
318 318
319 319 diff -r 000000000000 -r 9161b9aeaf16 a
320 320 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
321 321 +++ b/a Thu Jan 01 00:00:01 1970 +0000
322 322 @@ -0,0 +1,1 @@
323 323 +a
324 324
325 325
326 326 log -pf, but no args
327 327
328 328 $ hg log -pf
329 329 changeset: 3:2ca5ba701980
330 330 user: test
331 331 date: Thu Jan 01 00:00:04 1970 +0000
332 332 summary: d
333 333
334 334 diff -r f8954cd4dc1f -r 2ca5ba701980 a
335 335 --- a/a Thu Jan 01 00:00:03 1970 +0000
336 336 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
337 337 @@ -1,1 +0,0 @@
338 338 -a
339 339 diff -r f8954cd4dc1f -r 2ca5ba701980 b
340 340 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
341 341 +++ b/b Thu Jan 01 00:00:04 1970 +0000
342 342 @@ -0,0 +1,1 @@
343 343 +a
344 344 diff -r f8954cd4dc1f -r 2ca5ba701980 d
345 345 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
346 346 +++ b/d Thu Jan 01 00:00:04 1970 +0000
347 347 @@ -0,0 +1,1 @@
348 348 +a
349 349 diff -r f8954cd4dc1f -r 2ca5ba701980 g
350 350 --- a/g Thu Jan 01 00:00:03 1970 +0000
351 351 +++ b/g Thu Jan 01 00:00:04 1970 +0000
352 352 @@ -1,2 +1,2 @@
353 353 f
354 354 -g
355 355 +f
356 356
357 357 changeset: 2:f8954cd4dc1f
358 358 user: test
359 359 date: Thu Jan 01 00:00:03 1970 +0000
360 360 summary: c
361 361
362 362 diff -r d89b0a12d229 -r f8954cd4dc1f b
363 363 --- a/b Thu Jan 01 00:00:02 1970 +0000
364 364 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
365 365 @@ -1,1 +0,0 @@
366 366 -a
367 367 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
368 368 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
369 369 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
370 370 @@ -0,0 +1,1 @@
371 371 +a
372 372 diff -r d89b0a12d229 -r f8954cd4dc1f f
373 373 --- a/f Thu Jan 01 00:00:02 1970 +0000
374 374 +++ b/f Thu Jan 01 00:00:03 1970 +0000
375 375 @@ -1,1 +1,2 @@
376 376 f
377 377 +f
378 378 diff -r d89b0a12d229 -r f8954cd4dc1f g
379 379 --- a/g Thu Jan 01 00:00:02 1970 +0000
380 380 +++ b/g Thu Jan 01 00:00:03 1970 +0000
381 381 @@ -1,1 +1,2 @@
382 382 f
383 383 +g
384 384
385 385 changeset: 1:d89b0a12d229
386 386 user: test
387 387 date: Thu Jan 01 00:00:02 1970 +0000
388 388 summary: b
389 389
390 390 diff -r 9161b9aeaf16 -r d89b0a12d229 b
391 391 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
392 392 +++ b/b Thu Jan 01 00:00:02 1970 +0000
393 393 @@ -0,0 +1,1 @@
394 394 +a
395 395 diff -r 9161b9aeaf16 -r d89b0a12d229 g
396 396 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
397 397 +++ b/g Thu Jan 01 00:00:02 1970 +0000
398 398 @@ -0,0 +1,1 @@
399 399 +f
400 400
401 401 changeset: 0:9161b9aeaf16
402 402 user: test
403 403 date: Thu Jan 01 00:00:01 1970 +0000
404 404 summary: a
405 405
406 406 diff -r 000000000000 -r 9161b9aeaf16 a
407 407 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
408 408 +++ b/a Thu Jan 01 00:00:01 1970 +0000
409 409 @@ -0,0 +1,1 @@
410 410 +a
411 411 diff -r 000000000000 -r 9161b9aeaf16 f
412 412 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
413 413 +++ b/f Thu Jan 01 00:00:01 1970 +0000
414 414 @@ -0,0 +1,1 @@
415 415 +f
416 416
417 417
418 418 log -vf dir/b
419 419
420 420 $ hg log -vf dir/b
421 421 changeset: 2:f8954cd4dc1f
422 422 user: test
423 423 date: Thu Jan 01 00:00:03 1970 +0000
424 424 files: b dir/b f g
425 425 description:
426 426 c
427 427
428 428
429 429 changeset: 1:d89b0a12d229
430 430 user: test
431 431 date: Thu Jan 01 00:00:02 1970 +0000
432 432 files: b g
433 433 description:
434 434 b
435 435
436 436
437 437 changeset: 0:9161b9aeaf16
438 438 user: test
439 439 date: Thu Jan 01 00:00:01 1970 +0000
440 440 files: a f
441 441 description:
442 442 a
443 443
444 444
445 445
446 446
447 447 -f and multiple filelog heads
448 448
449 449 $ hg up -q 2
450 450 $ hg log -f g --template '{rev}\n'
451 451 2
452 452 1
453 453 0
454 454 $ hg up -q tip
455 455 $ hg log -f g --template '{rev}\n'
456 456 3
457 457 2
458 458 0
459 459
460 460
461 461 log copies with --copies
462 462
463 463 $ hg log -vC --template '{rev} {file_copies}\n'
464 464 4 e (dir/b)
465 465 3 b (a)g (f)
466 466 2 dir/b (b)
467 467 1 b (a)g (f)
468 468 0
469 469
470 470 log copies switch without --copies, with old filecopy template
471 471
472 472 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
473 473 4
474 474 3
475 475 2
476 476 1
477 477 0
478 478
479 479 log copies switch with --copies
480 480
481 481 $ hg log -vC --template '{rev} {file_copies_switch}\n'
482 482 4 e (dir/b)
483 483 3 b (a)g (f)
484 484 2 dir/b (b)
485 485 1 b (a)g (f)
486 486 0
487 487
488 488
489 489 log copies with hardcoded style and with --style=default
490 490
491 491 $ hg log -vC -r4
492 492 changeset: 4:7e4639b4691b
493 493 tag: tip
494 494 user: test
495 495 date: Thu Jan 01 00:00:05 1970 +0000
496 496 files: dir/b e
497 497 copies: e (dir/b)
498 498 description:
499 499 e
500 500
501 501
502 502 $ hg log -vC -r4 --style=default
503 503 changeset: 4:7e4639b4691b
504 504 tag: tip
505 505 user: test
506 506 date: Thu Jan 01 00:00:05 1970 +0000
507 507 files: dir/b e
508 508 copies: e (dir/b)
509 509 description:
510 510 e
511 511
512 512
513 513 $ hg log -vC -r4 -Tjson
514 514 [
515 515 {
516 516 "rev": 4,
517 517 "node": "7e4639b4691b9f84b81036a8d4fb218ce3c5e3a3",
518 518 "branch": "default",
519 519 "phase": "draft",
520 520 "user": "test",
521 521 "date": [5, 0],
522 522 "desc": "e",
523 523 "bookmarks": [],
524 524 "tags": ["tip"],
525 525 "parents": ["2ca5ba7019804f1f597249caddf22a64d34df0ba"],
526 526 "files": ["dir/b", "e"],
527 527 "copies": {"e": "dir/b"}
528 528 }
529 529 ]
530 530
531 531 log copies, non-linear manifest
532 532
533 533 $ hg up -C 3
534 534 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
535 535 $ hg mv dir/b e
536 536 $ echo foo > foo
537 537 $ hg ci -Ame2 -d '6 0'
538 538 adding foo
539 539 created new head
540 540 $ hg log -v --template '{rev} {file_copies}\n' -r 5
541 541 5 e (dir/b)
542 542
543 543
544 544 log copies, execute bit set
545 545
546 546 #if execbit
547 547 $ chmod +x e
548 548 $ hg ci -me3 -d '7 0'
549 549 $ hg log -v --template '{rev} {file_copies}\n' -r 6
550 550 6
551 551 #endif
552 552
553 553
554 554 log -p d
555 555
556 556 $ hg log -pv d
557 557 changeset: 3:2ca5ba701980
558 558 user: test
559 559 date: Thu Jan 01 00:00:04 1970 +0000
560 560 files: a b d g
561 561 description:
562 562 d
563 563
564 564
565 565 diff -r f8954cd4dc1f -r 2ca5ba701980 d
566 566 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
567 567 +++ b/d Thu Jan 01 00:00:04 1970 +0000
568 568 @@ -0,0 +1,1 @@
569 569 +a
570 570
571 571
572 572
573 573 log --removed file
574 574
575 575 $ hg log --removed -v a
576 576 changeset: 3:2ca5ba701980
577 577 user: test
578 578 date: Thu Jan 01 00:00:04 1970 +0000
579 579 files: a b d g
580 580 description:
581 581 d
582 582
583 583
584 584 changeset: 0:9161b9aeaf16
585 585 user: test
586 586 date: Thu Jan 01 00:00:01 1970 +0000
587 587 files: a f
588 588 description:
589 589 a
590 590
591 591
592 592
593 593 log --removed revrange file
594 594
595 595 $ hg log --removed -v -r0:2 a
596 596 changeset: 0:9161b9aeaf16
597 597 user: test
598 598 date: Thu Jan 01 00:00:01 1970 +0000
599 599 files: a f
600 600 description:
601 601 a
602 602
603 603
604 604 $ cd ..
605 605
606 606 log --follow tests
607 607
608 608 $ hg init follow
609 609 $ cd follow
610 610
611 611 $ echo base > base
612 612 $ hg ci -Ambase -d '1 0'
613 613 adding base
614 614
615 615 $ echo r1 >> base
616 616 $ hg ci -Amr1 -d '1 0'
617 617 $ echo r2 >> base
618 618 $ hg ci -Amr2 -d '1 0'
619 619
620 620 $ hg up -C 1
621 621 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
622 622 $ echo b1 > b1
623 623
624 624 log -r "follow('set:clean()')"
625 625
626 626 $ hg log -r "follow('set:clean()')"
627 627 changeset: 0:67e992f2c4f3
628 628 user: test
629 629 date: Thu Jan 01 00:00:01 1970 +0000
630 630 summary: base
631 631
632 632 changeset: 1:3d5bf5654eda
633 633 user: test
634 634 date: Thu Jan 01 00:00:01 1970 +0000
635 635 summary: r1
636 636
637 637
638 638 $ hg ci -Amb1 -d '1 0'
639 639 adding b1
640 640 created new head
641 641
642 642
643 643 log -f
644 644
645 645 $ hg log -f
646 646 changeset: 3:e62f78d544b4
647 647 tag: tip
648 648 parent: 1:3d5bf5654eda
649 649 user: test
650 650 date: Thu Jan 01 00:00:01 1970 +0000
651 651 summary: b1
652 652
653 653 changeset: 1:3d5bf5654eda
654 654 user: test
655 655 date: Thu Jan 01 00:00:01 1970 +0000
656 656 summary: r1
657 657
658 658 changeset: 0:67e992f2c4f3
659 659 user: test
660 660 date: Thu Jan 01 00:00:01 1970 +0000
661 661 summary: base
662 662
663 663
664 664 log -r follow('glob:b*')
665 665
666 666 $ hg log -r "follow('glob:b*')"
667 667 changeset: 0:67e992f2c4f3
668 668 user: test
669 669 date: Thu Jan 01 00:00:01 1970 +0000
670 670 summary: base
671 671
672 672 changeset: 1:3d5bf5654eda
673 673 user: test
674 674 date: Thu Jan 01 00:00:01 1970 +0000
675 675 summary: r1
676 676
677 677 changeset: 3:e62f78d544b4
678 678 tag: tip
679 679 parent: 1:3d5bf5654eda
680 680 user: test
681 681 date: Thu Jan 01 00:00:01 1970 +0000
682 682 summary: b1
683 683
684 684 log -f -r '1 + 4'
685 685
686 686 $ hg up -C 0
687 687 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
688 688 $ echo b2 > b2
689 689 $ hg ci -Amb2 -d '1 0'
690 690 adding b2
691 691 created new head
692 692 $ hg log -f -r '1 + 4'
693 693 changeset: 4:ddb82e70d1a1
694 694 tag: tip
695 695 parent: 0:67e992f2c4f3
696 696 user: test
697 697 date: Thu Jan 01 00:00:01 1970 +0000
698 698 summary: b2
699 699
700 700 changeset: 1:3d5bf5654eda
701 701 user: test
702 702 date: Thu Jan 01 00:00:01 1970 +0000
703 703 summary: r1
704 704
705 705 changeset: 0:67e992f2c4f3
706 706 user: test
707 707 date: Thu Jan 01 00:00:01 1970 +0000
708 708 summary: base
709 709
710 710 log -r "follow('set:grep(b2)')"
711 711
712 712 $ hg log -r "follow('set:grep(b2)')"
713 713 changeset: 4:ddb82e70d1a1
714 714 tag: tip
715 715 parent: 0:67e992f2c4f3
716 716 user: test
717 717 date: Thu Jan 01 00:00:01 1970 +0000
718 718 summary: b2
719 719
720 720 log -r "follow('set:grep(b2)', 4)"
721 721
722 722 $ hg up -qC 0
723 723 $ hg log -r "follow('set:grep(b2)', 4)"
724 724 changeset: 4:ddb82e70d1a1
725 725 tag: tip
726 726 parent: 0:67e992f2c4f3
727 727 user: test
728 728 date: Thu Jan 01 00:00:01 1970 +0000
729 729 summary: b2
730 730
731 731 $ hg up -qC 4
732 732
733 733 log -f -r null
734 734
735 735 $ hg log -f -r null
736 736 changeset: -1:000000000000
737 737 user:
738 738 date: Thu Jan 01 00:00:00 1970 +0000
739 739
740 740 $ hg log -f -r null -G
741 741 o changeset: -1:000000000000
742 742 user:
743 743 date: Thu Jan 01 00:00:00 1970 +0000
744 744
745 745
746 746
747 747 log -f with null parent
748 748
749 749 $ hg up -C null
750 750 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
751 751 $ hg log -f
752 752
753 753
754 754 log -r . with two parents
755 755
756 756 $ hg up -C 3
757 757 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
758 758 $ hg merge tip
759 759 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
760 760 (branch merge, don't forget to commit)
761 761 $ hg log -r .
762 762 changeset: 3:e62f78d544b4
763 763 parent: 1:3d5bf5654eda
764 764 user: test
765 765 date: Thu Jan 01 00:00:01 1970 +0000
766 766 summary: b1
767 767
768 768
769 769
770 770 log -r . with one parent
771 771
772 772 $ hg ci -mm12 -d '1 0'
773 773 $ hg log -r .
774 774 changeset: 5:302e9dd6890d
775 775 tag: tip
776 776 parent: 3:e62f78d544b4
777 777 parent: 4:ddb82e70d1a1
778 778 user: test
779 779 date: Thu Jan 01 00:00:01 1970 +0000
780 780 summary: m12
781 781
782 782
783 783 $ echo postm >> b1
784 784 $ hg ci -Amb1.1 -d'1 0'
785 785
786 786
787 787 log --follow-first
788 788
789 789 $ hg log --follow-first
790 790 changeset: 6:2404bbcab562
791 791 tag: tip
792 792 user: test
793 793 date: Thu Jan 01 00:00:01 1970 +0000
794 794 summary: b1.1
795 795
796 796 changeset: 5:302e9dd6890d
797 797 parent: 3:e62f78d544b4
798 798 parent: 4:ddb82e70d1a1
799 799 user: test
800 800 date: Thu Jan 01 00:00:01 1970 +0000
801 801 summary: m12
802 802
803 803 changeset: 3:e62f78d544b4
804 804 parent: 1:3d5bf5654eda
805 805 user: test
806 806 date: Thu Jan 01 00:00:01 1970 +0000
807 807 summary: b1
808 808
809 809 changeset: 1:3d5bf5654eda
810 810 user: test
811 811 date: Thu Jan 01 00:00:01 1970 +0000
812 812 summary: r1
813 813
814 814 changeset: 0:67e992f2c4f3
815 815 user: test
816 816 date: Thu Jan 01 00:00:01 1970 +0000
817 817 summary: base
818 818
819 819
820 820
821 821 log -P 2
822 822
823 823 $ hg log -P 2
824 824 changeset: 6:2404bbcab562
825 825 tag: tip
826 826 user: test
827 827 date: Thu Jan 01 00:00:01 1970 +0000
828 828 summary: b1.1
829 829
830 830 changeset: 5:302e9dd6890d
831 831 parent: 3:e62f78d544b4
832 832 parent: 4:ddb82e70d1a1
833 833 user: test
834 834 date: Thu Jan 01 00:00:01 1970 +0000
835 835 summary: m12
836 836
837 837 changeset: 4:ddb82e70d1a1
838 838 parent: 0:67e992f2c4f3
839 839 user: test
840 840 date: Thu Jan 01 00:00:01 1970 +0000
841 841 summary: b2
842 842
843 843 changeset: 3:e62f78d544b4
844 844 parent: 1:3d5bf5654eda
845 845 user: test
846 846 date: Thu Jan 01 00:00:01 1970 +0000
847 847 summary: b1
848 848
849 849
850 850
851 851 log -r tip -p --git
852 852
853 853 $ hg log -r tip -p --git
854 854 changeset: 6:2404bbcab562
855 855 tag: tip
856 856 user: test
857 857 date: Thu Jan 01 00:00:01 1970 +0000
858 858 summary: b1.1
859 859
860 860 diff --git a/b1 b/b1
861 861 --- a/b1
862 862 +++ b/b1
863 863 @@ -1,1 +1,2 @@
864 864 b1
865 865 +postm
866 866
867 867
868 868
869 869 log -r ""
870 870
871 871 $ hg log -r ''
872 872 hg: parse error: empty query
873 873 [255]
874 874
875 875 log -r <some unknown node id>
876 876
877 877 $ hg log -r 1000000000000000000000000000000000000000
878 878 abort: unknown revision '1000000000000000000000000000000000000000'!
879 879 [255]
880 880
881 881 log -k r1
882 882
883 883 $ hg log -k r1
884 884 changeset: 1:3d5bf5654eda
885 885 user: test
886 886 date: Thu Jan 01 00:00:01 1970 +0000
887 887 summary: r1
888 888
889 889 log -p -l2 --color=always
890 890
891 891 $ hg --config extensions.color= --config color.mode=ansi \
892 892 > log -p -l2 --color=always
893 893 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
894 894 tag: tip
895 895 user: test
896 896 date: Thu Jan 01 00:00:01 1970 +0000
897 897 summary: b1.1
898 898
899 899 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
900 900 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
901 901 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
902 902 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
903 903 b1
904 904 \x1b[0;32m+postm\x1b[0m (esc)
905 905
906 906 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
907 907 parent: 3:e62f78d544b4
908 908 parent: 4:ddb82e70d1a1
909 909 user: test
910 910 date: Thu Jan 01 00:00:01 1970 +0000
911 911 summary: m12
912 912
913 913 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
914 914 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
915 915 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
916 916 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
917 917 \x1b[0;32m+b2\x1b[0m (esc)
918 918
919 919
920 920
921 921 log -r tip --stat
922 922
923 923 $ hg log -r tip --stat
924 924 changeset: 6:2404bbcab562
925 925 tag: tip
926 926 user: test
927 927 date: Thu Jan 01 00:00:01 1970 +0000
928 928 summary: b1.1
929 929
930 930 b1 | 1 +
931 931 1 files changed, 1 insertions(+), 0 deletions(-)
932 932
933 933
934 934 $ cd ..
935 935
936 936 log --follow --patch FILE in repository where linkrev isn't trustworthy
937 937 (issue5376)
938 938
939 939 $ hg init follow-dup
940 940 $ cd follow-dup
941 941 $ cat <<EOF >> .hg/hgrc
942 942 > [ui]
943 943 > logtemplate = '=== {rev}: {desc}\n'
944 944 > [diff]
945 945 > nodates = True
946 946 > EOF
947 947 $ echo 0 >> a
948 948 $ hg ci -qAm 'a0'
949 949 $ echo 1 >> a
950 950 $ hg ci -m 'a1'
951 951 $ hg up -q 0
952 952 $ echo 1 >> a
953 953 $ touch b
954 954 $ hg ci -qAm 'a1 with b'
955 955 $ echo 3 >> a
956 956 $ hg ci -m 'a3'
957 957
958 958 fctx.rev() == 2, but fctx.linkrev() == 1
959 959
960 960 $ hg log -pf a
961 961 === 3: a3
962 962 diff -r 4ea02ba94d66 -r e7a6331a34f0 a
963 963 --- a/a
964 964 +++ b/a
965 965 @@ -1,2 +1,3 @@
966 966 0
967 967 1
968 968 +3
969 969
970 970 === 2: a1 with b
971 971 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
972 972 --- a/a
973 973 +++ b/a
974 974 @@ -1,1 +1,2 @@
975 975 0
976 976 +1
977 977
978 978 === 0: a0
979 979 diff -r 000000000000 -r 49b5e81287e2 a
980 980 --- /dev/null
981 981 +++ b/a
982 982 @@ -0,0 +1,1 @@
983 983 +0
984 984
985 985
986 986 fctx.introrev() == 2, but fctx.linkrev() == 1
987 987
988 988 $ hg up -q 2
989 989 $ hg log -pf a
990 990 === 2: a1 with b
991 991 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
992 992 --- a/a
993 993 +++ b/a
994 994 @@ -1,1 +1,2 @@
995 995 0
996 996 +1
997 997
998 998 === 0: a0
999 999 diff -r 000000000000 -r 49b5e81287e2 a
1000 1000 --- /dev/null
1001 1001 +++ b/a
1002 1002 @@ -0,0 +1,1 @@
1003 1003 +0
1004 1004
1005 1005
1006 1006 $ cd ..
1007 1007
1008 1008 Test that log should respect the order of -rREV even if multiple OR conditions
1009 1009 are specified (issue5100):
1010 1010
1011 1011 $ hg init revorder
1012 1012 $ cd revorder
1013 1013
1014 1014 $ hg branch -q b0
1015 1015 $ echo 0 >> f0
1016 1016 $ hg ci -qAm k0 -u u0
1017 1017 $ hg branch -q b1
1018 1018 $ echo 1 >> f1
1019 1019 $ hg ci -qAm k1 -u u1
1020 1020 $ hg branch -q b2
1021 1021 $ echo 2 >> f2
1022 1022 $ hg ci -qAm k2 -u u2
1023 1023
1024 1024 $ hg update -q b2
1025 1025 $ echo 3 >> f2
1026 1026 $ hg ci -qAm k2 -u u2
1027 1027 $ hg update -q b1
1028 1028 $ echo 4 >> f1
1029 1029 $ hg ci -qAm k1 -u u1
1030 1030 $ hg update -q b0
1031 1031 $ echo 5 >> f0
1032 1032 $ hg ci -qAm k0 -u u0
1033 1033
1034 1034 summary of revisions:
1035 1035
1036 1036 $ hg log -G -T '{rev} {branch} {author} {desc} {files}\n'
1037 1037 @ 5 b0 u0 k0 f0
1038 1038 |
1039 1039 | o 4 b1 u1 k1 f1
1040 1040 | |
1041 1041 | | o 3 b2 u2 k2 f2
1042 1042 | | |
1043 1043 | | o 2 b2 u2 k2 f2
1044 1044 | |/
1045 1045 | o 1 b1 u1 k1 f1
1046 1046 |/
1047 1047 o 0 b0 u0 k0 f0
1048 1048
1049 1049
1050 1050 log -b BRANCH in ascending order:
1051 1051
1052 1052 $ hg log -r0:tip -T '{rev} {branch}\n' -b b0 -b b1
1053 1053 0 b0
1054 1054 1 b1
1055 1055 4 b1
1056 1056 5 b0
1057 1057 $ hg log -r0:tip -T '{rev} {branch}\n' -b b1 -b b0
1058 1058 0 b0
1059 1059 1 b1
1060 1060 4 b1
1061 1061 5 b0
1062 1062
1063 1063 log --only-branch BRANCH in descending order:
1064 1064
1065 1065 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b1 --only-branch b2
1066 1066 4 b1
1067 1067 3 b2
1068 1068 2 b2
1069 1069 1 b1
1070 1070 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b2 --only-branch b1
1071 1071 4 b1
1072 1072 3 b2
1073 1073 2 b2
1074 1074 1 b1
1075 1075
1076 1076 log -u USER in ascending order, against compound set:
1077 1077
1078 1078 $ hg log -r'::head()' -T '{rev} {author}\n' -u u0 -u u2
1079 1079 0 u0
1080 1080 2 u2
1081 1081 3 u2
1082 1082 5 u0
1083 1083 $ hg log -r'::head()' -T '{rev} {author}\n' -u u2 -u u0
1084 1084 0 u0
1085 1085 2 u2
1086 1086 3 u2
1087 1087 5 u0
1088 1088
1089 1089 log -k TEXT in descending order, against compound set:
1090 1090
1091 1091 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k0 -k k1 -k k2
1092 1092 5 k0
1093 1093 3 k2
1094 1094 2 k2
1095 1095 1 k1
1096 1096 0 k0
1097 1097 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k2 -k k1 -k k0
1098 1098 5 k0
1099 1099 3 k2
1100 1100 2 k2
1101 1101 1 k1
1102 1102 0 k0
1103 1103
1104 1104 log FILE in ascending order, against dagrange:
1105 1105
1106 1106 $ hg log -r1:: -T '{rev} {files}\n' f1 f2
1107 1107 1 f1
1108 1108 2 f2
1109 1109 3 f2
1110 1110 4 f1
1111 1111 $ hg log -r1:: -T '{rev} {files}\n' f2 f1
1112 1112 1 f1
1113 1113 2 f2
1114 1114 3 f2
1115 1115 4 f1
1116 1116
1117 1117 $ cd ..
1118 1118
1119 1119 User
1120 1120
1121 1121 $ hg init usertest
1122 1122 $ cd usertest
1123 1123
1124 1124 $ echo a > a
1125 1125 $ hg ci -A -m "a" -u "User One <user1@example.org>"
1126 1126 adding a
1127 1127 $ echo b > b
1128 1128 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
1129 1129 adding b
1130 1130
1131 1131 $ hg log -u "User One <user1@example.org>"
1132 1132 changeset: 0:29a4c94f1924
1133 1133 user: User One <user1@example.org>
1134 1134 date: Thu Jan 01 00:00:00 1970 +0000
1135 1135 summary: a
1136 1136
1137 1137 $ hg log -u "user1" -u "user2"
1138 1138 changeset: 1:e834b5e69c0e
1139 1139 tag: tip
1140 1140 user: User Two <user2@example.org>
1141 1141 date: Thu Jan 01 00:00:00 1970 +0000
1142 1142 summary: b
1143 1143
1144 1144 changeset: 0:29a4c94f1924
1145 1145 user: User One <user1@example.org>
1146 1146 date: Thu Jan 01 00:00:00 1970 +0000
1147 1147 summary: a
1148 1148
1149 1149 $ hg log -u "user3"
1150 1150
1151 1151 $ cd ..
1152 1152
1153 1153 $ hg init branches
1154 1154 $ cd branches
1155 1155
1156 1156 $ echo a > a
1157 1157 $ hg ci -A -m "commit on default"
1158 1158 adding a
1159 1159 $ hg branch test
1160 1160 marked working directory as branch test
1161 1161 (branches are permanent and global, did you want a bookmark?)
1162 1162 $ echo b > b
1163 1163 $ hg ci -A -m "commit on test"
1164 1164 adding b
1165 1165
1166 1166 $ hg up default
1167 1167 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1168 1168 $ echo c > c
1169 1169 $ hg ci -A -m "commit on default"
1170 1170 adding c
1171 1171 $ hg up test
1172 1172 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1173 1173 $ echo c > c
1174 1174 $ hg ci -A -m "commit on test"
1175 1175 adding c
1176 1176
1177 1177
1178 1178 log -b default
1179 1179
1180 1180 $ hg log -b default
1181 1181 changeset: 2:c3a4f03cc9a7
1182 1182 parent: 0:24427303d56f
1183 1183 user: test
1184 1184 date: Thu Jan 01 00:00:00 1970 +0000
1185 1185 summary: commit on default
1186 1186
1187 1187 changeset: 0:24427303d56f
1188 1188 user: test
1189 1189 date: Thu Jan 01 00:00:00 1970 +0000
1190 1190 summary: commit on default
1191 1191
1192 1192
1193 1193
1194 1194 log -b test
1195 1195
1196 1196 $ hg log -b test
1197 1197 changeset: 3:f5d8de11c2e2
1198 1198 branch: test
1199 1199 tag: tip
1200 1200 parent: 1:d32277701ccb
1201 1201 user: test
1202 1202 date: Thu Jan 01 00:00:00 1970 +0000
1203 1203 summary: commit on test
1204 1204
1205 1205 changeset: 1:d32277701ccb
1206 1206 branch: test
1207 1207 user: test
1208 1208 date: Thu Jan 01 00:00:00 1970 +0000
1209 1209 summary: commit on test
1210 1210
1211 1211
1212 1212
1213 1213 log -b dummy
1214 1214
1215 1215 $ hg log -b dummy
1216 1216 abort: unknown revision 'dummy'!
1217 1217 [255]
1218 1218
1219 1219
1220 1220 log -b .
1221 1221
1222 1222 $ hg log -b .
1223 1223 changeset: 3:f5d8de11c2e2
1224 1224 branch: test
1225 1225 tag: tip
1226 1226 parent: 1:d32277701ccb
1227 1227 user: test
1228 1228 date: Thu Jan 01 00:00:00 1970 +0000
1229 1229 summary: commit on test
1230 1230
1231 1231 changeset: 1:d32277701ccb
1232 1232 branch: test
1233 1233 user: test
1234 1234 date: Thu Jan 01 00:00:00 1970 +0000
1235 1235 summary: commit on test
1236 1236
1237 1237
1238 1238
1239 1239 log -b default -b test
1240 1240
1241 1241 $ hg log -b default -b test
1242 1242 changeset: 3:f5d8de11c2e2
1243 1243 branch: test
1244 1244 tag: tip
1245 1245 parent: 1:d32277701ccb
1246 1246 user: test
1247 1247 date: Thu Jan 01 00:00:00 1970 +0000
1248 1248 summary: commit on test
1249 1249
1250 1250 changeset: 2:c3a4f03cc9a7
1251 1251 parent: 0:24427303d56f
1252 1252 user: test
1253 1253 date: Thu Jan 01 00:00:00 1970 +0000
1254 1254 summary: commit on default
1255 1255
1256 1256 changeset: 1:d32277701ccb
1257 1257 branch: test
1258 1258 user: test
1259 1259 date: Thu Jan 01 00:00:00 1970 +0000
1260 1260 summary: commit on test
1261 1261
1262 1262 changeset: 0:24427303d56f
1263 1263 user: test
1264 1264 date: Thu Jan 01 00:00:00 1970 +0000
1265 1265 summary: commit on default
1266 1266
1267 1267
1268 1268
1269 1269 log -b default -b .
1270 1270
1271 1271 $ hg log -b default -b .
1272 1272 changeset: 3:f5d8de11c2e2
1273 1273 branch: test
1274 1274 tag: tip
1275 1275 parent: 1:d32277701ccb
1276 1276 user: test
1277 1277 date: Thu Jan 01 00:00:00 1970 +0000
1278 1278 summary: commit on test
1279 1279
1280 1280 changeset: 2:c3a4f03cc9a7
1281 1281 parent: 0:24427303d56f
1282 1282 user: test
1283 1283 date: Thu Jan 01 00:00:00 1970 +0000
1284 1284 summary: commit on default
1285 1285
1286 1286 changeset: 1:d32277701ccb
1287 1287 branch: test
1288 1288 user: test
1289 1289 date: Thu Jan 01 00:00:00 1970 +0000
1290 1290 summary: commit on test
1291 1291
1292 1292 changeset: 0:24427303d56f
1293 1293 user: test
1294 1294 date: Thu Jan 01 00:00:00 1970 +0000
1295 1295 summary: commit on default
1296 1296
1297 1297
1298 1298
1299 1299 log -b . -b test
1300 1300
1301 1301 $ hg log -b . -b test
1302 1302 changeset: 3:f5d8de11c2e2
1303 1303 branch: test
1304 1304 tag: tip
1305 1305 parent: 1:d32277701ccb
1306 1306 user: test
1307 1307 date: Thu Jan 01 00:00:00 1970 +0000
1308 1308 summary: commit on test
1309 1309
1310 1310 changeset: 1:d32277701ccb
1311 1311 branch: test
1312 1312 user: test
1313 1313 date: Thu Jan 01 00:00:00 1970 +0000
1314 1314 summary: commit on test
1315 1315
1316 1316
1317 1317
1318 1318 log -b 2
1319 1319
1320 1320 $ hg log -b 2
1321 1321 changeset: 2:c3a4f03cc9a7
1322 1322 parent: 0:24427303d56f
1323 1323 user: test
1324 1324 date: Thu Jan 01 00:00:00 1970 +0000
1325 1325 summary: commit on default
1326 1326
1327 1327 changeset: 0:24427303d56f
1328 1328 user: test
1329 1329 date: Thu Jan 01 00:00:00 1970 +0000
1330 1330 summary: commit on default
1331 1331
1332 1332 #if gettext
1333 1333
1334 1334 Test that all log names are translated (e.g. branches, bookmarks, tags):
1335 1335
1336 1336 $ hg bookmark babar -r tip
1337 1337
1338 1338 $ HGENCODING=UTF-8 LANGUAGE=de hg log -r tip
1339 1339 \xc3\x84nderung: 3:f5d8de11c2e2 (esc)
1340 1340 Zweig: test
1341 1341 Lesezeichen: babar
1342 1342 Marke: tip
1343 1343 Vorg\xc3\xa4nger: 1:d32277701ccb (esc)
1344 1344 Nutzer: test
1345 1345 Datum: Thu Jan 01 00:00:00 1970 +0000
1346 1346 Zusammenfassung: commit on test
1347 1347
1348 1348 $ hg bookmark -d babar
1349 1349
1350 1350 #endif
1351 1351
1352 1352 log -p --cwd dir (in subdir)
1353 1353
1354 1354 $ mkdir dir
1355 1355 $ hg log -p --cwd dir
1356 1356 changeset: 3:f5d8de11c2e2
1357 1357 branch: test
1358 1358 tag: tip
1359 1359 parent: 1:d32277701ccb
1360 1360 user: test
1361 1361 date: Thu Jan 01 00:00:00 1970 +0000
1362 1362 summary: commit on test
1363 1363
1364 1364 diff -r d32277701ccb -r f5d8de11c2e2 c
1365 1365 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1366 1366 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1367 1367 @@ -0,0 +1,1 @@
1368 1368 +c
1369 1369
1370 1370 changeset: 2:c3a4f03cc9a7
1371 1371 parent: 0:24427303d56f
1372 1372 user: test
1373 1373 date: Thu Jan 01 00:00:00 1970 +0000
1374 1374 summary: commit on default
1375 1375
1376 1376 diff -r 24427303d56f -r c3a4f03cc9a7 c
1377 1377 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1378 1378 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1379 1379 @@ -0,0 +1,1 @@
1380 1380 +c
1381 1381
1382 1382 changeset: 1:d32277701ccb
1383 1383 branch: test
1384 1384 user: test
1385 1385 date: Thu Jan 01 00:00:00 1970 +0000
1386 1386 summary: commit on test
1387 1387
1388 1388 diff -r 24427303d56f -r d32277701ccb b
1389 1389 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1390 1390 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1391 1391 @@ -0,0 +1,1 @@
1392 1392 +b
1393 1393
1394 1394 changeset: 0:24427303d56f
1395 1395 user: test
1396 1396 date: Thu Jan 01 00:00:00 1970 +0000
1397 1397 summary: commit on default
1398 1398
1399 1399 diff -r 000000000000 -r 24427303d56f a
1400 1400 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1401 1401 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1402 1402 @@ -0,0 +1,1 @@
1403 1403 +a
1404 1404
1405 1405
1406 1406
1407 1407 log -p -R repo
1408 1408
1409 1409 $ cd dir
1410 1410 $ hg log -p -R .. ../a
1411 1411 changeset: 0:24427303d56f
1412 1412 user: test
1413 1413 date: Thu Jan 01 00:00:00 1970 +0000
1414 1414 summary: commit on default
1415 1415
1416 1416 diff -r 000000000000 -r 24427303d56f a
1417 1417 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1418 1418 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1419 1419 @@ -0,0 +1,1 @@
1420 1420 +a
1421 1421
1422 1422
1423 1423 $ cd ../..
1424 1424
1425 1425 $ hg init follow2
1426 1426 $ cd follow2
1427 1427
1428 1428 # Build the following history:
1429 1429 # tip - o - x - o - x - x
1430 1430 # \ /
1431 1431 # o - o - o - x
1432 1432 # \ /
1433 1433 # o
1434 1434 #
1435 1435 # Where "o" is a revision containing "foo" and
1436 1436 # "x" is a revision without "foo"
1437 1437
1438 1438 $ touch init
1439 1439 $ hg ci -A -m "init, unrelated"
1440 1440 adding init
1441 1441 $ echo 'foo' > init
1442 1442 $ hg ci -m "change, unrelated"
1443 1443 $ echo 'foo' > foo
1444 1444 $ hg ci -A -m "add unrelated old foo"
1445 1445 adding foo
1446 1446 $ hg rm foo
1447 1447 $ hg ci -m "delete foo, unrelated"
1448 1448 $ echo 'related' > foo
1449 1449 $ hg ci -A -m "add foo, related"
1450 1450 adding foo
1451 1451
1452 1452 $ hg up 0
1453 1453 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1454 1454 $ touch branch
1455 1455 $ hg ci -A -m "first branch, unrelated"
1456 1456 adding branch
1457 1457 created new head
1458 1458 $ touch foo
1459 1459 $ hg ci -A -m "create foo, related"
1460 1460 adding foo
1461 1461 $ echo 'change' > foo
1462 1462 $ hg ci -m "change foo, related"
1463 1463
1464 1464 $ hg up 6
1465 1465 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1466 1466 $ echo 'change foo in branch' > foo
1467 1467 $ hg ci -m "change foo in branch, related"
1468 1468 created new head
1469 1469 $ hg merge 7
1470 1470 merging foo
1471 1471 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1472 1472 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1473 1473 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1474 1474 [1]
1475 1475 $ echo 'merge 1' > foo
1476 1476 $ hg resolve -m foo
1477 1477 (no more unresolved files)
1478 1478 $ hg ci -m "First merge, related"
1479 1479
1480 1480 $ hg merge 4
1481 1481 merging foo
1482 1482 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1483 1483 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1484 1484 use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
1485 1485 [1]
1486 1486 $ echo 'merge 2' > foo
1487 1487 $ hg resolve -m foo
1488 1488 (no more unresolved files)
1489 1489 $ hg ci -m "Last merge, related"
1490 1490
1491 1491 $ hg log --graph
1492 1492 @ changeset: 10:4dae8563d2c5
1493 1493 |\ tag: tip
1494 1494 | | parent: 9:7b35701b003e
1495 1495 | | parent: 4:88176d361b69
1496 1496 | | user: test
1497 1497 | | date: Thu Jan 01 00:00:00 1970 +0000
1498 1498 | | summary: Last merge, related
1499 1499 | |
1500 1500 | o changeset: 9:7b35701b003e
1501 1501 | |\ parent: 8:e5416ad8a855
1502 1502 | | | parent: 7:87fe3144dcfa
1503 1503 | | | user: test
1504 1504 | | | date: Thu Jan 01 00:00:00 1970 +0000
1505 1505 | | | summary: First merge, related
1506 1506 | | |
1507 1507 | | o changeset: 8:e5416ad8a855
1508 1508 | | | parent: 6:dc6c325fe5ee
1509 1509 | | | user: test
1510 1510 | | | date: Thu Jan 01 00:00:00 1970 +0000
1511 1511 | | | summary: change foo in branch, related
1512 1512 | | |
1513 1513 | o | changeset: 7:87fe3144dcfa
1514 1514 | |/ user: test
1515 1515 | | date: Thu Jan 01 00:00:00 1970 +0000
1516 1516 | | summary: change foo, related
1517 1517 | |
1518 1518 | o changeset: 6:dc6c325fe5ee
1519 1519 | | user: test
1520 1520 | | date: Thu Jan 01 00:00:00 1970 +0000
1521 1521 | | summary: create foo, related
1522 1522 | |
1523 1523 | o changeset: 5:73db34516eb9
1524 1524 | | parent: 0:e87515fd044a
1525 1525 | | user: test
1526 1526 | | date: Thu Jan 01 00:00:00 1970 +0000
1527 1527 | | summary: first branch, unrelated
1528 1528 | |
1529 1529 o | changeset: 4:88176d361b69
1530 1530 | | user: test
1531 1531 | | date: Thu Jan 01 00:00:00 1970 +0000
1532 1532 | | summary: add foo, related
1533 1533 | |
1534 1534 o | changeset: 3:dd78ae4afb56
1535 1535 | | user: test
1536 1536 | | date: Thu Jan 01 00:00:00 1970 +0000
1537 1537 | | summary: delete foo, unrelated
1538 1538 | |
1539 1539 o | changeset: 2:c4c64aedf0f7
1540 1540 | | user: test
1541 1541 | | date: Thu Jan 01 00:00:00 1970 +0000
1542 1542 | | summary: add unrelated old foo
1543 1543 | |
1544 1544 o | changeset: 1:e5faa7440653
1545 1545 |/ user: test
1546 1546 | date: Thu Jan 01 00:00:00 1970 +0000
1547 1547 | summary: change, unrelated
1548 1548 |
1549 1549 o changeset: 0:e87515fd044a
1550 1550 user: test
1551 1551 date: Thu Jan 01 00:00:00 1970 +0000
1552 1552 summary: init, unrelated
1553 1553
1554 1554
1555 1555 $ hg --traceback log -f foo
1556 1556 changeset: 10:4dae8563d2c5
1557 1557 tag: tip
1558 1558 parent: 9:7b35701b003e
1559 1559 parent: 4:88176d361b69
1560 1560 user: test
1561 1561 date: Thu Jan 01 00:00:00 1970 +0000
1562 1562 summary: Last merge, related
1563 1563
1564 1564 changeset: 9:7b35701b003e
1565 1565 parent: 8:e5416ad8a855
1566 1566 parent: 7:87fe3144dcfa
1567 1567 user: test
1568 1568 date: Thu Jan 01 00:00:00 1970 +0000
1569 1569 summary: First merge, related
1570 1570
1571 1571 changeset: 8:e5416ad8a855
1572 1572 parent: 6:dc6c325fe5ee
1573 1573 user: test
1574 1574 date: Thu Jan 01 00:00:00 1970 +0000
1575 1575 summary: change foo in branch, related
1576 1576
1577 1577 changeset: 7:87fe3144dcfa
1578 1578 user: test
1579 1579 date: Thu Jan 01 00:00:00 1970 +0000
1580 1580 summary: change foo, related
1581 1581
1582 1582 changeset: 6:dc6c325fe5ee
1583 1583 user: test
1584 1584 date: Thu Jan 01 00:00:00 1970 +0000
1585 1585 summary: create foo, related
1586 1586
1587 1587 changeset: 4:88176d361b69
1588 1588 user: test
1589 1589 date: Thu Jan 01 00:00:00 1970 +0000
1590 1590 summary: add foo, related
1591 1591
1592 1592
1593 1593 Also check when maxrev < lastrevfilelog
1594 1594
1595 1595 $ hg --traceback log -f -r4 foo
1596 1596 changeset: 4:88176d361b69
1597 1597 user: test
1598 1598 date: Thu Jan 01 00:00:00 1970 +0000
1599 1599 summary: add foo, related
1600 1600
1601 1601 changeset: 2:c4c64aedf0f7
1602 1602 user: test
1603 1603 date: Thu Jan 01 00:00:00 1970 +0000
1604 1604 summary: add unrelated old foo
1605 1605
1606 1606 $ cd ..
1607 1607
1608 1608 Issue2383: hg log showing _less_ differences than hg diff
1609 1609
1610 1610 $ hg init issue2383
1611 1611 $ cd issue2383
1612 1612
1613 1613 Create a test repo:
1614 1614
1615 1615 $ echo a > a
1616 1616 $ hg ci -Am0
1617 1617 adding a
1618 1618 $ echo b > b
1619 1619 $ hg ci -Am1
1620 1620 adding b
1621 1621 $ hg co 0
1622 1622 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1623 1623 $ echo b > a
1624 1624 $ hg ci -m2
1625 1625 created new head
1626 1626
1627 1627 Merge:
1628 1628
1629 1629 $ hg merge
1630 1630 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1631 1631 (branch merge, don't forget to commit)
1632 1632
1633 1633 Make sure there's a file listed in the merge to trigger the bug:
1634 1634
1635 1635 $ echo c > a
1636 1636 $ hg ci -m3
1637 1637
1638 1638 Two files shown here in diff:
1639 1639
1640 1640 $ hg diff --rev 2:3
1641 1641 diff -r b09be438c43a -r 8e07aafe1edc a
1642 1642 --- a/a Thu Jan 01 00:00:00 1970 +0000
1643 1643 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1644 1644 @@ -1,1 +1,1 @@
1645 1645 -b
1646 1646 +c
1647 1647 diff -r b09be438c43a -r 8e07aafe1edc b
1648 1648 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1649 1649 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1650 1650 @@ -0,0 +1,1 @@
1651 1651 +b
1652 1652
1653 1653 Diff here should be the same:
1654 1654
1655 1655 $ hg log -vpr 3
1656 1656 changeset: 3:8e07aafe1edc
1657 1657 tag: tip
1658 1658 parent: 2:b09be438c43a
1659 1659 parent: 1:925d80f479bb
1660 1660 user: test
1661 1661 date: Thu Jan 01 00:00:00 1970 +0000
1662 1662 files: a
1663 1663 description:
1664 1664 3
1665 1665
1666 1666
1667 1667 diff -r b09be438c43a -r 8e07aafe1edc a
1668 1668 --- a/a Thu Jan 01 00:00:00 1970 +0000
1669 1669 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1670 1670 @@ -1,1 +1,1 @@
1671 1671 -b
1672 1672 +c
1673 1673 diff -r b09be438c43a -r 8e07aafe1edc b
1674 1674 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1675 1675 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1676 1676 @@ -0,0 +1,1 @@
1677 1677 +b
1678 1678
1679 1679 $ cd ..
1680 1680
1681 1681 'hg log -r rev fn' when last(filelog(fn)) != rev
1682 1682
1683 1683 $ hg init simplelog
1684 1684 $ cd simplelog
1685 1685 $ echo f > a
1686 1686 $ hg ci -Am'a' -d '0 0'
1687 1687 adding a
1688 1688 $ echo f >> a
1689 1689 $ hg ci -Am'a bis' -d '1 0'
1690 1690
1691 1691 $ hg log -r0 a
1692 1692 changeset: 0:9f758d63dcde
1693 1693 user: test
1694 1694 date: Thu Jan 01 00:00:00 1970 +0000
1695 1695 summary: a
1696 1696
1697 1697 enable obsolete to test hidden feature
1698 1698
1699 1699 $ cat >> $HGRCPATH << EOF
1700 1700 > [experimental]
1701 1701 > evolution=createmarkers
1702 1702 > EOF
1703 1703
1704 1704 $ hg log --template='{rev}:{node}\n'
1705 1705 1:a765632148dc55d38c35c4f247c618701886cb2f
1706 1706 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1707 1707 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
1708 1708 $ hg up null -q
1709 1709 $ hg log --template='{rev}:{node}\n'
1710 1710 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1711 1711 $ hg log --template='{rev}:{node}\n' --hidden
1712 1712 1:a765632148dc55d38c35c4f247c618701886cb2f
1713 1713 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1714 1714 $ hg log -r a
1715 1715 abort: hidden revision 'a'!
1716 1716 (use --hidden to access hidden revisions)
1717 1717 [255]
1718 1718
1719 1719 test that parent prevent a changeset to be hidden
1720 1720
1721 1721 $ hg up 1 -q --hidden
1722 1722 $ hg log --template='{rev}:{node}\n'
1723 1723 1:a765632148dc55d38c35c4f247c618701886cb2f
1724 1724 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1725 1725
1726 1726 test that second parent prevent a changeset to be hidden too
1727 1727
1728 1728 $ hg debugsetparents 0 1 # nothing suitable to merge here
1729 1729 $ hg log --template='{rev}:{node}\n'
1730 1730 1:a765632148dc55d38c35c4f247c618701886cb2f
1731 1731 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1732 1732 $ hg debugsetparents 1
1733 1733 $ hg up -q null
1734 1734
1735 1735 bookmarks prevent a changeset being hidden
1736 1736
1737 1737 $ hg bookmark --hidden -r 1 X
1738 1738 $ hg log --template '{rev}:{node}\n'
1739 1739 1:a765632148dc55d38c35c4f247c618701886cb2f
1740 1740 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1741 1741 $ hg bookmark -d X
1742 1742
1743 1743 divergent bookmarks are not hidden
1744 1744
1745 1745 $ hg bookmark --hidden -r 1 X@foo
1746 1746 $ hg log --template '{rev}:{node}\n'
1747 1747 1:a765632148dc55d38c35c4f247c618701886cb2f
1748 1748 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1749 1749
1750 1750 test hidden revision 0 (issue5385)
1751 1751
1752 1752 $ hg bookmark -d X@foo
1753 1753 $ hg up null -q
1754 1754 $ hg debugobsolete 9f758d63dcde62d547ebfb08e1e7ee96535f2b05
1755 1755 $ echo f > b
1756 1756 $ hg ci -Am'b' -d '2 0'
1757 1757 adding b
1758 1758 $ echo f >> b
1759 1759 $ hg ci -m'b bis' -d '3 0'
1760 1760 $ hg log -T'{rev}:{node}\n'
1761 1761 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1762 1762 2:94375ec45bddd2a824535fc04855bd058c926ec0
1763 1763
1764 1764 $ hg log -T'{rev}:{node}\n' -r:
1765 1765 2:94375ec45bddd2a824535fc04855bd058c926ec0
1766 1766 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1767 1767 $ hg log -T'{rev}:{node}\n' -r:tip
1768 1768 2:94375ec45bddd2a824535fc04855bd058c926ec0
1769 1769 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1770 1770 $ hg log -T'{rev}:{node}\n' -r:0
1771 1771 abort: hidden revision '0'!
1772 1772 (use --hidden to access hidden revisions)
1773 1773 [255]
1774 1774 $ hg log -T'{rev}:{node}\n' -f
1775 1775 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
1776 1776 2:94375ec45bddd2a824535fc04855bd058c926ec0
1777 1777
1778 1778 clear extensions configuration
1779 1779 $ echo '[extensions]' >> $HGRCPATH
1780 1780 $ echo "obs=!" >> $HGRCPATH
1781 1781 $ cd ..
1782 1782
1783 1783 test -u/-k for problematic encoding
1784 1784 # unicode: cp932:
1785 1785 # u30A2 0x83 0x41(= 'A')
1786 1786 # u30C2 0x83 0x61(= 'a')
1787 1787
1788 1788 $ hg init problematicencoding
1789 1789 $ cd problematicencoding
1790 1790
1791 1791 $ python > setup.sh <<EOF
1792 1792 > print u'''
1793 1793 > echo a > text
1794 1794 > hg add text
1795 1795 > hg --encoding utf-8 commit -u '\u30A2' -m none
1796 1796 > echo b > text
1797 1797 > hg --encoding utf-8 commit -u '\u30C2' -m none
1798 1798 > echo c > text
1799 1799 > hg --encoding utf-8 commit -u none -m '\u30A2'
1800 1800 > echo d > text
1801 1801 > hg --encoding utf-8 commit -u none -m '\u30C2'
1802 1802 > '''.encode('utf-8')
1803 1803 > EOF
1804 1804 $ sh < setup.sh
1805 1805
1806 1806 test in problematic encoding
1807 1807 $ python > test.sh <<EOF
1808 1808 > print u'''
1809 1809 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
1810 1810 > echo ====
1811 1811 > hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
1812 1812 > echo ====
1813 1813 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
1814 1814 > echo ====
1815 1815 > hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
1816 1816 > '''.encode('cp932')
1817 1817 > EOF
1818 1818 $ sh < test.sh
1819 1819 0
1820 1820 ====
1821 1821 1
1822 1822 ====
1823 1823 2
1824 1824 0
1825 1825 ====
1826 1826 3
1827 1827 1
1828 1828
1829 1829 $ cd ..
1830 1830
1831 1831 test hg log on non-existent files and on directories
1832 1832 $ hg init issue1340
1833 1833 $ cd issue1340
1834 1834 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
1835 1835 $ echo 1 > d1/f1
1836 1836 $ echo 1 > D2/f1
1837 1837 $ echo 1 > D3.i/f1
1838 1838 $ echo 1 > d4.hg/f1
1839 1839 $ echo 1 > d5.d/f1
1840 1840 $ echo 1 > .d6/f1
1841 1841 $ hg -q add .
1842 1842 $ hg commit -m "a bunch of weird directories"
1843 1843 $ hg log -l1 d1/f1 | grep changeset
1844 1844 changeset: 0:65624cd9070a
1845 1845 $ hg log -l1 f1
1846 1846 $ hg log -l1 . | grep changeset
1847 1847 changeset: 0:65624cd9070a
1848 1848 $ hg log -l1 ./ | grep changeset
1849 1849 changeset: 0:65624cd9070a
1850 1850 $ hg log -l1 d1 | grep changeset
1851 1851 changeset: 0:65624cd9070a
1852 1852 $ hg log -l1 D2 | grep changeset
1853 1853 changeset: 0:65624cd9070a
1854 1854 $ hg log -l1 D2/f1 | grep changeset
1855 1855 changeset: 0:65624cd9070a
1856 1856 $ hg log -l1 D3.i | grep changeset
1857 1857 changeset: 0:65624cd9070a
1858 1858 $ hg log -l1 D3.i/f1 | grep changeset
1859 1859 changeset: 0:65624cd9070a
1860 1860 $ hg log -l1 d4.hg | grep changeset
1861 1861 changeset: 0:65624cd9070a
1862 1862 $ hg log -l1 d4.hg/f1 | grep changeset
1863 1863 changeset: 0:65624cd9070a
1864 1864 $ hg log -l1 d5.d | grep changeset
1865 1865 changeset: 0:65624cd9070a
1866 1866 $ hg log -l1 d5.d/f1 | grep changeset
1867 1867 changeset: 0:65624cd9070a
1868 1868 $ hg log -l1 .d6 | grep changeset
1869 1869 changeset: 0:65624cd9070a
1870 1870 $ hg log -l1 .d6/f1 | grep changeset
1871 1871 changeset: 0:65624cd9070a
1872 1872
1873 1873 issue3772: hg log -r :null showing revision 0 as well
1874 1874
1875 1875 $ hg log -r :null
1876 1876 changeset: 0:65624cd9070a
1877 1877 tag: tip
1878 1878 user: test
1879 1879 date: Thu Jan 01 00:00:00 1970 +0000
1880 1880 summary: a bunch of weird directories
1881 1881
1882 1882 changeset: -1:000000000000
1883 1883 user:
1884 1884 date: Thu Jan 01 00:00:00 1970 +0000
1885 1885
1886 1886 $ hg log -r null:null
1887 1887 changeset: -1:000000000000
1888 1888 user:
1889 1889 date: Thu Jan 01 00:00:00 1970 +0000
1890 1890
1891 1891 working-directory revision requires special treatment
1892 1892
1893 1893 clean:
1894 1894
1895 1895 $ hg log -r 'wdir()' --debug
1896 1896 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
1897 1897 phase: draft
1898 1898 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
1899 1899 parent: -1:0000000000000000000000000000000000000000
1900 1900 user: test
1901 1901 date: [A-Za-z0-9:+ ]+ (re)
1902 1902 extra: branch=default
1903 1903
1904 1904 $ hg log -r 'wdir()' -p --stat
1905 1905 changeset: 2147483647:ffffffffffff
1906 1906 parent: 0:65624cd9070a
1907 1907 user: test
1908 1908 date: [A-Za-z0-9:+ ]+ (re)
1909 1909
1910 1910
1911 1911
1912 1912
1913 1913 dirty:
1914 1914
1915 1915 $ echo 2 >> d1/f1
1916 1916 $ echo 2 > d1/f2
1917 1917 $ hg add d1/f2
1918 1918 $ hg remove .d6/f1
1919 1919 $ hg status
1920 1920 M d1/f1
1921 1921 A d1/f2
1922 1922 R .d6/f1
1923 1923
1924 1924 $ hg log -r 'wdir()'
1925 1925 changeset: 2147483647:ffffffffffff
1926 1926 parent: 0:65624cd9070a
1927 1927 user: test
1928 1928 date: [A-Za-z0-9:+ ]+ (re)
1929 1929
1930 1930 $ hg log -r 'wdir()' -q
1931 1931 2147483647:ffffffffffff
1932 1932
1933 1933 $ hg log -r 'wdir()' --debug
1934 1934 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
1935 1935 phase: draft
1936 1936 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
1937 1937 parent: -1:0000000000000000000000000000000000000000
1938 1938 user: test
1939 1939 date: [A-Za-z0-9:+ ]+ (re)
1940 1940 files: d1/f1
1941 1941 files+: d1/f2
1942 1942 files-: .d6/f1
1943 1943 extra: branch=default
1944 1944
1945 1945 $ hg log -r 'wdir()' -p --stat --git
1946 1946 changeset: 2147483647:ffffffffffff
1947 1947 parent: 0:65624cd9070a
1948 1948 user: test
1949 1949 date: [A-Za-z0-9:+ ]+ (re)
1950 1950
1951 1951 .d6/f1 | 1 -
1952 1952 d1/f1 | 1 +
1953 1953 d1/f2 | 1 +
1954 1954 3 files changed, 2 insertions(+), 1 deletions(-)
1955 1955
1956 1956 diff --git a/.d6/f1 b/.d6/f1
1957 1957 deleted file mode 100644
1958 1958 --- a/.d6/f1
1959 1959 +++ /dev/null
1960 1960 @@ -1,1 +0,0 @@
1961 1961 -1
1962 1962 diff --git a/d1/f1 b/d1/f1
1963 1963 --- a/d1/f1
1964 1964 +++ b/d1/f1
1965 1965 @@ -1,1 +1,2 @@
1966 1966 1
1967 1967 +2
1968 1968 diff --git a/d1/f2 b/d1/f2
1969 1969 new file mode 100644
1970 1970 --- /dev/null
1971 1971 +++ b/d1/f2
1972 1972 @@ -0,0 +1,1 @@
1973 1973 +2
1974 1974
1975 1975 $ hg log -r 'wdir()' -Tjson
1976 1976 [
1977 1977 {
1978 1978 "rev": null,
1979 1979 "node": null,
1980 1980 "branch": "default",
1981 1981 "phase": "draft",
1982 1982 "user": "test",
1983 1983 "date": [*, 0], (glob)
1984 1984 "desc": "",
1985 1985 "bookmarks": [],
1986 1986 "tags": [],
1987 1987 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"]
1988 1988 }
1989 1989 ]
1990 1990
1991 1991 $ hg log -r 'wdir()' -Tjson -q
1992 1992 [
1993 1993 {
1994 1994 "rev": null,
1995 1995 "node": null
1996 1996 }
1997 1997 ]
1998 1998
1999 1999 $ hg log -r 'wdir()' -Tjson --debug
2000 2000 [
2001 2001 {
2002 2002 "rev": null,
2003 2003 "node": null,
2004 2004 "branch": "default",
2005 2005 "phase": "draft",
2006 2006 "user": "test",
2007 2007 "date": [*, 0], (glob)
2008 2008 "desc": "",
2009 2009 "bookmarks": [],
2010 2010 "tags": [],
2011 2011 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"],
2012 2012 "manifest": null,
2013 2013 "extra": {"branch": "default"},
2014 2014 "modified": ["d1/f1"],
2015 2015 "added": ["d1/f2"],
2016 2016 "removed": [".d6/f1"]
2017 2017 }
2018 2018 ]
2019 2019
2020 2020 $ hg revert -aqC
2021 2021
2022 2022 Check that adding an arbitrary name shows up in log automatically
2023 2023
2024 2024 $ cat > ../names.py <<EOF
2025 2025 > """A small extension to test adding arbitrary names to a repo"""
2026 2026 > from mercurial.namespaces import namespace
2027 2027 >
2028 2028 > def reposetup(ui, repo):
2029 2029 > foo = {'foo': repo[0].node()}
2030 2030 > names = lambda r: foo.keys()
2031 2031 > namemap = lambda r, name: foo.get(name)
2032 2032 > nodemap = lambda r, node: [name for name, n in foo.iteritems()
2033 2033 > if n == node]
2034 2034 > ns = namespace("bars", templatename="bar", logname="barlog",
2035 2035 > colorname="barcolor", listnames=names, namemap=namemap,
2036 2036 > nodemap=nodemap)
2037 2037 >
2038 2038 > repo.names.addnamespace(ns)
2039 2039 > EOF
2040 2040
2041 2041 $ hg --config extensions.names=../names.py log -r 0
2042 2042 changeset: 0:65624cd9070a
2043 2043 tag: tip
2044 2044 barlog: foo
2045 2045 user: test
2046 2046 date: Thu Jan 01 00:00:00 1970 +0000
2047 2047 summary: a bunch of weird directories
2048 2048
2049 2049 $ hg --config extensions.names=../names.py \
2050 2050 > --config extensions.color= --config color.log.barcolor=red \
2051 2051 > --color=always log -r 0
2052 2052 \x1b[0;33mchangeset: 0:65624cd9070a\x1b[0m (esc)
2053 2053 tag: tip
2054 2054 \x1b[0;31mbarlog: foo\x1b[0m (esc)
2055 2055 user: test
2056 2056 date: Thu Jan 01 00:00:00 1970 +0000
2057 2057 summary: a bunch of weird directories
2058 2058
2059 2059 $ hg --config extensions.names=../names.py log -r 0 --template '{bars}\n'
2060 2060 foo
2061 2061
2062 2062 $ cd ..
2063 2063
2064 2064 hg log -f dir across branches
2065 2065
2066 2066 $ hg init acrossbranches
2067 2067 $ cd acrossbranches
2068 2068 $ mkdir d
2069 2069 $ echo a > d/a && hg ci -Aqm a
2070 2070 $ echo b > d/a && hg ci -Aqm b
2071 2071 $ hg up -q 0
2072 2072 $ echo b > d/a && hg ci -Aqm c
2073 2073 $ hg log -f d -T '{desc}' -G
2074 2074 @ c
2075 2075 |
2076 2076 o a
2077 2077
2078 2078 Ensure that largefiles doesn't interfere with following a normal file
2079 2079 $ hg --config extensions.largefiles= log -f d -T '{desc}' -G
2080 2080 @ c
2081 2081 |
2082 2082 o a
2083 2083
2084 2084 $ hg log -f d/a -T '{desc}' -G
2085 2085 @ c
2086 2086 |
2087 2087 o a
2088 2088
2089 2089 $ cd ..
2090 2090
2091 2091 hg log -f with linkrev pointing to another branch
2092 2092 -------------------------------------------------
2093 2093
2094 2094 create history with a filerev whose linkrev points to another branch
2095 2095
2096 2096 $ hg init branchedlinkrev
2097 2097 $ cd branchedlinkrev
2098 2098 $ echo 1 > a
2099 2099 $ hg commit -Am 'content1'
2100 2100 adding a
2101 2101 $ echo 2 > a
2102 2102 $ hg commit -m 'content2'
2103 2103 $ hg up --rev 'desc(content1)'
2104 2104 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2105 2105 $ echo unrelated > unrelated
2106 2106 $ hg commit -Am 'unrelated'
2107 2107 adding unrelated
2108 2108 created new head
2109 2109 $ hg graft -r 'desc(content2)'
2110 2110 grafting 1:2294ae80ad84 "content2"
2111 2111 $ echo 3 > a
2112 2112 $ hg commit -m 'content3'
2113 2113 $ hg log -G
2114 2114 @ changeset: 4:50b9b36e9c5d
2115 2115 | tag: tip
2116 2116 | user: test
2117 2117 | date: Thu Jan 01 00:00:00 1970 +0000
2118 2118 | summary: content3
2119 2119 |
2120 2120 o changeset: 3:15b2327059e5
2121 2121 | user: test
2122 2122 | date: Thu Jan 01 00:00:00 1970 +0000
2123 2123 | summary: content2
2124 2124 |
2125 2125 o changeset: 2:2029acd1168c
2126 2126 | parent: 0:ae0a3c9f9e95
2127 2127 | user: test
2128 2128 | date: Thu Jan 01 00:00:00 1970 +0000
2129 2129 | summary: unrelated
2130 2130 |
2131 2131 | o changeset: 1:2294ae80ad84
2132 2132 |/ user: test
2133 2133 | date: Thu Jan 01 00:00:00 1970 +0000
2134 2134 | summary: content2
2135 2135 |
2136 2136 o changeset: 0:ae0a3c9f9e95
2137 2137 user: test
2138 2138 date: Thu Jan 01 00:00:00 1970 +0000
2139 2139 summary: content1
2140 2140
2141 2141
2142 2142 log -f on the file should list the graft result.
2143 2143
2144 2144 $ hg log -Gf a
2145 2145 @ changeset: 4:50b9b36e9c5d
2146 2146 | tag: tip
2147 2147 | user: test
2148 2148 | date: Thu Jan 01 00:00:00 1970 +0000
2149 2149 | summary: content3
2150 2150 |
2151 2151 o changeset: 3:15b2327059e5
2152 2152 : user: test
2153 2153 : date: Thu Jan 01 00:00:00 1970 +0000
2154 2154 : summary: content2
2155 2155 :
2156 2156 o changeset: 0:ae0a3c9f9e95
2157 2157 user: test
2158 2158 date: Thu Jan 01 00:00:00 1970 +0000
2159 2159 summary: content1
2160 2160
2161 2161
2162 2162 plain log lists the original version
2163 2163 (XXX we should probably list both)
2164 2164
2165 2165 $ hg log -G a
2166 2166 @ changeset: 4:50b9b36e9c5d
2167 2167 : tag: tip
2168 2168 : user: test
2169 2169 : date: Thu Jan 01 00:00:00 1970 +0000
2170 2170 : summary: content3
2171 2171 :
2172 2172 : o changeset: 1:2294ae80ad84
2173 2173 :/ user: test
2174 2174 : date: Thu Jan 01 00:00:00 1970 +0000
2175 2175 : summary: content2
2176 2176 :
2177 2177 o changeset: 0:ae0a3c9f9e95
2178 2178 user: test
2179 2179 date: Thu Jan 01 00:00:00 1970 +0000
2180 2180 summary: content1
2181 2181
2182 2182
2183 2183 hg log -f from the grafted changeset
2184 2184 (The bootstrap should properly take the topology in account)
2185 2185
2186 2186 $ hg up 'desc(content3)^'
2187 2187 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2188 2188 $ hg log -Gf a
2189 2189 @ changeset: 3:15b2327059e5
2190 2190 : user: test
2191 2191 : date: Thu Jan 01 00:00:00 1970 +0000
2192 2192 : summary: content2
2193 2193 :
2194 2194 o changeset: 0:ae0a3c9f9e95
2195 2195 user: test
2196 2196 date: Thu Jan 01 00:00:00 1970 +0000
2197 2197 summary: content1
2198 2198
2199 2199
2200 2200 Test that we use the first non-hidden changeset in that case.
2201 2201
2202 2202 (hide the changeset)
2203 2203
2204 2204 $ hg log -T '{node}\n' -r 1
2205 2205 2294ae80ad8447bc78383182eeac50cb049df623
2206 2206 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
2207 2207 $ hg log -G
2208 2208 o changeset: 4:50b9b36e9c5d
2209 2209 | tag: tip
2210 2210 | user: test
2211 2211 | date: Thu Jan 01 00:00:00 1970 +0000
2212 2212 | summary: content3
2213 2213 |
2214 2214 @ changeset: 3:15b2327059e5
2215 2215 | user: test
2216 2216 | date: Thu Jan 01 00:00:00 1970 +0000
2217 2217 | summary: content2
2218 2218 |
2219 2219 o changeset: 2:2029acd1168c
2220 2220 | parent: 0:ae0a3c9f9e95
2221 2221 | user: test
2222 2222 | date: Thu Jan 01 00:00:00 1970 +0000
2223 2223 | summary: unrelated
2224 2224 |
2225 2225 o changeset: 0:ae0a3c9f9e95
2226 2226 user: test
2227 2227 date: Thu Jan 01 00:00:00 1970 +0000
2228 2228 summary: content1
2229 2229
2230 2230
2231 2231 Check that log on the file does not drop the file revision.
2232 2232
2233 2233 $ hg log -G a
2234 2234 o changeset: 4:50b9b36e9c5d
2235 2235 | tag: tip
2236 2236 | user: test
2237 2237 | date: Thu Jan 01 00:00:00 1970 +0000
2238 2238 | summary: content3
2239 2239 |
2240 2240 @ changeset: 3:15b2327059e5
2241 2241 : user: test
2242 2242 : date: Thu Jan 01 00:00:00 1970 +0000
2243 2243 : summary: content2
2244 2244 :
2245 2245 o changeset: 0:ae0a3c9f9e95
2246 2246 user: test
2247 2247 date: Thu Jan 01 00:00:00 1970 +0000
2248 2248 summary: content1
2249 2249
2250 2250
2251 2251 Even when a head revision is linkrev-shadowed.
2252 2252
2253 2253 $ hg log -T '{node}\n' -r 4
2254 2254 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2255 2255 $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2256 2256 $ hg log -G a
2257 2257 @ changeset: 3:15b2327059e5
2258 2258 : tag: tip
2259 2259 : user: test
2260 2260 : date: Thu Jan 01 00:00:00 1970 +0000
2261 2261 : summary: content2
2262 2262 :
2263 2263 o changeset: 0:ae0a3c9f9e95
2264 2264 user: test
2265 2265 date: Thu Jan 01 00:00:00 1970 +0000
2266 2266 summary: content1
2267 2267
2268 2268
2269 2269 $ cd ..
2270 2270
2271 2271 Even when the file revision is missing from some head:
2272 2272
2273 2273 $ hg init issue4490
2274 2274 $ cd issue4490
2275 2275 $ echo '[experimental]' >> .hg/hgrc
2276 2276 $ echo 'evolution=createmarkers' >> .hg/hgrc
2277 2277 $ echo a > a
2278 2278 $ hg ci -Am0
2279 2279 adding a
2280 2280 $ echo b > b
2281 2281 $ hg ci -Am1
2282 2282 adding b
2283 2283 $ echo B > b
2284 2284 $ hg ci --amend -m 1
2285 2285 $ hg up 0
2286 2286 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2287 2287 $ echo c > c
2288 2288 $ hg ci -Am2
2289 2289 adding c
2290 2290 created new head
2291 2291 $ hg up 'head() and not .'
2292 2292 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
2293 2293 $ hg log -G
2294 2294 o changeset: 4:db815d6d32e6
2295 2295 | tag: tip
2296 2296 | parent: 0:f7b1eb17ad24
2297 2297 | user: test
2298 2298 | date: Thu Jan 01 00:00:00 1970 +0000
2299 2299 | summary: 2
2300 2300 |
2301 2301 | @ changeset: 3:9bc8ce7f9356
2302 2302 |/ parent: 0:f7b1eb17ad24
2303 2303 | user: test
2304 2304 | date: Thu Jan 01 00:00:00 1970 +0000
2305 2305 | summary: 1
2306 2306 |
2307 2307 o changeset: 0:f7b1eb17ad24
2308 2308 user: test
2309 2309 date: Thu Jan 01 00:00:00 1970 +0000
2310 2310 summary: 0
2311 2311
2312 2312 $ hg log -f -G b
2313 2313 @ changeset: 3:9bc8ce7f9356
2314 2314 | parent: 0:f7b1eb17ad24
2315 2315 ~ user: test
2316 2316 date: Thu Jan 01 00:00:00 1970 +0000
2317 2317 summary: 1
2318 2318
2319 2319 $ hg log -G b
2320 2320 @ changeset: 3:9bc8ce7f9356
2321 2321 | parent: 0:f7b1eb17ad24
2322 2322 ~ user: test
2323 2323 date: Thu Jan 01 00:00:00 1970 +0000
2324 2324 summary: 1
2325 2325
2326 2326 $ cd ..
2327 2327
2328 2328 Check proper report when the manifest changes but not the file issue4499
2329 2329 ------------------------------------------------------------------------
2330 2330
2331 2331 $ hg init issue4499
2332 2332 $ cd issue4499
2333 2333 $ 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
2334 2334 > echo 1 > $f;
2335 2335 > hg add $f;
2336 2336 > done
2337 2337 $ hg commit -m 'A1B1C1'
2338 2338 $ echo 2 > A
2339 2339 $ echo 2 > B
2340 2340 $ echo 2 > C
2341 2341 $ hg commit -m 'A2B2C2'
2342 2342 $ hg up 0
2343 2343 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2344 2344 $ echo 3 > A
2345 2345 $ echo 2 > B
2346 2346 $ echo 2 > C
2347 2347 $ hg commit -m 'A3B2C2'
2348 2348 created new head
2349 2349
2350 2350 $ hg log -G
2351 2351 @ changeset: 2:fe5fc3d0eb17
2352 2352 | tag: tip
2353 2353 | parent: 0:abf4f0e38563
2354 2354 | user: test
2355 2355 | date: Thu Jan 01 00:00:00 1970 +0000
2356 2356 | summary: A3B2C2
2357 2357 |
2358 2358 | o changeset: 1:07dcc6b312c0
2359 2359 |/ user: test
2360 2360 | date: Thu Jan 01 00:00:00 1970 +0000
2361 2361 | summary: A2B2C2
2362 2362 |
2363 2363 o changeset: 0:abf4f0e38563
2364 2364 user: test
2365 2365 date: Thu Jan 01 00:00:00 1970 +0000
2366 2366 summary: A1B1C1
2367 2367
2368 2368
2369 2369 Log -f on B should reports current changesets
2370 2370
2371 2371 $ hg log -fG B
2372 2372 @ changeset: 2:fe5fc3d0eb17
2373 2373 | tag: tip
2374 2374 | parent: 0:abf4f0e38563
2375 2375 | user: test
2376 2376 | date: Thu Jan 01 00:00:00 1970 +0000
2377 2377 | summary: A3B2C2
2378 2378 |
2379 2379 o changeset: 0:abf4f0e38563
2380 2380 user: test
2381 2381 date: Thu Jan 01 00:00:00 1970 +0000
2382 2382 summary: A1B1C1
2383 2383
2384 2384 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now