/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/transform.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-11 04:08:32 UTC
  • mto: (7143.16.20 even-more-cleanups)
  • mto: This revision was merged to the branch mainline in revision 7175.
  • Revision ID: jelmer@jelmer.uk-20181111040832-nsljjynzzwmznf3h
Run autopep8.

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
 
78
78
ROOT_PARENT = "root-parent"
79
79
 
 
80
 
80
81
def unique_add(map, key, value):
81
82
    if key in map:
82
83
        raise DuplicateKey(key=key)
83
84
    map[key] = value
84
85
 
85
86
 
86
 
 
87
87
class _TransformResults(object):
88
88
    def __init__(self, modified_paths, rename_count):
89
89
        object.__init__(self)
175
175
    def _assign_id(self):
176
176
        """Produce a new tranform id"""
177
177
        new_id = "new-%s" % self._id_number
178
 
        self._id_number +=1
 
178
        self._id_number += 1
179
179
        return new_id
180
180
 
181
181
    def create_path(self, name, parent):
259
259
            self.unversion_file(old_new_root)
260
260
        # if, at this stage, root still has an old file_id, zap it so we can
261
261
        # stick a new one in.
262
 
        if (self.tree_file_id(self._new_root) is not None and
263
 
            self._new_root not in self._removed_id):
 
262
        if (self.tree_file_id(self._new_root) is not None
 
263
                and self._new_root not in self._removed_id):
264
264
            self.unversion_file(self._new_root)
265
265
        if file_id is not None:
266
266
            self.version_file(file_id, self._new_root)
512
512
        by_parent = {}
513
513
        items = list(viewitems(self._new_parent))
514
514
        items.extend((t, self.final_parent(t))
515
 
            for t in list(self._tree_id_paths))
 
515
                     for t in list(self._tree_id_paths))
516
516
        for trans_id, parent_id in items:
517
517
            if parent_id not in by_parent:
518
518
                by_parent[parent_id] = set()
643
643
            for child_id in children:
644
644
                if self.final_file_id(child_id) is not None:
645
645
                    conflicts.append(('unversioned parent', parent_id))
646
 
                    break;
 
646
                    break
647
647
        return conflicts
648
648
 
649
649
    def _improper_versioning(self):
686
686
                continue
687
687
            if trans_id not in self._removed_contents:
688
688
                conflicts.append(('overwrite', trans_id,
689
 
                                 self.final_name(trans_id)))
 
689
                                  self.final_name(trans_id)))
690
690
        return conflicts
691
691
 
692
692
    def _duplicate_entries(self, by_parent):
713
713
                    continue
714
714
                if name == last_name:
715
715
                    conflicts.append(('duplicate', last_trans_id, trans_id,
716
 
                    name))
 
716
                                      name))
717
717
                last_name = name
718
718
                last_trans_id = trans_id
719
719
        return conflicts
903
903
        if from_versioned:
904
904
            # get data from working tree if versioned
905
905
            from_entry = next(self._tree.iter_entries_by_dir(
906
 
                    specific_files=[from_path]))[1]
 
906
                specific_files=[from_path]))[1]
907
907
            from_name = from_entry.name
908
908
            from_parent = from_entry.parent_id
909
909
        else:
990
990
            if from_kind != to_kind:
991
991
                modified = True
992
992
            elif to_kind in ('file', 'symlink') and (
993
 
                to_trans_id != from_trans_id or
994
 
                to_trans_id in self._new_contents):
 
993
                    to_trans_id != from_trans_id
 
994
                    or to_trans_id in self._new_contents):
995
995
                modified = True
996
 
            if (not modified and from_versioned == to_versioned and
997
 
                from_parent==to_parent and from_name == to_name and
998
 
                from_executable == to_executable):
 
996
            if (not modified and from_versioned == to_versioned
 
997
                and from_parent == to_parent and from_name == to_name
 
998
                    and from_executable == to_executable):
999
999
                continue
1000
1000
            results.append((file_id, (from_path, to_path), modified,
1001
 
                   (from_versioned, to_versioned),
1002
 
                   (from_parent, to_parent),
1003
 
                   (from_name, to_name),
1004
 
                   (from_kind, to_kind),
1005
 
                   (from_executable, to_executable)))
 
1001
                            (from_versioned, to_versioned),
 
1002
                            (from_parent, to_parent),
 
1003
                            (from_name, to_name),
 
1004
                            (from_kind, to_kind),
 
1005
                            (from_executable, to_executable)))
1006
1006
 
1007
1007
        def path_key(t):
1008
1008
            paths = t[1]
1146
1146
                if not isinstance(content, bytes):
1147
1147
                    content = content.encode('utf-8')
1148
1148
            yield serializer.bytes_record(
1149
 
                    content, ((trans_id.encode('utf-8'), kind.encode('ascii')),))
 
1149
                content, ((trans_id.encode('utf-8'), kind.encode('ascii')),))
1150
1150
 
1151
1151
    def deserialize(self, records):
1152
1152
        """Deserialize a stored TreeTransform.
1162
1162
        self._new_parent = {k.decode('utf-8'): v.decode('utf-8')
1163
1163
                            for k, v in viewitems(attribs[b'_new_parent'])}
1164
1164
        self._new_executability = {k.decode('utf-8'): bool(v)
1165
 
            for k, v in viewitems(attribs[b'_new_executability'])}
 
1165
                                   for k, v in viewitems(attribs[b'_new_executability'])}
1166
1166
        self._new_id = {k.decode('utf-8'): v
1167
1167
                        for k, v in viewitems(attribs[b'_new_id'])}
1168
1168
        self._r_new_id = {v: k for k, v in viewitems(self._new_id)}
1281
1281
        previous_parent = self._new_parent.get(trans_id)
1282
1282
        previous_name = self._new_name.get(trans_id)
1283
1283
        TreeTransformBase.adjust_path(self, name, parent, trans_id)
1284
 
        if (trans_id in self._limbo_files and
1285
 
            trans_id not in self._needs_rename):
 
1284
        if (trans_id in self._limbo_files
 
1285
                and trans_id not in self._needs_rename):
1286
1286
            self._rename_in_limbo([trans_id])
1287
1287
            if previous_parent != parent:
1288
1288
                self._limbo_children[previous_parent].remove(trans_id)
1556
1556
    FileMover does not delete files until it is sure that a rollback will not
1557
1557
    happen.
1558
1558
    """
 
1559
 
1559
1560
    def __init__(self, tree, pb=None):
1560
1561
        """Note: a tree_write lock is taken on the tree.
1561
1562
 
1653
1654
        try:
1654
1655
            children = os.listdir(self._tree.abspath(path))
1655
1656
        except OSError as e:
1656
 
            if not (osutils._is_error_enotdir(e)
1657
 
                    or e.errno in (errno.ENOENT, errno.ESRCH)):
 
1657
            if not (osutils._is_error_enotdir(e) or
 
1658
                    e.errno in (errno.ENOENT, errno.ESRCH)):
1658
1659
                raise
1659
1660
            return
1660
1661
 
1691
1692
                # if it is already associated with this trans_id.
1692
1693
                elif self._case_sensitive_target:
1693
1694
                    if (self._limbo_children_names[parent].get(filename)
1694
 
                        in (trans_id, None)):
 
1695
                            in (trans_id, None)):
1695
1696
                        use_direct_path = True
1696
1697
                else:
1697
1698
                    for l_filename, l_trans_id in viewitems(
1767
1768
        with ui.ui_factory.nested_progress_bar() as child_pb:
1768
1769
            for num, trans_id in enumerate(self._removed_id):
1769
1770
                if (num % 10) == 0:
1770
 
                    child_pb.update(gettext('removing file'), num, total_entries)
 
1771
                    child_pb.update(gettext('removing file'),
 
1772
                                    num, total_entries)
1771
1773
                if trans_id == self._new_root:
1772
1774
                    file_id = self._tree.get_root_id()
1773
1775
                else:
1791
1793
                kind = self.final_kind(trans_id)
1792
1794
                if kind is None:
1793
1795
                    kind = self._tree.stored_kind(
1794
 
                            self._tree.id2path(file_id), file_id)
 
1796
                        self._tree.id2path(file_id), file_id)
1795
1797
                parent_trans_id = self.final_parent(trans_id)
1796
1798
                parent_file_id = new_path_file_ids.get(parent_trans_id)
1797
1799
                if parent_file_id is None:
1804
1806
                        None, self._new_reference_revision[trans_id])
1805
1807
                else:
1806
1808
                    new_entry = inventory.make_entry(kind,
1807
 
                        self.final_name(trans_id),
1808
 
                        parent_file_id, file_id)
 
1809
                                                     self.final_name(trans_id),
 
1810
                                                     parent_file_id, file_id)
1809
1811
                try:
1810
1812
                    old_path = self._tree.id2path(new_entry.file_id)
1811
1813
                except errors.NoSuchId:
1837
1839
                if trans_id in self._removed_contents:
1838
1840
                    delete_path = os.path.join(self._deletiondir, trans_id)
1839
1841
                    mover.pre_delete(full_path, delete_path)
1840
 
                elif (trans_id in self._new_name
1841
 
                      or trans_id in self._new_parent):
 
1842
                elif (trans_id in self._new_name or
 
1843
                      trans_id in self._new_parent):
1842
1844
                    try:
1843
1845
                        mover.rename(full_path, self._limbo_name(trans_id))
1844
1846
                    except errors.TransformRenameFailed as e:
1864
1866
        with ui.ui_factory.nested_progress_bar() as child_pb:
1865
1867
            for num, (path, trans_id) in enumerate(new_paths):
1866
1868
                if (num % 10) == 0:
1867
 
                    child_pb.update(gettext('adding file'), num, len(new_paths))
 
1869
                    child_pb.update(gettext('adding file'),
 
1870
                                    num, len(new_paths))
1868
1871
                full_path = self._tree.abspath(path)
1869
1872
                if trans_id in self._needs_rename:
1870
1873
                    try:
1878
1881
                    # TODO: if trans_id in self._observed_sha1s, we should
1879
1882
                    #       re-stat the final target, since ctime will be
1880
1883
                    #       updated by the change.
1881
 
                if (trans_id in self._new_contents or
1882
 
                    self.path_changed(trans_id)):
 
1884
                if (trans_id in self._new_contents
 
1885
                        or self.path_changed(trans_id)):
1883
1886
                    if trans_id in self._new_contents:
1884
1887
                        modified_paths.append(full_path)
1885
1888
                if trans_id in self._new_executability:
1962
1965
            return
1963
1966
        try:
1964
1967
            entry = next(self._tree.iter_entries_by_dir(
1965
 
                    specific_files=[path]))[1]
 
1968
                specific_files=[path]))[1]
1966
1969
        except StopIteration:
1967
1970
            return
1968
1971
        children = getattr(entry, 'children', {})
2010
2013
 
2011
2014
    def _get_file_revision(self, path, file_id, vf, tree_revision):
2012
2015
        parent_keys = [
2013
 
                (file_id, t.get_file_revision(t.id2path(file_id), file_id))
2014
 
                for t in self._iter_parent_trees()]
 
2016
            (file_id, t.get_file_revision(t.id2path(file_id), file_id))
 
2017
            for t in self._iter_parent_trees()]
2015
2018
        vf.add_lines((file_id, tree_revision), parent_keys,
2016
2019
                     self.get_file_lines(path, file_id))
2017
2020
        repo = self._get_repository()
2072
2075
        if file_id in self._transform._r_new_id:
2073
2076
            return True
2074
2077
        elif file_id in {self._transform.tree_file_id(trans_id) for
2075
 
            trans_id in self._transform._removed_id}:
 
2078
                         trans_id in self._transform._removed_id}:
2076
2079
            return False
2077
2080
        else:
2078
2081
            return fallback_check(file_id)
2149
2152
            file_id = self._transform.final_file_id(trans_id)
2150
2153
            if file_id is None:
2151
2154
                continue
2152
 
            if (specific_files is not None and
2153
 
                self._final_paths.get_path(trans_id) not in specific_files):
 
2155
            if (specific_files is not None
 
2156
                    and self._final_paths.get_path(trans_id) not in specific_files):
2154
2157
                continue
2155
2158
            kind = self._transform.final_kind(trans_id)
2156
2159
            if kind is None:
2194
2197
        # position.
2195
2198
        ordered_ids = self._list_files_by_dir()
2196
2199
        for entry, trans_id in self._make_inv_entries(ordered_ids,
2197
 
            specific_files):
 
2200
                                                      specific_files):
2198
2201
            yield self._final_paths.get_path(trans_id), entry
2199
2202
 
2200
2203
    def _iter_entries_for_dir(self, dir_path):
2230
2233
        else:
2231
2234
            if from_dir is None and include_root is True:
2232
2235
                root_entry = inventory.make_entry('directory', '',
2233
 
                    ROOT_PARENT, self.get_root_id())
 
2236
                                                  ROOT_PARENT, self.get_root_id())
2234
2237
                yield '', 'V', 'directory', root_entry.file_id, root_entry
2235
2238
            entries = self._iter_entries_for_dir(from_dir or '')
2236
2239
            for path, entry in entries:
2259
2262
            raise errors.NoSuchFile(path)
2260
2263
        if not self._content_change(file_id):
2261
2264
            return self._transform._tree.get_file_mtime(
2262
 
                    self._transform._tree.id2path(file_id), file_id)
 
2265
                self._transform._tree.id2path(file_id), file_id)
2263
2266
        trans_id = self._path2trans_id(path)
2264
2267
        return self._stat_limbo_file(trans_id).st_mtime
2265
2268
 
2358
2361
        return kind, size, executable, link_or_sha1
2359
2362
 
2360
2363
    def iter_changes(self, from_tree, include_unchanged=False,
2361
 
                      specific_files=None, pb=None, extra_trees=None,
2362
 
                      require_versioned=True, want_unversioned=False):
 
2364
                     specific_files=None, pb=None, extra_trees=None,
 
2365
                     require_versioned=True, want_unversioned=False):
2363
2366
        """See InterTree.iter_changes.
2364
2367
 
2365
2368
        This has a fast path that is only used when the from_tree matches
2366
2369
        the transform tree, and no fancy options are supplied.
2367
2370
        """
2368
 
        if (from_tree is not self._transform._tree or include_unchanged or
2369
 
            specific_files or want_unversioned):
 
2371
        if (from_tree is not self._transform._tree or include_unchanged
 
2372
                or specific_files or want_unversioned):
2370
2373
            return tree.InterTree(from_tree, self).iter_changes(
2371
2374
                include_unchanged=include_unchanged,
2372
2375
                specific_files=specific_files,
2406
2409
            get_old = (kind[0] == 'file' and versioned[0])
2407
2410
        if get_old:
2408
2411
            old_annotation = self._transform._tree.annotate_iter(
2409
 
                    path, file_id=file_id, default_revision=default_revision)
 
2412
                path, file_id=file_id, default_revision=default_revision)
2410
2413
        else:
2411
2414
            old_annotation = []
2412
2415
        if changes is None:
2447
2450
                path_from_root = self._final_paths.get_path(child_id)
2448
2451
                basename = self._transform.final_name(child_id)
2449
2452
                file_id = self._transform.final_file_id(child_id)
2450
 
                kind  = self._transform.final_kind(child_id)
 
2453
                kind = self._transform.final_kind(child_id)
2451
2454
                if kind is not None:
2452
2455
                    versioned_kind = kind
2453
2456
                else:
2454
2457
                    kind = 'unknown'
2455
2458
                    versioned_kind = self._transform._tree.stored_kind(
2456
 
                            self._transform._tree.id2path(file_id),
2457
 
                            file_id)
 
2459
                        self._transform._tree.id2path(file_id),
 
2460
                        file_id)
2458
2461
                if versioned_kind == 'directory':
2459
2462
                    subdirs.append(child_id)
2460
2463
                children.append((path_from_root, basename, kind, None,
2489
2492
    The underlying tree must not be manipulated between calls, or else
2490
2493
    the results will likely be incorrect.
2491
2494
    """
 
2495
 
2492
2496
    def __init__(self, transform):
2493
2497
        object.__init__(self)
2494
2498
        self._known_paths = {}
2514
2518
        return [(self.get_path(t), t) for t in trans_ids]
2515
2519
 
2516
2520
 
2517
 
 
2518
2521
def topology_sorted_ids(tree):
2519
2522
    """Determine the topological order of the ids in a tree"""
2520
2523
    file_ids = list(tree)
2601
2604
                for dir, files in wt.walkdirs():
2602
2605
                    existing_files.update(f[0] for f in files)
2603
2606
            for num, (tree_path, entry) in \
2604
 
                enumerate(tree.iter_entries_by_dir()):
2605
 
                pb.update(gettext("Building tree"), num - len(deferred_contents), total)
 
2607
                    enumerate(tree.iter_entries_by_dir()):
 
2608
                pb.update(gettext("Building tree"), num
 
2609
                          - len(deferred_contents), total)
2606
2610
                if entry.parent_id is None:
2607
2611
                    continue
2608
2612
                reparent = False
2619
2623
                            pass
2620
2624
                        else:
2621
2625
                            divert.add(file_id)
2622
 
                    if (file_id not in divert and
2623
 
                        _content_match(tree, entry, tree_path, file_id, kind,
2624
 
                        target_path)):
 
2626
                    if (file_id not in divert
 
2627
                        and _content_match(tree, entry, tree_path, file_id, kind,
 
2628
                                       target_path)):
2625
2629
                        tt.delete_contents(tt.trans_id_tree_path(tree_path))
2626
2630
                        if kind == 'directory':
2627
2631
                            reparent = True
2635
2639
                    executable = tree.is_executable(tree_path, file_id)
2636
2640
                    if executable:
2637
2641
                        tt.set_executability(executable, trans_id)
2638
 
                    trans_data = (trans_id, file_id, tree_path, entry.text_sha1)
 
2642
                    trans_data = (trans_id, file_id,
 
2643
                                  tree_path, entry.text_sha1)
2639
2644
                    deferred_contents.append((tree_path, trans_data))
2640
2645
                else:
2641
2646
                    file_trans_id[file_id] = new_by_entry(
2642
 
                            tree_path, tt, entry, parent_id, tree)
 
2647
                        tree_path, tt, entry, parent_id, tree)
2643
2648
                if reparent:
2644
2649
                    new_trans_id = file_trans_id[file_id]
2645
2650
                    old_parent = tt.trans_id_tree_path(tree_path)
2649
2654
                          accelerator_tree, hardlink)
2650
2655
        pp.next_phase()
2651
2656
        divert_trans = set(file_trans_id[f] for f in divert)
2652
 
        resolver = lambda t, c: resolve_checkout(t, c, divert_trans)
 
2657
 
 
2658
        def resolver(t, c): return resolve_checkout(t, c, divert_trans)
2653
2659
        raw_conflicts = resolve_conflicts(tt, pass_func=resolver)
2654
2660
        if len(raw_conflicts) > 0:
2655
2661
            precomputed_delta = None
2688
2694
            accelerator_path = unchanged.get(tree_path)
2689
2695
            if accelerator_path is None:
2690
2696
                new_desired_files.append((tree_path,
2691
 
                    (trans_id, file_id, tree_path, text_sha1)))
 
2697
                                          (trans_id, file_id, tree_path, text_sha1)))
2692
2698
                continue
2693
2699
            pb.update(gettext('Adding file contents'), count + offset, total)
2694
2700
            if hardlink:
2700
2706
                    if wt.supports_content_filtering():
2701
2707
                        filters = wt._content_filter_stack(tree_path)
2702
2708
                        chunks = filtered_output_bytes(chunks, filters,
2703
 
                            ContentFilterContext(tree_path, tree))
 
2709
                                                       ContentFilterContext(tree_path, tree))
2704
2710
                    tt.create_file(chunks, trans_id, sha1=text_sha1)
2705
2711
            count += 1
2706
2712
        offset += count
2709
2715
        if wt.supports_content_filtering():
2710
2716
            filters = wt._content_filter_stack(tree_path)
2711
2717
            contents = filtered_output_bytes(contents, filters,
2712
 
                ContentFilterContext(tree_path, tree))
 
2718
                                             ContentFilterContext(tree_path, tree))
2713
2719
        tt.create_file(contents, trans_id, sha1=text_sha1)
2714
2720
        pb.update(gettext('Adding file contents'), count + offset, total)
2715
2721
 
2733
2739
        return True
2734
2740
    if entry.kind == "file":
2735
2741
        with open(target_path, 'rb') as f1, \
2736
 
             tree.get_file(tree_path, file_id) as f2:
 
2742
                tree.get_file(tree_path, file_id) as f2:
2737
2743
            if osutils.compare_files(f1, f2):
2738
2744
                return True
2739
2745
    elif entry.kind == "symlink":
2760
2766
        # resolved
2761
2767
        final_parent = tt.final_parent(old_file)
2762
2768
        if new_file in divert:
2763
 
            new_name = tt.final_name(old_file)+'.diverted'
 
2769
            new_name = tt.final_name(old_file) + '.diverted'
2764
2770
            tt.adjust_path(new_name, final_parent, new_file)
2765
2771
            new_conflicts.add((c_type, 'Diverted to',
2766
2772
                               new_file, old_file))
2767
2773
        else:
2768
 
            new_name = tt.final_name(old_file)+'.moved'
 
2774
            new_name = tt.final_name(old_file) + '.moved'
2769
2775
            tt.adjust_path(new_name, final_parent, old_file)
2770
2776
            new_conflicts.add((c_type, 'Moved existing file to',
2771
2777
                               old_file, new_file))
2780
2786
        with tree.get_file(path, entry.file_id) as f:
2781
2787
            executable = tree.is_executable(path, entry.file_id)
2782
2788
            return tt.new_file(
2783
 
                    name, parent_id, osutils.file_iterator(f), entry.file_id,
2784
 
                    executable)
 
2789
                name, parent_id, osutils.file_iterator(f), entry.file_id,
 
2790
                executable)
2785
2791
    elif kind in ('directory', 'tree-reference'):
2786
2792
        trans_id = tt.new_directory(name, parent_id, entry.file_id)
2787
2793
        if kind == 'tree-reference':
2795
2801
 
2796
2802
 
2797
2803
def create_from_tree(tt, trans_id, tree, path, file_id=None, chunks=None,
2798
 
    filter_tree_path=None):
 
2804
                     filter_tree_path=None):
2799
2805
    """Create new file contents according to tree contents.
2800
2806
 
2801
2807
    :param filter_tree_path: the tree path to use to lookup
2816
2822
            if wt.supports_content_filtering() and filter_tree_path is not None:
2817
2823
                filters = wt._content_filter_stack(filter_tree_path)
2818
2824
                chunks = filtered_output_bytes(chunks, filters,
2819
 
                    ContentFilterContext(filter_tree_path, tree))
 
2825
                                               ContentFilterContext(filter_tree_path, tree))
2820
2826
            tt.create_file(chunks, trans_id)
2821
2827
        finally:
2822
2828
            if f is not None:
2868
2874
                                      merge_modified, basis_tree)
2869
2875
    with ui.ui_factory.nested_progress_bar() as child_pb:
2870
2876
        raw_conflicts = resolve_conflicts(tt, child_pb,
2871
 
            lambda t, c: conflict_pass(t, c, target_tree))
 
2877
                                          lambda t, c: conflict_pass(t, c, target_tree))
2872
2878
    conflicts = cook_conflicts(raw_conflicts, tt)
2873
2879
    return conflicts, merge_modified
2874
2880
 
2882
2888
    # optimizer to compare itself to a target, but no optimizer for the
2883
2889
    # reverse.
2884
2890
    change_list = working_tree.iter_changes(target_tree,
2885
 
        specific_files=specific_files, pb=pb)
 
2891
                                            specific_files=specific_files, pb=pb)
2886
2892
    if not target_tree.is_versioned(u''):
2887
2893
        skip_root = True
2888
2894
    else:
2890
2896
    try:
2891
2897
        deferred_files = []
2892
2898
        for id_num, (file_id, path, changed_content, versioned, parent, name,
2893
 
                kind, executable) in enumerate(change_list):
 
2899
                     kind, executable) in enumerate(change_list):
2894
2900
            target_path, wt_path = path
2895
2901
            target_versioned, wt_versioned = versioned
2896
2902
            target_parent, wt_parent = parent
2912
2918
                        if basis_tree is None:
2913
2919
                            basis_tree = working_tree.basis_tree()
2914
2920
                            basis_tree.lock_read()
2915
 
                        basis_path = find_previous_path(working_tree, basis_tree, wt_path)
 
2921
                        basis_path = find_previous_path(
 
2922
                            working_tree, basis_tree, wt_path)
2916
2923
                        if basis_path is None:
2917
2924
                            if target_kind is None and not target_versioned:
2918
2925
                                keep_content = True
2939
2946
                    tt.create_directory(trans_id)
2940
2947
                    if target_kind == 'tree-reference':
2941
2948
                        revision = target_tree.get_reference_revision(
2942
 
                                target_path, file_id)
 
2949
                            target_path, file_id)
2943
2950
                        tt.set_tree_reference(revision, trans_id)
2944
2951
                elif target_kind == 'symlink':
2945
2952
                    tt.create_symlink(target_tree.get_symlink_target(
2946
 
                            target_path, file_id), trans_id)
 
2953
                        target_path, file_id), trans_id)
2947
2954
                elif target_kind == 'file':
2948
 
                    deferred_files.append((target_path, (trans_id, mode_id, file_id)))
 
2955
                    deferred_files.append(
 
2956
                        (target_path, (trans_id, mode_id, file_id)))
2949
2957
                    if basis_tree is None:
2950
2958
                        basis_tree = working_tree.basis_tree()
2951
2959
                        basis_tree.lock_read()
2952
2960
                    new_sha1 = target_tree.get_file_sha1(target_path, file_id)
2953
 
                    basis_path = find_previous_path(target_tree, basis_tree, target_path)
2954
 
                    if (basis_path is not None and
2955
 
                        new_sha1 == basis_tree.get_file_sha1(basis_path, file_id)):
 
2961
                    basis_path = find_previous_path(
 
2962
                        target_tree, basis_tree, target_path)
 
2963
                    if (basis_path is not None
 
2964
                            and new_sha1 == basis_tree.get_file_sha1(basis_path, file_id)):
2956
2965
                        if file_id in merge_modified:
2957
2966
                            del merge_modified[file_id]
2958
2967
                    else:
2967
2976
                tt.version_file(file_id, trans_id)
2968
2977
            if wt_versioned and not target_versioned:
2969
2978
                tt.unversion_file(trans_id)
2970
 
            if (target_name is not None and
2971
 
                (wt_name != target_name or wt_parent != target_parent)):
 
2979
            if (target_name is not None
 
2980
                    and (wt_name != target_name or wt_parent != target_parent)):
2972
2981
                if target_name == '' and target_parent is None:
2973
2982
                    parent_trans = ROOT_PARENT
2974
2983
                else:
2981
2990
                tt.set_executability(target_executable, trans_id)
2982
2991
        if working_tree.supports_content_filtering():
2983
2992
            for (trans_id, mode_id, file_id), bytes in (
2984
 
                target_tree.iter_files_bytes(deferred_files)):
 
2993
                    target_tree.iter_files_bytes(deferred_files)):
2985
2994
                # We're reverting a tree to the target tree so using the
2986
2995
                # target tree to find the file path seems the best choice
2987
2996
                # here IMO - Ian C 27/Oct/2009
2988
2997
                filter_tree_path = target_tree.id2path(file_id)
2989
2998
                filters = working_tree._content_filter_stack(filter_tree_path)
2990
2999
                bytes = filtered_output_bytes(bytes, filters,
2991
 
                    ContentFilterContext(filter_tree_path, working_tree))
 
3000
                                              ContentFilterContext(filter_tree_path, working_tree))
2992
3001
                tt.create_file(bytes, trans_id, mode_id)
2993
3002
        else:
2994
3003
            for (trans_id, mode_id, file_id), bytes in target_tree.iter_files_bytes(
2995
 
                deferred_files):
 
3004
                    deferred_files):
2996
3005
                tt.create_file(bytes, trans_id, mode_id)
2997
3006
        tt.fixup_new_roots()
2998
3007
    finally:
3008
3017
    new_conflicts = set()
3009
3018
    with ui.ui_factory.nested_progress_bar() as pb:
3010
3019
        for n in range(10):
3011
 
            pb.update(gettext('Resolution pass'), n+1, 10)
 
3020
            pb.update(gettext('Resolution pass'), n + 1, 10)
3012
3021
            conflicts = tt.find_conflicts()
3013
3022
            if len(conflicts) == 0:
3014
3023
                return new_conflicts
3107
3116
            # special-case the other tree root (move its children instead)
3108
3117
            if path_tree and path_tree.path2id('') == file_id:
3109
3118
                    # This is the root entry, skip it
3110
 
                    continue
 
3119
                continue
3111
3120
            tt.version_file(file_id, conflict[1])
3112
3121
            new_conflicts.add((c_type, 'Versioned directory', conflict[1]))
3113
3122
        elif c_type == 'non-directory parent':
3116
3125
            parent_name = tt.final_name(parent_id)
3117
3126
            parent_file_id = tt.final_file_id(parent_id)
3118
3127
            new_parent_id = tt.new_directory(parent_name + '.new',
3119
 
                parent_parent, parent_file_id)
 
3128
                                             parent_parent, parent_file_id)
3120
3129
            _reparent_transform_children(tt, parent_id, new_parent_id)
3121
3130
            if parent_file_id is not None:
3122
3131
                tt.unversion_file(parent_id)
3212
3221
    try:
3213
3222
        for (file_id, paths, changed_content, versioned, parent, name, kind,
3214
3223
             executable) in target_tree.iter_changes(source_tree,
3215
 
             include_unchanged=True):
 
3224
                                                     include_unchanged=True):
3216
3225
            if changed_content:
3217
3226
                continue
3218
3227
            if kind != ('file', 'file'):