Rev 3777: Allow merging into PreviewTrees in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Oct 14 04:18:40 BST 2008


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

------------------------------------------------------------
revno: 3777
revision-id: pqm at pqm.ubuntu.com-20081014031836-0pn8u98igc7gvtv0
parent: pqm at pqm.ubuntu.com-20081013060130-008463ut01xr4rx2
parent: aaron at aaronbentley.com-20081014024517-pu1q1kz1v51rvk9f
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2008-10-14 04:18:36 +0100
message:
  Allow merging into PreviewTrees
modified:
  bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
  bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.29
    revision-id: aaron at aaronbentley.com-20081014024517-pu1q1kz1v51rvk9f
    parent: aaron at aaronbentley.com-20081014024442-i1kwl151g3ybu724
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Mon 2008-10-13 22:45:17 -0400
    message:
      Remove obsolete NEWS entry
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
    ------------------------------------------------------------
    revno: 3363.17.28
    revision-id: aaron at aaronbentley.com-20081014024442-i1kwl151g3ybu724
    parent: aaron at aaronbentley.com-20081014023456-fczp9t705gxk3856
    parent: pqm at pqm.ubuntu.com-20081013060130-008463ut01xr4rx2
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Mon 2008-10-13 22:44:42 -0400
    message:
      Merge bzr.dev
    added:
      bzrlib/tests/blackbox/test_dump_btree.py test_dump_btree.py-20081008203335-zkpcq230b6vubszz-1
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/blackbox/__init__.py __init__.py-20051128053524-eba30d8255e08dc3
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
      doc/developers/ppa.txt         ppa.txt-20080722055539-606u7t2z32t3ae4w-1
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
    ------------------------------------------------------------
    revno: 3363.17.27
    revision-id: aaron at aaronbentley.com-20081014023456-fczp9t705gxk3856
    parent: aaron at aaronbentley.com-20081010225929-08pkzo68wbfr3yqg
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Mon 2008-10-13 22:34:56 -0400
    message:
      Add default case for create_from_tree
    modified:
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.26
    revision-id: aaron at aaronbentley.com-20081010225929-08pkzo68wbfr3yqg
    parent: aaron at aaronbentley.com-20081010115503-6aolshz5fz0s2ai4
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Fri 2008-10-10 18:59:29 -0400
    message:
      Deprecate create_by_entry
    modified:
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.25
    revision-id: aaron at aaronbentley.com-20081010115503-6aolshz5fz0s2ai4
    parent: aaron at aaronbentley.com-20081010052720-izbsk3d87f5rv6eq
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Fri 2008-10-10 07:55:03 -0400
    message:
      remove get_inventory_entry, replace with create_from_tree
    modified:
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/tests/tree_implementations/test_tree.py test_tree.py-20061215160206-usu7lwcj8aq2n3br-1
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
    ------------------------------------------------------------
    revno: 3363.17.24
    revision-id: aaron at aaronbentley.com-20081010052720-izbsk3d87f5rv6eq
    parent: aaron at aaronbentley.com-20081009025721-ibrbd8v2p48ycgeg
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Fri 2008-10-10 01:27:20 -0400
    message:
      Implement create_by_tree
    modified:
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.23
    revision-id: aaron at aaronbentley.com-20081009025721-ibrbd8v2p48ycgeg
    parent: aaron at aaronbentley.com-20081008024214-sfcpqtc252v6enah
    parent: pqm at pqm.ubuntu.com-20081008020104-e68hyxx45qo19nzx
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Wed 2008-10-08 22:57:21 -0400
    message:
      Merge with bzr.dev
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/api.py                  api.py-20070626082640-35lspz7j0ys7a8ld-1
      bzrlib/plugin.py               plugin.py-20050622060424-829b654519533d69
      bzrlib/tests/test_api.py       testapi.py-20051027033546-6f9be2d308d18a52
      bzrlib/tests/test_plugins.py   plugins.py-20050622075746-32002b55e5e943e9
    ------------------------------------------------------------
    revno: 3363.17.22
    revision-id: aaron at aaronbentley.com-20081008024214-sfcpqtc252v6enah
    parent: aaron at aaronbentley.com-20081007210107-pdm9xz7ae1ouzv39
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 22:42:14 -0400
    message:
      Cache expensive operations
    modified:
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.21
    revision-id: aaron at aaronbentley.com-20081007210107-pdm9xz7ae1ouzv39
    parent: aaron at aaronbentley.com-20081007202840-dd9hmkmysht6onv3
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 17:01:07 -0400
    message:
      Conflicts are handled when merging from preview trees
    modified:
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
    ------------------------------------------------------------
    revno: 3363.17.20
    revision-id: aaron at aaronbentley.com-20081007202840-dd9hmkmysht6onv3
    parent: aaron at aaronbentley.com-20081007202625-ftgbfta1rlmladcq
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 16:28:40 -0400
    message:
      Fix merging from PreviewTree
    modified:
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
    ------------------------------------------------------------
    revno: 3363.17.19
    revision-id: aaron at aaronbentley.com-20081007202625-ftgbfta1rlmladcq
    parent: aaron at aaronbentley.com-20081007195431-9ney90m41jciyi03
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 16:26:25 -0400
    message:
      Implement get_inventory_entry
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/tests/tree_implementations/test_tree.py test_tree.py-20061215160206-usu7lwcj8aq2n3br-1
      bzrlib/tree.py                 tree.py-20050309040759-9d5f2496be663e77
    ------------------------------------------------------------
    revno: 3363.17.18
    revision-id: aaron at aaronbentley.com-20081007195431-9ney90m41jciyi03
    parent: aaron at aaronbentley.com-20081007190743-w0n16qt57ahg61cw
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 15:54:31 -0400
    message:
      Fix is_executable for PreviewTree
    modified:
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.17
    revision-id: aaron at aaronbentley.com-20081007190743-w0n16qt57ahg61cw
    parent: aaron at aaronbentley.com-20081007183754-dmv7o3wb34jao306
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 15:07:43 -0400
    message:
      Start testing merging PreviewTree as OTHER
    modified:
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
      bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
      bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
    ------------------------------------------------------------
    revno: 3363.17.16
    revision-id: aaron at aaronbentley.com-20081007183754-dmv7o3wb34jao306
    parent: aaron at aaronbentley.com-20080929184621-reu2x9oi16wrahfs
    parent: pqm at pqm.ubuntu.com-20081007110356-zmp1x6pyx5lnlh5k
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into2
    timestamp: Tue 2008-10-07 14:37:54 -0400
    message:
      Merge with bzr.dev
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzr                            bzr.py-20050313053754-5485f144c7006fa6
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_dirstate_helpers_c.pyx dirstate_helpers.pyx-20070503201057-u425eni465q4idwn-3
      bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
      bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/bundle/__init__.py      changeset.py-20050513021216-b02ab57fb9738913
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/cmd_version_info.py     __init__.py-20051228204928-697d01fdca29c99b
      bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/config.py               config.py-20051011043216-070c74f4e9e338e8
      bzrlib/diff.py                 diff.py-20050309040759-26944fbbf2ebbf36
      bzrlib/directory_service.py    directory_service.py-20080305221044-vr2mkvlsk8jypa2y-1
      bzrlib/errors.py               errors.py-20050309040759-20512168c4e14fbd
      bzrlib/hashcache.py            hashcache.py-20050706091756-fe3a8cc1143ff24f
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/lock.py                 lock.py-20050527050856-ec090bb51bc03349
      bzrlib/lockdir.py              lockdir.py-20060220222025-98258adf27fbdda3
      bzrlib/mail_client.py          mail_client.py-20070809192806-vuxt3t19srtpjpdn-1
      bzrlib/msgeditor.py            msgeditor.py-20050901111708-ef6d8de98f5d8f2f
      bzrlib/option.py               option.py-20051014052914-661fb36e76e7362f
      bzrlib/osutils.py              osutils.py-20050309040759-eeaff12fbf77ac86
      bzrlib/patches.py              patches.py-20050727183609-378c1cc5972ce908
      bzrlib/plugin.py               plugin.py-20050622060424-829b654519533d69
      bzrlib/repofmt/knitrepo.py     knitrepo.py-20070206081537-pyy4a00xdas0j4pf-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/revision.py             revision.py-20050309040759-e77802c08f3999d5
      bzrlib/revisionspec.py         revisionspec.py-20050907152633-17567659fd5c0ddb
      bzrlib/smart/client.py         client.py-20061116014825-2k6ada6xgulslami-1
      bzrlib/smart/medium.py         medium.py-20061103051856-rgu2huy59fkz902q-1
      bzrlib/smart/request.py        request.py-20061108095550-gunadhxmzkdjfeek-1
      bzrlib/smart/server.py         server.py-20061110062051-chzu10y32vx8gvur-1
      bzrlib/status.py               status.py-20050505062338-431bfa63ec9b19e6
      bzrlib/store/__init__.py       store.py-20050309040759-164dc5173d6406c2
      bzrlib/store/versioned/__init__.py weavestore.py-20050907094258-88262e0434babab9
      bzrlib/tag.py                  tag.py-20070212110532-91cw79inah2cfozx-1
      bzrlib/testament.py            testament.py-20051011100429-6d319a18183b13c8
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_commit.py test_commit.py-20060212094538-ae88fc861d969db0
      bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
      bzrlib/tests/blackbox/test_merge.py test_merge.py-20060323225809-9bc0459c19917f41
      bzrlib/tests/blackbox/test_non_ascii.py test_non_ascii.py-20060105214030-68010be784a5d854
      bzrlib/tests/blackbox/test_status.py teststatus.py-20050712014354-508855eb9f29f7dc
      bzrlib/tests/blackbox/test_version.py test_version.py-20070312060045-ol7th9z035r3im3d-1
      bzrlib/tests/http_server.py    httpserver.py-20061012142527-m1yxdj1xazsf8d7s-1
      bzrlib/tests/http_utils.py     HTTPTestUtil.py-20050914180604-247d3aafb7a43343
      bzrlib/tests/per_repository/test_check_reconcile.py test_broken.py-20070928125406-62236394w0jpbpd6-2
      bzrlib/tests/test_bundle.py    test.py-20050630184834-092aa401ab9f039c
      bzrlib/tests/test_hashcache.py testhashcache.py-20050706091800-0288ab2659338981
      bzrlib/tests/test_http.py      testhttp.py-20051018020158-b2eef6e867c514d9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_msgeditor.py test_msgeditor.py-20051202041359-920315ec6011ee51
      bzrlib/tests/test_options.py   testoptions.py-20051014093702-96457cfc86319a8f
      bzrlib/tests/test_osutils.py   test_osutils.py-20051201224856-e48ee24c12182989
      bzrlib/tests/test_osutils_encodings.py test_osutils_encodin-20061226013130-kkp732tpt3lm91vv-1
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
      bzrlib/tests/test_testament.py testtestament.py-20051011100429-5df1657310caa929
      bzrlib/tests/test_urlutils.py  test_urlutils.py-20060502192900-46b1f9579987cf9c
      bzrlib/tests/test_workingtree.py testworkingtree.py-20051004024258-b88d0fe8f101d468
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/ftp/_gssapi.py _gssapi.py-20080611190840-7ejrtp884bk5eu72-2
      bzrlib/transport/http/__init__.py http_transport.py-20050711212304-506c5fd1059ace96
      bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/tuned_gzip.py           tuned_gzip.py-20060407014720-5aadc518e928e8d2
      bzrlib/util/configobj/configobj.py configobj.py-20051018184548-06992a2246425e3e
      bzrlib/version.py              version.py-20060816024207-ves6ult9a11taj9t-1
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/weave.py                knit.py-20050627021749-759c29984154256b
      bzrlib/win32utils.py           win32console.py-20051021033308-123c6c929d04973d
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      setup.py                       setup.py-20050314065409-02f8a0a6e3f9bc70
    ------------------------------------------------------------
    revno: 3363.17.15
    revision-id: aaron at aaronbentley.com-20080929184621-reu2x9oi16wrahfs
    parent: aaron at aaronbentley.com-20080929184305-1ayhg56t6k943qd6
    committer: Aaron Bentley <aaron at aaronbentley.com>
    branch nick: merge-into
    timestamp: Mon 2008-09-29 14:46:21 -0400
    message:
      Update docs
    modified:
      bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py	2008-09-29 18:43:05 +0000
+++ b/bzrlib/merge.py	2008-10-10 11:55:03 +0000
@@ -55,7 +55,7 @@
 from bzrlib.trace import mutter, warning, note, is_quiet
 from bzrlib.transform import (TransformPreview, TreeTransform,
                               resolve_conflicts, cook_conflicts,
-                              conflict_pass, FinalPaths, create_by_entry,
+                              conflict_pass, FinalPaths, create_from_tree,
                               unique_add, ROOT_PARENT)
 from bzrlib.versionedfile import PlanWeaveMerge
 from bzrlib import ui
@@ -132,15 +132,18 @@
                                       _set_base_is_other_ancestor)
 
     @staticmethod
-    def from_uncommitted(tree, other_tree, pb):
+    def from_uncommitted(tree, other_tree, pb, base_tree=None):
         """Return a Merger for uncommitted changes in other_tree.
 
         :param tree: The tree to merge into
         :param other_tree: The tree to get uncommitted changes from
         :param pb: A progress indicator
+        :param base_tree: The basis to use for the merge.  If unspecified,
+            other_tree.basis_tree() will be used.
         """
-        merger = Merger(tree.branch, other_tree, other_tree.basis_tree(), tree,
-                        pb)
+        if base_tree is None:
+            base_tree = other_tree.basis_tree()
+        merger = Merger(tree.branch, other_tree, base_tree, tree, pb)
         merger.base_rev_id = merger.base_tree.get_revision_id()
         merger.other_rev_id = None
         merger.other_basis = merger.base_rev_id
@@ -176,6 +179,7 @@
                           tree_branch=None):
         """Return a Merger for revision-ids.
 
+        :param pb: A progress indicator
         :param tree: The tree to merge changes into
         :param other: The revision-id to use as OTHER
         :param base: The revision-id to use as BASE.  If not specified, will
@@ -186,7 +190,8 @@
             not supplied, other_branch or tree.branch will be used.
         :param revision_graph: If you have a revision_graph precomputed, pass
             it in, otherwise it will be created for you.
-        :param pb: A progress indicator
+        :param tree_branch: The branch associated with tree.  If not supplied,
+            tree.branch will be used.
         """
         if tree_branch is None:
             tree_branch = tree.branch
@@ -873,9 +878,9 @@
         if self.tt.final_file_id(self.tt.root) is None:
             self.tt.version_file(self.tt.tree_file_id(self.tt.root), 
                                  self.tt.root)
-        if self.other_tree.inventory.root is None:
-            return
         other_root_file_id = self.other_tree.get_root_id()
+        if other_root_file_id is None:
+            return
         other_root = self.tt.trans_id_file_id(other_root_file_id)
         if other_root == self.tt.root:
             return
@@ -1131,9 +1136,8 @@
                     self.tt.delete_contents(trans_id)
                 if file_id in self.other_tree:
                     # OTHER changed the file
-                    create_by_entry(self.tt,
-                                    self.other_tree.inventory[file_id],
-                                    self.other_tree, trans_id)
+                    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"
@@ -1237,13 +1241,12 @@
                     versioned = True
         return file_group
            
-    def _conflict_file(self, name, parent_id, tree, file_id, suffix, 
+    def _conflict_file(self, name, parent_id, tree, file_id, suffix,
                        lines=None):
         """Emit a single conflict file."""
         name = name + '.' + suffix
         trans_id = self.tt.create_path(name, parent_id)
-        entry = tree.inventory[file_id]
-        create_by_entry(self.tt, entry, tree, trans_id, lines)
+        create_from_tree(self.tt, trans_id, tree, file_id, lines)
         return trans_id
 
     def merge_executable(self, file_id, file_status):

=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py	2008-09-22 18:50:38 +0000
+++ b/bzrlib/tests/test_transform.py	2008-10-10 11:55:03 +0000
@@ -53,7 +53,7 @@
                               resolve_conflicts, cook_conflicts, 
                               build_tree, get_backup_name,
                               _FileMover, resolve_checkout,
-                              TransformPreview)
+                              TransformPreview, create_from_tree)
 
 class TestTreeTransform(tests.TestCaseWithTransport):
 
@@ -1313,6 +1313,43 @@
         transform.cancel_creation(trans_id)
         transform.apply()
 
+    def test_create_from_tree(self):
+        tree1 = self.make_branch_and_tree('tree1')
+        self.build_tree_contents([('tree1/foo/',), ('tree1/bar', 'baz')])
+        tree1.add(['foo', 'bar'], ['foo-id', 'bar-id'])
+        tree2 = self.make_branch_and_tree('tree2')
+        tt = TreeTransform(tree2)
+        foo_trans_id = tt.create_path('foo', tt.root)
+        create_from_tree(tt, foo_trans_id, tree1, 'foo-id')
+        bar_trans_id = tt.create_path('bar', tt.root)
+        create_from_tree(tt, bar_trans_id, tree1, 'bar-id')
+        tt.apply()
+        self.assertEqual('directory', osutils.file_kind('tree2/foo'))
+        self.assertFileEqual('baz', 'tree2/bar')
+
+    def test_create_from_tree_bytes(self):
+        """Provided lines are used instead of tree content."""
+        tree1 = self.make_branch_and_tree('tree1')
+        self.build_tree_contents([('tree1/foo', 'bar'),])
+        tree1.add('foo', 'foo-id')
+        tree2 = self.make_branch_and_tree('tree2')
+        tt = TreeTransform(tree2)
+        foo_trans_id = tt.create_path('foo', tt.root)
+        create_from_tree(tt, foo_trans_id, tree1, 'foo-id', bytes='qux')
+        tt.apply()
+        self.assertFileEqual('qux', 'tree2/foo')
+
+    def test_create_from_tree_symlink(self):
+        self.requireFeature(SymlinkFeature)
+        tree1 = self.make_branch_and_tree('tree1')
+        os.symlink('bar', 'tree1/foo')
+        tree1.add('foo', 'foo-id')
+        tt = TreeTransform(self.make_branch_and_tree('tree2'))
+        foo_trans_id = tt.create_path('foo', tt.root)
+        create_from_tree(tt, foo_trans_id, tree1, 'foo-id')
+        tt.apply()
+        self.assertEqual('bar', os.readlink('tree2/foo'))
+
 
 class TransformGroup(object):
 
@@ -2497,3 +2534,43 @@
         self.addCleanup(tt.finalize)
         final_tree = tt.get_preview_tree()
         self.assertEqual('a\nb\nc\n', final_tree.get_file_text('file-id'))
+
+    def test_merge_preview_into_workingtree(self):
+        tree = self.make_branch_and_tree('tree')
+        tt = TransformPreview(tree)
+        self.addCleanup(tt.finalize)
+        tt.new_file('name', tt.root, 'content', 'file-id')
+        tree2 = self.make_branch_and_tree('tree2')
+        pb = progress.DummyProgress()
+        merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
+                                         pb, tree.basis_tree())
+        merger.merge_type = Merge3Merger
+        merger.do_merge()
+
+    def test_merge_preview_into_workingtree_handles_conflicts(self):
+        tree = self.make_branch_and_tree('tree')
+        self.build_tree_contents([('tree/foo', 'bar')])
+        tree.add('foo', 'foo-id')
+        tree.commit('foo')
+        tt = TransformPreview(tree)
+        self.addCleanup(tt.finalize)
+        trans_id = tt.trans_id_file_id('foo-id')
+        tt.delete_contents(trans_id)
+        tt.create_file('baz', trans_id)
+        tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
+        self.build_tree_contents([('tree2/foo', 'qux')])
+        pb = progress.DummyProgress()
+        merger = Merger.from_uncommitted(tree2, tt.get_preview_tree(),
+                                         pb, tree.basis_tree())
+        merger.merge_type = Merge3Merger
+        merger.do_merge()
+
+    def test_is_executable(self):
+        tree = self.make_branch_and_tree('tree')
+        preview = TransformPreview(tree)
+        self.addCleanup(preview.finalize)
+        preview.new_file('foo', preview.root, 'bar', 'baz-id')
+        preview_tree = preview.get_preview_tree()
+        self.assertEqual(False, preview_tree.is_executable('baz-id',
+                                                           'tree/foo'))
+        self.assertEqual(False, preview_tree.is_executable('baz-id'))

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2008-09-08 20:44:53 +0000
+++ b/bzrlib/transform.py	2008-10-14 02:34:56 +0000
@@ -48,6 +48,7 @@
 from bzrlib.progress import DummyProgress, ProgressPhase
 from bzrlib.symbol_versioning import (
         deprecated_function,
+        deprecated_in,
         )
 from bzrlib.trace import mutter, warning
 from bzrlib import tree
@@ -1458,6 +1459,9 @@
         self._final_paths = FinalPaths(transform)
         self.__by_parent = None
         self._parent_ids = []
+        self._all_children_cache = {}
+        self._path2trans_id_cache = {}
+        self._final_name_cache = {}
 
     def _changes(self, file_id):
         for changes in self._transform.iter_changes():
@@ -1550,15 +1554,25 @@
             return self._transform._tree.has_id(file_id)
 
     def _path2trans_id(self, path):
+        # We must not use None here, because that is a valid value to store.
+        trans_id = self._path2trans_id_cache.get(path, object)
+        if trans_id is not object:
+            return trans_id
         segments = splitpath(path)
         cur_parent = self._transform.root
         for cur_segment in segments:
             for child in self._all_children(cur_parent):
-                if self._transform.final_name(child) == cur_segment:
+                final_name = self._final_name_cache.get(child)
+                if final_name is None:
+                    final_name = self._transform.final_name(child)
+                    self._final_name_cache[child] = final_name
+                if final_name == cur_segment:
                     cur_parent = child
                     break
             else:
+                self._path2trans_id_cache[path] = None
                 return None
+        self._path2trans_id_cache[path] = cur_parent
         return cur_parent
 
     def path2id(self, path):
@@ -1572,10 +1586,14 @@
             raise errors.NoSuchId(self, file_id)
 
     def _all_children(self, trans_id):
+        children = self._all_children_cache.get(trans_id)
+        if children is not None:
+            return children
         children = set(self._transform.iter_tree_children(trans_id))
         # children in the _new_parent set are provided by _by_parent.
         children.difference_update(self._transform._new_parent.keys())
         children.update(self._by_parent.get(trans_id, []))
+        self._all_children_cache[trans_id] = children
         return children
 
     def iter_children(self, file_id):
@@ -1690,7 +1708,14 @@
         try:
             return self._transform._new_executability[trans_id]
         except KeyError:
-            return self._transform._tree.is_executable(file_id, path)
+            try:
+                return self._transform._tree.is_executable(file_id, path)
+            except OSError, e:
+                if e.errno == errno.ENOENT:
+                    return False
+                raise
+            except errors.NoSuchId:
+                return False
 
     def path_content_summary(self, path):
         trans_id = self._path2trans_id(path)
@@ -2140,8 +2165,12 @@
         raise errors.BadFileKindError(name, kind)
 
 
+ at deprecated_function(deprecated_in((1, 9, 0)))
 def create_by_entry(tt, entry, tree, trans_id, lines=None, mode_id=None):
-    """Create new file contents according to an inventory entry."""
+    """Create new file contents according to an inventory entry.
+
+    DEPRECATED.  Use create_from_tree instead.
+    """
     if entry.kind == "file":
         if lines is None:
             lines = tree.get_file(entry.file_id).readlines()
@@ -2152,6 +2181,25 @@
         tt.create_directory(trans_id)
 
 
+def create_from_tree(tt, trans_id, tree, file_id, bytes=None):
+    """Create new file contents according to tree contents."""
+    kind = tree.kind(file_id)
+    if kind == 'directory':
+        tt.create_directory(trans_id)
+    elif kind == "file":
+        if bytes is None:
+            tree_file = tree.get_file(file_id)
+            try:
+                bytes = tree_file.readlines()
+            finally:
+                tree_file.close()
+        tt.create_file(bytes, trans_id)
+    elif kind == "symlink":
+        tt.create_symlink(tree.get_symlink_target(file_id), trans_id)
+    else:
+        raise AssertionError('Unknown kind %r' % kind)
+
+
 def create_entry_executability(tt, entry, trans_id):
     """Set the executability of a trans_id according to an inventory entry"""
     if entry.kind == "file":




More information about the bazaar-commits mailing list