~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree_4.py

Merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
99
99
# This is the Windows equivalent of ENOTDIR
100
100
# It is defined in pywin32.winerror, but we don't want a strong dependency for
101
101
# just an error code.
 
102
ERROR_PATH_NOT_FOUND = 3
102
103
ERROR_DIRECTORY = 267
103
104
 
104
105
 
669
670
            new_entry = to_block[1][added_entry_index]
670
671
            rollbacks.append(lambda:state._make_absent(new_entry))
671
672
 
672
 
        # create rename entries and tuples
673
673
        for from_rel in from_paths:
674
674
            # from_rel is 'pathinroot/foo/bar'
675
675
            from_rel_utf8 = from_rel.encode('utf8')
773
773
 
774
774
                if minikind == 'd':
775
775
                    def update_dirblock(from_dir, to_key, to_dir_utf8):
776
 
                        """all entries in this block need updating.
777
 
 
778
 
                        TODO: This is pretty ugly, and doesn't support
779
 
                        reverting, but it works.
780
 
                        """
 
776
                        """Recursively update all entries in this dirblock."""
781
777
                        assert from_dir != '', "renaming root not supported"
782
778
                        from_key = (from_dir, '')
783
779
                        from_block_idx, present = \
794
790
                        to_block_index = state._ensure_block(
795
791
                            to_block_index, to_entry_index, to_dir_utf8)
796
792
                        to_block = state._dirblocks[to_block_index]
797
 
                        for entry in from_block[1]:
 
793
 
 
794
                        # Grab a copy since move_one may update the list.
 
795
                        for entry in from_block[1][:]:
798
796
                            assert entry[0][0] == from_dir
799
797
                            cur_details = entry[1][0]
800
798
                            to_key = (to_dir_utf8, entry[0][1], entry[0][2])
801
799
                            from_path_utf8 = osutils.pathjoin(entry[0][0], entry[0][1])
802
800
                            to_path_utf8 = osutils.pathjoin(to_dir_utf8, entry[0][1])
803
801
                            minikind = cur_details[0]
 
802
                            if minikind in 'ar':
 
803
                                # Deleted children of a renamed directory
 
804
                                # Do not need to be updated.
 
805
                                # Children that have been renamed out of this
 
806
                                # directory should also not be updated
 
807
                                continue
804
808
                            move_one(entry, from_path_utf8=from_path_utf8,
805
809
                                     minikind=minikind,
806
810
                                     executable=cur_details[3],
1245
1249
        :param revision_id: allows creating a working tree at a different
1246
1250
        revision than the branch is at.
1247
1251
 
1248
 
        These trees get an initial random root id.
 
1252
        These trees get an initial random root id, if their repository supports
 
1253
        rich root data, TREE_ROOT otherwise.
1249
1254
        """
1250
1255
        revision_id = osutils.safe_revision_id(revision_id)
1251
1256
        if not isinstance(a_bzrdir.transport, LocalTransport):
1273
1278
        wt.current_dirstate()._validate()
1274
1279
        try:
1275
1280
            if revision_id in (None, NULL_REVISION):
1276
 
                wt._set_root_id(generate_ids.gen_root_id())
 
1281
                if branch.repository.supports_rich_root():
 
1282
                    wt._set_root_id(generate_ids.gen_root_id())
 
1283
                else:
 
1284
                    wt._set_root_id(ROOT_ID)
1277
1285
                wt.flush()
1278
1286
                wt.current_dirstate()._validate()
1279
1287
            wt.set_last_revision(revision_id)
1915
1923
                    #       parent entry will be the same as the source entry.
1916
1924
                    target_parent_entry = state._get_entry(target_index,
1917
1925
                                                           path_utf8=new_dirname)
 
1926
                    assert target_parent_entry != (None, None), (
 
1927
                        "Could not find target parent in wt: %s\nparent of: %s"
 
1928
                        % (new_dirname, entry))
1918
1929
                    target_parent_id = target_parent_entry[0][2]
1919
1930
                    if target_parent_id == entry[0][2]:
1920
1931
                        # This is the root, so the parent is None
2082
2093
                    # python 2.5 has e.errno == EINVAL,
2083
2094
                    #            and e.winerror == ERROR_DIRECTORY
2084
2095
                    e_winerror = getattr(e, 'winerror', None)
 
2096
                    win_errors = (ERROR_DIRECTORY, ERROR_PATH_NOT_FOUND)
2085
2097
                    # there may be directories in the inventory even though
2086
2098
                    # this path is not a file on disk: so mark it as end of
2087
2099
                    # iterator
2088
2100
                    if e.errno in (errno.ENOENT, errno.ENOTDIR, errno.EINVAL):
2089
2101
                        current_dir_info = None
2090
2102
                    elif (sys.platform == 'win32'
2091
 
                          and ERROR_DIRECTORY in (e.errno, e_winerror)):
 
2103
                          and (e.errno in win_errors
 
2104
                               or e_winerror in win_errors)):
2092
2105
                        current_dir_info = None
2093
2106
                    else:
2094
2107
                        raise
2114
2127
                        # this has two possibilities:
2115
2128
                        # A) it is versioned but empty, so there is no block for it
2116
2129
                        # B) it is not versioned.
2117
 
                        # in either case it was processed by the containing directories walk:
2118
 
                        # if it is root/foo, when we walked root we emitted it,
2119
 
                        # or if we ere given root/foo to walk specifically, we
2120
 
                        # emitted it when checking the walk-root entries
2121
 
                        # advance the iterator and loop - we dont need to emit it.
 
2130
 
 
2131
                        # if (A) then we need to recurse into it to check for
 
2132
                        # new unknown files or directories.
 
2133
                        # if (B) then we should ignore it, because we don't
 
2134
                        # recurse into unknown directories.
 
2135
                        if want_unversioned:
 
2136
                            path_index = 0
 
2137
                            while path_index < len(current_dir_info[1]):
 
2138
                                    current_path_info = current_dir_info[1][path_index]
 
2139
                                    if current_path_info[2] == 'directory':
 
2140
                                        if self.target._directory_is_tree_reference(
 
2141
                                            current_path_info[0].decode('utf8')):
 
2142
                                            current_path_info = current_path_info[:2] + \
 
2143
                                                ('tree-reference',) + current_path_info[3:]
 
2144
                                    new_executable = bool(
 
2145
                                        stat.S_ISREG(current_path_info[3].st_mode)
 
2146
                                        and stat.S_IEXEC & current_path_info[3].st_mode)
 
2147
                                    yield (None,
 
2148
                                        (None, utf8_decode_or_none(current_path_info[0])),
 
2149
                                        True,
 
2150
                                        (False, False),
 
2151
                                        (None, None),
 
2152
                                        (None, utf8_decode_or_none(current_path_info[1])),
 
2153
                                        (None, current_path_info[2]),
 
2154
                                        (None, new_executable))
 
2155
                                    # dont descend into this unversioned path if it is
 
2156
                                    # a dir
 
2157
                                    if current_path_info[2] in ('directory',
 
2158
                                                                'tree-reference'):
 
2159
                                        del current_dir_info[1][path_index]
 
2160
                                        path_index -= 1
 
2161
                                    path_index += 1
 
2162
 
 
2163
                        # This dir info has been handled, go to the next
2122
2164
                        try:
2123
2165
                            current_dir_info = dir_iterator.next()
2124
2166
                        except StopIteration:
2287
2329
                                new_executable = bool(
2288
2330
                                    stat.S_ISREG(current_path_info[3].st_mode)
2289
2331
                                    and stat.S_IEXEC & current_path_info[3].st_mode)
2290
 
                                if want_unversioned:
2291
 
                                    yield (None,
2292
 
                                        (None, utf8_decode_or_none(current_path_info[0])),
2293
 
                                        True,
2294
 
                                        (False, False),
2295
 
                                        (None, None),
2296
 
                                        (None, utf8_decode_or_none(current_path_info[1])),
2297
 
                                        (None, current_path_info[2]),
2298
 
                                        (None, new_executable))
 
2332
                                yield (None,
 
2333
                                    (None, utf8_decode_or_none(current_path_info[0])),
 
2334
                                    True,
 
2335
                                    (False, False),
 
2336
                                    (None, None),
 
2337
                                    (None, utf8_decode_or_none(current_path_info[1])),
 
2338
                                    (None, current_path_info[2]),
 
2339
                                    (None, new_executable))
2299
2340
                            # dont descend into this unversioned path if it is
2300
2341
                            # a dir
2301
2342
                            if current_path_info[2] in ('directory'):