229
232
lf.show(revno, rev, delta)
233
# revno is 1 based, so -2 to get back 1 less.
234
excludes = set(branch.get_ancestry(revision_history[revno - 2]))
235
pending = list(rev.parent_ids)
237
rev_id = pending.pop()
238
if rev_id in excludes:
240
# prevent showing merged revs twice if they multi-path.
243
rev = branch.get_revision(rev_id)
244
except errors.NoSuchRevision:
246
pending.extend(rev.parent_ids)
233
if hasattr(lf, 'show_merge'):
237
# revno is 1 based, so -2 to get back 1 less.
238
excludes = set(branch.get_ancestry(revision_history[revno - 2]))
239
pending = list(rev.parent_ids)
241
rev_id = pending.pop()
242
if rev_id in excludes:
244
# prevent showing merged revs twice if they multi-path.
247
rev = branch.get_revision(rev_id)
248
except errors.NoSuchRevision:
250
pending.extend(rev.parent_ids)
250
254
def deltas_for_log_dummy(branch, which_revs):
340
344
def show(self, revno, rev, delta):
341
345
raise NotImplementedError('not implemented in abstract base')
343
def show_merge(self, rev):
347
def short_committer(self, rev):
348
return re.sub('<.*@.*>', '', rev.committer).strip(' ')
347
351
class LongLogFormatter(LogFormatter):
348
352
def show(self, revno, rev, delta):
349
from osutils import format_date
351
to_file = self.to_file
353
print >>to_file, '-' * 60
354
print >>to_file, 'revno:', revno
356
print >>to_file, 'revision-id:', rev.revision_id
358
for parent_id in rev.parent_ids:
359
print >>to_file, 'parent:', parent_id
361
print >>to_file, 'committer:', rev.committer
363
date_str = format_date(rev.timestamp,
366
print >>to_file, 'timestamp: %s' % date_str
368
print >>to_file, 'message:'
370
print >>to_file, ' (no message)'
372
for l in rev.message.split('\n'):
373
print >>to_file, ' ' + l
376
delta.show(to_file, self.show_ids)
353
return self._show_helper(revno=revno, rev=rev, delta=delta)
378
355
def show_merge(self, rev):
379
from osutils import format_date
356
return self._show_helper(rev=rev, indent=' ', merged=True, delta=None)
358
def _show_helper(self, rev=None, revno=None, indent='', merged=False, delta=None):
359
"""Show a revision, either merged or not."""
360
from bzrlib.osutils import format_date
381
361
to_file = self.to_file
385
362
print >>to_file, indent+'-' * 60
386
print >>to_file, indent+'merged:', rev.revision_id
363
if revno is not None:
364
print >>to_file, 'revno:', revno
366
print >>to_file, indent+'merged:', rev.revision_id
368
print >>to_file, indent+'revision-id:', rev.revision_id
387
369
if self.show_ids:
388
370
for parent_id in rev.parent_ids:
389
371
print >>to_file, indent+'parent:', parent_id
391
372
print >>to_file, indent+'committer:', rev.committer
374
print >>to_file, indent+'branch nick: %s' % \
375
rev.properties['branch-nick']
393
378
date_str = format_date(rev.timestamp,
394
379
rev.timezone or 0,
395
380
self.show_timezone)
408
396
from bzrlib.osutils import format_date
410
398
to_file = self.to_file
412
print >>to_file, "%5d %s\t%s" % (revno, rev.committer,
399
date_str = format_date(rev.timestamp, rev.timezone or 0,
401
print >>to_file, "%5d %s\t%s" % (revno, self.short_committer(rev),
413
402
format_date(rev.timestamp, rev.timezone or 0,
403
self.show_timezone, date_fmt="%Y-%m-%d",
415
405
if self.show_ids:
416
406
print >>to_file, ' revision-id:', rev.revision_id
417
407
if not rev.message:
418
408
print >>to_file, ' (no message)'
420
for l in rev.message.split('\n'):
410
message = rev.message.rstrip('\r\n')
411
for l in message.split('\n'):
421
412
print >>to_file, ' ' + l
423
414
# TODO: Why not show the modified files in a shorter form as
424
415
# well? rewrap them single lines of appropriate length
425
416
if delta != None:
426
417
delta.show(to_file, self.show_ids)
420
class LineLogFormatter(LogFormatter):
421
def truncate(self, str, max_len):
422
if len(str) <= max_len:
424
return str[:max_len-3]+'...'
426
def date_string(self, rev):
427
from bzrlib.osutils import format_date
428
return format_date(rev.timestamp, rev.timezone or 0,
429
self.show_timezone, date_fmt="%Y-%m-%d",
432
def message(self, rev):
434
return '(no message)'
438
def show(self, revno, rev, delta):
439
print >> self.to_file, self.log_string(rev, 79)
441
def log_string(self, rev, max_chars):
442
out = [self.truncate(self.short_committer(rev), 20)]
443
out.append(self.date_string(rev))
444
out.append(self.message(rev).replace('\n', ' '))
445
return self.truncate(" ".join(out).rstrip('\n'), max_chars)
447
def line_log(rev, max_chars):
448
lf = LineLogFormatter(None)
449
return lf.log_string(rev, max_chars)
431
451
FORMATTERS = {'long': LongLogFormatter,
432
452
'short': ShortLogFormatter,
453
'line': LineLogFormatter,
436
457
def log_formatter(name, *args, **kwargs):
437
458
"""Construct a formatter from arguments.
439
name -- Name of the formatter to construct; currently 'long' and
440
'short' are supported.
460
name -- Name of the formatter to construct; currently 'long', 'short' and
461
'line' are supported.
442
463
from bzrlib.errors import BzrCommandError
449
470
# deprecated; for compatability
450
471
lf = LongLogFormatter(to_file=to_file, show_timezone=show_timezone)
451
472
lf.show(revno, rev, delta)
474
def show_changed_revisions(branch, old_rh, new_rh, to_file=None, log_format='long'):
475
"""Show the change in revision history comparing the old revision history to the new one.
477
:param branch: The branch where the revisions exist
478
:param old_rh: The old revision history
479
:param new_rh: The new revision history
480
:param to_file: A file to write the results to. If None, stdout will be used
486
to_file = codecs.getwriter(bzrlib.user_encoding)(sys.stdout, errors='replace')
487
lf = log_formatter(log_format,
490
show_timezone='original')
492
# This is the first index which is different between
495
for i in xrange(max(len(new_rh),
499
or new_rh[i] != old_rh[i]):
504
to_file.write('Nothing seems to have changed\n')
506
## TODO: It might be nice to do something like show_log
507
## and show the merged entries. But since this is the
508
## removed revisions, it shouldn't be as important
509
if base_idx < len(old_rh):
510
to_file.write('*'*60)
511
to_file.write('\nRemoved Revisions:\n')
512
for i in range(base_idx, len(old_rh)):
513
rev = branch.get_revision(old_rh[i])
514
lf.show(i+1, rev, None)
515
to_file.write('*'*60)
516
to_file.write('\n\n')
517
if base_idx < len(new_rh):
518
to_file.write('Added Revisions:\n')
524
start_revision=base_idx+1,
525
end_revision=len(new_rh),