~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-08-29 01:46:49 UTC
  • mfrom: (3363.10.29 preview-post)
  • Revision ID: pqm@pqm.ubuntu.com-20080829014649-2xy77164nvtxzl9y
Test interface of PreviewTree in the post-change state (abentley)

Show diffs side-by-side

added added

removed removed

Lines of Context:
129
129
        # Cache of relpath results, to speed up canonical_path
130
130
        self._relpaths = {}
131
131
        # The trans_id that will be used as the tree root
132
 
        self._new_root = self.trans_id_tree_file_id(tree.get_root_id())
 
132
        root_id = tree.get_root_id()
 
133
        if root_id is not None:
 
134
            self._new_root = self.trans_id_tree_file_id(root_id)
 
135
        else:
 
136
            self._new_root = None
133
137
        # Indictor of whether the transform has been applied
134
138
        self._done = False
135
139
        # A progress bar
196
200
        previous_name = self._new_name.get(trans_id)
197
201
        self._new_name[trans_id] = name
198
202
        self._new_parent[trans_id] = parent
 
203
        if parent == ROOT_PARENT:
 
204
            if self._new_root is not None:
 
205
                raise ValueError("Cannot have multiple roots.")
 
206
            self._new_root = trans_id
199
207
        if (trans_id in self._limbo_files and
200
208
            trans_id not in self._needs_rename):
201
209
            self._rename_in_limbo([trans_id])
258
266
        This reflects only files that already exist, not ones that will be
259
267
        added by transactions.
260
268
        """
 
269
        if inventory_id is None:
 
270
            raise ValueError('None is not a valid file id')
261
271
        path = self._tree.id2path(inventory_id)
262
272
        return self.trans_id_tree_path(path)
263
273
 
267
277
        a transaction has been unversioned, it is deliberately still returned.
268
278
        (this will likely lead to an unversioned parent conflict.)
269
279
        """
 
280
        if file_id is None:
 
281
            raise ValueError('None is not a valid file id')
270
282
        if file_id in self._r_new_id and self._r_new_id[file_id] is not None:
271
283
            return self._r_new_id[file_id]
272
284
        elif file_id in self._tree.inventory:
1526
1538
        for (file_id, paths, changed, versioned, parent, name, kind,
1527
1539
             executable) in self._transform.iter_changes():
1528
1540
            if paths[1] in to_find:
1529
 
                result.append(file_id)
 
1541
                result.add(file_id)
1530
1542
                to_find.remove(paths[1])
1531
1543
        result.update(self._transform._tree.paths2ids(to_find,
1532
1544
                      trees=[], require_versioned=require_versioned))
1579
1591
                parent_file_id, file_id)
1580
1592
            yield new_entry, trans_id
1581
1593
 
1582
 
    def iter_entries_by_dir(self, specific_file_ids=None):
1583
 
        # This may not be a maximally efficient implementation, but it is
1584
 
        # reasonably straightforward.  An implementation that grafts the
1585
 
        # TreeTransform changes onto the tree's iter_entries_by_dir results
1586
 
        # might be more efficient, but requires tricky inferences about stack
1587
 
        # position.
 
1594
    def _list_files_by_dir(self):
1588
1595
        todo = [ROOT_PARENT]
1589
1596
        ordered_ids = []
1590
1597
        while len(todo) > 0:
1596
1603
            todo.extend(reversed(children))
1597
1604
            for trans_id in children:
1598
1605
                ordered_ids.append((trans_id, parent_file_id))
 
1606
        return ordered_ids
 
1607
 
 
1608
    def iter_entries_by_dir(self, specific_file_ids=None):
 
1609
        # This may not be a maximally efficient implementation, but it is
 
1610
        # reasonably straightforward.  An implementation that grafts the
 
1611
        # TreeTransform changes onto the tree's iter_entries_by_dir results
 
1612
        # might be more efficient, but requires tricky inferences about stack
 
1613
        # position.
 
1614
        ordered_ids = self._list_files_by_dir()
1599
1615
        for entry, trans_id in self._make_inv_entries(ordered_ids,
1600
1616
                                                      specific_file_ids):
1601
1617
            yield unicode(self._final_paths.get_path(trans_id)), entry
1602
1618
 
 
1619
    def list_files(self, include_root=False):
 
1620
        """See Tree.list_files."""
 
1621
        # XXX This should behave like WorkingTree.list_files, but is really
 
1622
        # more like RevisionTree.list_files.
 
1623
        for path, entry in self.iter_entries_by_dir():
 
1624
            if entry.name == '' and not include_root:
 
1625
                continue
 
1626
            yield path, 'V', entry.kind, entry.file_id, entry
 
1627
 
1603
1628
    def kind(self, file_id):
1604
1629
        trans_id = self._transform.trans_id_file_id(file_id)
1605
1630
        return self._transform.final_kind(trans_id)
1731
1756
        name = self._transform._limbo_name(trans_id)
1732
1757
        return os.readlink(name)
1733
1758
 
1734
 
    def list_files(self, include_root=False):
1735
 
        return self._transform._tree.list_files(include_root)
1736
 
 
1737
1759
    def walkdirs(self, prefix=''):
1738
1760
        pending = [self._transform.root]
1739
1761
        while len(pending) > 0:
2147
2169
    tt = TreeTransform(working_tree, pb)
2148
2170
    try:
2149
2171
        pp = ProgressPhase("Revert phase", 3, pb)
2150
 
        pp.next_phase()
2151
 
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
2152
 
        try:
2153
 
            merge_modified = _alter_files(working_tree, target_tree, tt,
2154
 
                                          child_pb, filenames, backups)
2155
 
        finally:
2156
 
            child_pb.finished()
2157
 
        pp.next_phase()
2158
 
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
2159
 
        try:
2160
 
            raw_conflicts = resolve_conflicts(tt, child_pb,
2161
 
                lambda t, c: conflict_pass(t, c, target_tree))
2162
 
        finally:
2163
 
            child_pb.finished()
2164
 
        conflicts = cook_conflicts(raw_conflicts, tt)
 
2172
        conflicts, merge_modified = _prepare_revert_transform(
 
2173
            working_tree, target_tree, tt, filenames, backups, pp)
2165
2174
        if change_reporter:
2166
2175
            change_reporter = delta._ChangeReporter(
2167
2176
                unversioned_filter=working_tree.is_ignored)
2178
2187
    return conflicts
2179
2188
 
2180
2189
 
 
2190
def _prepare_revert_transform(working_tree, target_tree, tt, filenames,
 
2191
                              backups, pp, basis_tree=None,
 
2192
                              merge_modified=None):
 
2193
    pp.next_phase()
 
2194
    child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
2195
    try:
 
2196
        if merge_modified is None:
 
2197
            merge_modified = working_tree.merge_modified()
 
2198
        merge_modified = _alter_files(working_tree, target_tree, tt,
 
2199
                                      child_pb, filenames, backups,
 
2200
                                      merge_modified, basis_tree)
 
2201
    finally:
 
2202
        child_pb.finished()
 
2203
    pp.next_phase()
 
2204
    child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
2205
    try:
 
2206
        raw_conflicts = resolve_conflicts(tt, child_pb,
 
2207
            lambda t, c: conflict_pass(t, c, target_tree))
 
2208
    finally:
 
2209
        child_pb.finished()
 
2210
    conflicts = cook_conflicts(raw_conflicts, tt)
 
2211
    return conflicts, merge_modified
 
2212
 
 
2213
 
2181
2214
def _alter_files(working_tree, target_tree, tt, pb, specific_files,
2182
 
                 backups):
2183
 
    merge_modified = working_tree.merge_modified()
 
2215
                 backups, merge_modified, basis_tree=None):
 
2216
    if basis_tree is not None:
 
2217
        basis_tree.lock_read()
2184
2218
    change_list = target_tree.iter_changes(working_tree,
2185
2219
        specific_files=specific_files, pb=pb)
2186
 
    if target_tree.inventory.root is None:
 
2220
    if target_tree.get_root_id() is None:
2187
2221
        skip_root = True
2188
2222
    else:
2189
2223
        skip_root = False
2190
 
    basis_tree = None
2191
2224
    try:
2192
2225
        deferred_files = []
2193
2226
        for id_num, (file_id, path, changed_content, versioned, parent, name,
2229
2262
                        # contents
2230
2263
                        mode_id = trans_id
2231
2264
                        trans_id = new_trans_id
2232
 
                if kind[1] == 'directory':
 
2265
                if kind[1] in ('directory', 'tree-reference'):
2233
2266
                    tt.create_directory(trans_id)
 
2267
                    if kind[1] == 'tree-reference':
 
2268
                        revision = target_tree.get_reference_revision(file_id,
 
2269
                                                                      path[1])
 
2270
                        tt.set_tree_reference(revision, trans_id)
2234
2271
                elif kind[1] == 'symlink':
2235
2272
                    tt.create_symlink(target_tree.get_symlink_target(file_id),
2236
2273
                                      trans_id)
2256
2293
                tt.version_file(file_id, trans_id)
2257
2294
            if versioned == (True, False):
2258
2295
                tt.unversion_file(trans_id)
2259
 
            if (name[1] is not None and 
 
2296
            if (name[1] is not None and
2260
2297
                (name[0] != name[1] or parent[0] != parent[1])):
2261
 
                tt.adjust_path(
2262
 
                    name[1], tt.trans_id_file_id(parent[1]), trans_id)
 
2298
                if name[1] == '' and parent[1] is None:
 
2299
                    parent_trans = ROOT_PARENT
 
2300
                else:
 
2301
                    parent_trans = tt.trans_id_file_id(parent[1])
 
2302
                tt.adjust_path(name[1], parent_trans, trans_id)
2263
2303
            if executable[0] != executable[1] and kind[1] == "file":
2264
2304
                tt.set_executability(executable[1], trans_id)
2265
2305
        for (trans_id, mode_id), bytes in target_tree.iter_files_bytes(
2373
2413
            if parent_file_id is not None:
2374
2414
                tt.unversion_file(parent_id)
2375
2415
            new_conflicts.add((c_type, 'Created directory', new_parent_id))
 
2416
        elif c_type == 'versioning no contents':
 
2417
            tt.cancel_versioning(conflict[1])
2376
2418
    return new_conflicts
2377
2419
 
2378
2420