Rev 3967: Make merge_content lca aware in http://bazaar.launchpad.net/%7Evila/bzr/bzr.integration

Vincent Ladeuil v.ladeuil+lp at free.fr
Wed Jan 28 14:28:18 GMT 2009


At http://bazaar.launchpad.net/%7Evila/bzr/bzr.integration

------------------------------------------------------------
revno: 3967
revision-id: v.ladeuil+lp at free.fr-20090128142739-50mm5oggx65rhsch
parent: pqm at pqm.ubuntu.com-20090128105451-ih99x6vzhtmfysjf
parent: v.ladeuil+lp at free.fr-20090123210648-yfb39g22yyo83d3y
committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
branch nick: bzr.integration
timestamp: Wed 2009-01-28 15:27:39 +0100
message:
  Make merge_content lca aware
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
  bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
    ------------------------------------------------------------
    revno: 3948.1.7
    revision-id: v.ladeuil+lp at free.fr-20090123210648-yfb39g22yyo83d3y
    parent: v.ladeuil+lp at free.fr-20090123194502-4i7lbovxs4s2oeh6
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: spurious-conflicts
    timestamp: Fri 2009-01-23 22:06:48 +0100
    message:
      Slight refactoring and test fixing.
      
      * bzrlib/tests/test_merge.py:
      (TestMergerEntriesLCAOnDisk.test_modified_symlink): Passing now.
      
      * bzrlib/merge.py:
      (Merge3Merger._lca_multi_way): Fix doc reference.
      (Merge3Merger.merge_contents.contents_conflict): Try to delay
      this_pair evaulation to avoid unnecessary sha1 (impyling file read
      from disk) calculation. Also slightly refactor to avoid repeated
      file_id in trees calculations.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
    ------------------------------------------------------------
    revno: 3948.1.6
    revision-id: v.ladeuil+lp at free.fr-20090123194502-4i7lbovxs4s2oeh6
    parent: v.ladeuil+lp at free.fr-20090123194036-y35ps7a7xghq3q31
    parent: john at arbash-meinel.com-20090123165453-uh76h1nfqzshc707
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: spurious-conflicts
    timestamp: Fri 2009-01-23 20:45:02 +0100
    message:
      Remerge jam fix and its ancestry
    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/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: 3955.2.1
        revision-id: john at arbash-meinel.com-20090123165453-uh76h1nfqzshc707
        parent: pqm at pqm.ubuntu.com-20090123103145-yvo3icrif75vkt20
        committer: John Arbash Meinel <john at arbash-meinel.com>
        branch nick: jam-integration
        timestamp: Fri 2009-01-23 10:54:53 -0600
        message:
          Change the workings of merge_content to be lca aware.
        modified:
          bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
          bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
    ------------------------------------------------------------
    revno: 3948.1.5
    revision-id: v.ladeuil+lp at free.fr-20090123194036-y35ps7a7xghq3q31
    parent: v.ladeuil+lp at free.fr-20090123095303-gvzd86p6p2ytmhxz
    committer: Vincent Ladeuil <v.ladeuil+lp at free.fr>
    branch nick: spurious-conflicts
    timestamp: Fri 2009-01-23 20:40:36 +0100
    message:
      merge jam fix
    modified:
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/tests/test_merge.py     testmerge.py-20050905070950-c1b5aa49ff911024
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2009-01-28 10:54:51 +0000
+++ b/NEWS	2009-01-28 14:27:39 +0000
@@ -23,6 +23,11 @@
       merge, we would cause the deletion to conflict a second time.
       (Vincent Ladeuil, John Arbash Meinel)
 
+    * There was another bug in how we chose the correct intermediate LCA in
+      criss-cross merges leading to several kind of changes be incorrectly
+      handled.
+      (John Arbash Meinel, Vincent Ladeuil)
+
   COMPATIBILITY BREAKS:
 
     * By default, ``bzr status`` after a merge now shows just the pending

=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py	2009-01-21 10:33:02 +0000
+++ b/bzrlib/merge.py	2009-01-23 21:06:48 +0000
@@ -977,7 +977,7 @@
         :return: 'this', 'other', or 'conflict' depending on whether an entry
             changed or not.
         """
-        # See doc/developers/lca_merge_resolution.txt for details about this
+        # See doc/developers/lca_tree_merging.txt for details about this
         # algorithm.
         if other == this:
             # Either Ambiguously clean, or nothing was actually changed. We
@@ -1118,33 +1118,44 @@
         # file kind...
         base_pair = contents_pair(self.base_tree)
         other_pair = contents_pair(self.other_tree)
-        if base_pair == other_pair:
-            # OTHER introduced no changes
-            return "unmodified"
-        this_pair = contents_pair(self.this_tree)
-        if this_pair == other_pair:
-            # THIS and OTHER introduced the same changes
-            return "unmodified"
-        else:
-            trans_id = self.tt.trans_id_file_id(file_id)
-            if this_pair == base_pair:
-                # only OTHER introduced changes
-                if file_id in self.this_tree:
-                    # Remove any existing contents
-                    self.tt.delete_contents(trans_id)
-                if file_id in self.other_tree:
-                    # OTHER changed the file
-                    create_from_tree(self.tt, trans_id,
-                                     self.other_tree, file_id)
-                    if file_id not in self.this_tree:
-                        self.tt.version_file(file_id, trans_id)
-                    return "modified"
-                elif file_id in self.this_tree.inventory:
-                    # OTHER deleted the file
-                    self.tt.unversion_file(trans_id)
-                    return "deleted"
-            #BOTH THIS and OTHER introduced changes; scalar conflict
-            elif this_pair[0] == "file" and other_pair[0] == "file":
+        if self._lca_trees:
+            this_pair = contents_pair(self.this_tree)
+            lca_pairs = [contents_pair(tree) for tree in self._lca_trees]
+            winner = self._lca_multi_way((base_pair, lca_pairs), other_pair,
+                                         this_pair, allow_overriding_lca=False)
+        else:
+            if base_pair == other_pair:
+                winner = 'this'
+            else:
+                # We delayed evaluating this_pair as long as we can to avoid
+                # unnecessary sha1 calculation
+                this_pair = contents_pair(self.this_tree)
+                winner = self._three_way(base_pair, other_pair, this_pair)
+        if winner == 'this':
+            # No interesting changes introduced by OTHER
+            return "unmodified"
+        trans_id = self.tt.trans_id_file_id(file_id)
+        if winner == 'other':
+            # OTHER is a straight winner, so replace this contents with other
+            file_in_this = file_id in self.this_tree
+            if file_in_this:
+                # Remove any existing contents
+                self.tt.delete_contents(trans_id)
+            if file_id in self.other_tree:
+                # OTHER changed the file
+                create_from_tree(self.tt, trans_id,
+                                 self.other_tree, file_id)
+                if not file_in_this:
+                    self.tt.version_file(file_id, trans_id)
+                return "modified"
+            elif file_in_this:
+                # OTHER deleted the file
+                self.tt.unversion_file(trans_id)
+                return "deleted"
+        else:
+            # We have a hypothetical conflict, but if we have files, then we
+            # can try to merge the content
+            if this_pair[0] == 'file' and other_pair[0] == 'file':
                 # THIS and OTHER are both files, so text merge.  Either
                 # BASE is a file, or both converted to files, so at least we
                 # have agreement that output should be a file.
@@ -1161,7 +1172,6 @@
                     pass
                 return "modified"
             else:
-                # Scalar conflict, can't text merge.  Dump conflicts
                 return contents_conflict()
 
     def get_lines(self, tree, file_id):

=== modified file 'bzrlib/tests/test_merge.py'
--- a/bzrlib/tests/test_merge.py	2009-01-23 09:53:03 +0000
+++ b/bzrlib/tests/test_merge.py	2009-01-23 21:06:48 +0000
@@ -2153,8 +2153,7 @@
         wt.merge_from_branch(wt.branch, 'C-id')
         wt.commit('D merges B & C', rev_id='D-id')
         conflicts = wt.merge_from_branch(wt.branch, to_revision='F-id')
-        self.expectFailure("Merge3Merger doesn't use lcas for symlink content",
-            self.assertEqual, 0, conflicts)
+        self.assertEqual(0, conflicts)
         self.assertEqual('bing', wt.get_symlink_target('foo-id'))
 
     def test_renamed_symlink(self):
@@ -2421,8 +2420,7 @@
         # TODO: We need to use the per-file graph to properly select a BASE
         #       before this will work. Or at least use the LCA trees to find
         #       the appropriate content base. (which is B, not A).
-        self.expectFailure("Merge3Merger doesn't recognize reverted content",
-            self.assertEqual, 'base content\n', wt.get_file_text('foo-id'))
+        self.assertEqual('base content\n', wt.get_file_text('foo-id'))
 
     def test_other_modified_content(self):
         builder = self.get_builder()
@@ -2438,8 +2436,6 @@
             [('modify', ('foo-id', 'F content\n'))]) # Override B content
         builder.build_snapshot('D-id', ['B-id', 'C-id'], [])
         wt, conflicts = self.do_merge(builder, 'F-id')
-        self.expectFailure("Merge3Merger only uses BASE for content",
-            self.assertEqual, 'F content\n', wt.get_file_text('foo-id'))
         self.assertEqual(0, conflicts)
         self.assertEqual('F content\n', wt.get_file_text('foo-id'))
 



More information about the bazaar-commits mailing list