Rev 3972: log -n/--levels (Ian Clatworthy) in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Thu Jan 29 07:19:02 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 3972
revision-id: pqm at pqm.ubuntu.com-20090129071857-l3ikkrm6b1rx96bx
parent: pqm at pqm.ubuntu.com-20090129064144-7kz4ibeppmn41zs9
parent: ian.clatworthy at canonical.com-20090129063122-6yyql6ej6zwwfqzn
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Thu 2009-01-29 07:18:57 +0000
message:
  log -n/--levels (Ian Clatworthy)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
  bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
  bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3970.1.1
    revision-id: ian.clatworthy at canonical.com-20090129063122-6yyql6ej6zwwfqzn
    parent: pqm at pqm.ubuntu.com-20090129060443-6hvfgxb55cd6r527
    parent: ian.clatworthy at canonical.com-20090129061825-8dbbry5u2vg0nwgp
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: ianc-integration
    timestamp: Thu 2009-01-29 16:31:22 +1000
    message:
      log -n/--levels (Ian Clatworthy)
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.10
    revision-id: ian.clatworthy at canonical.com-20090129061825-8dbbry5u2vg0nwgp
    parent: ian.clatworthy at canonical.com-20090123090721-x2438gy3f0c1ocl0
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Thu 2009-01-29 16:18:25 +1000
    message:
      review feedback from vila
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.9
    revision-id: ian.clatworthy at canonical.com-20090123090721-x2438gy3f0c1ocl0
    parent: ian.clatworthy at canonical.com-20090123083933-qi3438mch4yev5mk
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Fri 2009-01-23 19:07:21 +1000
    message:
      get offset right when dotted-revno in column 1
    modified:
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.8
    revision-id: ian.clatworthy at canonical.com-20090123083933-qi3438mch4yev5mk
    parent: ian.clatworthy at canonical.com-20090123033613-z8ptv0bfy2y6atbm
    parent: pqm at pqm.ubuntu.com-20090123042837-r1lyxrbk6nd5pp3g
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Fri 2009-01-23 18:39:33 +1000
    message:
      merge bzr.dev r3954
    added:
      bzrlib/tests/branch_implementations/test_dotted_revno_to_revision_id.py test_dotted_revno_to-20090121014844-6x7d9jtri5sspg1o-1
      bzrlib/tests/branch_implementations/test_revision_id_to_dotted_revno.py test_revision_id_to_-20090122052032-g3czslif6sdqfkh3-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/tests/branch_implementations/__init__.py __init__.py-20060123013057-b12a52c3f361daf4
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
      bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
    ------------------------------------------------------------
    revno: 3947.1.7
    revision-id: ian.clatworthy at canonical.com-20090123033613-z8ptv0bfy2y6atbm
    parent: ian.clatworthy at canonical.com-20090122161308-bjto7ouxgoixjdpz
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Fri 2009-01-23 13:36:13 +1000
    message:
      tweak indenting/offsetting for --short given dotted revno lengths
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.6
    revision-id: ian.clatworthy at canonical.com-20090122161308-bjto7ouxgoixjdpz
    parent: ian.clatworthy at canonical.com-20090120215204-x3xpx3ymwutpcvai
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Fri 2009-01-23 02:13:08 +1000
    message:
      log -n/--level-count N option
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.5
    revision-id: ian.clatworthy at canonical.com-20090120215204-x3xpx3ymwutpcvai
    parent: ian.clatworthy at canonical.com-20090120084231-1woopagx76kp0lws
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Wed 2009-01-21 07:52:04 +1000
    message:
      rename --merge-revisions to --include-merges
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.4
    revision-id: ian.clatworthy at canonical.com-20090120084231-1woopagx76kp0lws
    parent: ian.clatworthy at canonical.com-20090120083731-kivv9vhmhy3kqfmq
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Tue 2009-01-20 18:42:31 +1000
    message:
      add NEWS item
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3947.1.3
    revision-id: ian.clatworthy at canonical.com-20090120083731-kivv9vhmhy3kqfmq
    parent: ian.clatworthy at canonical.com-20090120082114-56vno4rarr3bnk2c
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Tue 2009-01-20 18:37:31 +1000
    message:
      blackbox tests
    modified:
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
    ------------------------------------------------------------
    revno: 3947.1.2
    revision-id: ian.clatworthy at canonical.com-20090120082114-56vno4rarr3bnk2c
    parent: ian.clatworthy at canonical.com-20090120071005-qgi0npvhnkdj1ln1
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Tue 2009-01-20 18:21:14 +1000
    message:
      formatter tests
    modified:
      bzrlib/tests/test_log.py       testlog.py-20050728115707-1a514809d7d49309
    ------------------------------------------------------------
    revno: 3947.1.1
    revision-id: ian.clatworthy at canonical.com-20090120071005-qgi0npvhnkdj1ln1
    parent: pqm at pqm.ubuntu.com-20090120032136-alahvfk4g7y8iczn
    committer: Ian Clatworthy <ian.clatworthy at canonical.com>
    branch nick: bzr.log-merge-revisions
    timestamp: Tue 2009-01-20 17:10:05 +1000
    message:
      add --merge-revisions to log
    modified:
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/log.py                  log.py-20050505065812-c40ce11702fe5fb1
=== modified file 'NEWS'
--- a/NEWS	2009-01-29 05:21:36 +0000
+++ b/NEWS	2009-01-29 06:31:22 +0000
@@ -30,6 +30,17 @@
       When logging a file, the diff only includes changes to that file.
       (Ian Clatworthy, #202331, #227335)
 
+    * ``bzr log`` supports a new option called ``-n N`` or ``--level N``.
+      A value of 0 (zero) means "show all nested merge revisions" while
+      a value of 1 (one) means "show just the top level". Values above
+      1 can be used to see a limited amount of nesting. That can be
+      useful for seeing the level or two below PQM submits for example.
+      To force the ``--short`` and ``--line`` formats to display all nested
+      merge revisions just like ``--long`` does by default, use a command
+      like ``bzr log --short -n0``. To display just the mainline using
+      ``--long`` format, ``bzr log --long -n1``.
+      (Ian Clatworthy)
+
   IMPROVEMENTS:
 
     * ``bzr init`` will now print a little less verbose output.

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2009-01-29 05:21:36 +0000
+++ b/bzrlib/builtins.py	2009-01-29 06:31:22 +0000
@@ -1818,6 +1818,14 @@
         raise errors.BzrCommandError(msg)
 
 
+def _parse_levels(s):
+    try:
+        return int(s)
+    except ValueError:
+        msg = "The levels argument must be an integer."
+        raise errors.BzrCommandError(msg)
+
+
 class cmd_log(Command):
     """Show log of a branch, file, or directory.
 
@@ -1858,6 +1866,11 @@
                    help='Show just the specified revision.'
                    ' See also "help revisionspec".'),
             'log-format',
+            Option('levels',
+                   short_name='n',
+                   help='Number of levels to display - 0 for all, 1 for flat.',
+                   argname='N',
+                   type=_parse_levels),
             Option('message',
                    short_name='m',
                    help='Show revisions whose message matches this '
@@ -1882,6 +1895,7 @@
             revision=None,
             change=None,
             log_format=None,
+            levels=None,
             message=None,
             limit=None,
             show_diff=False):
@@ -1931,7 +1945,8 @@
 
             lf = log_format(show_ids=show_ids, to_file=self.outf,
                             show_timezone=timezone,
-                            delta_format=get_verbosity_level())
+                            delta_format=get_verbosity_level(),
+                            levels=levels)
 
             show_log(b,
                      lf,

=== modified file 'bzrlib/log.py'
--- a/bzrlib/log.py	2009-01-27 23:06:35 +0000
+++ b/bzrlib/log.py	2009-01-29 06:31:22 +0000
@@ -202,9 +202,12 @@
 
     if specific_fileid:
         trace.mutter('get log for file_id %r', specific_fileid)
-    generate_merge_revisions = getattr(lf, 'supports_merge_revisions', False)
-    allow_single_merge_revision = getattr(lf,
-        'supports_single_merge_revision', False)
+    levels_to_display = lf.get_levels()
+    generate_merge_revisions = levels_to_display != 1
+    allow_single_merge_revision = True
+    if not getattr(lf, 'supports_merge_revisions', False):
+        allow_single_merge_revision = getattr(lf,
+            'supports_single_merge_revision', False)
     view_revisions = calculate_view_revisions(branch, start_revision,
                                               end_revision, direction,
                                               specific_fileid,
@@ -226,6 +229,9 @@
         generate_delta, search)
     for revs in revision_iterator:
         for (rev_id, revno, merge_depth), rev, delta in revs:
+            # Note: 0 levels means show everything; merge_depth counts from 0
+            if levels_to_display != 0 and merge_depth >= levels_to_display:
+                continue
             if generate_diff:
                 diff = _format_diff(repo, rev, rev_id, specific_fileid)
             else:
@@ -753,6 +759,10 @@
         also not True, then only mainline revisions will be passed to the 
         formatter.
 
+    - preferred_levels is the number of levels this formatter defaults to.
+        The default value is zero meaning display all levels.
+        This value is only relevant if supports_merge_revisions is True.
+
     - supports_single_merge_revision must be True if this log formatter
         supports logging only a single merge revision.  This flag is
         only relevant if supports_merge_revisions is not True.
@@ -770,9 +780,20 @@
             # code that returns a dict {'name':'value'} of the properties 
             # to be shown
     """
+    preferred_levels = 0
 
     def __init__(self, to_file, show_ids=False, show_timezone='original',
-                 delta_format=None):
+                 delta_format=None, levels=None):
+        """Create a LogFormatter.
+
+        :param to_file: the file to output to
+        :param show_ids: if True, revision-ids are to be displayed
+        :param show_timezone: the timezone to use
+        :param delta_format: the level of delta information to display
+          or None to leave it u to the formatter to decide
+        :param levels: the number of levels to display; None or -1 to
+          let the log formatter decide.
+        """
         self.to_file = to_file
         self.show_ids = show_ids
         self.show_timezone = show_timezone
@@ -780,16 +801,23 @@
             # Ensures backward compatibility
             delta_format = 2 # long format
         self.delta_format = delta_format
-
-# TODO: uncomment this block after show() has been removed.
-# Until then defining log_revision would prevent _show_log calling show() 
-# in legacy formatters.
-#    def log_revision(self, revision):
-#        """Log a revision.
-#
-#        :param  revision:   The LogRevision to be logged.
-#        """
-#        raise NotImplementedError('not implemented in abstract base')
+        self.levels = levels
+
+    def get_levels(self):
+        """Get the number of levels to display or 0 for all."""
+        if getattr(self, 'supports_merge_revisions', False):
+            if self.levels is None or self.levels == -1:
+                return self.preferred_levels
+            else:
+                return self.levels
+        return 1
+
+    def log_revision(self, revision):
+        """Log a revision.
+
+        :param  revision:   The LogRevision to be logged.
+        """
+        raise NotImplementedError('not implemented in abstract base')
 
     def short_committer(self, rev):
         name, address = config.parse_username(rev.committer)
@@ -874,12 +902,36 @@
 
 class ShortLogFormatter(LogFormatter):
 
+    supports_merge_revisions = True
+    preferred_levels = 1
     supports_delta = True
     supports_tags = True
-    supports_single_merge_revision = True
     supports_diff = True
 
+    def __init__(self, *args, **kwargs):
+        super(ShortLogFormatter, self).__init__(*args, **kwargs)
+        self.revno_width_by_depth = {}
+
     def log_revision(self, revision):
+        # We need two indents: one per depth and one for the information
+        # relative to that indent. Most mainline revnos are 5 chars or
+        # less while dotted revnos are typically 11 chars or less. Once
+        # calculated, we need to remember the offset for a given depth
+        # as we might be starting from a dotted revno in the first column
+        # and we want subsequent mainline revisions to line up.
+        depth = revision.merge_depth
+        indent = '    ' * depth
+        revno_width = self.revno_width_by_depth.get(depth)
+        if revno_width is None:
+            if revision.revno.find('.') == -1:
+                # mainline revno, e.g. 12345
+                revno_width = 5
+            else:
+                # dotted revno, e.g. 12345.10.55
+                revno_width = 11
+            self.revno_width_by_depth[depth] = revno_width
+        offset = ' ' * (revno_width + 1)
+
         to_file = self.to_file
         is_merge = ''
         if len(revision.rev.parent_ids) > 1:
@@ -887,26 +939,25 @@
         tags = ''
         if revision.tags:
             tags = ' {%s}' % (', '.join(revision.tags))
-
-        to_file.write("%5s %s\t%s%s%s\n" % (revision.revno,
-                self.short_author(revision.rev),
+        to_file.write(indent + "%*s %s\t%s%s%s\n" % (revno_width,
+                revision.revno, self.short_author(revision.rev),
                 format_date(revision.rev.timestamp,
                             revision.rev.timezone or 0,
                             self.show_timezone, date_fmt="%Y-%m-%d",
                             show_offset=False),
                 tags, is_merge))
         if self.show_ids:
-            to_file.write('      revision-id:%s\n'
+            to_file.write(indent + offset + 'revision-id:%s\n'
                           % (revision.rev.revision_id,))
         if not revision.rev.message:
-            to_file.write('      (no message)\n')
+            to_file.write(indent + offset + '(no message)\n')
         else:
             message = revision.rev.message.rstrip('\r\n')
             for l in message.split('\n'):
-                to_file.write('      %s\n' % (l,))
+                to_file.write(indent + offset + '%s\n' % (l,))
 
         if revision.delta is not None:
-            revision.delta.show(to_file, self.show_ids,
+            revision.delta.show(to_file, self.show_ids, indent=indent + offset,
                                 short_status=self.delta_format==1)
         if revision.diff is not None:
             self.show_diff(to_file, revision.diff, '      ')
@@ -915,8 +966,9 @@
 
 class LineLogFormatter(LogFormatter):
 
+    supports_merge_revisions = True
+    preferred_levels = 1
     supports_tags = True
-    supports_single_merge_revision = True
 
     def __init__(self, *args, **kwargs):
         super(LineLogFormatter, self).__init__(*args, **kwargs)
@@ -939,17 +991,19 @@
             return rev.message
 
     def log_revision(self, revision):
+        indent = '  ' * revision.merge_depth
         self.to_file.write(self.log_string(revision.revno, revision.rev,
-            self._max_chars, revision.tags))
+            self._max_chars, revision.tags, indent))
         self.to_file.write('\n')
 
-    def log_string(self, revno, rev, max_chars, tags=None):
+    def log_string(self, revno, rev, max_chars, tags=None, prefix=''):
         """Format log info into one string. Truncate tail of string
         :param  revno:      revision number or None.
                             Revision numbers counts from 1.
         :param  rev:        revision object
         :param  max_chars:  maximum length of resulting string
         :param  tags:       list of tags or None
+        :param  prefix:     string to prefix each line
         :return:            formatted truncated string
         """
         out = []
@@ -962,7 +1016,7 @@
             tag_str = '{%s}' % (', '.join(tags))
             out.append(tag_str)
         out.append(rev.get_summary())
-        return self.truncate(" ".join(out).rstrip('\n'), max_chars)
+        return self.truncate(prefix + " ".join(out).rstrip('\n'), max_chars)
 
 
 def line_log(rev, max_chars):

=== modified file 'bzrlib/tests/blackbox/test_log.py'
--- a/bzrlib/tests/blackbox/test_log.py	2009-01-27 23:02:21 +0000
+++ b/bzrlib/tests/blackbox/test_log.py	2009-01-29 06:31:22 +0000
@@ -256,14 +256,14 @@
     def assertUseShortDeltaFormat(self, cmd):
         log = self.run_bzr(cmd)[0]
         # Check that we use the short status format
-        self.assertContainsRe(log, '(?m)^A  hello.txt$')
-        self.assertNotContainsRe(log, '(?m)^added:$')
+        self.assertContainsRe(log, '(?m)^\s*A  hello.txt$')
+        self.assertNotContainsRe(log, '(?m)^\s*added:$')
 
     def assertUseLongDeltaFormat(self, cmd):
         log = self.run_bzr(cmd)[0]
         # Check that we use the long status format
-        self.assertNotContainsRe(log, '(?m)^A  hello.txt$')
-        self.assertContainsRe(log, '(?m)^added:$')
+        self.assertNotContainsRe(log, '(?m)^\s*A  hello.txt$')
+        self.assertContainsRe(log, '(?m)^\s*added:$')
 
     def test_log_short_verbose(self):
         self.assertUseShortDeltaFormat(['log', '--short', '-v'])
@@ -298,6 +298,30 @@
         parent_tree.commit(message='merge branch 1')
         os.chdir('parent')
 
+    def _prepare_short(self):
+        parent_tree = self.make_branch_and_tree('parent')
+        parent_tree.commit(message='first post',
+            timestamp=1132586700, timezone=36000,
+            committer='Joe Foo <joe at foo.com>')
+        child_tree = parent_tree.bzrdir.sprout('child').open_workingtree()
+        child_tree.commit(message='branch 1',
+            timestamp=1132586800, timezone=36000,
+            committer='Joe Foo <joe at foo.com>')
+        smaller_tree = \
+                child_tree.bzrdir.sprout('smallerchild').open_workingtree()
+        smaller_tree.commit(message='branch 2',
+            timestamp=1132586900, timezone=36000,
+            committer='Joe Foo <joe at foo.com>')
+        child_tree.merge_from_branch(smaller_tree.branch)
+        child_tree.commit(message='merge branch 2',
+            timestamp=1132587000, timezone=36000,
+            committer='Joe Foo <joe at foo.com>')
+        parent_tree.merge_from_branch(child_tree.branch)
+        parent_tree.commit(message='merge branch 1',
+            timestamp=1132587100, timezone=36000,
+            committer='Joe Foo <joe at foo.com>')
+        os.chdir('parent')
+
     def test_merges_are_indented_by_level(self):
         self._prepare()
         out,err = self.run_bzr('log')
@@ -341,6 +365,71 @@
   first post
 """)
 
+    def test_force_merge_revisions_off(self):
+        self._prepare()
+        out,err = self.run_bzr('log --long -n1')
+        self.assertEqual('', err)
+        log = normalize_log(out)
+        self.assertEqualDiff(log, """\
+------------------------------------------------------------
+revno: 2
+committer: Lorem Ipsum <test at example.com>
+branch nick: parent
+timestamp: Just now
+message:
+  merge branch 1
+------------------------------------------------------------
+revno: 1
+committer: Lorem Ipsum <test at example.com>
+branch nick: parent
+timestamp: Just now
+message:
+  first post
+""")
+
+    def test_force_merge_revisions_on(self):
+        self._prepare_short()
+        out,err = self.run_bzr('log --short -n0')
+        self.assertEqual('', err)
+        log = normalize_log(out)
+        self.assertEqualDiff(log, """\
+    2 Joe Foo\t2005-11-22 [merge]
+      merge branch 1
+
+          1.1.2 Joe Foo\t2005-11-22 [merge]
+                merge branch 2
+
+              1.2.1 Joe Foo\t2005-11-22
+                    branch 2
+
+          1.1.1 Joe Foo\t2005-11-22
+                branch 1
+
+    1 Joe Foo\t2005-11-22
+      first post
+
+""")
+
+    def test_force_merge_revisions_N(self):
+        self._prepare_short()
+        out,err = self.run_bzr('log --short -n2')
+        self.assertEqual('', err)
+        log = normalize_log(out)
+        self.assertEqualDiff(log, """\
+    2 Joe Foo\t2005-11-22 [merge]
+      merge branch 1
+
+          1.1.2 Joe Foo\t2005-11-22 [merge]
+                merge branch 2
+
+          1.1.1 Joe Foo\t2005-11-22
+                branch 1
+
+    1 Joe Foo\t2005-11-22
+      first post
+
+""")
+
     def test_merges_single_merge_rev(self):
         self._prepare()
         out,err = self.run_bzr('log -r1.1.2')

=== modified file 'bzrlib/tests/test_log.py'
--- a/bzrlib/tests/test_log.py	2009-01-23 02:29:42 +0000
+++ b/bzrlib/tests/test_log.py	2009-01-29 06:18:25 +0000
@@ -410,8 +410,75 @@
         rev = revspec.in_history(wtb)
         log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
         self.assertEqualDiff("""\
-1.1.1 Joe Foo\t2005-11-22
-      rev-merged
+      1.1.1 Joe Foo\t2005-11-22
+            rev-merged
+
+""",
+                             logfile.getvalue())
+
+
+class TestShortLogFormatterWithMergeRevisions(tests.TestCaseWithTransport):
+
+    def test_short_merge_revs_log_with_merges(self):
+        wt = self.make_branch_and_memory_tree('.')
+        wt.lock_write()
+        self.addCleanup(wt.unlock)
+        wt.add('')
+        wt.commit('rev-1', rev_id='rev-1',
+                  timestamp=1132586655, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.commit('rev-merged', rev_id='rev-2a',
+                  timestamp=1132586700, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.set_parent_ids(['rev-1', 'rev-2a'])
+        wt.branch.set_last_revision_info(1, 'rev-1')
+        wt.commit('rev-2', rev_id='rev-2b',
+                  timestamp=1132586800, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        logfile = self.make_utf8_encoded_stringio()
+        formatter = log.ShortLogFormatter(to_file=logfile, levels=0)
+        log.show_log(wt.branch, formatter)
+        # Note that the 1.1.1 indenting is in fact correct given that
+        # the revision numbers are right justified within 5 characters
+        # for mainline revnos and 9 characters for dotted revnos.
+        self.assertEqualDiff("""\
+    2 Joe Foo\t2005-11-22 [merge]
+      rev-2
+
+          1.1.1 Joe Foo\t2005-11-22
+                rev-merged
+
+    1 Joe Foo\t2005-11-22
+      rev-1
+
+""",
+                             logfile.getvalue())
+
+    def test_short_merge_revs_log_single_merge_revision(self):
+        wt = self.make_branch_and_memory_tree('.')
+        wt.lock_write()
+        self.addCleanup(wt.unlock)
+        wt.add('')
+        wt.commit('rev-1', rev_id='rev-1',
+                  timestamp=1132586655, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.commit('rev-merged', rev_id='rev-2a',
+                  timestamp=1132586700, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.set_parent_ids(['rev-1', 'rev-2a'])
+        wt.branch.set_last_revision_info(1, 'rev-1')
+        wt.commit('rev-2', rev_id='rev-2b',
+                  timestamp=1132586800, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        logfile = self.make_utf8_encoded_stringio()
+        formatter = log.ShortLogFormatter(to_file=logfile, levels=0)
+        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
+        wtb = wt.branch
+        rev = revspec.in_history(wtb)
+        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
+        self.assertEqualDiff("""\
+      1.1.1 Joe Foo\t2005-11-22
+            rev-merged
 
 """,
                              logfile.getvalue())
@@ -731,6 +798,189 @@
                 'bad_argument_prop_handler')
 
 
+class TestLongLogFormatterWithoutMergeRevisions(TestCaseWithoutPropsHandler):
+
+    def test_long_verbose_log(self):
+        """Verbose log includes changed files
+        
+        bug #4676
+        """
+        wt = self.make_branch_and_tree('.')
+        b = wt.branch
+        self.build_tree(['a'])
+        wt.add('a')
+        # XXX: why does a longer nick show up?
+        b.nick = 'test_verbose_log'
+        wt.commit(message='add a',
+                  timestamp=1132711707,
+                  timezone=36000,
+                  committer='Lorem Ipsum <test at example.com>')
+        logfile = file('out.tmp', 'w+')
+        formatter = log.LongLogFormatter(to_file=logfile, levels=1)
+        log.show_log(b, formatter, verbose=True)
+        logfile.flush()
+        logfile.seek(0)
+        log_contents = logfile.read()
+        self.assertEqualDiff('''\
+------------------------------------------------------------
+revno: 1
+committer: Lorem Ipsum <test at example.com>
+branch nick: test_verbose_log
+timestamp: Wed 2005-11-23 12:08:27 +1000
+message:
+  add a
+added:
+  a
+''',
+                             log_contents)
+
+    def test_long_verbose_contain_deltas(self):
+        wt = self.make_branch_and_tree('parent')
+        self.build_tree(['parent/f1', 'parent/f2'])
+        wt.add(['f1','f2'])
+        wt.commit('first post')
+        self.run_bzr('branch parent child')
+        os.unlink('child/f1')
+        file('child/f2', 'wb').write('hello\n')
+        self.run_bzr(['commit', '-m', 'removed f1 and modified f2',
+            'child'])
+        os.chdir('parent')
+        self.run_bzr('merge ../child')
+        wt.commit('merge branch 1')
+        b = wt.branch
+        sio = self.make_utf8_encoded_stringio()
+        lf = log.LongLogFormatter(to_file=sio, levels=1)
+        log.show_log(b, lf, verbose=True)
+        the_log = normalize_log(sio.getvalue())
+        self.assertEqualDiff("""\
+------------------------------------------------------------
+revno: 2
+committer: Lorem Ipsum <test at example.com>
+branch nick: parent
+timestamp: Just now
+message:
+  merge branch 1
+removed:
+  f1
+modified:
+  f2
+------------------------------------------------------------
+revno: 1
+committer: Lorem Ipsum <test at example.com>
+branch nick: parent
+timestamp: Just now
+message:
+  first post
+added:
+  f1
+  f2
+""",
+                             the_log)
+
+    def test_long_trailing_newlines(self):
+        wt = self.make_branch_and_tree('.')
+        b = make_commits_with_trailing_newlines(wt)
+        sio = self.make_utf8_encoded_stringio()
+        lf = log.LongLogFormatter(to_file=sio, levels=1)
+        log.show_log(b, lf)
+        self.assertEqualDiff("""\
+------------------------------------------------------------
+revno: 3
+committer: Joe Foo <joe at foo.com>
+branch nick: test
+timestamp: Mon 2005-11-21 09:32:56 -0600
+message:
+  single line with trailing newline
+------------------------------------------------------------
+revno: 2
+author: Joe Bar <joe at bar.com>
+committer: Joe Foo <joe at foo.com>
+branch nick: test
+timestamp: Mon 2005-11-21 09:27:22 -0600
+message:
+  multiline
+  log
+  message
+------------------------------------------------------------
+revno: 1
+committer: Joe Foo <joe at foo.com>
+branch nick: test
+timestamp: Mon 2005-11-21 09:24:15 -0600
+message:
+  simple log message
+""",
+                             sio.getvalue())
+
+    def test_long_author_in_log(self):
+        """Log includes the author name if it's set in
+        the revision properties
+        """
+        wt = self.make_branch_and_tree('.')
+        b = wt.branch
+        self.build_tree(['a'])
+        wt.add('a')
+        b.nick = 'test_author_log'
+        wt.commit(message='add a',
+                  timestamp=1132711707,
+                  timezone=36000,
+                  committer='Lorem Ipsum <test at example.com>',
+                  author='John Doe <jdoe at example.com>')
+        sio = StringIO()
+        formatter = log.LongLogFormatter(to_file=sio, levels=1)
+        log.show_log(b, formatter)
+        self.assertEqualDiff('''\
+------------------------------------------------------------
+revno: 1
+author: John Doe <jdoe at example.com>
+committer: Lorem Ipsum <test at example.com>
+branch nick: test_author_log
+timestamp: Wed 2005-11-23 12:08:27 +1000
+message:
+  add a
+''',
+                             sio.getvalue())
+
+    def test_long_properties_in_log(self):
+        """Log includes the custom properties returned by the registered 
+        handlers.
+        """
+        wt = self.make_branch_and_tree('.')
+        b = wt.branch
+        self.build_tree(['a'])
+        wt.add('a')
+        b.nick = 'test_properties_in_log'
+        wt.commit(message='add a',
+                  timestamp=1132711707,
+                  timezone=36000,
+                  committer='Lorem Ipsum <test at example.com>',
+                  author='John Doe <jdoe at example.com>')
+        sio = StringIO()
+        formatter = log.LongLogFormatter(to_file=sio, levels=1)
+        try:
+            def trivial_custom_prop_handler(revision):
+                return {'test_prop':'test_value'}
+
+            log.properties_handler_registry.register(
+                'trivial_custom_prop_handler',
+                trivial_custom_prop_handler)
+            log.show_log(b, formatter)
+        finally:
+            log.properties_handler_registry.remove(
+                'trivial_custom_prop_handler')
+            self.assertEqualDiff('''\
+------------------------------------------------------------
+revno: 1
+test_prop: test_value
+author: John Doe <jdoe at example.com>
+committer: Lorem Ipsum <test at example.com>
+branch nick: test_properties_in_log
+timestamp: Wed 2005-11-23 12:08:27 +1000
+message:
+  add a
+''',
+                                 sio.getvalue())
+
+
 class TestLineLogFormatter(tests.TestCaseWithTransport):
 
     def test_line_log(self):
@@ -820,6 +1070,83 @@
 """,
                              logfile.getvalue())
 
+class TestLineLogFormatterWithMergeRevisions(tests.TestCaseWithTransport):
+
+    def test_line_merge_revs_log(self):
+        """Line log should show revno
+        
+        bug #5162
+        """
+        wt = self.make_branch_and_tree('.')
+        b = wt.branch
+        self.build_tree(['a'])
+        wt.add('a')
+        b.nick = 'test-line-log'
+        wt.commit(message='add a',
+                  timestamp=1132711707,
+                  timezone=36000,
+                  committer='Line-Log-Formatter Tester <test at line.log>')
+        logfile = file('out.tmp', 'w+')
+        formatter = log.LineLogFormatter(to_file=logfile, levels=0)
+        log.show_log(b, formatter)
+        logfile.flush()
+        logfile.seek(0)
+        log_contents = logfile.read()
+        self.assertEqualDiff('1: Line-Log-Formatte... 2005-11-23 add a\n',
+                             log_contents)
+
+    def test_line_merge_revs_log_single_merge_revision(self):
+        wt = self.make_branch_and_memory_tree('.')
+        wt.lock_write()
+        self.addCleanup(wt.unlock)
+        wt.add('')
+        wt.commit('rev-1', rev_id='rev-1',
+                  timestamp=1132586655, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.commit('rev-merged', rev_id='rev-2a',
+                  timestamp=1132586700, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.set_parent_ids(['rev-1', 'rev-2a'])
+        wt.branch.set_last_revision_info(1, 'rev-1')
+        wt.commit('rev-2', rev_id='rev-2b',
+                  timestamp=1132586800, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        logfile = self.make_utf8_encoded_stringio()
+        formatter = log.LineLogFormatter(to_file=logfile, levels=0)
+        revspec = revisionspec.RevisionSpec.from_string('1.1.1')
+        wtb = wt.branch
+        rev = revspec.in_history(wtb)
+        log.show_log(wtb, formatter, start_revision=rev, end_revision=rev)
+        self.assertEqualDiff("""\
+1.1.1: Joe Foo 2005-11-22 rev-merged
+""",
+                             logfile.getvalue())
+
+    def test_line_merge_revs_log_with_merges(self):
+        wt = self.make_branch_and_memory_tree('.')
+        wt.lock_write()
+        self.addCleanup(wt.unlock)
+        wt.add('')
+        wt.commit('rev-1', rev_id='rev-1',
+                  timestamp=1132586655, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.commit('rev-merged', rev_id='rev-2a',
+                  timestamp=1132586700, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        wt.set_parent_ids(['rev-1', 'rev-2a'])
+        wt.branch.set_last_revision_info(1, 'rev-1')
+        wt.commit('rev-2', rev_id='rev-2b',
+                  timestamp=1132586800, timezone=36000,
+                  committer='Joe Foo <joe at foo.com>')
+        logfile = self.make_utf8_encoded_stringio()
+        formatter = log.LineLogFormatter(to_file=logfile, levels=0)
+        log.show_log(wt.branch, formatter)
+        self.assertEqualDiff("""\
+2: Joe Foo 2005-11-22 rev-2
+  1.1.1: Joe Foo 2005-11-22 rev-merged
+1: Joe Foo 2005-11-22 rev-1
+""",
+                             logfile.getvalue())
 
 class TestGetViewRevisions(tests.TestCaseWithTransport):
 




More information about the bazaar-commits mailing list