bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1  | 
# (C) 2005 Canonical Ltd
 | 
| 
1448
by Robert Collins
 revert symlinks correctly  | 
2  | 
#
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
3  | 
# This program is free software; you can redistribute it and/or modify
 | 
4  | 
# it under the terms of the GNU General Public License as published by
 | 
|
5  | 
# the Free Software Foundation; either version 2 of the License, or
 | 
|
6  | 
# (at your option) any later version.
 | 
|
| 
1448
by Robert Collins
 revert symlinks correctly  | 
7  | 
#
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
8  | 
# This program is distributed in the hope that it will be useful,
 | 
9  | 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|
10  | 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|
11  | 
# GNU General Public License for more details.
 | 
|
| 
1448
by Robert Collins
 revert symlinks correctly  | 
12  | 
#
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
13  | 
# You should have received a copy of the GNU General Public License
 | 
14  | 
# along with this program; if not, write to the Free Software
 | 
|
15  | 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
|
16  | 
||
| 
1185.16.72
by Martin Pool
 [merge] from robert and fix up tests  | 
17  | 
# FIXME: This refactoring of the workingtree code doesn't seem to keep 
 | 
18  | 
# the WorkingTree's copy of the inventory in sync with the branch.  The
 | 
|
19  | 
# branch modifies its working inventory when it does a commit to make
 | 
|
20  | 
# missing files permanently removed.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
21  | 
|
| 
1197
by Martin Pool
 doc  | 
22  | 
# TODO: Maybe also keep the full path of the entry, and the children?
 | 
23  | 
# But those depend on its position within a particular inventory, and
 | 
|
24  | 
# it would be nice not to need to hold the backpointer here.
 | 
|
25  | 
||
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
26  | 
# This should really be an id randomly assigned when the tree is
 | 
27  | 
# created, but it's not for now.
 | 
|
28  | 
ROOT_ID = "TREE_ROOT"  | 
|
29  | 
||
30  | 
||
| 
1185.1.41
by Robert Collins
 massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid  | 
31  | 
import os.path  | 
32  | 
import re  | 
|
33  | 
import sys  | 
|
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
34  | 
import tarfile  | 
| 
1185.1.41
by Robert Collins
 massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid  | 
35  | 
import types  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
36  | 
|
| 
800
by Martin Pool
 Merge John's import-speedup branch:  | 
37  | 
import bzrlib  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
38  | 
from bzrlib.osutils import (pumpfile, quotefn, splitpath, joinpath,  | 
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
39  | 
pathjoin, sha_strings)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
40  | 
from bzrlib.trace import mutter  | 
| 
1185.16.63
by Martin Pool
 - more error conversion  | 
41  | 
from bzrlib.errors import (NotVersionedError, InvalidEntryName,  | 
42  | 
BzrError, BzrCheckError)  | 
|
| 
1185.1.41
by Robert Collins
 massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid  | 
43  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
44  | 
|
| 
802
by Martin Pool
 - Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions  | 
45  | 
class InventoryEntry(object):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
46  | 
"""Description of a versioned file.  | 
47  | 
||
48  | 
    An InventoryEntry has the following fields, which are also
 | 
|
49  | 
    present in the XML inventory-entry element:
 | 
|
50  | 
||
| 
1197
by Martin Pool
 doc  | 
51  | 
    file_id
 | 
52  | 
||
53  | 
    name
 | 
|
54  | 
        (within the parent directory)
 | 
|
55  | 
||
56  | 
    parent_id
 | 
|
57  | 
        file_id of the parent directory, or ROOT_ID
 | 
|
58  | 
||
| 
1092.2.21
by Robert Collins
 convert name_version to revision in inventory entries  | 
59  | 
    revision
 | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
60  | 
        the revision_id in which this variation of this file was 
 | 
| 
1092.2.22
by Robert Collins
 text_version and name_version unification looking reasonable  | 
61  | 
        introduced.
 | 
| 
1197
by Martin Pool
 doc  | 
62  | 
|
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
63  | 
    executable
 | 
64  | 
        Indicates that this file should be executable on systems
 | 
|
65  | 
        that support it.
 | 
|
66  | 
||
| 
1197
by Martin Pool
 doc  | 
67  | 
    text_sha1
 | 
68  | 
        sha-1 of the text of the file
 | 
|
69  | 
        
 | 
|
70  | 
    text_size
 | 
|
71  | 
        size in bytes of the text of the file
 | 
|
72  | 
        
 | 
|
73  | 
    (reading a version 4 tree created a text_id field.)
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
74  | 
|
75  | 
    >>> i = Inventory()
 | 
|
76  | 
    >>> i.path2id('')
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
77  | 
    'TREE_ROOT'
 | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
78  | 
    >>> i.add(InventoryDirectory('123', 'src', ROOT_ID))
 | 
79  | 
    InventoryDirectory('123', 'src', parent_id='TREE_ROOT')
 | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
80  | 
    >>> i.add(InventoryFile('2323', 'hello.c', parent_id='123'))
 | 
81  | 
    InventoryFile('2323', 'hello.c', parent_id='123')
 | 
|
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
82  | 
    >>> shouldbe = {0: 'src', 1: pathjoin('src','hello.c')}
 | 
| 
1185.16.151
by Martin Pool
 [patch] win32 fix for InventoryEntry doctest (Alexander, patch 21)  | 
83  | 
    >>> for ix, j in enumerate(i.iter_entries()):
 | 
84  | 
    ...   print (j[0] == shouldbe[ix], j[1])
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
85  | 
    ... 
 | 
| 
1185.16.151
by Martin Pool
 [patch] win32 fix for InventoryEntry doctest (Alexander, patch 21)  | 
86  | 
    (True, InventoryDirectory('123', 'src', parent_id='TREE_ROOT'))
 | 
87  | 
    (True, InventoryFile('2323', 'hello.c', parent_id='123'))
 | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
88  | 
    >>> i.add(InventoryFile('2323', 'bye.c', '123'))
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
89  | 
    Traceback (most recent call last):
 | 
90  | 
    ...
 | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
91  | 
    BzrError: inventory already contains entry with id {2323}
 | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
92  | 
    >>> i.add(InventoryFile('2324', 'bye.c', '123'))
 | 
93  | 
    InventoryFile('2324', 'bye.c', parent_id='123')
 | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
94  | 
    >>> i.add(InventoryDirectory('2325', 'wibble', '123'))
 | 
95  | 
    InventoryDirectory('2325', 'wibble', parent_id='123')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
96  | 
    >>> i.path2id('src/wibble')
 | 
97  | 
    '2325'
 | 
|
98  | 
    >>> '2325' in i
 | 
|
99  | 
    True
 | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
100  | 
    >>> i.add(InventoryFile('2326', 'wibble.c', '2325'))
 | 
101  | 
    InventoryFile('2326', 'wibble.c', parent_id='2325')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
102  | 
    >>> i['2326']
 | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
103  | 
    InventoryFile('2326', 'wibble.c', parent_id='2325')
 | 
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
104  | 
    >>> for path, entry in i.iter_entries():
 | 
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
105  | 
    ...     print path
 | 
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
106  | 
    ...     assert i.path2id(path)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
107  | 
    ... 
 | 
108  | 
    src
 | 
|
109  | 
    src/bye.c
 | 
|
110  | 
    src/hello.c
 | 
|
111  | 
    src/wibble
 | 
|
112  | 
    src/wibble/wibble.c
 | 
|
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
113  | 
    >>> i.id2path('2326')
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
114  | 
    'src/wibble/wibble.c'
 | 
115  | 
    """
 | 
|
| 
1197
by Martin Pool
 doc  | 
116  | 
|
| 
955
by Martin Pool
 - use __slots__ on InventoryEntry; rather faster  | 
117  | 
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',  | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
118  | 
'text_id', 'parent_id', 'children', 'executable',  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
119  | 
'revision']  | 
| 
1185
by Martin Pool
 - add xml round-trip test for revisions  | 
120  | 
|
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
121  | 
def _add_text_to_weave(self, new_lines, parents, weave_store, transaction):  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
122  | 
versionedfile = weave_store.get_weave_or_empty(self.file_id,  | 
123  | 
transaction)  | 
|
| 
1563.2.10
by Robert Collins
 Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.  | 
124  | 
versionedfile.add_lines(self.revision, parents, new_lines)  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
125  | 
|
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
126  | 
def detect_changes(self, old_entry):  | 
127  | 
"""Return a (text_modified, meta_modified) from this to old_entry.  | 
|
128  | 
        
 | 
|
129  | 
        _read_tree_state must have been called on self and old_entry prior to 
 | 
|
130  | 
        calling detect_changes.
 | 
|
131  | 
        """
 | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
132  | 
return False, False  | 
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
133  | 
|
| 
1399.1.4
by Robert Collins
 move diff and symlink conditionals into inventory.py from diff.py  | 
134  | 
def diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
135  | 
output_to, reverse=False):  | 
|
136  | 
"""Perform a diff from this to to_entry.  | 
|
137  | 
||
138  | 
        text_diff will be used for textual difference calculation.
 | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
139  | 
        This is a template method, override _diff in child classes.
 | 
| 
1399.1.4
by Robert Collins
 move diff and symlink conditionals into inventory.py from diff.py  | 
140  | 
        """
 | 
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
141  | 
self._read_tree_state(tree.id2path(self.file_id), tree)  | 
| 
1399.1.4
by Robert Collins
 move diff and symlink conditionals into inventory.py from diff.py  | 
142  | 
if to_entry:  | 
143  | 
            # cannot diff from one kind to another - you must do a removal
 | 
|
144  | 
            # and an addif they do not match.
 | 
|
145  | 
assert self.kind == to_entry.kind  | 
|
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
146  | 
to_entry._read_tree_state(to_tree.id2path(to_entry.file_id),  | 
147  | 
to_tree)  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
148  | 
self._diff(text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
149  | 
output_to, reverse)  | 
|
150  | 
||
151  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
152  | 
output_to, reverse=False):  | 
|
153  | 
"""Perform a diff between two entries of the same kind."""  | 
|
| 
1399.1.4
by Robert Collins
 move diff and symlink conditionals into inventory.py from diff.py  | 
154  | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
155  | 
def find_previous_heads(self, previous_inventories,  | 
156  | 
versioned_file_store,  | 
|
157  | 
transaction,  | 
|
158  | 
entry_vf=None):  | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
159  | 
"""Return the revisions and entries that directly preceed this.  | 
160  | 
||
161  | 
        Returned as a map from revision to inventory entry.
 | 
|
162  | 
||
163  | 
        This is a map containing the file revisions in all parents
 | 
|
164  | 
        for which the file exists, and its revision is not a parent of
 | 
|
165  | 
        any other. If the file is new, the set will be empty.
 | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
166  | 
|
167  | 
        :param versioned_file_store: A store where ancestry data on this
 | 
|
168  | 
                                     file id can be queried.
 | 
|
169  | 
        :param transaction: The transaction that queries to the versioned 
 | 
|
170  | 
                            file store should be completed under.
 | 
|
171  | 
        :param entry_vf: The entry versioned file, if its already available.
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
172  | 
        """
 | 
| 
1411
by Robert Collins
 use weave ancestry to determine inventory entry previous heads, prevent propogating 'I did a merge' merges.  | 
173  | 
def get_ancestors(weave, entry):  | 
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
174  | 
return set(weave.get_ancestry(entry.revision))  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
175  | 
        # revision:ie mapping for each ie found in previous_inventories.
 | 
176  | 
candidates = {}  | 
|
177  | 
        # revision:ie mapping with one revision for each head.
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
178  | 
heads = {}  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
179  | 
        # revision: ancestor list for each head
 | 
| 
1411
by Robert Collins
 use weave ancestry to determine inventory entry previous heads, prevent propogating 'I did a merge' merges.  | 
180  | 
head_ancestors = {}  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
181  | 
        # identify candidate head revision ids.
 | 
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
182  | 
for inv in previous_inventories:  | 
183  | 
if self.file_id in inv:  | 
|
184  | 
ie = inv[self.file_id]  | 
|
185  | 
assert ie.file_id == self.file_id  | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
186  | 
if ie.revision in candidates:  | 
187  | 
                    # same revision value in two different inventories:
 | 
|
188  | 
                    # correct possible inconsistencies:
 | 
|
189  | 
                    #     * there was a bug in revision updates with 'x' bit 
 | 
|
190  | 
                    #       support.
 | 
|
| 
1185.1.51
by Robert Collins
 merge in reweave support  | 
191  | 
try:  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
192  | 
if candidates[ie.revision].executable != ie.executable:  | 
193  | 
candidates[ie.revision].executable = False  | 
|
| 
1185.1.51
by Robert Collins
 merge in reweave support  | 
194  | 
ie.executable = False  | 
195  | 
except AttributeError:  | 
|
196  | 
                        pass
 | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
197  | 
                    # must now be the same.
 | 
198  | 
assert candidates[ie.revision] == ie  | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
199  | 
else:  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
200  | 
                    # add this revision as a candidate.
 | 
201  | 
candidates[ie.revision] = ie  | 
|
202  | 
||
203  | 
        # common case optimisation
 | 
|
204  | 
if len(candidates) == 1:  | 
|
205  | 
            # if there is only one candidate revision found
 | 
|
206  | 
            # then we can opening the versioned file to access ancestry:
 | 
|
207  | 
            # there cannot be any ancestors to eliminate when there is 
 | 
|
208  | 
            # only one revision available.
 | 
|
209  | 
heads[ie.revision] = ie  | 
|
210  | 
return heads  | 
|
211  | 
||
212  | 
        # eliminate ancestors amongst the available candidates:
 | 
|
213  | 
        # heads are those that are not an ancestor of any other candidate
 | 
|
214  | 
        # - this provides convergence at a per-file level.
 | 
|
215  | 
for ie in candidates.values():  | 
|
216  | 
            # may be an ancestor of a known head:
 | 
|
217  | 
already_present = 0 != len(  | 
|
218  | 
[head for head in heads  | 
|
219  | 
if ie.revision in head_ancestors[head]])  | 
|
220  | 
if already_present:  | 
|
221  | 
                # an ancestor of an analyzed candidate.
 | 
|
222  | 
                continue
 | 
|
223  | 
            # not an ancestor of a known head:
 | 
|
224  | 
            # load the versioned file for this file id if needed
 | 
|
225  | 
if entry_vf is None:  | 
|
226  | 
entry_vf = versioned_file_store.get_weave_or_empty(  | 
|
227  | 
self.file_id, transaction)  | 
|
228  | 
ancestors = get_ancestors(entry_vf, ie)  | 
|
229  | 
            # may knock something else out:
 | 
|
230  | 
check_heads = list(heads.keys())  | 
|
231  | 
for head in check_heads:  | 
|
232  | 
if head in ancestors:  | 
|
233  | 
                    # this previously discovered 'head' is not
 | 
|
234  | 
                    # really a head - its an ancestor of the newly 
 | 
|
235  | 
                    # found head,
 | 
|
236  | 
heads.pop(head)  | 
|
237  | 
head_ancestors[ie.revision] = ancestors  | 
|
238  | 
heads[ie.revision] = ie  | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
239  | 
return heads  | 
240  | 
||
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
241  | 
def get_tar_item(self, root, dp, now, tree):  | 
| 
1399.1.7
by Robert Collins
 implement symlink exporting to tarballs  | 
242  | 
"""Get a tarfile item and a file stream for its content."""  | 
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
243  | 
item = tarfile.TarInfo(pathjoin(root, dp))  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
244  | 
        # TODO: would be cool to actually set it to the timestamp of the
 | 
245  | 
        # revision it was last changed
 | 
|
246  | 
item.mtime = now  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
247  | 
fileobj = self._put_in_tar(item, tree)  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
248  | 
return item, fileobj  | 
249  | 
||
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
250  | 
def has_text(self):  | 
251  | 
"""Return true if the object this entry represents has textual data.  | 
|
252  | 
||
253  | 
        Note that textual data includes binary content.
 | 
|
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
254  | 
|
255  | 
        Also note that all entries get weave files created for them.
 | 
|
256  | 
        This attribute is primarily used when upgrading from old trees that
 | 
|
257  | 
        did not have the weave index for all inventory entries.
 | 
|
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
258  | 
        """
 | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
259  | 
return False  | 
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
260  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
261  | 
def __init__(self, file_id, name, parent_id, text_id=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
262  | 
"""Create an InventoryEntry  | 
263  | 
        
 | 
|
264  | 
        The filename must be a single component, relative to the
 | 
|
265  | 
        parent directory; it cannot be a whole path or relative name.
 | 
|
266  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
267  | 
        >>> e = InventoryFile('123', 'hello.c', ROOT_ID)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
268  | 
        >>> e.name
 | 
269  | 
        'hello.c'
 | 
|
270  | 
        >>> e.file_id
 | 
|
271  | 
        '123'
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
272  | 
        >>> e = InventoryFile('123', 'src/hello.c', ROOT_ID)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
273  | 
        Traceback (most recent call last):
 | 
| 
1185.16.63
by Martin Pool
 - more error conversion  | 
274  | 
        InvalidEntryName: Invalid entry name: src/hello.c
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
275  | 
        """
 | 
| 
1183
by Martin Pool
 - implement version 5 xml storage, and tests  | 
276  | 
assert isinstance(name, basestring), name  | 
| 
376
by Martin Pool
 - fix slow invariant check when reading in InventoryEntry objects  | 
277  | 
if '/' in name or '\\' in name:  | 
| 
1185.16.63
by Martin Pool
 - more error conversion  | 
278  | 
raise InvalidEntryName(name=name)  | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
279  | 
self.executable = False  | 
| 
1092.2.21
by Robert Collins
 convert name_version to revision in inventory entries  | 
280  | 
self.revision = None  | 
| 
955
by Martin Pool
 - use __slots__ on InventoryEntry; rather faster  | 
281  | 
self.text_sha1 = None  | 
282  | 
self.text_size = None  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
283  | 
self.file_id = file_id  | 
284  | 
self.name = name  | 
|
285  | 
self.text_id = text_id  | 
|
286  | 
self.parent_id = parent_id  | 
|
| 
1092.2.6
by Robert Collins
 symlink support updated to work  | 
287  | 
self.symlink_target = None  | 
| 
237
by mbp at sourcefrog
 - Better assertions in InventoryEntry constructor  | 
288  | 
|
| 
1399.1.2
by Robert Collins
 push kind character creation into InventoryEntry and TreeEntry  | 
289  | 
def kind_character(self):  | 
290  | 
"""Return a short kind indicator useful for appending to names."""  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
291  | 
raise BzrError('unknown kind %r' % self.kind)  | 
| 
1399.1.2
by Robert Collins
 push kind character creation into InventoryEntry and TreeEntry  | 
292  | 
|
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
293  | 
known_kinds = ('file', 'directory', 'symlink', 'root_directory')  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
294  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
295  | 
def _put_in_tar(self, item, tree):  | 
296  | 
"""populate item for stashing in a tar, and return the content stream.  | 
|
297  | 
||
298  | 
        If no content is available, return None.
 | 
|
299  | 
        """
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
300  | 
raise BzrError("don't know how to export {%s} of kind %r" %  | 
301  | 
(self.file_id, self.kind))  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
302  | 
|
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
303  | 
def put_on_disk(self, dest, dp, tree):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
304  | 
"""Create a representation of self on disk in the prefix dest.  | 
305  | 
        
 | 
|
306  | 
        This is a template method - implement _put_on_disk in subclasses.
 | 
|
307  | 
        """
 | 
|
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
308  | 
fullpath = pathjoin(dest, dp)  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
309  | 
self._put_on_disk(fullpath, tree)  | 
| 
1185.31.4
by John Arbash Meinel
 Fixing mutter() calls to not have to do string processing.  | 
310  | 
mutter(" export {%s} kind %s to %s", self.file_id,  | 
311  | 
self.kind, fullpath)  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
312  | 
|
313  | 
def _put_on_disk(self, fullpath, tree):  | 
|
314  | 
"""Put this entry onto disk at fullpath, from tree tree."""  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
315  | 
raise BzrError("don't know how to export {%s} of kind %r" % (self.file_id, self.kind))  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
316  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
317  | 
def sorted_children(self):  | 
318  | 
l = self.children.items()  | 
|
319  | 
l.sort()  | 
|
320  | 
return l  | 
|
321  | 
||
| 
1399.1.1
by Robert Collins
 move checks for versionability of file kinds into InventoryEntry  | 
322  | 
    @staticmethod
 | 
323  | 
def versionable_kind(kind):  | 
|
324  | 
return kind in ('file', 'directory', 'symlink')  | 
|
325  | 
||
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
326  | 
def check(self, checker, rev_id, inv, tree):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
327  | 
"""Check this inventory entry is intact.  | 
328  | 
||
329  | 
        This is a template method, override _check for kind specific
 | 
|
330  | 
        tests.
 | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
331  | 
|
332  | 
        :param checker: Check object providing context for the checks; 
 | 
|
333  | 
             can be used to find out what parts of the repository have already
 | 
|
334  | 
             been checked.
 | 
|
335  | 
        :param rev_id: Revision id from which this InventoryEntry was loaded.
 | 
|
336  | 
             Not necessarily the last-changed revision for this file.
 | 
|
337  | 
        :param inv: Inventory from which the entry was loaded.
 | 
|
338  | 
        :param tree: RevisionTree for this entry.
 | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
339  | 
        """
 | 
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
340  | 
if self.parent_id != None:  | 
341  | 
if not inv.has_id(self.parent_id):  | 
|
342  | 
raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'  | 
|
343  | 
% (self.parent_id, rev_id))  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
344  | 
self._check(checker, rev_id, tree)  | 
345  | 
||
346  | 
def _check(self, checker, rev_id, tree):  | 
|
347  | 
"""Check this inventory entry for kind specific errors."""  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
348  | 
raise BzrCheckError('unknown entry kind %r in revision {%s}' %  | 
349  | 
(self.kind, rev_id))  | 
|
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
350  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
351  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
352  | 
def copy(self):  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
353  | 
"""Clone this inventory entry."""  | 
354  | 
raise NotImplementedError  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
355  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
356  | 
def _get_snapshot_change(self, previous_entries):  | 
357  | 
if len(previous_entries) > 1:  | 
|
358  | 
return 'merged'  | 
|
359  | 
elif len(previous_entries) == 0:  | 
|
360  | 
return 'added'  | 
|
361  | 
else:  | 
|
362  | 
return 'modified/renamed/reparented'  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
363  | 
|
364  | 
def __repr__(self):  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
365  | 
return ("%s(%r, %r, parent_id=%r)"  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
366  | 
% (self.__class__.__name__,  | 
367  | 
self.file_id,  | 
|
368  | 
self.name,  | 
|
369  | 
self.parent_id))  | 
|
370  | 
||
| 
1411
by Robert Collins
 use weave ancestry to determine inventory entry previous heads, prevent propogating 'I did a merge' merges.  | 
371  | 
def snapshot(self, revision, path, previous_entries,  | 
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
372  | 
work_tree, weave_store, transaction):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
373  | 
"""Make a snapshot of this entry which may or may not have changed.  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
374  | 
        
 | 
375  | 
        This means that all its fields are populated, that it has its
 | 
|
376  | 
        text stored in the text store or weave.
 | 
|
377  | 
        """
 | 
|
378  | 
mutter('new parents of %s are %r', path, previous_entries)  | 
|
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
379  | 
self._read_tree_state(path, work_tree)  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
380  | 
if len(previous_entries) == 1:  | 
381  | 
            # cannot be unchanged unless there is only one parent file rev.
 | 
|
382  | 
parent_ie = previous_entries.values()[0]  | 
|
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
383  | 
if self._unchanged(parent_ie):  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
384  | 
mutter("found unchanged entry")  | 
385  | 
self.revision = parent_ie.revision  | 
|
386  | 
return "unchanged"  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
387  | 
return self.snapshot_revision(revision, previous_entries,  | 
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
388  | 
work_tree, weave_store, transaction)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
389  | 
|
390  | 
def snapshot_revision(self, revision, previous_entries, work_tree,  | 
|
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
391  | 
weave_store, transaction):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
392  | 
"""Record this revision unconditionally."""  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
393  | 
mutter('new revision for {%s}', self.file_id)  | 
394  | 
self.revision = revision  | 
|
395  | 
change = self._get_snapshot_change(previous_entries)  | 
|
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
396  | 
self._snapshot_text(previous_entries, work_tree, weave_store,  | 
397  | 
transaction)  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
398  | 
return change  | 
399  | 
||
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
400  | 
def _snapshot_text(self, file_parents, work_tree, weave_store, transaction):  | 
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
401  | 
"""Record the 'text' of this entry, whatever form that takes.  | 
402  | 
        
 | 
|
403  | 
        This default implementation simply adds an empty text.
 | 
|
404  | 
        """
 | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
405  | 
mutter('storing file {%s} in revision {%s}',  | 
406  | 
self.file_id, self.revision)  | 
|
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
407  | 
self._add_text_to_weave([], file_parents.keys(), weave_store, transaction)  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
408  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
409  | 
def __eq__(self, other):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
410  | 
if not isinstance(other, InventoryEntry):  | 
411  | 
return NotImplemented  | 
|
412  | 
||
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
413  | 
return ((self.file_id == other.file_id)  | 
414  | 
and (self.name == other.name)  | 
|
415  | 
and (other.symlink_target == self.symlink_target)  | 
|
416  | 
and (self.text_sha1 == other.text_sha1)  | 
|
417  | 
and (self.text_size == other.text_size)  | 
|
418  | 
and (self.text_id == other.text_id)  | 
|
419  | 
and (self.parent_id == other.parent_id)  | 
|
420  | 
and (self.kind == other.kind)  | 
|
421  | 
and (self.revision == other.revision)  | 
|
422  | 
and (self.executable == other.executable)  | 
|
423  | 
                )
 | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
424  | 
|
425  | 
def __ne__(self, other):  | 
|
426  | 
return not (self == other)  | 
|
427  | 
||
428  | 
def __hash__(self):  | 
|
429  | 
raise ValueError('not hashable')  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
430  | 
|
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
431  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
432  | 
"""Has this entry changed relative to previous_ie.  | 
433  | 
||
434  | 
        This method should be overriden in child classes.
 | 
|
435  | 
        """
 | 
|
| 
1092.2.22
by Robert Collins
 text_version and name_version unification looking reasonable  | 
436  | 
compatible = True  | 
437  | 
        # different inv parent
 | 
|
438  | 
if previous_ie.parent_id != self.parent_id:  | 
|
439  | 
compatible = False  | 
|
440  | 
        # renamed
 | 
|
441  | 
elif previous_ie.name != self.name:  | 
|
442  | 
compatible = False  | 
|
443  | 
return compatible  | 
|
444  | 
||
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
445  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
446  | 
"""Populate fields in the inventory entry from the given tree.  | 
447  | 
        
 | 
|
448  | 
        Note that this should be modified to be a noop on virtual trees
 | 
|
449  | 
        as all entries created there are prepopulated.
 | 
|
450  | 
        """
 | 
|
| 
1185.16.5
by Martin Pool
 doc  | 
451  | 
        # TODO: Rather than running this manually, we should check the 
 | 
452  | 
        # working sha1 and other expensive properties when they're
 | 
|
453  | 
        # first requested, or preload them if they're already known
 | 
|
454  | 
pass # nothing to do by default  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
455  | 
|
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
456  | 
def _forget_tree_state(self):  | 
457  | 
        pass
 | 
|
458  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
459  | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
460  | 
class RootEntry(InventoryEntry):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
461  | 
|
462  | 
def _check(self, checker, rev_id, tree):  | 
|
463  | 
"""See InventoryEntry._check"""  | 
|
464  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
465  | 
def __init__(self, file_id):  | 
466  | 
self.file_id = file_id  | 
|
467  | 
self.children = {}  | 
|
468  | 
self.kind = 'root_directory'  | 
|
469  | 
self.parent_id = None  | 
|
| 
1185.33.66
by Martin Pool
 [patch] use unicode literals for all hardcoded paths (Alexander Belchenko)  | 
470  | 
self.name = u''  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
471  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
472  | 
def __eq__(self, other):  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
473  | 
if not isinstance(other, RootEntry):  | 
474  | 
return NotImplemented  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
475  | 
|
476  | 
return (self.file_id == other.file_id) \  | 
|
477  | 
and (self.children == other.children)  | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
478  | 
|
479  | 
||
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
480  | 
class InventoryDirectory(InventoryEntry):  | 
481  | 
"""A directory in an inventory."""  | 
|
482  | 
||
483  | 
def _check(self, checker, rev_id, tree):  | 
|
484  | 
"""See InventoryEntry._check"""  | 
|
485  | 
if self.text_sha1 != None or self.text_size != None or self.text_id != None:  | 
|
486  | 
raise BzrCheckError('directory {%s} has text in revision {%s}'  | 
|
487  | 
% (self.file_id, rev_id))  | 
|
488  | 
||
489  | 
def copy(self):  | 
|
490  | 
other = InventoryDirectory(self.file_id, self.name, self.parent_id)  | 
|
491  | 
other.revision = self.revision  | 
|
492  | 
        # note that children are *not* copied; they're pulled across when
 | 
|
493  | 
        # others are added
 | 
|
494  | 
return other  | 
|
495  | 
||
496  | 
def __init__(self, file_id, name, parent_id):  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
497  | 
super(InventoryDirectory, self).__init__(file_id, name, parent_id)  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
498  | 
self.children = {}  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
499  | 
self.kind = 'directory'  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
500  | 
|
501  | 
def kind_character(self):  | 
|
502  | 
"""See InventoryEntry.kind_character."""  | 
|
503  | 
return '/'  | 
|
504  | 
||
505  | 
def _put_in_tar(self, item, tree):  | 
|
506  | 
"""See InventoryEntry._put_in_tar."""  | 
|
507  | 
item.type = tarfile.DIRTYPE  | 
|
508  | 
fileobj = None  | 
|
509  | 
item.name += '/'  | 
|
510  | 
item.size = 0  | 
|
511  | 
item.mode = 0755  | 
|
512  | 
return fileobj  | 
|
513  | 
||
514  | 
def _put_on_disk(self, fullpath, tree):  | 
|
515  | 
"""See InventoryEntry._put_on_disk."""  | 
|
516  | 
os.mkdir(fullpath)  | 
|
517  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
518  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
519  | 
class InventoryFile(InventoryEntry):  | 
520  | 
"""A file in an inventory."""  | 
|
521  | 
||
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
522  | 
def _check(self, checker, tree_revision_id, tree):  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
523  | 
"""See InventoryEntry._check"""  | 
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
524  | 
t = (self.file_id, self.revision)  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
525  | 
if t in checker.checked_texts:  | 
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
526  | 
prev_sha = checker.checked_texts[t]  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
527  | 
if prev_sha != self.text_sha1:  | 
528  | 
raise BzrCheckError('mismatched sha1 on {%s} in {%s}' %  | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
529  | 
(self.file_id, tree_revision_id))  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
530  | 
else:  | 
531  | 
checker.repeated_text_cnt += 1  | 
|
532  | 
                return
 | 
|
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
533  | 
|
534  | 
if self.file_id not in checker.checked_weaves:  | 
|
535  | 
mutter('check weave {%s}', self.file_id)  | 
|
536  | 
w = tree.get_weave(self.file_id)  | 
|
537  | 
            # Not passing a progress bar, because it creates a new
 | 
|
538  | 
            # progress, which overwrites the current progress,
 | 
|
539  | 
            # and doesn't look nice
 | 
|
540  | 
w.check()  | 
|
541  | 
checker.checked_weaves[self.file_id] = True  | 
|
542  | 
else:  | 
|
| 
1563.2.14
by Robert Collins
 Prepare weave store to delegate copy details to the versioned file.  | 
543  | 
w = tree.get_weave(self.file_id)  | 
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
544  | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
545  | 
mutter('check version {%s} of {%s}', tree_revision_id, self.file_id)  | 
| 
1616.1.7
by Martin Pool
 New developer commands 'weave-list' and 'weave-join'.  | 
546  | 
checker.checked_text_cnt += 1  | 
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
547  | 
        # We can't check the length, because Weave doesn't store that
 | 
548  | 
        # information, and the whole point of looking at the weave's
 | 
|
549  | 
        # sha1sum is that we don't have to extract the text.
 | 
|
550  | 
if self.text_sha1 != w.get_sha1(self.revision):  | 
|
551  | 
raise BzrCheckError('text {%s} version {%s} wrong sha1'  | 
|
552  | 
% (self.file_id, self.revision))  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
553  | 
checker.checked_texts[t] = self.text_sha1  | 
554  | 
||
555  | 
def copy(self):  | 
|
556  | 
other = InventoryFile(self.file_id, self.name, self.parent_id)  | 
|
557  | 
other.executable = self.executable  | 
|
558  | 
other.text_id = self.text_id  | 
|
559  | 
other.text_sha1 = self.text_sha1  | 
|
560  | 
other.text_size = self.text_size  | 
|
561  | 
other.revision = self.revision  | 
|
562  | 
return other  | 
|
563  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
564  | 
def detect_changes(self, old_entry):  | 
565  | 
"""See InventoryEntry.detect_changes."""  | 
|
566  | 
assert self.text_sha1 != None  | 
|
567  | 
assert old_entry.text_sha1 != None  | 
|
568  | 
text_modified = (self.text_sha1 != old_entry.text_sha1)  | 
|
569  | 
meta_modified = (self.executable != old_entry.executable)  | 
|
570  | 
return text_modified, meta_modified  | 
|
571  | 
||
572  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
573  | 
output_to, reverse=False):  | 
|
574  | 
"""See InventoryEntry._diff."""  | 
|
575  | 
from_text = tree.get_file(self.file_id).readlines()  | 
|
576  | 
if to_entry:  | 
|
577  | 
to_text = to_tree.get_file(to_entry.file_id).readlines()  | 
|
578  | 
else:  | 
|
579  | 
to_text = []  | 
|
580  | 
if not reverse:  | 
|
581  | 
text_diff(from_label, from_text,  | 
|
582  | 
to_label, to_text, output_to)  | 
|
583  | 
else:  | 
|
584  | 
text_diff(to_label, to_text,  | 
|
585  | 
from_label, from_text, output_to)  | 
|
586  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
587  | 
def has_text(self):  | 
588  | 
"""See InventoryEntry.has_text."""  | 
|
589  | 
return True  | 
|
590  | 
||
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
591  | 
def __init__(self, file_id, name, parent_id):  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
592  | 
super(InventoryFile, self).__init__(file_id, name, parent_id)  | 
593  | 
self.kind = 'file'  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
594  | 
|
595  | 
def kind_character(self):  | 
|
596  | 
"""See InventoryEntry.kind_character."""  | 
|
597  | 
return ''  | 
|
598  | 
||
599  | 
def _put_in_tar(self, item, tree):  | 
|
600  | 
"""See InventoryEntry._put_in_tar."""  | 
|
601  | 
item.type = tarfile.REGTYPE  | 
|
602  | 
fileobj = tree.get_file(self.file_id)  | 
|
603  | 
item.size = self.text_size  | 
|
604  | 
if tree.is_executable(self.file_id):  | 
|
605  | 
item.mode = 0755  | 
|
606  | 
else:  | 
|
607  | 
item.mode = 0644  | 
|
608  | 
return fileobj  | 
|
609  | 
||
610  | 
def _put_on_disk(self, fullpath, tree):  | 
|
611  | 
"""See InventoryEntry._put_on_disk."""  | 
|
612  | 
pumpfile(tree.get_file(self.file_id), file(fullpath, 'wb'))  | 
|
613  | 
if tree.is_executable(self.file_id):  | 
|
614  | 
os.chmod(fullpath, 0755)  | 
|
615  | 
||
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
616  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
617  | 
"""See InventoryEntry._read_tree_state."""  | 
618  | 
self.text_sha1 = work_tree.get_file_sha1(self.file_id)  | 
|
619  | 
self.executable = work_tree.is_executable(self.file_id)  | 
|
620  | 
||
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
621  | 
def _forget_tree_state(self):  | 
622  | 
self.text_sha1 = None  | 
|
623  | 
self.executable = None  | 
|
624  | 
||
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
625  | 
def _snapshot_text(self, file_parents, work_tree, weave_store, transaction):  | 
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
626  | 
"""See InventoryEntry._snapshot_text."""  | 
627  | 
mutter('storing file {%s} in revision {%s}',  | 
|
628  | 
self.file_id, self.revision)  | 
|
629  | 
        # special case to avoid diffing on renames or 
 | 
|
630  | 
        # reparenting
 | 
|
631  | 
if (len(file_parents) == 1  | 
|
632  | 
and self.text_sha1 == file_parents.values()[0].text_sha1  | 
|
633  | 
and self.text_size == file_parents.values()[0].text_size):  | 
|
634  | 
previous_ie = file_parents.values()[0]  | 
|
| 
1563.2.10
by Robert Collins
 Change weave store to be a versioned store, using WeaveFiles which maintain integrity without needing explicit 'put' operations.  | 
635  | 
versionedfile = weave_store.get_weave(self.file_id, transaction)  | 
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
636  | 
versionedfile.clone_text(self.revision, previous_ie.revision, file_parents.keys())  | 
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
637  | 
else:  | 
638  | 
new_lines = work_tree.get_file(self.file_id).readlines()  | 
|
| 
1563.2.18
by Robert Collins
 get knit repositories really using knits for text storage.  | 
639  | 
self._add_text_to_weave(new_lines, file_parents.keys(), weave_store,  | 
| 
1417.1.8
by Robert Collins
 use transactions in the weave store interface, which enables caching for log  | 
640  | 
transaction)  | 
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
641  | 
self.text_sha1 = sha_strings(new_lines)  | 
642  | 
self.text_size = sum(map(len, new_lines))  | 
|
643  | 
||
644  | 
||
645  | 
def _unchanged(self, previous_ie):  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
646  | 
"""See InventoryEntry._unchanged."""  | 
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
647  | 
compatible = super(InventoryFile, self)._unchanged(previous_ie)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
648  | 
if self.text_sha1 != previous_ie.text_sha1:  | 
649  | 
compatible = False  | 
|
650  | 
else:  | 
|
651  | 
            # FIXME: 20050930 probe for the text size when getting sha1
 | 
|
652  | 
            # in _read_tree_state
 | 
|
653  | 
self.text_size = previous_ie.text_size  | 
|
| 
1185.1.52
by Robert Collins
 fix detection of changes in inventory entries when the x bit is toggled  | 
654  | 
if self.executable != previous_ie.executable:  | 
655  | 
compatible = False  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
656  | 
return compatible  | 
657  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
658  | 
|
659  | 
class InventoryLink(InventoryEntry):  | 
|
660  | 
"""A file in an inventory."""  | 
|
661  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
662  | 
__slots__ = ['symlink_target']  | 
663  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
664  | 
def _check(self, checker, rev_id, tree):  | 
665  | 
"""See InventoryEntry._check"""  | 
|
666  | 
if self.text_sha1 != None or self.text_size != None or self.text_id != None:  | 
|
667  | 
raise BzrCheckError('symlink {%s} has text in revision {%s}'  | 
|
668  | 
% (self.file_id, rev_id))  | 
|
669  | 
if self.symlink_target == None:  | 
|
670  | 
raise BzrCheckError('symlink {%s} has no target in revision {%s}'  | 
|
671  | 
% (self.file_id, rev_id))  | 
|
672  | 
||
673  | 
def copy(self):  | 
|
674  | 
other = InventoryLink(self.file_id, self.name, self.parent_id)  | 
|
675  | 
other.symlink_target = self.symlink_target  | 
|
676  | 
other.revision = self.revision  | 
|
677  | 
return other  | 
|
678  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
679  | 
def detect_changes(self, old_entry):  | 
680  | 
"""See InventoryEntry.detect_changes."""  | 
|
681  | 
        # FIXME: which _modified field should we use ? RBC 20051003
 | 
|
682  | 
text_modified = (self.symlink_target != old_entry.symlink_target)  | 
|
683  | 
if text_modified:  | 
|
684  | 
mutter(" symlink target changed")  | 
|
685  | 
meta_modified = False  | 
|
686  | 
return text_modified, meta_modified  | 
|
687  | 
||
688  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
689  | 
output_to, reverse=False):  | 
|
690  | 
"""See InventoryEntry._diff."""  | 
|
691  | 
from_text = self.symlink_target  | 
|
692  | 
if to_entry is not None:  | 
|
693  | 
to_text = to_entry.symlink_target  | 
|
694  | 
if reverse:  | 
|
695  | 
temp = from_text  | 
|
696  | 
from_text = to_text  | 
|
697  | 
to_text = temp  | 
|
698  | 
print >>output_to, '=== target changed %r => %r' % (from_text, to_text)  | 
|
699  | 
else:  | 
|
700  | 
if not reverse:  | 
|
701  | 
print >>output_to, '=== target was %r' % self.symlink_target  | 
|
702  | 
else:  | 
|
703  | 
print >>output_to, '=== target is %r' % self.symlink_target  | 
|
704  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
705  | 
def __init__(self, file_id, name, parent_id):  | 
706  | 
super(InventoryLink, self).__init__(file_id, name, parent_id)  | 
|
707  | 
self.kind = 'symlink'  | 
|
708  | 
||
709  | 
def kind_character(self):  | 
|
710  | 
"""See InventoryEntry.kind_character."""  | 
|
711  | 
return ''  | 
|
712  | 
||
713  | 
def _put_in_tar(self, item, tree):  | 
|
714  | 
"""See InventoryEntry._put_in_tar."""  | 
|
| 
1185.33.3
by Martin Pool
 [merge] jelmer  | 
715  | 
item.type = tarfile.SYMTYPE  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
716  | 
fileobj = None  | 
717  | 
item.size = 0  | 
|
718  | 
item.mode = 0755  | 
|
719  | 
item.linkname = self.symlink_target  | 
|
720  | 
return fileobj  | 
|
721  | 
||
722  | 
def _put_on_disk(self, fullpath, tree):  | 
|
723  | 
"""See InventoryEntry._put_on_disk."""  | 
|
724  | 
try:  | 
|
725  | 
os.symlink(self.symlink_target, fullpath)  | 
|
726  | 
except OSError,e:  | 
|
727  | 
raise BzrError("Failed to create symlink %r -> %r, error: %s" % (fullpath, self.symlink_target, e))  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
728  | 
|
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
729  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
730  | 
"""See InventoryEntry._read_tree_state."""  | 
731  | 
self.symlink_target = work_tree.get_symlink_target(self.file_id)  | 
|
732  | 
||
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
733  | 
def _forget_tree_state(self):  | 
734  | 
self.symlink_target = None  | 
|
735  | 
||
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
736  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
737  | 
"""See InventoryEntry._unchanged."""  | 
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
738  | 
compatible = super(InventoryLink, self)._unchanged(previous_ie)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
739  | 
if self.symlink_target != previous_ie.symlink_target:  | 
740  | 
compatible = False  | 
|
741  | 
return compatible  | 
|
742  | 
||
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
743  | 
|
| 
802
by Martin Pool
 - Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions  | 
744  | 
class Inventory(object):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
745  | 
"""Inventory of versioned files in a tree.  | 
746  | 
||
| 
240
by mbp at sourcefrog
 doc  | 
747  | 
    This describes which file_id is present at each point in the tree,
 | 
748  | 
    and possibly the SHA-1 or other information about the file.
 | 
|
749  | 
    Entries can be looked up either by path or by file_id.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
750  | 
|
751  | 
    The inventory represents a typical unix file tree, with
 | 
|
752  | 
    directories containing files and subdirectories.  We never store
 | 
|
753  | 
    the full path to a file, because renaming a directory implicitly
 | 
|
754  | 
    moves all of its contents.  This class internally maintains a
 | 
|
755  | 
    lookup tree that allows the children under a directory to be
 | 
|
756  | 
    returned quickly.
 | 
|
757  | 
||
758  | 
    InventoryEntry objects must not be modified after they are
 | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
759  | 
    inserted, other than through the Inventory API.
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
760  | 
|
761  | 
    >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
762  | 
    >>> inv.add(InventoryFile('123-123', 'hello.c', ROOT_ID))
 | 
763  | 
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
764  | 
    >>> inv['123-123'].name
 | 
765  | 
    'hello.c'
 | 
|
766  | 
||
767  | 
    May be treated as an iterator or set to look up file ids:
 | 
|
768  | 
    
 | 
|
769  | 
    >>> bool(inv.path2id('hello.c'))
 | 
|
770  | 
    True
 | 
|
771  | 
    >>> '123-123' in inv
 | 
|
772  | 
    True
 | 
|
773  | 
||
774  | 
    May also look up by name:
 | 
|
775  | 
||
776  | 
    >>> [x[0] for x in inv.iter_entries()]
 | 
|
777  | 
    ['hello.c']
 | 
|
| 
909
by Martin Pool
 - merge John's code to give the tree root an explicit file id  | 
778  | 
    >>> inv = Inventory('TREE_ROOT-12345678-12345678')
 | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
779  | 
    >>> inv.add(InventoryFile('123-123', 'hello.c', ROOT_ID))
 | 
780  | 
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT-12345678-12345678')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
781  | 
    """
 | 
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
782  | 
def __init__(self, root_id=ROOT_ID, revision_id=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
783  | 
"""Create or read an inventory.  | 
784  | 
||
785  | 
        If a working directory is specified, the inventory is read
 | 
|
786  | 
        from there.  If the file is specified, read from that. If not,
 | 
|
787  | 
        the inventory is created empty.
 | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
788  | 
|
789  | 
        The inventory is created with a default root directory, with
 | 
|
790  | 
        an id of None.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
791  | 
        """
 | 
| 
1534.4.26
by Robert Collins
 Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.  | 
792  | 
        # We are letting Branch.create() create a unique inventory
 | 
| 
909
by Martin Pool
 - merge John's code to give the tree root an explicit file id  | 
793  | 
        # root id. Rather than generating a random one here.
 | 
794  | 
        #if root_id is None:
 | 
|
795  | 
        #    root_id = bzrlib.branch.gen_file_id('TREE_ROOT')
 | 
|
796  | 
self.root = RootEntry(root_id)  | 
|
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
797  | 
self.revision_id = revision_id  | 
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
798  | 
self._byid = {self.root.file_id: self.root}  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
799  | 
|
800  | 
||
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
801  | 
def copy(self):  | 
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
802  | 
        # TODO: jam 20051218 Should copy also copy the revision_id?
 | 
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
803  | 
other = Inventory(self.root.file_id)  | 
| 
1206
by Martin Pool
 - fix bug in Inventory.copy()  | 
804  | 
        # copy recursively so we know directories will be added before
 | 
805  | 
        # their children.  There are more efficient ways than this...
 | 
|
806  | 
for path, entry in self.iter_entries():  | 
|
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
807  | 
if entry == self.root:  | 
808  | 
                continue
 | 
|
809  | 
other.add(entry.copy())  | 
|
810  | 
return other  | 
|
811  | 
||
812  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
813  | 
def __iter__(self):  | 
814  | 
return iter(self._byid)  | 
|
815  | 
||
816  | 
||
817  | 
def __len__(self):  | 
|
818  | 
"""Returns number of entries."""  | 
|
819  | 
return len(self._byid)  | 
|
820  | 
||
821  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
822  | 
def iter_entries(self, from_dir=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
823  | 
"""Return (path, entry) pairs, in order by name."""  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
824  | 
if from_dir == None:  | 
825  | 
assert self.root  | 
|
826  | 
from_dir = self.root  | 
|
827  | 
elif isinstance(from_dir, basestring):  | 
|
828  | 
from_dir = self._byid[from_dir]  | 
|
829  | 
||
830  | 
kids = from_dir.children.items()  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
831  | 
kids.sort()  | 
832  | 
for name, ie in kids:  | 
|
833  | 
yield name, ie  | 
|
834  | 
if ie.kind == 'directory':  | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
835  | 
for cn, cie in self.iter_entries(from_dir=ie.file_id):  | 
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
836  | 
yield pathjoin(name, cn), cie  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
837  | 
|
838  | 
||
839  | 
def entries(self):  | 
|
840  | 
"""Return list of (path, ie) for all entries except the root.  | 
|
841  | 
||
842  | 
        This may be faster than iter_entries.
 | 
|
843  | 
        """
 | 
|
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
844  | 
accum = []  | 
845  | 
def descend(dir_ie, dir_path):  | 
|
| 
556
by Martin Pool
 - fix up Inventory.entries()  | 
846  | 
kids = dir_ie.children.items()  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
847  | 
kids.sort()  | 
848  | 
for name, ie in kids:  | 
|
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
849  | 
child_path = pathjoin(dir_path, name)  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
850  | 
accum.append((child_path, ie))  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
851  | 
if ie.kind == 'directory':  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
852  | 
descend(ie, child_path)  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
853  | 
|
| 
1185.33.66
by Martin Pool
 [patch] use unicode literals for all hardcoded paths (Alexander Belchenko)  | 
854  | 
descend(self.root, u'')  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
855  | 
return accum  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
856  | 
|
857  | 
||
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
858  | 
def directories(self):  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
859  | 
"""Return (path, entry) pairs for all directories, including the root.  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
860  | 
        """
 | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
861  | 
accum = []  | 
862  | 
def descend(parent_ie, parent_path):  | 
|
863  | 
accum.append((parent_path, parent_ie))  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
864  | 
|
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
865  | 
kids = [(ie.name, ie) for ie in parent_ie.children.itervalues() if ie.kind == 'directory']  | 
866  | 
kids.sort()  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
867  | 
|
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
868  | 
for name, child_ie in kids:  | 
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
869  | 
child_path = pathjoin(parent_path, name)  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
870  | 
descend(child_ie, child_path)  | 
| 
1185.33.66
by Martin Pool
 [patch] use unicode literals for all hardcoded paths (Alexander Belchenko)  | 
871  | 
descend(self.root, u'')  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
872  | 
return accum  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
873  | 
|
874  | 
||
875  | 
||
876  | 
def __contains__(self, file_id):  | 
|
877  | 
"""True if this entry contains a file with given id.  | 
|
878  | 
||
879  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
880  | 
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
 | 
881  | 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
882  | 
        >>> '123' in inv
 | 
883  | 
        True
 | 
|
884  | 
        >>> '456' in inv
 | 
|
885  | 
        False
 | 
|
886  | 
        """
 | 
|
887  | 
return file_id in self._byid  | 
|
888  | 
||
889  | 
||
890  | 
def __getitem__(self, file_id):  | 
|
891  | 
"""Return the entry for given file_id.  | 
|
892  | 
||
893  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
894  | 
        >>> inv.add(InventoryFile('123123', 'hello.c', ROOT_ID))
 | 
895  | 
        InventoryFile('123123', 'hello.c', parent_id='TREE_ROOT')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
896  | 
        >>> inv['123123'].name
 | 
897  | 
        'hello.c'
 | 
|
898  | 
        """
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
899  | 
try:  | 
900  | 
return self._byid[file_id]  | 
|
901  | 
except KeyError:  | 
|
| 
380
by Martin Pool
 - Slight optimization for Inventory.__getitem__  | 
902  | 
if file_id == None:  | 
903  | 
raise BzrError("can't look up file_id None")  | 
|
904  | 
else:  | 
|
905  | 
raise BzrError("file_id {%s} not in inventory" % file_id)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
906  | 
|
907  | 
||
| 
460
by Martin Pool
 - new testing command compare-trees  | 
908  | 
def get_file_kind(self, file_id):  | 
909  | 
return self._byid[file_id].kind  | 
|
910  | 
||
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
911  | 
def get_child(self, parent_id, filename):  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
912  | 
return self[parent_id].children.get(filename)  | 
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
913  | 
|
914  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
915  | 
def add(self, entry):  | 
916  | 
"""Add entry to inventory.  | 
|
917  | 
||
918  | 
        To add  a file to a branch ready to be committed, use Branch.add,
 | 
|
| 
1180
by Martin Pool
 - start splitting code for xml (de)serialization away from objects  | 
919  | 
        which calls this.
 | 
920  | 
||
921  | 
        Returns the new entry object.
 | 
|
922  | 
        """
 | 
|
| 
139
by mbp at sourcefrog
 simplified/faster Inventory.add  | 
923  | 
if entry.file_id in self._byid:  | 
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
924  | 
raise BzrError("inventory already contains entry with id {%s}" % entry.file_id)  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
925  | 
|
| 
909
by Martin Pool
 - merge John's code to give the tree root an explicit file id  | 
926  | 
if entry.parent_id == ROOT_ID or entry.parent_id is None:  | 
927  | 
entry.parent_id = self.root.file_id  | 
|
928  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
929  | 
try:  | 
930  | 
parent = self._byid[entry.parent_id]  | 
|
931  | 
except KeyError:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
932  | 
raise BzrError("parent_id {%s} not in inventory" % entry.parent_id)  | 
| 
139
by mbp at sourcefrog
 simplified/faster Inventory.add  | 
933  | 
|
934  | 
if parent.children.has_key(entry.name):  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
935  | 
raise BzrError("%s is already versioned" %  | 
| 
1185.31.32
by John Arbash Meinel
 Updated the bzr sourcecode to use bzrlib.osutils.pathjoin rather than os.path.join to enforce internal use of / instead of \  | 
936  | 
pathjoin(self.id2path(parent.file_id), entry.name))  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
937  | 
|
938  | 
self._byid[entry.file_id] = entry  | 
|
| 
139
by mbp at sourcefrog
 simplified/faster Inventory.add  | 
939  | 
parent.children[entry.name] = entry  | 
| 
1092.1.30
by Robert Collins
 change smart_add reporting of added files to callback with the entry, and change the inventory.add signature to return the added entry  | 
940  | 
return entry  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
941  | 
|
942  | 
||
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
943  | 
def add_path(self, relpath, kind, file_id=None):  | 
944  | 
"""Add entry from a path.  | 
|
945  | 
||
| 
1180
by Martin Pool
 - start splitting code for xml (de)serialization away from objects  | 
946  | 
        The immediate parent must already be versioned.
 | 
947  | 
||
948  | 
        Returns the new entry object."""
 | 
|
| 
1508.1.5
by Robert Collins
 Move add from Branch to WorkingTree.  | 
949  | 
from bzrlib.workingtree import gen_file_id  | 
| 
1015
by Martin Pool
 - fix circular imports  | 
950  | 
|
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
951  | 
parts = bzrlib.osutils.splitpath(relpath)  | 
952  | 
||
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
953  | 
if file_id == None:  | 
| 
800
by Martin Pool
 Merge John's import-speedup branch:  | 
954  | 
file_id = gen_file_id(relpath)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
955  | 
|
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
956  | 
if len(parts) == 0:  | 
957  | 
self.root = RootEntry(file_id)  | 
|
958  | 
self._byid = {self.root.file_id: self.root}  | 
|
959  | 
            return
 | 
|
960  | 
else:  | 
|
961  | 
parent_path = parts[:-1]  | 
|
962  | 
parent_id = self.path2id(parent_path)  | 
|
963  | 
if parent_id == None:  | 
|
964  | 
raise NotVersionedError(path=parent_path)  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
965  | 
if kind == 'directory':  | 
966  | 
ie = InventoryDirectory(file_id, parts[-1], parent_id)  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
967  | 
elif kind == 'file':  | 
968  | 
ie = InventoryFile(file_id, parts[-1], parent_id)  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
969  | 
elif kind == 'symlink':  | 
970  | 
ie = InventoryLink(file_id, parts[-1], parent_id)  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
971  | 
else:  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
972  | 
raise BzrError("unknown kind %r" % kind)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
973  | 
return self.add(ie)  | 
974  | 
||
975  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
976  | 
def __delitem__(self, file_id):  | 
977  | 
"""Remove entry by id.  | 
|
978  | 
||
979  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
980  | 
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
 | 
981  | 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
982  | 
        >>> '123' in inv
 | 
983  | 
        True
 | 
|
984  | 
        >>> del inv['123']
 | 
|
985  | 
        >>> '123' in inv
 | 
|
986  | 
        False
 | 
|
987  | 
        """
 | 
|
988  | 
ie = self[file_id]  | 
|
989  | 
||
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
990  | 
assert ie.parent_id is None or \  | 
991  | 
self[ie.parent_id].children[ie.name] == ie  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
992  | 
|
993  | 
del self._byid[file_id]  | 
|
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
994  | 
if ie.parent_id is not None:  | 
995  | 
del self[ie.parent_id].children[ie.name]  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
996  | 
|
997  | 
||
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
998  | 
def __eq__(self, other):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
999  | 
"""Compare two sets by comparing their contents.  | 
1000  | 
||
1001  | 
        >>> i1 = Inventory()
 | 
|
1002  | 
        >>> i2 = Inventory()
 | 
|
1003  | 
        >>> i1 == i2
 | 
|
1004  | 
        True
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1005  | 
        >>> i1.add(InventoryFile('123', 'foo', ROOT_ID))
 | 
1006  | 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1007  | 
        >>> i1 == i2
 | 
1008  | 
        False
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1009  | 
        >>> i2.add(InventoryFile('123', 'foo', ROOT_ID))
 | 
1010  | 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT')
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1011  | 
        >>> i1 == i2
 | 
1012  | 
        True
 | 
|
1013  | 
        """
 | 
|
1014  | 
if not isinstance(other, Inventory):  | 
|
1015  | 
return NotImplemented  | 
|
1016  | 
||
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1017  | 
if len(self._byid) != len(other._byid):  | 
| 
543
by Martin Pool
 - More cleanups for set type  | 
1018  | 
            # shortcut: obviously not the same
 | 
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1019  | 
return False  | 
1020  | 
||
1021  | 
return self._byid == other._byid  | 
|
1022  | 
||
1023  | 
||
1024  | 
def __ne__(self, other):  | 
|
| 
1249
by Martin Pool
 - improvements to weave commit [broken]  | 
1025  | 
return not self.__eq__(other)  | 
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1026  | 
|
1027  | 
||
1028  | 
def __hash__(self):  | 
|
1029  | 
raise ValueError('not hashable')  | 
|
1030  | 
||
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1031  | 
def _iter_file_id_parents(self, file_id):  | 
1032  | 
"""Yield the parents of file_id up to the root."""  | 
|
1033  | 
while file_id != None:  | 
|
1034  | 
try:  | 
|
1035  | 
ie = self._byid[file_id]  | 
|
1036  | 
except KeyError:  | 
|
1037  | 
raise BzrError("file_id {%s} not found in inventory" % file_id)  | 
|
1038  | 
yield ie  | 
|
1039  | 
file_id = ie.parent_id  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1040  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1041  | 
def get_idpath(self, file_id):  | 
1042  | 
"""Return a list of file_ids for the path to an entry.  | 
|
1043  | 
||
1044  | 
        The list contains one element for each directory followed by
 | 
|
1045  | 
        the id of the file itself.  So the length of the returned list
 | 
|
1046  | 
        is equal to the depth of the file in the tree, counting the
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1047  | 
        root directory as depth 1.
 | 
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1048  | 
        """
 | 
1049  | 
p = []  | 
|
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1050  | 
for parent in self._iter_file_id_parents(file_id):  | 
1051  | 
p.insert(0, parent.file_id)  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1052  | 
return p  | 
1053  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1054  | 
def id2path(self, file_id):  | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1055  | 
"""Return as a string the path to file_id.  | 
| 
1393.1.32
by Martin Pool
 - add docstring demonstrating use of Inventory.id2path  | 
1056  | 
        
 | 
1057  | 
        >>> i = Inventory()
 | 
|
1058  | 
        >>> e = i.add(InventoryDirectory('src-id', 'src', ROOT_ID))
 | 
|
1059  | 
        >>> e = i.add(InventoryFile('foo-id', 'foo.c', parent_id='src-id'))
 | 
|
| 
1185.31.34
by John Arbash Meinel
 Removing instances of os.sep  | 
1060  | 
        >>> print i.id2path('foo-id')
 | 
| 
1393.1.32
by Martin Pool
 - add docstring demonstrating use of Inventory.id2path  | 
1061  | 
        src/foo.c
 | 
1062  | 
        """
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1063  | 
        # get all names, skipping root
 | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1064  | 
return '/'.join(reversed(  | 
1065  | 
[parent.name for parent in  | 
|
1066  | 
self._iter_file_id_parents(file_id)][:-1]))  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1067  | 
|
1068  | 
def path2id(self, name):  | 
|
1069  | 
"""Walk down through directories to return entry of last component.  | 
|
1070  | 
||
1071  | 
        names may be either a list of path components, or a single
 | 
|
1072  | 
        string, in which case it is automatically split.
 | 
|
1073  | 
||
1074  | 
        This returns the entry of the last component in the path,
 | 
|
1075  | 
        which may be either a file or a directory.
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1076  | 
|
1077  | 
        Returns None iff the path is not found.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1078  | 
        """
 | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1079  | 
if isinstance(name, types.StringTypes):  | 
1080  | 
name = splitpath(name)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1081  | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1082  | 
mutter("lookup path %r" % name)  | 
1083  | 
||
1084  | 
parent = self.root  | 
|
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1085  | 
for f in name:  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1086  | 
try:  | 
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1087  | 
cie = parent.children[f]  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1088  | 
assert cie.name == f  | 
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1089  | 
assert cie.parent_id == parent.file_id  | 
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1090  | 
parent = cie  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1091  | 
except KeyError:  | 
1092  | 
                # or raise an error?
 | 
|
1093  | 
return None  | 
|
1094  | 
||
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1095  | 
return parent.file_id  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1096  | 
|
1097  | 
||
1098  | 
def has_filename(self, names):  | 
|
1099  | 
return bool(self.path2id(names))  | 
|
1100  | 
||
1101  | 
||
1102  | 
def has_id(self, file_id):  | 
|
1103  | 
return self._byid.has_key(file_id)  | 
|
1104  | 
||
1105  | 
||
| 
160
by mbp at sourcefrog
 - basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think  | 
1106  | 
def rename(self, file_id, new_parent_id, new_name):  | 
1107  | 
"""Move a file within the inventory.  | 
|
1108  | 
||
1109  | 
        This can change either the name, or the parent, or both.
 | 
|
1110  | 
||
1111  | 
        This does not move the working file."""
 | 
|
1112  | 
if not is_valid_name(new_name):  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1113  | 
raise BzrError("not an acceptable filename: %r" % new_name)  | 
| 
160
by mbp at sourcefrog
 - basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think  | 
1114  | 
|
1115  | 
new_parent = self._byid[new_parent_id]  | 
|
1116  | 
if new_name in new_parent.children:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1117  | 
raise BzrError("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))  | 
| 
160
by mbp at sourcefrog
 - basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think  | 
1118  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1119  | 
new_parent_idpath = self.get_idpath(new_parent_id)  | 
1120  | 
if file_id in new_parent_idpath:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1121  | 
raise BzrError("cannot move directory %r into a subdirectory of itself, %r"  | 
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1122  | 
% (self.id2path(file_id), self.id2path(new_parent_id)))  | 
1123  | 
||
| 
160
by mbp at sourcefrog
 - basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think  | 
1124  | 
file_ie = self._byid[file_id]  | 
1125  | 
old_parent = self._byid[file_ie.parent_id]  | 
|
1126  | 
||
1127  | 
        # TODO: Don't leave things messed up if this fails
 | 
|
1128  | 
||
1129  | 
del old_parent.children[file_ie.name]  | 
|
1130  | 
new_parent.children[new_name] = file_ie  | 
|
1131  | 
||
1132  | 
file_ie.name = new_name  | 
|
1133  | 
file_ie.parent_id = new_parent_id  | 
|
1134  | 
||
1135  | 
||
1136  | 
||
1137  | 
||
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
1138  | 
_NAME_RE = None  | 
| 
160
by mbp at sourcefrog
 - basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think  | 
1139  | 
|
1140  | 
def is_valid_name(name):  | 
|
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
1141  | 
global _NAME_RE  | 
1142  | 
if _NAME_RE == None:  | 
|
1143  | 
_NAME_RE = re.compile(r'^[^/\\]+$')  | 
|
1144  | 
||
| 
160
by mbp at sourcefrog
 - basic support for moving files to different directories - have not done support for renaming them yet, but should be straightforward - some tests, but many cases are not handled yet i think  | 
1145  | 
return bool(_NAME_RE.match(name))  |