Rev 5139: Merging in trunk with root-id preserved in file:///home/vila/src/bzr/bugs/805809-no-final-path/

Vincent Ladeuil v.ladeuil+lp at free.fr
Thu Jul 7 10:19:01 UTC 2011


At file:///home/vila/src/bzr/bugs/805809-no-final-path/

------------------------------------------------------------
revno: 5139 [merge]
revision-id: v.ladeuil+lp at free.fr-20110707101900-b0mxc2cnwu2dql97
parent: v.ladeuil+lp at free.fr-20110706092200-7iai2mwzc0sqdsvf
parent: v.ladeuil+lp at free.fr-20110707101207-6pmr7hhtqh1wqdd6
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: 805809-no-final-path
timestamp: Thu 2011-07-07 12:19:00 +0200
message:
  Merging in trunk with root-id preserved
modified:
  bzr                            bzr.py-20050313053754-5485f144c7006fa6
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/delta.py                delta.py-20050729221636-54cf14ef94783d0a
  bzrlib/shelf.py                prepare_shelf.py-20081005181341-n74qe6gu1e65ad4v-1
  bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
  bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
  bzrlib/tests/test_shelf_ui.py  test_shelf_ui.py-20081027155203-wtcuazg85wp9u4fv-1
  bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
  bzrlib/tests/test_version_info.py test_version_info.py-20051228204928-2c364e30b702b41b
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
  bzrlib/version_info_formats/__init__.py generate_version_info.py-20051228204928-8358edabcddcd97e
  bzrlib/version_info_formats/format_custom.py format_custom.py-20071029100350-ajovqhbpb5khf6gu-1
  bzrlib/version_info_formats/format_python.py format_python.py-20060809202444-ike7i9ub03gb432p-1
  bzrlib/version_info_formats/format_rio.py format_rio.py-20060809202444-ike7i9ub03gb432p-2
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
-------------- next part --------------
=== modified file 'bzr'
--- a/bzr	2011-05-17 20:58:43 +0000
+++ b/bzr	2011-07-01 21:48:58 +0000
@@ -28,7 +28,7 @@
 try:
     version_info = sys.version_info
 except AttributeError:
-    version_info = 1, 5 # 1.5 or older
+    version_info = 1, 5  # 1.5 or older
 
 REINVOKE = "__BZR_REINVOKE"
 NEED_VERS = (2, 6)
@@ -108,10 +108,16 @@
     raise
 
 if bzrlib.version_info[:3] != _script_version:
-    sys.stderr.write("bzr: WARNING: bzrlib version doesn't match the bzr program.\n"
-            "This may indicate an installation problem.\n"
-            "bzrlib from %s is version %r\n"
-            % (bzrlib.__path__, bzrlib.version_info))
+    sys.stderr.write(
+        "bzr: WARNING: bzrlib version doesn't match the bzr program.\n"
+        "This may indicate an installation problem.\n"
+        "bzrlib is version %s from %s\n"
+        "bzr is version %s from %s\n" % (
+        bzrlib._format_version_tuple(bzrlib.version_info),
+        bzrlib.__path__[0],
+        bzrlib._format_version_tuple(_script_version),
+        __file__))
+
 
 import bzrlib.inspect_for_copy
 bzrlib.inspect_for_copy.import_copy_with_hacked_inspect()

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2011-06-30 11:14:06 +0000
+++ b/bzrlib/builtins.py	2011-07-06 13:30:21 +0000
@@ -232,9 +232,10 @@
     unknown
         Not versioned and not matching an ignore pattern.
 
-    Additionally for directories, symlinks and files with an executable
-    bit, Bazaar indicates their type using a trailing character: '/', '@'
-    or '*' respectively.
+    Additionally for directories, symlinks and files with a changed
+    executable bit, Bazaar indicates their type using a trailing
+    character: '/', '@' or '*' respectively. These decorations can be
+    disabled using the '--no-classify' option.
 
     To see ignored files use 'bzr ignored'.  For details on the
     changes to file texts, use 'bzr diff'.
@@ -271,6 +272,9 @@
                             short_name='V'),
                      Option('no-pending', help='Don\'t show pending merges.',
                            ),
+                     Option('no-classify',
+                            help='Do not mark object type using indicator.',
+                           ),
                      ]
     aliases = ['st', 'stat']
 
@@ -279,7 +283,8 @@
 
     @display_command
     def run(self, show_ids=False, file_list=None, revision=None, short=False,
-            versioned=False, no_pending=False, verbose=False):
+            versioned=False, no_pending=False, verbose=False,
+            no_classify=False):
         from bzrlib.status import show_tree_status
 
         if revision and len(revision) > 2:
@@ -299,7 +304,8 @@
         show_tree_status(tree, show_ids=show_ids,
                          specific_files=relfile_list, revision=revision,
                          to_file=self.outf, short=short, versioned=versioned,
-                         show_pending=(not no_pending), verbose=verbose)
+                         show_pending=(not no_pending), verbose=verbose,
+                         classify=not no_classify)
 
 
 class cmd_cat_revision(Command):

=== modified file 'bzrlib/delta.py'
--- a/bzrlib/delta.py	2010-10-20 14:38:53 +0000
+++ b/bzrlib/delta.py	2011-06-01 12:53:56 +0000
@@ -174,7 +174,8 @@
     """Report changes between two trees"""
 
     def __init__(self, output=None, suppress_root_add=True,
-                 output_file=None, unversioned_filter=None, view_info=None):
+                 output_file=None, unversioned_filter=None, view_info=None,
+                 classify=True):
         """Constructor
 
         :param output: a function with the signature of trace.note, i.e.
@@ -189,6 +190,7 @@
         :param view_info: A tuple of view_name,view_files if only
             items inside a view are to be reported on, or None for
             no view filtering.
+        :param classify: Add special symbols to indicate file kind.
         """
         if output_file is not None:
             if output is not None:
@@ -213,6 +215,10 @@
                               'unversioned': '?', # versioned in neither
                               }
         self.unversioned_filter = unversioned_filter
+        if classify:
+            self.kind_marker = osutils.kind_marker
+        else:
+            self.kind_marker = lambda kind: ''
         if view_info is None:
             self.view_name = None
             self.view_files = []
@@ -267,7 +273,7 @@
             # if the file is not missing in the source, we show its kind
             # when we show two paths.
             if kind[0] is not None:
-                old_path += osutils.kind_marker(kind[0])
+                old_path += self.kind_marker(kind[0])
             old_path += " => "
         elif versioned == 'removed':
             # not present in target
@@ -282,10 +288,10 @@
             rename = self.versioned_map[versioned]
         # we show the old kind on the new path when the content is deleted.
         if modified == 'deleted':
-            path += osutils.kind_marker(kind[0])
+            path += self.kind_marker(kind[0])
         # otherwise we always show the current kind when there is one
         elif kind[1] is not None:
-            path += osutils.kind_marker(kind[1])
+            path += self.kind_marker(kind[1])
         if exe_change:
             exe = '*'
         else:
@@ -340,7 +346,7 @@
                         exe_change, kind)
 
 def report_delta(to_file, delta, short_status=False, show_ids=False, 
-         show_unchanged=False, indent='', filter=None):
+         show_unchanged=False, indent='', filter=None, classify=True):
     """Output this delta in status-like form to to_file.
 
     :param to_file: A file-like object where the output is displayed.
@@ -358,9 +364,13 @@
 
     :param filter: A callable receiving a path and a file id and
         returning True if the path should be displayed.
+
+    :param classify: Add special symbols to indicate file kind.
     """
 
     def decorate_path(path, kind, meta_modified=None):
+        if not classify:
+            return path
         if kind == 'directory':
             path += '/'
         elif kind == 'symlink':

=== modified file 'bzrlib/shelf.py'
--- a/bzrlib/shelf.py	2011-05-19 09:32:38 +0000
+++ b/bzrlib/shelf.py	2011-07-06 21:37:16 +0000
@@ -82,6 +82,9 @@
             # when a tree root was deleted / renamed.
             if kind[0] is None and names[1] == '':
                 continue
+            # Also don't shelve deletion of tree root.
+            if kind[1] is None and names[0] == '':
+                continue
             if kind[0] is None or versioned[0] == False:
                 self.creation[file_id] = (kind[1], names[1], parents[1],
                                           versioned)

=== modified file 'bzrlib/status.py'
--- a/bzrlib/status.py	2011-05-21 16:43:19 +0000
+++ b/bzrlib/status.py	2011-06-01 12:53:56 +0000
@@ -34,7 +34,7 @@
 def report_changes(to_file, old, new, specific_files, 
                    show_short_reporter, show_long_callback, 
                    short=False, want_unchanged=False, 
-                   want_unversioned=False, show_ids=False):
+                   want_unversioned=False, show_ids=False, classify=True):
     """Display summary of changes.
 
     This compares two trees with regards to a list of files, and delegates 
@@ -59,6 +59,7 @@
         files.
     :param show_ids: If set, includes each file's id.
     :param want_unversioned: If False, only shows versioned files.
+    :param classify: Add special symbols to indicate file kind.
     """
 
     if short:
@@ -76,7 +77,8 @@
             delta.unversioned if not new.is_ignored(unversioned[0])]
         show_long_callback(to_file, delta, 
                            show_ids=show_ids,
-                           show_unchanged=want_unchanged)
+                           show_unchanged=want_unchanged,
+                           classify=classify)
 
 
 def show_tree_status(wt, show_unchanged=None,
@@ -88,6 +90,7 @@
                      short=False,
                      verbose=False,
                      versioned=False,
+                     classify=True,
                      show_long_callback=_mod_delta.report_delta):
     """Display summary of changes.
 
@@ -117,6 +120,7 @@
     :param verbose: If True, show all merged revisions, not just
         the merge tips
     :param versioned: If True, only shows versioned files.
+    :param classify: Add special symbols to indicate file kind.
     :param show_long_callback: A callback: message = show_long_callback(to_file, delta, 
         show_ids, show_unchanged, indent, filter), only used with the long output
     """
@@ -161,11 +165,12 @@
 
             # Reporter used for short outputs
             reporter = _mod_delta._ChangeReporter(output_file=to_file,
-                unversioned_filter=new.is_ignored)
+                unversioned_filter=new.is_ignored, classify=classify)
             report_changes(to_file, old, new, specific_files, 
                            reporter, show_long_callback, 
                            short=short, want_unchanged=show_unchanged, 
-                           want_unversioned=want_unversioned, show_ids=show_ids)
+                           want_unversioned=want_unversioned, show_ids=show_ids,
+                           classify=classify)
 
             # show the ignored files among specific files (i.e. show the files
             # identified from input that we choose to ignore). 

=== modified file 'bzrlib/tests/test_merge.py'
--- a/bzrlib/tests/test_merge.py	2011-06-28 13:40:29 +0000
+++ b/bzrlib/tests/test_merge.py	2011-07-07 10:04:39 +0000
@@ -135,6 +135,29 @@
             preview = tt.get_preview_tree()
             self.assertEqual(wt.get_root_id(), preview.get_root_id())
 
+    def test_merge_unrelated_retains_root(self):
+        wt = self.make_branch_and_tree('tree')
+        root_id_before_merge = wt.get_root_id()
+        other_tree = self.make_branch_and_tree('other')
+        # Do a commit so there is something to merge
+        other_tree.commit('commit other')
+        self.assertNotEquals(root_id_before_merge, other_tree.get_root_id())
+        wt.merge_from_branch(other_tree.branch,
+                             from_revision=_mod_revision.NULL_REVISION)
+        self.assertEqual(root_id_before_merge, wt.get_root_id())
+
+    def test_merge_preview_unrelated_retains_root(self):
+        wt = self.make_branch_and_tree('tree')
+        other_tree = self.make_branch_and_tree('other')
+        # Do a commit so there is something to merge
+        other_tree.commit('commit other')
+        merger = _mod_merge.Merge3Merger(wt, wt, wt.basis_tree(), other_tree,
+                                         this_branch=wt.branch,
+                                         do_merge=False)
+        with merger.make_preview_transform() as tt:
+            preview = tt.get_preview_tree()
+            self.assertEqual(wt.get_root_id(), preview.get_root_id())
+
     def test_create_rename(self):
         """Rename an inventory entry while creating the file"""
         tree =self.make_branch_and_tree('.')

=== modified file 'bzrlib/tests/test_shelf_ui.py'
--- a/bzrlib/tests/test_shelf_ui.py	2011-06-13 14:44:22 +0000
+++ b/bzrlib/tests/test_shelf_ui.py	2011-07-07 09:34:06 +0000
@@ -302,16 +302,19 @@
         finally:
             tree.unlock()
 
-    def test_shelve_old_root_deleted(self):
+    def test_shelve_old_root_preserved(self):
         tree1 = self.make_branch_and_tree('tree1')
         tree1.commit('add root')
+        tree1_root_id = tree1.get_root_id()
         tree2 = self.make_branch_and_tree('tree2')
         rev2 = tree2.commit('add root')
+        self.assertNotEquals(tree1_root_id, tree2.get_root_id())
         tree1.merge_from_branch(tree2.branch,
                                 from_revision=revision.NULL_REVISION)
-        tree1.commit('Replaced root entry')
+        tree1.commit('merging in tree2')
+        self.assertEquals(tree1_root_id, tree1.get_root_id())
         # This is essentially assertNotRaises(InconsistentDelta)
-        # With testtools 0.99, it can be rewritten as:
+        # With testtools 0.9.9, it can be rewritten as:
         # with ExpectedException(AssertionError,
         #                        'InconsistentDelta not raised'):
         #     with ExpectedException(errors.InconsistentDelta, ''):

=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py	2011-06-28 13:40:29 +0000
+++ b/bzrlib/tests/test_transform.py	2011-07-06 20:52:00 +0000
@@ -285,9 +285,24 @@
         new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
         self.assertRaises(ValueError, transform.fixup_new_roots)
 
+    def test_retain_existing_root(self):
+        tt, root = self.get_transform()
+        with tt:
+            tt.new_directory('', ROOT_PARENT, 'new-root-id')
+            tt.fixup_new_roots()
+            self.assertNotEqual('new-root-id', tt.final_file_id(tt.root))
+
+    def test_retain_existing_root_added_file(self):
+        tt, root = self.get_transform()
+        new_trans_id = tt.new_directory('', ROOT_PARENT, 'new-root-id')
+        child = tt.new_directory('child', new_trans_id, 'child-id')
+        tt.fixup_new_roots()
+        self.assertEqual(tt.root, tt.final_parent(child))
+
     def test_add_unversioned_root(self):
         transform, root = self.get_transform()
         new_trans_id = transform.new_directory('', ROOT_PARENT, None)
+        transform.delete_contents(transform.root)
         transform.fixup_new_roots()
         self.assertNotIn(transform.root, transform._new_id)
 

=== modified file 'bzrlib/tests/test_version_info.py'
--- a/bzrlib/tests/test_version_info.py	2011-05-13 12:51:05 +0000
+++ b/bzrlib/tests/test_version_info.py	2011-06-14 17:01:15 +0000
@@ -53,6 +53,25 @@
 
         return wt
 
+    def create_tree_with_dotted_revno(self):
+        wt = self.make_branch_and_tree('branch')
+        self.build_tree(['branch/a'])
+        wt.add('a')
+        wt.commit('a', rev_id='r1')
+
+        other = wt.bzrdir.sprout('other').open_workingtree()
+        self.build_tree(['other/b.a'])
+        other.add(['b.a'])
+        other.commit('b.a', rev_id='o2')
+
+        os.chdir('branch')
+        self.run_bzr('merge ../other')
+        wt.commit('merge', rev_id='merge')
+
+        wt.update(revision='o2')
+
+        return wt
+
     def test_rio_null(self):
         wt = self.make_branch_and_tree('branch')
 
@@ -63,6 +82,15 @@
         self.assertContainsRe(val, 'build-date:')
         self.assertContainsRe(val, 'revno: 0')
 
+    def test_rio_dotted_revno(self):
+        wt = self.create_tree_with_dotted_revno()
+
+        sio = StringIO()
+        builder = RioVersionInfoBuilder(wt.branch, working_tree=wt)
+        builder.generate(sio)
+        val = sio.getvalue()
+        self.assertContainsRe(val, 'revno: 1.1.1')
+
     def test_rio_version_text(self):
         wt = self.create_branch()
 
@@ -191,9 +219,18 @@
         builder.generate(sio)
         val = sio.getvalue()
         self.assertContainsRe(val, "'revision_id': None")
-        self.assertContainsRe(val, "'revno': 0")
+        self.assertContainsRe(val, "'revno': '0'")
         self.assertNotContainsString(val, '\n\n\n\n')
 
+    def test_python_dotted_revno(self):
+        wt = self.create_tree_with_dotted_revno()
+
+        sio = StringIO()
+        builder = PythonVersionInfoBuilder(wt.branch, working_tree=wt)
+        builder.generate(sio)
+        val = sio.getvalue()
+        self.assertContainsRe(val, "'revno': '1.1.1'")
+
     def test_python_version(self):
         wt = self.create_branch()
 
@@ -223,7 +260,7 @@
             return tvi
 
         tvi = regen()
-        self.assertEqual(3, tvi.version_info['revno'])
+        self.assertEqual('3', tvi.version_info['revno'])
         self.assertEqual('r3', tvi.version_info['revision_id'])
         self.assertTrue(tvi.version_info.has_key('date'))
         self.assertEqual(None, tvi.version_info['clean'])
@@ -283,6 +320,14 @@
         self.assertRaises(errors.MissingTemplateVariable, 
             builder.generate, sio)
 
+    def test_custom_dotted_revno(self):
+        sio = StringIO()
+        wt = self.create_tree_with_dotted_revno()
+        builder = CustomVersionInfoBuilder(wt.branch, working_tree=wt, 
+            template='{revno} revid: {revision_id}')
+        builder.generate(sio)
+        self.assertEquals("1.1.1 revid: o2", sio.getvalue())
+
     def test_custom_version_text(self):
         wt = self.create_branch()
 

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2011-06-28 17:25:26 +0000
+++ b/bzrlib/transform.py	2011-07-06 20:52:00 +0000
@@ -243,13 +243,11 @@
             self._new_root = new_roots[0]
             return
         old_new_root = new_roots[0]
-        # TODO: What to do if a old_new_root is present, but self._new_root is
-        #       not listed as being removed? This code explicitly unversions
-        #       the old root and versions it with the new file_id. Though that
-        #       seems like an incomplete delta
-
         # unversion the new root's directory.
-        file_id = self.final_file_id(old_new_root)
+        if self.final_kind(self._new_root) is None:
+            file_id = self.final_file_id(old_new_root)
+        else:
+            file_id = self.final_file_id(self._new_root)
         if old_new_root in self._new_id:
             self.cancel_versioning(old_new_root)
         else:

=== modified file 'bzrlib/version_info_formats/__init__.py'
--- a/bzrlib/version_info_formats/__init__.py	2010-07-15 13:41:31 +0000
+++ b/bzrlib/version_info_formats/__init__.py	2011-06-12 20:09:55 +0000
@@ -159,6 +159,11 @@
             return self._working_tree.last_revision()
         return self._branch.last_revision()
 
+    def _get_revno_str(self, revision_id):
+        numbers = self._branch.revision_id_to_dotted_revno(revision_id)
+        revno_str = '.'.join([str(num) for num in numbers])
+        return revno_str
+
     def generate(self, to_file):
         """Output the version information to the supplied file.
 

=== modified file 'bzrlib/version_info_formats/format_custom.py'
--- a/bzrlib/version_info_formats/format_custom.py	2009-04-03 21:23:55 +0000
+++ b/bzrlib/version_info_formats/format_custom.py	2011-06-12 20:09:55 +0000
@@ -93,7 +93,7 @@
         if revision_id == NULL_REVISION:
             info.add('revno', 0)
         else:
-            info.add('revno', self._branch.revision_id_to_revno(revision_id))
+            info.add('revno', self._get_revno_str(revision_id))
             info.add('revision_id', revision_id)
             rev = self._branch.repository.get_revision(revision_id)
             info.add('date', create_date_str(rev.timestamp, rev.timezone))

=== modified file 'bzrlib/version_info_formats/format_python.py'
--- a/bzrlib/version_info_formats/format_python.py	2011-01-12 21:28:39 +0000
+++ b/bzrlib/version_info_formats/format_python.py	2011-06-12 20:09:55 +0000
@@ -39,7 +39,7 @@
 
 _py_version_footer = '''
 if __name__ == '__main__':
-    print 'revision: %(revno)d' % version_info
+    print 'revision: %(revno)s' % version_info
     print 'nick: %(branch_nick)s' % version_info
     print 'revision id: %(revision_id)s' % version_info
 '''
@@ -60,9 +60,9 @@
 
         revision_id = self._get_revision_id()
         if revision_id == NULL_REVISION:
-            info['revno'] = 0
+            info['revno'] = '0'
         else:
-            info['revno'] = self._branch.revision_id_to_revno(revision_id)
+            info['revno'] = self._get_revno_str(revision_id)
             info['revision_id'] = revision_id
             rev = self._branch.repository.get_revision(revision_id)
             info['date'] = create_date_str(rev.timestamp, rev.timezone)

=== modified file 'bzrlib/version_info_formats/format_rio.py'
--- a/bzrlib/version_info_formats/format_rio.py	2011-03-30 11:45:54 +0000
+++ b/bzrlib/version_info_formats/format_rio.py	2011-06-12 20:09:55 +0000
@@ -38,7 +38,7 @@
             info.add('revision-id', revision_id)
             rev = self._branch.repository.get_revision(revision_id)
             info.add('date', create_date_str(rev.timestamp, rev.timezone))
-            revno = str(self._branch.revision_id_to_revno(revision_id))
+            revno = self._get_revno_str(revision_id)
             for hook in RioVersionInfoBuilder.hooks['revision']:
                 hook(rev, info)
         else:

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-07-04 07:49:46 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-07-07 09:34:06 +0000
@@ -52,6 +52,11 @@
   modifying and renaming a file in a branch that deleted it (or vice-versa).
   (Vincent Ladeuil, #688101)
 
+* Give a more helpful message when the bzr executable doesn't match the
+  library.  (This typically happens because of a misconfigured PYTHONPATH
+  or half-installed bzr.)  
+  (Martin Pool, #804553)
+
 * Properly load utf8-encoded config files. (Vincent Ladeuil, #799212)
 
 * ``GraphThunkIdsToKeys.merge_sort`` now properly returns
@@ -78,6 +83,9 @@
   ``RepositoryFormat.supports_versioned_directories``.
   (Jelmer Vernooij, #765815)
 
+* The "revno" field type when using the python version-info format is now
+  a string (to handle dotted revnos) (Beno��t Pierre, #796259)
+
 Internals
 *********
 
@@ -134,10 +142,12 @@
   exception caused while running bzr serve.
   (Jonathan Riddell, #274578)
 
-
 * New hook set_commit_message in bzrlib.msgeditor to set a commit message
   and revision properties.  (Jonathan Riddell, #274578)
 
+* Preserve existing ``root-id`` when merging an unrelated branch.
+  (Aaron Bentley, #806356)
+
 * Support ``-S`` as an alias for ``--short`` for the ``log`` and
   ``missing`` commands. (Martin von Gagern, #38655)
 
@@ -163,6 +173,9 @@
   ``True``.
   (Martin Pool, #220464)
 
+* ``bzr version-info`` now works when the tree is on a dotted revno.
+  (Beno��t Pierre, #796259)
+
 * Credentials in the log output produced by ``-Dhttp`` are masked so users
   can more freely post them in bug reports. (Vincent Ladeuil, #723074)
 



More information about the bazaar-commits mailing list