341 if fp is None: |
341 if fp is None: |
342 fp = repo.ui |
342 fp = repo.ui |
343 |
343 |
344 if not node1: |
344 if not node1: |
345 node1 = repo.dirstate.parents()[0] |
345 node1 = repo.dirstate.parents()[0] |
|
346 |
|
347 clcache = {} |
|
348 def getchangelog(n): |
|
349 if n not in clcache: |
|
350 clcache[n] = repo.changelog.read(n) |
|
351 return clcache[n] |
|
352 mcache = {} |
|
353 def getmanifest(n): |
|
354 if n not in mcache: |
|
355 mcache[n] = repo.manifest.read(n) |
|
356 return mcache[n] |
|
357 fcache = {} |
|
358 def getfile(f): |
|
359 if f not in fcache: |
|
360 fcache[f] = repo.file(f) |
|
361 return fcache[f] |
|
362 |
346 # reading the data for node1 early allows it to play nicely |
363 # reading the data for node1 early allows it to play nicely |
347 # with repo.status and the revlog cache. |
364 # with repo.status and the revlog cache. |
348 change = repo.changelog.read(node1) |
365 change = getchangelog(node1) |
349 mmap = repo.manifest.read(change[0]) |
366 mmap = getmanifest(change[0]) |
350 date1 = util.datestr(change[2]) |
367 date1 = util.datestr(change[2]) |
351 |
368 |
352 if not changes: |
369 if not changes: |
353 changes = repo.status(node1, node2, files, match=match)[:5] |
370 changes = repo.status(node1, node2, files, match=match)[:5] |
354 modified, added, removed, deleted, unknown = changes |
371 modified, added, removed, deleted, unknown = changes |
365 modified, added, removed = map(filterfiles, (modified, added, removed)) |
382 modified, added, removed = map(filterfiles, (modified, added, removed)) |
366 |
383 |
367 if not modified and not added and not removed: |
384 if not modified and not added and not removed: |
368 return |
385 return |
369 |
386 |
|
387 def renamedbetween(f, n1, n2): |
|
388 r1, r2 = map(repo.changelog.rev, (n1, n2)) |
|
389 src = None |
|
390 while r2 > r1: |
|
391 cl = getchangelog(n2)[0] |
|
392 m = getmanifest(cl) |
|
393 try: |
|
394 src = getfile(f).renamed(m[f]) |
|
395 except KeyError: |
|
396 return None |
|
397 if src: |
|
398 f = src[0] |
|
399 n2 = repo.changelog.parents(n2)[0] |
|
400 r2 = repo.changelog.rev(n2) |
|
401 return src |
|
402 |
370 if node2: |
403 if node2: |
371 change = repo.changelog.read(node2) |
404 change = getchangelog(node2) |
372 mmap2 = repo.manifest.read(change[0]) |
405 mmap2 = getmanifest(change[0]) |
373 _date2 = util.datestr(change[2]) |
406 _date2 = util.datestr(change[2]) |
374 def date2(f): |
407 def date2(f): |
375 return _date2 |
408 return _date2 |
376 def read(f): |
409 def read(f): |
377 return repo.file(f).read(mmap2[f]) |
410 return getfile(f).read(mmap2[f]) |
378 def renamed(f): |
411 def renamed(f): |
379 src = repo.file(f).renamed(mmap2[f]) |
412 return renamedbetween(f, node1, node2) |
380 return src and src[0] or None |
|
381 else: |
413 else: |
382 tz = util.makedate()[1] |
414 tz = util.makedate()[1] |
383 _date2 = util.datestr() |
415 _date2 = util.datestr() |
384 def date2(f): |
416 def date2(f): |
385 try: |
417 try: |
388 if err.errno != errno.ENOENT: raise |
420 if err.errno != errno.ENOENT: raise |
389 return _date2 |
421 return _date2 |
390 def read(f): |
422 def read(f): |
391 return repo.wread(f) |
423 return repo.wread(f) |
392 def renamed(f): |
424 def renamed(f): |
393 return repo.dirstate.copies.get(f) |
425 src = repo.dirstate.copies.get(f) |
|
426 parent = repo.dirstate.parents()[0] |
|
427 if src: |
|
428 f = src[0] |
|
429 of = renamedbetween(f, node1, parent) |
|
430 if of: |
|
431 return of |
|
432 elif src: |
|
433 cl = getchangelog(parent)[0] |
|
434 return (src, getmanifest(cl)[src]) |
|
435 else: |
|
436 return None |
394 |
437 |
395 if repo.ui.quiet: |
438 if repo.ui.quiet: |
396 r = None |
439 r = None |
397 else: |
440 else: |
398 hexfunc = repo.ui.verbose and hex or short |
441 hexfunc = repo.ui.verbose and hex or short |
430 if node2: |
473 if node2: |
431 mode = gitmode(mmap2.execf(f)) |
474 mode = gitmode(mmap2.execf(f)) |
432 else: |
475 else: |
433 mode = gitmode(util.is_exec(repo.wjoin(f), None)) |
476 mode = gitmode(util.is_exec(repo.wjoin(f), None)) |
434 if f in copied: |
477 if f in copied: |
435 a = copied[f] |
478 a, arev = copied[f] |
436 omode = gitmode(mmap.execf(a)) |
479 omode = gitmode(mmap.execf(a)) |
437 addmodehdr(header, omode, mode) |
480 addmodehdr(header, omode, mode) |
438 op = a in removed and 'rename' or 'copy' |
481 op = a in removed and 'rename' or 'copy' |
439 header.append('%s from %s\n' % (op, a)) |
482 header.append('%s from %s\n' % (op, a)) |
440 header.append('%s to %s\n' % (op, f)) |
483 header.append('%s to %s\n' % (op, f)) |
441 to = repo.file(a).read(mmap[a]) |
484 to = getfile(a).read(arev) |
442 else: |
485 else: |
443 header.append('new file mode %s\n' % mode) |
486 header.append('new file mode %s\n' % mode) |
444 elif f in removed: |
487 elif f in removed: |
445 if f in srcs: |
488 if f in srcs: |
446 dodiff = False |
489 dodiff = False |