bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
2255.2.158
by Martin Pool
 Most of the integration of dirstate and subtree  | 
1  | 
# Copyright (C) 2005, 2006, 2007 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  | 
||
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
30  | 
import os  | 
| 
1185.1.41
by Robert Collins
 massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid  | 
31  | 
import re  | 
32  | 
import sys  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
33  | 
|
34  | 
from bzrlib.lazy_import import lazy_import  | 
|
35  | 
lazy_import(globals(), """  | 
|
36  | 
import collections
 | 
|
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
37  | 
import tarfile
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
38  | 
|
| 
800
by Martin Pool
 Merge John's import-speedup branch:  | 
39  | 
import bzrlib
 | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
40  | 
from bzrlib import (
 | 
41  | 
    errors,
 | 
|
| 
2116.4.1
by John Arbash Meinel
 Update file and revision id generators.  | 
42  | 
    generate_ids,
 | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
43  | 
    osutils,
 | 
44  | 
    symbol_versioning,
 | 
|
| 
2094.3.5
by John Arbash Meinel
 Fix imports to ensure modules are loaded before they are used  | 
45  | 
    workingtree,
 | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
46  | 
    )
 | 
47  | 
""")  | 
|
48  | 
||
49  | 
from bzrlib.errors import (  | 
|
50  | 
BzrCheckError,  | 
|
51  | 
BzrError,  | 
|
52  | 
    )
 | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
53  | 
from bzrlib.symbol_versioning import deprecated_method, zero_ninetyone  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
54  | 
from bzrlib.trace import mutter  | 
| 
1185.1.41
by Robert Collins
 massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid  | 
55  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
56  | 
|
| 
802
by Martin Pool
 - Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions  | 
57  | 
class InventoryEntry(object):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
58  | 
"""Description of a versioned file.  | 
59  | 
||
60  | 
    An InventoryEntry has the following fields, which are also
 | 
|
61  | 
    present in the XML inventory-entry element:
 | 
|
62  | 
||
| 
1197
by Martin Pool
 doc  | 
63  | 
    file_id
 | 
64  | 
||
65  | 
    name
 | 
|
66  | 
        (within the parent directory)
 | 
|
67  | 
||
68  | 
    parent_id
 | 
|
69  | 
        file_id of the parent directory, or ROOT_ID
 | 
|
70  | 
||
| 
1092.2.21
by Robert Collins
 convert name_version to revision in inventory entries  | 
71  | 
    revision
 | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
72  | 
        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  | 
73  | 
        introduced.
 | 
| 
1197
by Martin Pool
 doc  | 
74  | 
|
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
75  | 
    executable
 | 
76  | 
        Indicates that this file should be executable on systems
 | 
|
77  | 
        that support it.
 | 
|
78  | 
||
| 
1197
by Martin Pool
 doc  | 
79  | 
    text_sha1
 | 
80  | 
        sha-1 of the text of the file
 | 
|
81  | 
        
 | 
|
82  | 
    text_size
 | 
|
83  | 
        size in bytes of the text of the file
 | 
|
84  | 
        
 | 
|
85  | 
    (reading a version 4 tree created a text_id field.)
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
86  | 
|
87  | 
    >>> i = Inventory()
 | 
|
88  | 
    >>> i.path2id('')
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
89  | 
    'TREE_ROOT'
 | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
90  | 
    >>> i.add(InventoryDirectory('123', 'src', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
91  | 
    InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None)
 | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
92  | 
    >>> i.add(InventoryFile('2323', 'hello.c', parent_id='123'))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
93  | 
    InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None)
 | 
| 
1996.3.13
by John Arbash Meinel
 Fix the inventory doc tests  | 
94  | 
    >>> shouldbe = {0: '', 1: 'src', 2: 'src/hello.c'}
 | 
| 
1185.16.151
by Martin Pool
 [patch] win32 fix for InventoryEntry doctest (Alexander, patch 21)  | 
95  | 
    >>> for ix, j in enumerate(i.iter_entries()):
 | 
96  | 
    ...   print (j[0] == shouldbe[ix], j[1])
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
97  | 
    ... 
 | 
| 
2294.1.8
by John Arbash Meinel
 Fix one doc test in Inventory which expected a plain str  | 
98  | 
    (True, InventoryDirectory('TREE_ROOT', u'', parent_id=None, revision=None))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
99  | 
    (True, InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None))
 | 
100  | 
    (True, InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None))
 | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
101  | 
    >>> i.add(InventoryFile('2324', 'bye.c', '123'))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
102  | 
    InventoryFile('2324', 'bye.c', parent_id='123', sha1=None, len=None)
 | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
103  | 
    >>> i.add(InventoryDirectory('2325', 'wibble', '123'))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
104  | 
    InventoryDirectory('2325', 'wibble', parent_id='123', revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
105  | 
    >>> i.path2id('src/wibble')
 | 
106  | 
    '2325'
 | 
|
107  | 
    >>> '2325' in i
 | 
|
108  | 
    True
 | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
109  | 
    >>> i.add(InventoryFile('2326', 'wibble.c', '2325'))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
110  | 
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
111  | 
    >>> i['2326']
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
112  | 
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None)
 | 
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
113  | 
    >>> 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 \  | 
114  | 
    ...     print path
 | 
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
115  | 
    ...     assert i.path2id(path)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
116  | 
    ... 
 | 
| 
1852.6.6
by Robert Collins
 Finish updating iter_entries change to make all tests pass.  | 
117  | 
    <BLANKLINE>
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
118  | 
    src
 | 
119  | 
    src/bye.c
 | 
|
120  | 
    src/hello.c
 | 
|
121  | 
    src/wibble
 | 
|
122  | 
    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 \  | 
123  | 
    >>> i.id2path('2326')
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
124  | 
    'src/wibble/wibble.c'
 | 
125  | 
    """
 | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
126  | 
|
127  | 
    # Constants returned by describe_change()
 | 
|
128  | 
    #
 | 
|
129  | 
    # TODO: These should probably move to some kind of FileChangeDescription 
 | 
|
130  | 
    # class; that's like what's inside a TreeDelta but we want to be able to 
 | 
|
131  | 
    # generate them just for one file at a time.
 | 
|
132  | 
RENAMED = 'renamed'  | 
|
133  | 
MODIFIED_AND_RENAMED = 'modified and renamed'  | 
|
| 
1197
by Martin Pool
 doc  | 
134  | 
|
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
135  | 
__slots__ = []  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
136  | 
|
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
137  | 
def detect_changes(self, old_entry):  | 
138  | 
"""Return a (text_modified, meta_modified) from this to old_entry.  | 
|
139  | 
        
 | 
|
140  | 
        _read_tree_state must have been called on self and old_entry prior to 
 | 
|
141  | 
        calling detect_changes.
 | 
|
142  | 
        """
 | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
143  | 
return False, False  | 
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
144  | 
|
| 
1399.1.4
by Robert Collins
 move diff and symlink conditionals into inventory.py from diff.py  | 
145  | 
def diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
146  | 
output_to, reverse=False):  | 
|
147  | 
"""Perform a diff from this to to_entry.  | 
|
148  | 
||
149  | 
        text_diff will be used for textual difference calculation.
 | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
150  | 
        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  | 
151  | 
        """
 | 
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
152  | 
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  | 
153  | 
if to_entry:  | 
154  | 
            # cannot diff from one kind to another - you must do a removal
 | 
|
155  | 
            # and an addif they do not match.
 | 
|
156  | 
assert self.kind == to_entry.kind  | 
|
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
157  | 
to_entry._read_tree_state(to_tree.id2path(to_entry.file_id),  | 
158  | 
to_tree)  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
159  | 
self._diff(text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
160  | 
output_to, reverse)  | 
|
161  | 
||
162  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
163  | 
output_to, reverse=False):  | 
|
164  | 
"""Perform a diff between two entries of the same kind."""  | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
165  | 
|
166  | 
def parent_candidates(self, previous_inventories):  | 
|
167  | 
"""Find possible per-file graph parents.  | 
|
168  | 
||
169  | 
        This is currently defined by:
 | 
|
170  | 
         - Select the last changed revision in the parent inventory.
 | 
|
171  | 
         - Do deal with a short lived bug in bzr 0.8's development two entries
 | 
|
172  | 
           that have the same last changed but different 'x' bit settings are
 | 
|
173  | 
           changed in-place.
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
174  | 
        """
 | 
| 
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  | 
        # identify candidate head revision ids.
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
178  | 
for inv in previous_inventories:  | 
179  | 
if self.file_id in inv:  | 
|
180  | 
ie = inv[self.file_id]  | 
|
181  | 
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.  | 
182  | 
if ie.revision in candidates:  | 
183  | 
                    # same revision value in two different inventories:
 | 
|
184  | 
                    # correct possible inconsistencies:
 | 
|
185  | 
                    #     * there was a bug in revision updates with 'x' bit 
 | 
|
186  | 
                    #       support.
 | 
|
| 
1185.1.51
by Robert Collins
 merge in reweave support  | 
187  | 
try:  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
188  | 
if candidates[ie.revision].executable != ie.executable:  | 
189  | 
candidates[ie.revision].executable = False  | 
|
| 
1185.1.51
by Robert Collins
 merge in reweave support  | 
190  | 
ie.executable = False  | 
191  | 
except AttributeError:  | 
|
192  | 
                        pass
 | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
193  | 
                    # must now be the same.
 | 
194  | 
assert candidates[ie.revision] == ie  | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
195  | 
else:  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
196  | 
                    # add this revision as a candidate.
 | 
197  | 
candidates[ie.revision] = ie  | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
198  | 
return candidates  | 
199  | 
||
200  | 
@deprecated_method(zero_ninetyone)  | 
|
201  | 
def find_previous_heads(self, previous_inventories,  | 
|
202  | 
versioned_file_store,  | 
|
203  | 
transaction,  | 
|
204  | 
entry_vf=None):  | 
|
205  | 
"""Return the revisions and entries that directly precede this.  | 
|
206  | 
||
207  | 
        Returned as a map from revision to inventory entry.
 | 
|
208  | 
||
209  | 
        This is a map containing the file revisions in all parents
 | 
|
210  | 
        for which the file exists, and its revision is not a parent of
 | 
|
211  | 
        any other. If the file is new, the set will be empty.
 | 
|
212  | 
||
213  | 
        :param versioned_file_store: A store where ancestry data on this
 | 
|
214  | 
                                     file id can be queried.
 | 
|
215  | 
        :param transaction: The transaction that queries to the versioned 
 | 
|
216  | 
                            file store should be completed under.
 | 
|
217  | 
        :param entry_vf: The entry versioned file, if its already available.
 | 
|
218  | 
        """
 | 
|
219  | 
candidates = self.parent_candidates(previous_inventories)  | 
|
220  | 
||
221  | 
        # revision:ie mapping with one revision for each head.
 | 
|
222  | 
heads = {}  | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
223  | 
        # common case optimisation
 | 
224  | 
if len(candidates) == 1:  | 
|
225  | 
            # if there is only one candidate revision found
 | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
226  | 
            # then we can avoid opening the versioned file to access ancestry:
 | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
227  | 
            # there cannot be any ancestors to eliminate when there is 
 | 
228  | 
            # only one revision available.
 | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
229  | 
return candidates  | 
230  | 
||
231  | 
        # --- what follows is now encapsulated in repository.get_graph.heads(), 
 | 
|
232  | 
        #     but that is not accessible from here as we have no repository
 | 
|
233  | 
        #     pointer. Note that the repository.get_graph.heads() call can return
 | 
|
234  | 
        #     different results *at the moment* because of the kind-changing check
 | 
|
235  | 
        #     we have in parent_candidates().
 | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
236  | 
|
237  | 
        # eliminate ancestors amongst the available candidates:
 | 
|
238  | 
        # heads are those that are not an ancestor of any other candidate
 | 
|
239  | 
        # - this provides convergence at a per-file level.
 | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
240  | 
def get_ancestors(weave, entry):  | 
241  | 
return set(weave.get_ancestry(entry.revision, topo_sorted=False))  | 
|
242  | 
        # revision: ancestor list for each head
 | 
|
243  | 
head_ancestors = {}  | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
244  | 
for ie in candidates.values():  | 
245  | 
            # may be an ancestor of a known head:
 | 
|
246  | 
already_present = 0 != len(  | 
|
247  | 
[head for head in heads  | 
|
248  | 
if ie.revision in head_ancestors[head]])  | 
|
249  | 
if already_present:  | 
|
250  | 
                # an ancestor of an analyzed candidate.
 | 
|
251  | 
                continue
 | 
|
252  | 
            # not an ancestor of a known head:
 | 
|
253  | 
            # load the versioned file for this file id if needed
 | 
|
254  | 
if entry_vf is None:  | 
|
255  | 
entry_vf = versioned_file_store.get_weave_or_empty(  | 
|
256  | 
self.file_id, transaction)  | 
|
257  | 
ancestors = get_ancestors(entry_vf, ie)  | 
|
258  | 
            # may knock something else out:
 | 
|
259  | 
check_heads = list(heads.keys())  | 
|
260  | 
for head in check_heads:  | 
|
261  | 
if head in ancestors:  | 
|
262  | 
                    # this previously discovered 'head' is not
 | 
|
263  | 
                    # really a head - its an ancestor of the newly 
 | 
|
264  | 
                    # found head,
 | 
|
265  | 
heads.pop(head)  | 
|
266  | 
head_ancestors[ie.revision] = ancestors  | 
|
267  | 
heads[ie.revision] = ie  | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
268  | 
return heads  | 
269  | 
||
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
270  | 
def get_tar_item(self, root, dp, now, tree):  | 
| 
1399.1.7
by Robert Collins
 implement symlink exporting to tarballs  | 
271  | 
"""Get a tarfile item and a file stream for its content."""  | 
| 
1996.3.20
by John Arbash Meinel
 [merge] bzr.dev 2063  | 
272  | 
item = tarfile.TarInfo(osutils.pathjoin(root, dp).encode('utf8'))  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
273  | 
        # TODO: would be cool to actually set it to the timestamp of the
 | 
274  | 
        # revision it was last changed
 | 
|
275  | 
item.mtime = now  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
276  | 
fileobj = self._put_in_tar(item, tree)  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
277  | 
return item, fileobj  | 
278  | 
||
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
279  | 
def has_text(self):  | 
280  | 
"""Return true if the object this entry represents has textual data.  | 
|
281  | 
||
282  | 
        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  | 
283  | 
|
284  | 
        Also note that all entries get weave files created for them.
 | 
|
285  | 
        This attribute is primarily used when upgrading from old trees that
 | 
|
286  | 
        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  | 
287  | 
        """
 | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
288  | 
return False  | 
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
289  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
290  | 
def __init__(self, file_id, name, parent_id, text_id=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
291  | 
"""Create an InventoryEntry  | 
292  | 
        
 | 
|
293  | 
        The filename must be a single component, relative to the
 | 
|
294  | 
        parent directory; it cannot be a whole path or relative name.
 | 
|
295  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
296  | 
        >>> e = InventoryFile('123', 'hello.c', ROOT_ID)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
297  | 
        >>> e.name
 | 
298  | 
        'hello.c'
 | 
|
299  | 
        >>> e.file_id
 | 
|
300  | 
        '123'
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
301  | 
        >>> e = InventoryFile('123', 'src/hello.c', ROOT_ID)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
302  | 
        Traceback (most recent call last):
 | 
| 
1185.16.63
by Martin Pool
 - more error conversion  | 
303  | 
        InvalidEntryName: Invalid entry name: src/hello.c
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
304  | 
        """
 | 
| 
1183
by Martin Pool
 - implement version 5 xml storage, and tests  | 
305  | 
assert isinstance(name, basestring), name  | 
| 
376
by Martin Pool
 - fix slow invariant check when reading in InventoryEntry objects  | 
306  | 
if '/' in name or '\\' in name:  | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
307  | 
raise errors.InvalidEntryName(name=name)  | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
308  | 
self.executable = False  | 
| 
1092.2.21
by Robert Collins
 convert name_version to revision in inventory entries  | 
309  | 
self.revision = None  | 
| 
955
by Martin Pool
 - use __slots__ on InventoryEntry; rather faster  | 
310  | 
self.text_sha1 = None  | 
311  | 
self.text_size = None  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
312  | 
self.file_id = file_id  | 
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
313  | 
assert isinstance(file_id, (str, None.__class__)), \  | 
314  | 
'bad type %r for %r' % (type(file_id), file_id)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
315  | 
self.name = name  | 
316  | 
self.text_id = text_id  | 
|
317  | 
self.parent_id = parent_id  | 
|
| 
1092.2.6
by Robert Collins
 symlink support updated to work  | 
318  | 
self.symlink_target = None  | 
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
319  | 
self.reference_revision = None  | 
| 
237
by mbp at sourcefrog
 - Better assertions in InventoryEntry constructor  | 
320  | 
|
| 
1399.1.2
by Robert Collins
 push kind character creation into InventoryEntry and TreeEntry  | 
321  | 
def kind_character(self):  | 
322  | 
"""Return a short kind indicator useful for appending to names."""  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
323  | 
raise BzrError('unknown kind %r' % self.kind)  | 
| 
1399.1.2
by Robert Collins
 push kind character creation into InventoryEntry and TreeEntry  | 
324  | 
|
| 
1731.1.2
by Aaron Bentley
 Removed all remaining uses of root_directory  | 
325  | 
known_kinds = ('file', 'directory', 'symlink')  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
326  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
327  | 
def _put_in_tar(self, item, tree):  | 
328  | 
"""populate item for stashing in a tar, and return the content stream.  | 
|
329  | 
||
330  | 
        If no content is available, return None.
 | 
|
331  | 
        """
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
332  | 
raise BzrError("don't know how to export {%s} of kind %r" %  | 
333  | 
(self.file_id, self.kind))  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
334  | 
|
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
335  | 
def put_on_disk(self, dest, dp, tree):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
336  | 
"""Create a representation of self on disk in the prefix dest.  | 
337  | 
        
 | 
|
338  | 
        This is a template method - implement _put_on_disk in subclasses.
 | 
|
339  | 
        """
 | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
340  | 
fullpath = osutils.pathjoin(dest, dp)  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
341  | 
self._put_on_disk(fullpath, tree)  | 
| 
1711.2.101
by John Arbash Meinel
 Clean up some unnecessary mutter() calls  | 
342  | 
        # mutter("  export {%s} kind %s to %s", self.file_id,
 | 
343  | 
        #         self.kind, fullpath)
 | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
344  | 
|
345  | 
def _put_on_disk(self, fullpath, tree):  | 
|
346  | 
"""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  | 
347  | 
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  | 
348  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
349  | 
def sorted_children(self):  | 
| 
1757.2.13
by Robert Collins
 Tweak InventoryEntry.sorted_children to be simpler.  | 
350  | 
return sorted(self.children.items())  | 
| 
156
by mbp at sourcefrog
 new "directories" command  | 
351  | 
|
| 
1399.1.1
by Robert Collins
 move checks for versionability of file kinds into InventoryEntry  | 
352  | 
    @staticmethod
 | 
353  | 
def versionable_kind(kind):  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
354  | 
return (kind in ('file', 'directory', 'symlink', 'tree-reference'))  | 
| 
1399.1.1
by Robert Collins
 move checks for versionability of file kinds into InventoryEntry  | 
355  | 
|
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
356  | 
def check(self, checker, rev_id, inv, tree):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
357  | 
"""Check this inventory entry is intact.  | 
358  | 
||
359  | 
        This is a template method, override _check for kind specific
 | 
|
360  | 
        tests.
 | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
361  | 
|
362  | 
        :param checker: Check object providing context for the checks; 
 | 
|
363  | 
             can be used to find out what parts of the repository have already
 | 
|
364  | 
             been checked.
 | 
|
365  | 
        :param rev_id: Revision id from which this InventoryEntry was loaded.
 | 
|
366  | 
             Not necessarily the last-changed revision for this file.
 | 
|
367  | 
        :param inv: Inventory from which the entry was loaded.
 | 
|
368  | 
        :param tree: RevisionTree for this entry.
 | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
369  | 
        """
 | 
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
370  | 
if self.parent_id is not None:  | 
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
371  | 
if not inv.has_id(self.parent_id):  | 
372  | 
raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'  | 
|
373  | 
% (self.parent_id, rev_id))  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
374  | 
self._check(checker, rev_id, tree)  | 
375  | 
||
376  | 
def _check(self, checker, rev_id, tree):  | 
|
377  | 
"""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  | 
378  | 
raise BzrCheckError('unknown entry kind %r in revision {%s}' %  | 
379  | 
(self.kind, rev_id))  | 
|
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
380  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
381  | 
def copy(self):  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
382  | 
"""Clone this inventory entry."""  | 
383  | 
raise NotImplementedError  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
384  | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
385  | 
    @staticmethod
 | 
386  | 
def describe_change(old_entry, new_entry):  | 
|
387  | 
"""Describe the change between old_entry and this.  | 
|
388  | 
        
 | 
|
389  | 
        This smells of being an InterInventoryEntry situation, but as its
 | 
|
390  | 
        the first one, we're making it a static method for now.
 | 
|
391  | 
||
392  | 
        An entry with a different parent, or different name is considered 
 | 
|
393  | 
        to be renamed. Reparenting is an internal detail.
 | 
|
394  | 
        Note that renaming the parent does not trigger a rename for the
 | 
|
395  | 
        child entry itself.
 | 
|
| 
1669.2.1
by Martin Pool
 verbose commit now specifically identifies modified/renamed/reparented files  | 
396  | 
        """
 | 
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
397  | 
        # TODO: Perhaps return an object rather than just a string
 | 
398  | 
if old_entry is new_entry:  | 
|
399  | 
            # also the case of both being None
 | 
|
400  | 
return 'unchanged'  | 
|
401  | 
elif old_entry is None:  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
402  | 
return 'added'  | 
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
403  | 
elif new_entry is None:  | 
404  | 
return 'removed'  | 
|
| 
1959.4.1
by Aaron Bentley
 Correctly handle all file kind changes  | 
405  | 
if old_entry.kind != new_entry.kind:  | 
406  | 
return 'modified'  | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
407  | 
text_modified, meta_modified = new_entry.detect_changes(old_entry)  | 
408  | 
if text_modified or meta_modified:  | 
|
409  | 
modified = True  | 
|
410  | 
else:  | 
|
411  | 
modified = False  | 
|
412  | 
        # TODO 20060511 (mbp, rbc) factor out 'detect_rename' here.
 | 
|
413  | 
if old_entry.parent_id != new_entry.parent_id:  | 
|
414  | 
renamed = True  | 
|
415  | 
elif old_entry.name != new_entry.name:  | 
|
416  | 
renamed = True  | 
|
417  | 
else:  | 
|
418  | 
renamed = False  | 
|
419  | 
if renamed and not modified:  | 
|
420  | 
return InventoryEntry.RENAMED  | 
|
421  | 
if modified and not renamed:  | 
|
422  | 
return 'modified'  | 
|
423  | 
if modified and renamed:  | 
|
424  | 
return InventoryEntry.MODIFIED_AND_RENAMED  | 
|
425  | 
return 'unchanged'  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
426  | 
|
427  | 
def __repr__(self):  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
428  | 
return ("%s(%r, %r, parent_id=%r, revision=%r)"  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
429  | 
% (self.__class__.__name__,  | 
430  | 
self.file_id,  | 
|
431  | 
self.name,  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
432  | 
self.parent_id,  | 
433  | 
self.revision))  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
434  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
435  | 
def __eq__(self, other):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
436  | 
if not isinstance(other, InventoryEntry):  | 
437  | 
return NotImplemented  | 
|
438  | 
||
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
439  | 
return ((self.file_id == other.file_id)  | 
440  | 
and (self.name == other.name)  | 
|
441  | 
and (other.symlink_target == self.symlink_target)  | 
|
442  | 
and (self.text_sha1 == other.text_sha1)  | 
|
443  | 
and (self.text_size == other.text_size)  | 
|
444  | 
and (self.text_id == other.text_id)  | 
|
445  | 
and (self.parent_id == other.parent_id)  | 
|
446  | 
and (self.kind == other.kind)  | 
|
447  | 
and (self.revision == other.revision)  | 
|
448  | 
and (self.executable == other.executable)  | 
|
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
449  | 
and (self.reference_revision == other.reference_revision)  | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
450  | 
                )
 | 
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
451  | 
|
452  | 
def __ne__(self, other):  | 
|
453  | 
return not (self == other)  | 
|
454  | 
||
455  | 
def __hash__(self):  | 
|
456  | 
raise ValueError('not hashable')  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
457  | 
|
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
458  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
459  | 
"""Has this entry changed relative to previous_ie.  | 
460  | 
||
| 
1759.2.1
by Jelmer Vernooij
 Fix some types (found using aspell).  | 
461  | 
        This method should be overridden in child classes.
 | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
462  | 
        """
 | 
| 
1092.2.22
by Robert Collins
 text_version and name_version unification looking reasonable  | 
463  | 
compatible = True  | 
464  | 
        # different inv parent
 | 
|
465  | 
if previous_ie.parent_id != self.parent_id:  | 
|
466  | 
compatible = False  | 
|
467  | 
        # renamed
 | 
|
468  | 
elif previous_ie.name != self.name:  | 
|
469  | 
compatible = False  | 
|
| 
2374.2.2
by John Arbash Meinel
 Fix the small bug that ie.snapshot() didn't think about kind changes.  | 
470  | 
elif previous_ie.kind != self.kind:  | 
471  | 
compatible = False  | 
|
| 
1092.2.22
by Robert Collins
 text_version and name_version unification looking reasonable  | 
472  | 
return compatible  | 
473  | 
||
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
474  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
475  | 
"""Populate fields in the inventory entry from the given tree.  | 
476  | 
        
 | 
|
477  | 
        Note that this should be modified to be a noop on virtual trees
 | 
|
478  | 
        as all entries created there are prepopulated.
 | 
|
479  | 
        """
 | 
|
| 
1185.16.5
by Martin Pool
 doc  | 
480  | 
        # TODO: Rather than running this manually, we should check the 
 | 
481  | 
        # working sha1 and other expensive properties when they're
 | 
|
482  | 
        # first requested, or preload them if they're already known
 | 
|
483  | 
pass # nothing to do by default  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
484  | 
|
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
485  | 
def _forget_tree_state(self):  | 
486  | 
        pass
 | 
|
487  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
488  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
489  | 
class RootEntry(InventoryEntry):  | 
490  | 
||
491  | 
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',  | 
|
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
492  | 
'text_id', 'parent_id', 'children', 'executable',  | 
493  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
494  | 
|
495  | 
def _check(self, checker, rev_id, tree):  | 
|
496  | 
"""See InventoryEntry._check"""  | 
|
497  | 
||
498  | 
def __init__(self, file_id):  | 
|
499  | 
self.file_id = file_id  | 
|
500  | 
self.children = {}  | 
|
501  | 
self.kind = 'directory'  | 
|
502  | 
self.parent_id = None  | 
|
503  | 
self.name = u''  | 
|
504  | 
self.revision = None  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
505  | 
symbol_versioning.warn('RootEntry is deprecated as of bzr 0.10.'  | 
506  | 
' Please use InventoryDirectory instead.',  | 
|
507  | 
DeprecationWarning, stacklevel=2)  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
508  | 
|
509  | 
def __eq__(self, other):  | 
|
510  | 
if not isinstance(other, RootEntry):  | 
|
511  | 
return NotImplemented  | 
|
512  | 
||
513  | 
return (self.file_id == other.file_id) \  | 
|
514  | 
and (self.children == other.children)  | 
|
515  | 
||
516  | 
||
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
517  | 
class InventoryDirectory(InventoryEntry):  | 
518  | 
"""A directory in an inventory."""  | 
|
519  | 
||
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
520  | 
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',  | 
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
521  | 
'text_id', 'parent_id', 'children', 'executable',  | 
522  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
523  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
524  | 
def _check(self, checker, rev_id, tree):  | 
525  | 
"""See InventoryEntry._check"""  | 
|
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
526  | 
if self.text_sha1 is not None or self.text_size is not None or self.text_id is not None:  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
527  | 
raise BzrCheckError('directory {%s} has text in revision {%s}'  | 
528  | 
% (self.file_id, rev_id))  | 
|
529  | 
||
530  | 
def copy(self):  | 
|
531  | 
other = InventoryDirectory(self.file_id, self.name, self.parent_id)  | 
|
532  | 
other.revision = self.revision  | 
|
533  | 
        # note that children are *not* copied; they're pulled across when
 | 
|
534  | 
        # others are added
 | 
|
535  | 
return other  | 
|
536  | 
||
537  | 
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  | 
538  | 
super(InventoryDirectory, self).__init__(file_id, name, parent_id)  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
539  | 
self.children = {}  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
540  | 
self.kind = 'directory'  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
541  | 
|
542  | 
def kind_character(self):  | 
|
543  | 
"""See InventoryEntry.kind_character."""  | 
|
544  | 
return '/'  | 
|
545  | 
||
546  | 
def _put_in_tar(self, item, tree):  | 
|
547  | 
"""See InventoryEntry._put_in_tar."""  | 
|
548  | 
item.type = tarfile.DIRTYPE  | 
|
549  | 
fileobj = None  | 
|
550  | 
item.name += '/'  | 
|
551  | 
item.size = 0  | 
|
552  | 
item.mode = 0755  | 
|
553  | 
return fileobj  | 
|
554  | 
||
555  | 
def _put_on_disk(self, fullpath, tree):  | 
|
556  | 
"""See InventoryEntry._put_on_disk."""  | 
|
557  | 
os.mkdir(fullpath)  | 
|
558  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
559  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
560  | 
class InventoryFile(InventoryEntry):  | 
561  | 
"""A file in an inventory."""  | 
|
562  | 
||
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
563  | 
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',  | 
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
564  | 
'text_id', 'parent_id', 'children', 'executable',  | 
565  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
566  | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
567  | 
def _check(self, checker, tree_revision_id, tree):  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
568  | 
"""See InventoryEntry._check"""  | 
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
569  | 
t = (self.file_id, self.revision)  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
570  | 
if t in checker.checked_texts:  | 
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
571  | 
prev_sha = checker.checked_texts[t]  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
572  | 
if prev_sha != self.text_sha1:  | 
| 
2745.6.41
by Andrew Bennetts
 Test repo.check against all_scenarios.  | 
573  | 
raise BzrCheckError(  | 
574  | 
'mismatched sha1 on {%s} in {%s} (%s != %s) %r' %  | 
|
575  | 
(self.file_id, tree_revision_id, prev_sha, self.text_sha1,  | 
|
576  | 
t))  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
577  | 
else:  | 
578  | 
checker.repeated_text_cnt += 1  | 
|
579  | 
                return
 | 
|
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
580  | 
|
581  | 
if self.file_id not in checker.checked_weaves:  | 
|
582  | 
mutter('check weave {%s}', self.file_id)  | 
|
| 
1551.15.50
by Aaron Bentley
 Deprecate RevisionTree.get_weave  | 
583  | 
w = tree._get_weave(self.file_id)  | 
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
584  | 
            # Not passing a progress bar, because it creates a new
 | 
585  | 
            # progress, which overwrites the current progress,
 | 
|
586  | 
            # and doesn't look nice
 | 
|
587  | 
w.check()  | 
|
588  | 
checker.checked_weaves[self.file_id] = True  | 
|
589  | 
else:  | 
|
| 
1551.15.50
by Aaron Bentley
 Deprecate RevisionTree.get_weave  | 
590  | 
w = tree._get_weave(self.file_id)  | 
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
591  | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
592  | 
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'.  | 
593  | 
checker.checked_text_cnt += 1  | 
| 
1185.50.28
by John Arbash Meinel
 Lots of updates for 'bzr check'  | 
594  | 
        # We can't check the length, because Weave doesn't store that
 | 
595  | 
        # information, and the whole point of looking at the weave's
 | 
|
596  | 
        # sha1sum is that we don't have to extract the text.
 | 
|
597  | 
if self.text_sha1 != w.get_sha1(self.revision):  | 
|
598  | 
raise BzrCheckError('text {%s} version {%s} wrong sha1'  | 
|
599  | 
% (self.file_id, self.revision))  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
600  | 
checker.checked_texts[t] = self.text_sha1  | 
601  | 
||
602  | 
def copy(self):  | 
|
603  | 
other = InventoryFile(self.file_id, self.name, self.parent_id)  | 
|
604  | 
other.executable = self.executable  | 
|
605  | 
other.text_id = self.text_id  | 
|
606  | 
other.text_sha1 = self.text_sha1  | 
|
607  | 
other.text_size = self.text_size  | 
|
608  | 
other.revision = self.revision  | 
|
609  | 
return other  | 
|
610  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
611  | 
def detect_changes(self, old_entry):  | 
612  | 
"""See InventoryEntry.detect_changes."""  | 
|
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
613  | 
assert self.text_sha1 is not None  | 
614  | 
assert old_entry.text_sha1 is not None  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
615  | 
text_modified = (self.text_sha1 != old_entry.text_sha1)  | 
616  | 
meta_modified = (self.executable != old_entry.executable)  | 
|
617  | 
return text_modified, meta_modified  | 
|
618  | 
||
619  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
620  | 
output_to, reverse=False):  | 
|
621  | 
"""See InventoryEntry._diff."""  | 
|
| 
1558.15.2
by Aaron Bentley
 Implemented binary file handling for diff  | 
622  | 
try:  | 
623  | 
from_text = tree.get_file(self.file_id).readlines()  | 
|
624  | 
if to_entry:  | 
|
625  | 
to_text = to_tree.get_file(to_entry.file_id).readlines()  | 
|
626  | 
else:  | 
|
627  | 
to_text = []  | 
|
628  | 
if not reverse:  | 
|
629  | 
text_diff(from_label, from_text,  | 
|
630  | 
to_label, to_text, output_to)  | 
|
631  | 
else:  | 
|
632  | 
text_diff(to_label, to_text,  | 
|
633  | 
from_label, from_text, output_to)  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
634  | 
except errors.BinaryFile:  | 
| 
1558.15.11
by Aaron Bentley
 Apply merge review suggestions  | 
635  | 
if reverse:  | 
636  | 
label_pair = (to_label, from_label)  | 
|
637  | 
else:  | 
|
638  | 
label_pair = (from_label, to_label)  | 
|
| 
2911.6.3
by Blake Winton
 Implemented suggestions from John Arbash Meinel.  | 
639  | 
output_to.write(  | 
| 
2911.6.2
by Blake Winton
 Fix typos.  | 
640  | 
("Binary files %s and %s differ\n" % label_pair).encode('utf8'))  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
641  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
642  | 
def has_text(self):  | 
643  | 
"""See InventoryEntry.has_text."""  | 
|
644  | 
return True  | 
|
645  | 
||
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
646  | 
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  | 
647  | 
super(InventoryFile, self).__init__(file_id, name, parent_id)  | 
648  | 
self.kind = 'file'  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
649  | 
|
650  | 
def kind_character(self):  | 
|
651  | 
"""See InventoryEntry.kind_character."""  | 
|
652  | 
return ''  | 
|
653  | 
||
654  | 
def _put_in_tar(self, item, tree):  | 
|
655  | 
"""See InventoryEntry._put_in_tar."""  | 
|
656  | 
item.type = tarfile.REGTYPE  | 
|
657  | 
fileobj = tree.get_file(self.file_id)  | 
|
658  | 
item.size = self.text_size  | 
|
659  | 
if tree.is_executable(self.file_id):  | 
|
660  | 
item.mode = 0755  | 
|
661  | 
else:  | 
|
662  | 
item.mode = 0644  | 
|
663  | 
return fileobj  | 
|
664  | 
||
665  | 
def _put_on_disk(self, fullpath, tree):  | 
|
666  | 
"""See InventoryEntry._put_on_disk."""  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
667  | 
osutils.pumpfile(tree.get_file(self.file_id), file(fullpath, 'wb'))  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
668  | 
if tree.is_executable(self.file_id):  | 
669  | 
os.chmod(fullpath, 0755)  | 
|
670  | 
||
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
671  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
672  | 
"""See InventoryEntry._read_tree_state."""  | 
| 
1732.1.19
by John Arbash Meinel
 If you have the path, use it rather than looking it up again  | 
673  | 
self.text_sha1 = work_tree.get_file_sha1(self.file_id, path=path)  | 
| 
1740.3.2
by Jelmer Vernooij
 Move storing file texts to commit builder.  | 
674  | 
        # FIXME: 20050930 probe for the text size when getting sha1
 | 
675  | 
        # in _read_tree_state
 | 
|
| 
1732.1.19
by John Arbash Meinel
 If you have the path, use it rather than looking it up again  | 
676  | 
self.executable = work_tree.is_executable(self.file_id, path=path)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
677  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
678  | 
def __repr__(self):  | 
679  | 
return ("%s(%r, %r, parent_id=%r, sha1=%r, len=%s)"  | 
|
680  | 
% (self.__class__.__name__,  | 
|
681  | 
self.file_id,  | 
|
682  | 
self.name,  | 
|
683  | 
self.parent_id,  | 
|
684  | 
self.text_sha1,  | 
|
685  | 
self.text_size))  | 
|
686  | 
||
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
687  | 
def _forget_tree_state(self):  | 
688  | 
self.text_sha1 = None  | 
|
689  | 
||
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
690  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
691  | 
"""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  | 
692  | 
compatible = super(InventoryFile, self)._unchanged(previous_ie)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
693  | 
if self.text_sha1 != previous_ie.text_sha1:  | 
694  | 
compatible = False  | 
|
695  | 
else:  | 
|
696  | 
            # FIXME: 20050930 probe for the text size when getting sha1
 | 
|
697  | 
            # in _read_tree_state
 | 
|
698  | 
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  | 
699  | 
if self.executable != previous_ie.executable:  | 
700  | 
compatible = False  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
701  | 
return compatible  | 
702  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
703  | 
|
704  | 
class InventoryLink(InventoryEntry):  | 
|
705  | 
"""A file in an inventory."""  | 
|
706  | 
||
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
707  | 
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',  | 
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
708  | 
'text_id', 'parent_id', 'children', 'executable',  | 
709  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
710  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
711  | 
def _check(self, checker, rev_id, tree):  | 
712  | 
"""See InventoryEntry._check"""  | 
|
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
713  | 
if self.text_sha1 is not None or self.text_size is not None or self.text_id is not None:  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
714  | 
raise BzrCheckError('symlink {%s} has text in revision {%s}'  | 
715  | 
% (self.file_id, rev_id))  | 
|
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
716  | 
if self.symlink_target is None:  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
717  | 
raise BzrCheckError('symlink {%s} has no target in revision {%s}'  | 
718  | 
% (self.file_id, rev_id))  | 
|
719  | 
||
720  | 
def copy(self):  | 
|
721  | 
other = InventoryLink(self.file_id, self.name, self.parent_id)  | 
|
722  | 
other.symlink_target = self.symlink_target  | 
|
723  | 
other.revision = self.revision  | 
|
724  | 
return other  | 
|
725  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
726  | 
def detect_changes(self, old_entry):  | 
727  | 
"""See InventoryEntry.detect_changes."""  | 
|
728  | 
        # FIXME: which _modified field should we use ? RBC 20051003
 | 
|
729  | 
text_modified = (self.symlink_target != old_entry.symlink_target)  | 
|
730  | 
if text_modified:  | 
|
731  | 
mutter(" symlink target changed")  | 
|
732  | 
meta_modified = False  | 
|
733  | 
return text_modified, meta_modified  | 
|
734  | 
||
735  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
736  | 
output_to, reverse=False):  | 
|
737  | 
"""See InventoryEntry._diff."""  | 
|
738  | 
from_text = self.symlink_target  | 
|
739  | 
if to_entry is not None:  | 
|
740  | 
to_text = to_entry.symlink_target  | 
|
741  | 
if reverse:  | 
|
742  | 
temp = from_text  | 
|
743  | 
from_text = to_text  | 
|
744  | 
to_text = temp  | 
|
| 
2911.6.1
by Blake Winton
 Change 'print >> f,'s to 'f.write('s.  | 
745  | 
output_to.write('=== target changed %r => %r\n' % (from_text, to_text))  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
746  | 
else:  | 
747  | 
if not reverse:  | 
|
| 
2911.6.1
by Blake Winton
 Change 'print >> f,'s to 'f.write('s.  | 
748  | 
output_to.write('=== target was %r\n' % self.symlink_target)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
749  | 
else:  | 
| 
2911.6.1
by Blake Winton
 Change 'print >> f,'s to 'f.write('s.  | 
750  | 
output_to.write('=== target is %r\n' % self.symlink_target)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
751  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
752  | 
def __init__(self, file_id, name, parent_id):  | 
753  | 
super(InventoryLink, self).__init__(file_id, name, parent_id)  | 
|
754  | 
self.kind = 'symlink'  | 
|
755  | 
||
756  | 
def kind_character(self):  | 
|
757  | 
"""See InventoryEntry.kind_character."""  | 
|
758  | 
return ''  | 
|
759  | 
||
760  | 
def _put_in_tar(self, item, tree):  | 
|
761  | 
"""See InventoryEntry._put_in_tar."""  | 
|
| 
1185.33.3
by Martin Pool
 [merge] jelmer  | 
762  | 
item.type = tarfile.SYMTYPE  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
763  | 
fileobj = None  | 
764  | 
item.size = 0  | 
|
765  | 
item.mode = 0755  | 
|
766  | 
item.linkname = self.symlink_target  | 
|
767  | 
return fileobj  | 
|
768  | 
||
769  | 
def _put_on_disk(self, fullpath, tree):  | 
|
770  | 
"""See InventoryEntry._put_on_disk."""  | 
|
771  | 
try:  | 
|
772  | 
os.symlink(self.symlink_target, fullpath)  | 
|
773  | 
except OSError,e:  | 
|
774  | 
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  | 
775  | 
|
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
776  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
777  | 
"""See InventoryEntry._read_tree_state."""  | 
778  | 
self.symlink_target = work_tree.get_symlink_target(self.file_id)  | 
|
779  | 
||
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
780  | 
def _forget_tree_state(self):  | 
781  | 
self.symlink_target = None  | 
|
782  | 
||
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
783  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
784  | 
"""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  | 
785  | 
compatible = super(InventoryLink, self)._unchanged(previous_ie)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
786  | 
if self.symlink_target != previous_ie.symlink_target:  | 
787  | 
compatible = False  | 
|
788  | 
return compatible  | 
|
789  | 
||
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
790  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
791  | 
class TreeReference(InventoryEntry):  | 
792  | 
||
793  | 
kind = 'tree-reference'  | 
|
794  | 
||
| 
2255.6.8
by Aaron Bentley
 Merge refactoring of add_reference  | 
795  | 
def __init__(self, file_id, name, parent_id, revision=None,  | 
796  | 
reference_revision=None):  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
797  | 
InventoryEntry.__init__(self, file_id, name, parent_id)  | 
798  | 
self.revision = revision  | 
|
799  | 
self.reference_revision = reference_revision  | 
|
800  | 
||
| 
2100.3.18
by Aaron Bentley
 Get commit working for tree references  | 
801  | 
def copy(self):  | 
802  | 
return TreeReference(self.file_id, self.name, self.parent_id,  | 
|
803  | 
self.revision, self.reference_revision)  | 
|
804  | 
||
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
805  | 
def _read_tree_state(self, path, work_tree):  | 
806  | 
"""Populate fields in the inventory entry from the given tree.  | 
|
807  | 
        """
 | 
|
| 
2255.2.226
by Robert Collins
 Get merge_nested finally working: change nested tree iterators to take file_ids, and ensure the right branch is connected to in the merge logic. May not be suitable for shared repositories yet.  | 
808  | 
self.reference_revision = work_tree.get_reference_revision(  | 
809  | 
self.file_id, path)  | 
|
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
810  | 
|
811  | 
def _forget_tree_state(self):  | 
|
812  | 
self.reference_revision = None  | 
|
813  | 
||
| 
2825.5.2
by Robert Collins
 Review feedback, and fix pointless commits with nested trees to raise PointlessCommit appropriately.  | 
814  | 
def _unchanged(self, previous_ie):  | 
815  | 
"""See InventoryEntry._unchanged."""  | 
|
816  | 
compatible = super(TreeReference, self)._unchanged(previous_ie)  | 
|
817  | 
if self.reference_revision != previous_ie.reference_revision:  | 
|
818  | 
compatible = False  | 
|
819  | 
return compatible  | 
|
820  | 
||
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
821  | 
|
| 
802
by Martin Pool
 - Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions  | 
822  | 
class Inventory(object):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
823  | 
"""Inventory of versioned files in a tree.  | 
824  | 
||
| 
240
by mbp at sourcefrog
 doc  | 
825  | 
    This describes which file_id is present at each point in the tree,
 | 
826  | 
    and possibly the SHA-1 or other information about the file.
 | 
|
827  | 
    Entries can be looked up either by path or by file_id.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
828  | 
|
829  | 
    The inventory represents a typical unix file tree, with
 | 
|
830  | 
    directories containing files and subdirectories.  We never store
 | 
|
831  | 
    the full path to a file, because renaming a directory implicitly
 | 
|
832  | 
    moves all of its contents.  This class internally maintains a
 | 
|
833  | 
    lookup tree that allows the children under a directory to be
 | 
|
834  | 
    returned quickly.
 | 
|
835  | 
||
836  | 
    InventoryEntry objects must not be modified after they are
 | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
837  | 
    inserted, other than through the Inventory API.
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
838  | 
|
839  | 
    >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
840  | 
    >>> inv.add(InventoryFile('123-123', 'hello.c', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
841  | 
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
842  | 
    >>> inv['123-123'].name
 | 
843  | 
    'hello.c'
 | 
|
844  | 
||
845  | 
    May be treated as an iterator or set to look up file ids:
 | 
|
846  | 
    
 | 
|
847  | 
    >>> bool(inv.path2id('hello.c'))
 | 
|
848  | 
    True
 | 
|
849  | 
    >>> '123-123' in inv
 | 
|
850  | 
    True
 | 
|
851  | 
||
852  | 
    May also look up by name:
 | 
|
853  | 
||
854  | 
    >>> [x[0] for x in inv.iter_entries()]
 | 
|
| 
1852.6.6
by Robert Collins
 Finish updating iter_entries change to make all tests pass.  | 
855  | 
    ['', u'hello.c']
 | 
| 
909
by Martin Pool
 - merge John's code to give the tree root an explicit file id  | 
856  | 
    >>> 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  | 
857  | 
    >>> inv.add(InventoryFile('123-123', 'hello.c', ROOT_ID))
 | 
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
858  | 
    Traceback (most recent call last):
 | 
859  | 
    BzrError: parent_id {TREE_ROOT} not in inventory
 | 
|
860  | 
    >>> inv.add(InventoryFile('123-123', 'hello.c', 'TREE_ROOT-12345678-12345678'))
 | 
|
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
861  | 
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT-12345678-12345678', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
862  | 
    """
 | 
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
863  | 
def __init__(self, root_id=ROOT_ID, revision_id=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
864  | 
"""Create or read an inventory.  | 
865  | 
||
866  | 
        If a working directory is specified, the inventory is read
 | 
|
867  | 
        from there.  If the file is specified, read from that. If not,
 | 
|
868  | 
        the inventory is created empty.
 | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
869  | 
|
870  | 
        The inventory is created with a default root directory, with
 | 
|
871  | 
        an id of None.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
872  | 
        """
 | 
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
873  | 
if root_id is not None:  | 
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
874  | 
assert root_id.__class__ == str  | 
| 
2294.1.5
by John Arbash Meinel
 Fix Inventory.iter_entries_by_dir to return Unicode paths,  | 
875  | 
self._set_root(InventoryDirectory(root_id, u'', None))  | 
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
876  | 
else:  | 
877  | 
self.root = None  | 
|
878  | 
self._byid = {}  | 
|
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
879  | 
self.revision_id = revision_id  | 
| 
1910.2.3
by Aaron Bentley
 All tests pass  | 
880  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
881  | 
def __repr__(self):  | 
882  | 
return "<Inventory object at %x, contents=%r>" % (id(self), self._byid)  | 
|
883  | 
||
884  | 
def apply_delta(self, delta):  | 
|
885  | 
"""Apply a delta to this inventory.  | 
|
886  | 
||
887  | 
        :param delta: A list of changes to apply. After all the changes are
 | 
|
888  | 
            applied the final inventory must be internally consistent, but it
 | 
|
889  | 
            is ok to supply changes which, if only half-applied would have an
 | 
|
890  | 
            invalid result - such as supplying two changes which rename two
 | 
|
891  | 
            files, 'A' and 'B' with each other : [('A', 'B', 'A-id', a_entry),
 | 
|
892  | 
            ('B', 'A', 'B-id', b_entry)].
 | 
|
893  | 
||
894  | 
            Each change is a tuple, of the form (old_path, new_path, file_id,
 | 
|
895  | 
            new_entry).
 | 
|
896  | 
            
 | 
|
897  | 
            When new_path is None, the change indicates the removal of an entry
 | 
|
898  | 
            from the inventory and new_entry will be ignored (using None is
 | 
|
899  | 
            appropriate). If new_path is not None, then new_entry must be an
 | 
|
900  | 
            InventoryEntry instance, which will be incorporated into the
 | 
|
901  | 
            inventory (and replace any existing entry with the same file id).
 | 
|
902  | 
            
 | 
|
903  | 
            When old_path is None, the change indicates the addition of
 | 
|
904  | 
            a new entry to the inventory.
 | 
|
905  | 
            
 | 
|
906  | 
            When neither new_path nor old_path are None, the change is a
 | 
|
907  | 
            modification to an entry, such as a rename, reparent, kind change
 | 
|
908  | 
            etc. 
 | 
|
909  | 
||
910  | 
            The children attribute of new_entry is ignored. This is because
 | 
|
| 
2865.1.3
by Robert Collins
 Review feedback.  | 
911  | 
            this method preserves children automatically across alterations to
 | 
912  | 
            the parent of the children, and cases where the parent id of a
 | 
|
913  | 
            child is changing require the child to be passed in as a separate
 | 
|
914  | 
            change regardless. E.g. in the recursive deletion of a directory -
 | 
|
915  | 
            the directory's children must be included in the delta, or the
 | 
|
916  | 
            final inventory will be invalid.
 | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
917  | 
        """
 | 
918  | 
children = {}  | 
|
919  | 
        # Remove all affected items which were in the original inventory,
 | 
|
920  | 
        # starting with the longest paths, thus ensuring parents are examined
 | 
|
921  | 
        # after their children, which means that everything we examine has no
 | 
|
922  | 
        # modified children remaining by the time we examine it.
 | 
|
923  | 
for old_path, file_id in sorted(((op, f) for op, np, f, e in delta  | 
|
924  | 
if op is not None), reverse=True):  | 
|
925  | 
if file_id not in self:  | 
|
926  | 
                # adds come later
 | 
|
927  | 
                continue
 | 
|
928  | 
            # Preserve unaltered children of file_id for later reinsertion.
 | 
|
929  | 
children[file_id] = getattr(self[file_id], 'children', {})  | 
|
930  | 
            # Remove file_id and the unaltered children. If file_id is not
 | 
|
931  | 
            # being deleted it will be reinserted back later.
 | 
|
932  | 
self.remove_recursive_id(file_id)  | 
|
933  | 
        # Insert all affected which should be in the new inventory, reattaching
 | 
|
934  | 
        # their children if they had any. This is done from shortest path to
 | 
|
935  | 
        # longest, ensuring that items which were modified and whose parents in
 | 
|
936  | 
        # the resulting inventory were also modified, are inserted after their
 | 
|
937  | 
        # parents.
 | 
|
938  | 
for new_path, new_entry in sorted((np, e) for op, np, f, e in  | 
|
939  | 
delta if np is not None):  | 
|
940  | 
if new_entry.kind == 'directory':  | 
|
941  | 
new_entry.children = children.get(new_entry.file_id, {})  | 
|
942  | 
self.add(new_entry)  | 
|
943  | 
||
| 
1910.2.3
by Aaron Bentley
 All tests pass  | 
944  | 
def _set_root(self, ie):  | 
945  | 
self.root = ie  | 
|
| 
1907.1.2
by Aaron Bentley
 More removal of unique-root stuff  | 
946  | 
self._byid = {self.root.file_id: self.root}  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
947  | 
|
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
948  | 
def copy(self):  | 
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
949  | 
        # TODO: jam 20051218 Should copy also copy the revision_id?
 | 
| 
1852.6.3
by Robert Collins
 Make iter(Tree) consistent for all tree types.  | 
950  | 
entries = self.iter_entries()  | 
| 
2938.2.1
by Jelmer Vernooij
 Handle empty inventories in Inventory.copy().  | 
951  | 
if self.root is None:  | 
952  | 
return Inventory(root_id=None)  | 
|
| 
1852.6.3
by Robert Collins
 Make iter(Tree) consistent for all tree types.  | 
953  | 
other = Inventory(entries.next()[1].file_id)  | 
| 
1206
by Martin Pool
 - fix bug in Inventory.copy()  | 
954  | 
        # copy recursively so we know directories will be added before
 | 
955  | 
        # their children.  There are more efficient ways than this...
 | 
|
| 
2935.2.1
by Jelmer Vernooij
 Fix Inventory.copy() and add a test for it.  | 
956  | 
for path, entry in entries:  | 
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
957  | 
other.add(entry.copy())  | 
958  | 
return other  | 
|
959  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
960  | 
def __iter__(self):  | 
961  | 
return iter(self._byid)  | 
|
962  | 
||
963  | 
def __len__(self):  | 
|
964  | 
"""Returns number of entries."""  | 
|
965  | 
return len(self._byid)  | 
|
966  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
967  | 
def iter_entries(self, from_dir=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
968  | 
"""Return (path, entry) pairs, in order by name."""  | 
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
969  | 
if from_dir is None:  | 
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
970  | 
if self.root is None:  | 
971  | 
                return
 | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
972  | 
from_dir = self.root  | 
| 
1852.6.3
by Robert Collins
 Make iter(Tree) consistent for all tree types.  | 
973  | 
yield '', self.root  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
974  | 
elif isinstance(from_dir, basestring):  | 
975  | 
from_dir = self._byid[from_dir]  | 
|
976  | 
||
| 
1732.1.24
by John Arbash Meinel
 iter_entries time drops to 1/6th time  | 
977  | 
        # unrolling the recursive called changed the time from
 | 
978  | 
        # 440ms/663ms (inline/total) to 116ms/116ms
 | 
|
| 
1732.1.23
by John Arbash Meinel
 Switch iter_entries from being a recursive function and using pathjoin  | 
979  | 
children = from_dir.children.items()  | 
980  | 
children.sort()  | 
|
981  | 
children = collections.deque(children)  | 
|
982  | 
stack = [(u'', children)]  | 
|
983  | 
while stack:  | 
|
984  | 
from_dir_relpath, children = stack[-1]  | 
|
985  | 
||
986  | 
while children:  | 
|
987  | 
name, ie = children.popleft()  | 
|
988  | 
||
989  | 
                # we know that from_dir_relpath never ends in a slash
 | 
|
990  | 
                # and 'f' doesn't begin with one, we can do a string op, rather
 | 
|
991  | 
                # than the checks of pathjoin(), though this means that all paths
 | 
|
992  | 
                # start with a slash
 | 
|
993  | 
path = from_dir_relpath + '/' + name  | 
|
994  | 
||
995  | 
yield path[1:], ie  | 
|
996  | 
||
997  | 
if ie.kind != 'directory':  | 
|
998  | 
                    continue
 | 
|
999  | 
||
1000  | 
                # But do this child first
 | 
|
1001  | 
new_children = ie.children.items()  | 
|
1002  | 
new_children.sort()  | 
|
1003  | 
new_children = collections.deque(new_children)  | 
|
1004  | 
stack.append((path, new_children))  | 
|
1005  | 
                # Break out of inner loop, so that we start outer loop with child
 | 
|
1006  | 
                break
 | 
|
1007  | 
else:  | 
|
1008  | 
                # if we finished all children, pop it off the stack
 | 
|
| 
1732.1.25
by John Arbash Meinel
 Fix list_files test, we don't need to check if children are empty if we fall off the loop.  | 
1009  | 
stack.pop()  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
1010  | 
|
| 
2825.7.1
by Robert Collins
 * Partial commits are now approximately 40% faster by walking over the  | 
1011  | 
def iter_entries_by_dir(self, from_dir=None, specific_file_ids=None,  | 
1012  | 
yield_parents=False):  | 
|
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1013  | 
"""Iterate over the entries in a directory first order.  | 
1014  | 
||
1015  | 
        This returns all entries for a directory before returning
 | 
|
1016  | 
        the entries for children of a directory. This is not
 | 
|
1017  | 
        lexicographically sorted order, and is a hybrid between
 | 
|
1018  | 
        depth-first and breadth-first.
 | 
|
1019  | 
||
| 
2825.7.1
by Robert Collins
 * Partial commits are now approximately 40% faster by walking over the  | 
1020  | 
        :param yield_parents: If True, yield the parents from the root leading
 | 
1021  | 
            down to specific_file_ids that have been requested. This has no
 | 
|
1022  | 
            impact if specific_file_ids is None.
 | 
|
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1023  | 
        :return: This yields (path, entry) pairs
 | 
1024  | 
        """
 | 
|
| 
2858.2.1
by Martin Pool
 Remove most calls to safe_file_id and safe_revision_id.  | 
1025  | 
if specific_file_ids and not isinstance(specific_file_ids, set):  | 
1026  | 
specific_file_ids = set(specific_file_ids)  | 
|
| 
1755.1.1
by Robert Collins
 (jam, robertc, ab)Merge new iter_entries_by_dirs routine which matches the order walkdirs provides.  | 
1027  | 
        # TODO? Perhaps this should return the from_dir so that the root is
 | 
1028  | 
        # yielded? or maybe an option?
 | 
|
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
1029  | 
if from_dir is None:  | 
| 
1731.1.47
by Aaron Bentley
 Merge bzr.dev  | 
1030  | 
if self.root is None:  | 
1031  | 
                return
 | 
|
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1032  | 
            # Optimize a common case
 | 
| 
2825.7.1
by Robert Collins
 * Partial commits are now approximately 40% faster by walking over the  | 
1033  | 
if (not yield_parents and specific_file_ids is not None and  | 
1034  | 
len(specific_file_ids) == 1):  | 
|
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1035  | 
file_id = list(specific_file_ids)[0]  | 
1036  | 
if file_id in self:  | 
|
1037  | 
yield self.id2path(file_id), self[file_id]  | 
|
1038  | 
                return 
 | 
|
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1039  | 
from_dir = self.root  | 
| 
2825.7.1
by Robert Collins
 * Partial commits are now approximately 40% faster by walking over the  | 
1040  | 
if (specific_file_ids is None or yield_parents or  | 
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1041  | 
self.root.file_id in specific_file_ids):  | 
| 
2294.1.5
by John Arbash Meinel
 Fix Inventory.iter_entries_by_dir to return Unicode paths,  | 
1042  | 
yield u'', self.root  | 
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1043  | 
elif isinstance(from_dir, basestring):  | 
1044  | 
from_dir = self._byid[from_dir]  | 
|
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1045  | 
|
1046  | 
if specific_file_ids is not None:  | 
|
| 
2309.4.2
by John Arbash Meinel
 Change iter_entries_by_dir to avoid extra file id safety checks.  | 
1047  | 
            # TODO: jam 20070302 This could really be done as a loop rather
 | 
1048  | 
            #       than a bunch of recursive calls.
 | 
|
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1049  | 
parents = set()  | 
| 
2309.4.2
by John Arbash Meinel
 Change iter_entries_by_dir to avoid extra file id safety checks.  | 
1050  | 
byid = self._byid  | 
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1051  | 
def add_ancestors(file_id):  | 
| 
2309.4.2
by John Arbash Meinel
 Change iter_entries_by_dir to avoid extra file id safety checks.  | 
1052  | 
if file_id not in byid:  | 
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1053  | 
                    return
 | 
| 
2309.4.2
by John Arbash Meinel
 Change iter_entries_by_dir to avoid extra file id safety checks.  | 
1054  | 
parent_id = byid[file_id].parent_id  | 
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1055  | 
if parent_id is None:  | 
1056  | 
                    return
 | 
|
1057  | 
if parent_id not in parents:  | 
|
1058  | 
parents.add(parent_id)  | 
|
1059  | 
add_ancestors(parent_id)  | 
|
1060  | 
for file_id in specific_file_ids:  | 
|
1061  | 
add_ancestors(file_id)  | 
|
1062  | 
else:  | 
|
1063  | 
parents = None  | 
|
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1064  | 
|
1065  | 
stack = [(u'', from_dir)]  | 
|
1066  | 
while stack:  | 
|
1067  | 
cur_relpath, cur_dir = stack.pop()  | 
|
1068  | 
||
1069  | 
child_dirs = []  | 
|
1070  | 
for child_name, child_ie in sorted(cur_dir.children.iteritems()):  | 
|
1071  | 
||
1072  | 
child_relpath = cur_relpath + child_name  | 
|
1073  | 
||
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1074  | 
if (specific_file_ids is None or  | 
| 
2825.7.1
by Robert Collins
 * Partial commits are now approximately 40% faster by walking over the  | 
1075  | 
child_ie.file_id in specific_file_ids or  | 
1076  | 
(yield_parents and child_ie.file_id in parents)):  | 
|
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1077  | 
yield child_relpath, child_ie  | 
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1078  | 
|
1079  | 
if child_ie.kind == 'directory':  | 
|
| 
1551.9.29
by Aaron Bentley
 Optimize Tree._iter_changes with specific file_ids  | 
1080  | 
if parents is None or child_ie.file_id in parents:  | 
1081  | 
child_dirs.append((child_relpath+'/', child_ie))  | 
|
| 
1711.2.36
by John Arbash Meinel
 Add an iter_entries_by_dir which returns directory children before their children.  | 
1082  | 
stack.extend(reversed(child_dirs))  | 
1083  | 
||
| 
2568.2.4
by Robert Collins
 * ``bzrlib.add.smart_add`` and ``bzrlib.add.smart_add_tree`` are now  | 
1084  | 
def make_entry(self, kind, name, parent_id, file_id=None):  | 
1085  | 
"""Simple thunk to bzrlib.inventory.make_entry."""  | 
|
1086  | 
return make_entry(kind, name, parent_id, file_id)  | 
|
1087  | 
||
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
1088  | 
def entries(self):  | 
1089  | 
"""Return list of (path, ie) for all entries except the root.  | 
|
1090  | 
||
1091  | 
        This may be faster than iter_entries.
 | 
|
1092  | 
        """
 | 
|
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1093  | 
accum = []  | 
1094  | 
def descend(dir_ie, dir_path):  | 
|
| 
556
by Martin Pool
 - fix up Inventory.entries()  | 
1095  | 
kids = dir_ie.children.items()  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
1096  | 
kids.sort()  | 
1097  | 
for name, ie in kids:  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
1098  | 
child_path = osutils.pathjoin(dir_path, name)  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1099  | 
accum.append((child_path, ie))  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
1100  | 
if ie.kind == 'directory':  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1101  | 
descend(ie, child_path)  | 
| 
555
by Martin Pool
 - New Inventory.entries() method  | 
1102  | 
|
| 
1185.33.66
by Martin Pool
 [patch] use unicode literals for all hardcoded paths (Alexander Belchenko)  | 
1103  | 
descend(self.root, u'')  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1104  | 
return accum  | 
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
1105  | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1106  | 
def directories(self):  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1107  | 
"""Return (path, entry) pairs for all directories, including the root.  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1108  | 
        """
 | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1109  | 
accum = []  | 
1110  | 
def descend(parent_ie, parent_path):  | 
|
1111  | 
accum.append((parent_path, parent_ie))  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
1112  | 
|
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1113  | 
kids = [(ie.name, ie) for ie in parent_ie.children.itervalues() if ie.kind == 'directory']  | 
1114  | 
kids.sort()  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
1115  | 
|
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1116  | 
for name, child_ie in kids:  | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
1117  | 
child_path = osutils.pathjoin(parent_path, name)  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1118  | 
descend(child_ie, child_path)  | 
| 
1185.33.66
by Martin Pool
 [patch] use unicode literals for all hardcoded paths (Alexander Belchenko)  | 
1119  | 
descend(self.root, u'')  | 
| 
557
by Martin Pool
 - Refactor/cleanup Inventory.entries()  | 
1120  | 
return accum  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1121  | 
|
1122  | 
def __contains__(self, file_id):  | 
|
1123  | 
"""True if this entry contains a file with given id.  | 
|
1124  | 
||
1125  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1126  | 
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
1127  | 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1128  | 
        >>> '123' in inv
 | 
1129  | 
        True
 | 
|
1130  | 
        >>> '456' in inv
 | 
|
1131  | 
        False
 | 
|
1132  | 
        """
 | 
|
| 
1711.9.11
by John Arbash Meinel
 change return foo in bar to return (foo in bar)  | 
1133  | 
return (file_id in self._byid)  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1134  | 
|
1135  | 
def __getitem__(self, file_id):  | 
|
1136  | 
"""Return the entry for given file_id.  | 
|
1137  | 
||
1138  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1139  | 
        >>> inv.add(InventoryFile('123123', 'hello.c', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
1140  | 
        InventoryFile('123123', 'hello.c', parent_id='TREE_ROOT', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1141  | 
        >>> inv['123123'].name
 | 
1142  | 
        'hello.c'
 | 
|
1143  | 
        """
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1144  | 
try:  | 
1145  | 
return self._byid[file_id]  | 
|
1146  | 
except KeyError:  | 
|
| 
2067.3.1
by Martin Pool
 Clean up BzrNewError, other exception classes and users.  | 
1147  | 
            # really we're passing an inventory, not a tree...
 | 
1148  | 
raise errors.NoSuchId(self, file_id)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1149  | 
|
| 
460
by Martin Pool
 - new testing command compare-trees  | 
1150  | 
def get_file_kind(self, file_id):  | 
1151  | 
return self._byid[file_id].kind  | 
|
1152  | 
||
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1153  | 
def get_child(self, parent_id, filename):  | 
| 
1732.1.18
by John Arbash Meinel
 50ms is probably not worth it  | 
1154  | 
return self[parent_id].children.get(filename)  | 
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1155  | 
|
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1156  | 
def _add_child(self, entry):  | 
1157  | 
"""Add an entry to the inventory, without adding it to its parent"""  | 
|
1158  | 
if entry.file_id in self._byid:  | 
|
1159  | 
raise BzrError("inventory already contains entry with id {%s}" %  | 
|
1160  | 
entry.file_id)  | 
|
1161  | 
self._byid[entry.file_id] = entry  | 
|
1162  | 
for child in getattr(entry, 'children', {}).itervalues():  | 
|
1163  | 
self._add_child(child)  | 
|
1164  | 
return entry  | 
|
1165  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1166  | 
def add(self, entry):  | 
1167  | 
"""Add entry to inventory.  | 
|
1168  | 
||
1169  | 
        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  | 
1170  | 
        which calls this.
 | 
1171  | 
||
1172  | 
        Returns the new entry object.
 | 
|
1173  | 
        """
 | 
|
| 
139
by mbp at sourcefrog
 simplified/faster Inventory.add  | 
1174  | 
if entry.file_id in self._byid:  | 
| 
2255.7.16
by John Arbash Meinel
 Make sure adding a duplicate file_id raises DuplicateFileId.  | 
1175  | 
raise errors.DuplicateFileId(entry.file_id,  | 
1176  | 
self._byid[entry.file_id])  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1177  | 
|
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
1178  | 
if entry.parent_id is None:  | 
| 
1910.2.3
by Aaron Bentley
 All tests pass  | 
1179  | 
assert self.root is None and len(self._byid) == 0  | 
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1180  | 
self.root = entry  | 
1181  | 
else:  | 
|
1182  | 
try:  | 
|
1183  | 
parent = self._byid[entry.parent_id]  | 
|
1184  | 
except KeyError:  | 
|
1185  | 
raise BzrError("parent_id {%s} not in inventory" %  | 
|
1186  | 
entry.parent_id)  | 
|
1187  | 
||
1188  | 
if entry.name in parent.children:  | 
|
1189  | 
raise BzrError("%s is already versioned" %  | 
|
1190  | 
osutils.pathjoin(self.id2path(parent.file_id),  | 
|
| 
1551.13.12
by Aaron Bentley
 Fix encoding of 'already versioned' error  | 
1191  | 
entry.name).encode('utf-8'))  | 
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1192  | 
parent.children[entry.name] = entry  | 
1193  | 
return self._add_child(entry)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1194  | 
|
| 
1713.1.11
by Robert Collins
 refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)  | 
1195  | 
def add_path(self, relpath, kind, file_id=None, parent_id=None):  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1196  | 
"""Add entry from a path.  | 
1197  | 
||
| 
1180
by Martin Pool
 - start splitting code for xml (de)serialization away from objects  | 
1198  | 
        The immediate parent must already be versioned.
 | 
1199  | 
||
1200  | 
        Returns the new entry object."""
 | 
|
| 
1015
by Martin Pool
 - fix circular imports  | 
1201  | 
|
| 
1830.3.5
by John Arbash Meinel
 make_entry refuses to create non-normalized entries.  | 
1202  | 
parts = osutils.splitpath(relpath)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1203  | 
|
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1204  | 
if len(parts) == 0:  | 
| 
1713.1.6
by Robert Collins
 Move file id random data selection out of the inner loop for 'bzr add'.  | 
1205  | 
if file_id is None:  | 
| 
2116.4.1
by John Arbash Meinel
 Update file and revision id generators.  | 
1206  | 
file_id = generate_ids.gen_root_id()  | 
| 
1731.1.1
by Aaron Bentley
 Make root entry an InventoryDirectory, make EmptyTree really empty  | 
1207  | 
self.root = InventoryDirectory(file_id, '', None)  | 
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1208  | 
self._byid = {self.root.file_id: self.root}  | 
| 
2178.2.2
by Jelmer Vernooij
 Make add_path() return inventory entry for root just like it does for other entries.  | 
1209  | 
return self.root  | 
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1210  | 
else:  | 
1211  | 
parent_path = parts[:-1]  | 
|
1212  | 
parent_id = self.path2id(parent_path)  | 
|
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
1213  | 
if parent_id is None:  | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
1214  | 
raise errors.NotVersionedError(path=parent_path)  | 
| 
1713.1.11
by Robert Collins
 refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)  | 
1215  | 
ie = make_entry(kind, parts[-1], parent_id, file_id)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1216  | 
return self.add(ie)  | 
1217  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1218  | 
def __delitem__(self, file_id):  | 
1219  | 
"""Remove entry by id.  | 
|
1220  | 
||
1221  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1222  | 
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
1223  | 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1224  | 
        >>> '123' in inv
 | 
1225  | 
        True
 | 
|
1226  | 
        >>> del inv['123']
 | 
|
1227  | 
        >>> '123' in inv
 | 
|
1228  | 
        False
 | 
|
1229  | 
        """
 | 
|
1230  | 
ie = self[file_id]  | 
|
1231  | 
||
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1232  | 
assert ie.parent_id is None or \  | 
1233  | 
self[ie.parent_id].children[ie.name] == ie  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1234  | 
|
1235  | 
del self._byid[file_id]  | 
|
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1236  | 
if ie.parent_id is not None:  | 
1237  | 
del self[ie.parent_id].children[ie.name]  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1238  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1239  | 
def __eq__(self, other):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1240  | 
"""Compare two sets by comparing their contents.  | 
1241  | 
||
1242  | 
        >>> i1 = Inventory()
 | 
|
1243  | 
        >>> i2 = Inventory()
 | 
|
1244  | 
        >>> i1 == i2
 | 
|
1245  | 
        True
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1246  | 
        >>> i1.add(InventoryFile('123', 'foo', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
1247  | 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1248  | 
        >>> i1 == i2
 | 
1249  | 
        False
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1250  | 
        >>> i2.add(InventoryFile('123', 'foo', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
1251  | 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT', sha1=None, len=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1252  | 
        >>> i1 == i2
 | 
1253  | 
        True
 | 
|
1254  | 
        """
 | 
|
1255  | 
if not isinstance(other, Inventory):  | 
|
1256  | 
return NotImplemented  | 
|
1257  | 
||
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1258  | 
return self._byid == other._byid  | 
1259  | 
||
1260  | 
def __ne__(self, other):  | 
|
| 
1249
by Martin Pool
 - improvements to weave commit [broken]  | 
1261  | 
return not self.__eq__(other)  | 
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1262  | 
|
1263  | 
def __hash__(self):  | 
|
1264  | 
raise ValueError('not hashable')  | 
|
1265  | 
||
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1266  | 
def _iter_file_id_parents(self, file_id):  | 
1267  | 
"""Yield the parents of file_id up to the root."""  | 
|
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
1268  | 
while file_id is not None:  | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1269  | 
try:  | 
1270  | 
ie = self._byid[file_id]  | 
|
1271  | 
except KeyError:  | 
|
| 
2255.11.5
by Martin Pool
 Tree.id2path should raise NoSuchId, not return None.  | 
1272  | 
raise errors.NoSuchId(tree=None, file_id=file_id)  | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1273  | 
yield ie  | 
1274  | 
file_id = ie.parent_id  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1275  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1276  | 
def get_idpath(self, file_id):  | 
1277  | 
"""Return a list of file_ids for the path to an entry.  | 
|
1278  | 
||
1279  | 
        The list contains one element for each directory followed by
 | 
|
1280  | 
        the id of the file itself.  So the length of the returned list
 | 
|
1281  | 
        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  | 
1282  | 
        root directory as depth 1.
 | 
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1283  | 
        """
 | 
1284  | 
p = []  | 
|
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1285  | 
for parent in self._iter_file_id_parents(file_id):  | 
1286  | 
p.insert(0, parent.file_id)  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1287  | 
return p  | 
1288  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1289  | 
def id2path(self, file_id):  | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1290  | 
"""Return as a string the path to file_id.  | 
| 
1393.1.32
by Martin Pool
 - add docstring demonstrating use of Inventory.id2path  | 
1291  | 
        
 | 
1292  | 
        >>> i = Inventory()
 | 
|
1293  | 
        >>> e = i.add(InventoryDirectory('src-id', 'src', ROOT_ID))
 | 
|
1294  | 
        >>> e = i.add(InventoryFile('foo-id', 'foo.c', parent_id='src-id'))
 | 
|
| 
1185.31.34
by John Arbash Meinel
 Removing instances of os.sep  | 
1295  | 
        >>> print i.id2path('foo-id')
 | 
| 
1393.1.32
by Martin Pool
 - add docstring demonstrating use of Inventory.id2path  | 
1296  | 
        src/foo.c
 | 
1297  | 
        """
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1298  | 
        # get all names, skipping root
 | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1299  | 
return '/'.join(reversed(  | 
1300  | 
[parent.name for parent in  | 
|
1301  | 
self._iter_file_id_parents(file_id)][:-1]))  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1302  | 
|
1303  | 
def path2id(self, name):  | 
|
1304  | 
"""Walk down through directories to return entry of last component.  | 
|
1305  | 
||
1306  | 
        names may be either a list of path components, or a single
 | 
|
1307  | 
        string, in which case it is automatically split.
 | 
|
1308  | 
||
1309  | 
        This returns the entry of the last component in the path,
 | 
|
1310  | 
        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  | 
1311  | 
|
| 
1713.1.11
by Robert Collins
 refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)  | 
1312  | 
        Returns None IFF the path is not found.
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1313  | 
        """
 | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
1314  | 
if isinstance(name, basestring):  | 
1315  | 
name = osutils.splitpath(name)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1316  | 
|
| 
1713.1.11
by Robert Collins
 refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)  | 
1317  | 
        # mutter("lookup path %r" % name)
 | 
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1318  | 
|
1319  | 
parent = self.root  | 
|
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
1320  | 
if parent is None:  | 
1321  | 
return None  | 
|
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1322  | 
for f in name:  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1323  | 
try:  | 
| 
2091.3.1
by Aaron Bentley
 When 'directory' path element isn't a directory, return None from path2id  | 
1324  | 
children = getattr(parent, 'children', None)  | 
| 
2091.3.3
by Aaron Bentley
 Test 'is None' not '== None'  | 
1325  | 
if children is None:  | 
| 
2091.3.1
by Aaron Bentley
 When 'directory' path element isn't a directory, return None from path2id  | 
1326  | 
return None  | 
1327  | 
cie = children[f]  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1328  | 
assert cie.name == f  | 
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1329  | 
assert cie.parent_id == parent.file_id  | 
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1330  | 
parent = cie  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1331  | 
except KeyError:  | 
1332  | 
                # or raise an error?
 | 
|
1333  | 
return None  | 
|
1334  | 
||
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1335  | 
return parent.file_id  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1336  | 
|
1337  | 
def has_filename(self, names):  | 
|
1338  | 
return bool(self.path2id(names))  | 
|
1339  | 
||
1340  | 
def has_id(self, file_id):  | 
|
| 
1711.9.11
by John Arbash Meinel
 change return foo in bar to return (foo in bar)  | 
1341  | 
return (file_id in self._byid)  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1342  | 
|
| 
1988.2.6
by Robert Collins
 Review feedback.  | 
1343  | 
def remove_recursive_id(self, file_id):  | 
1344  | 
"""Remove file_id, and children, from the inventory.  | 
|
1345  | 
        
 | 
|
1346  | 
        :param file_id: A file_id to remove.
 | 
|
1347  | 
        """
 | 
|
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1348  | 
to_find_delete = [self._byid[file_id]]  | 
1349  | 
to_delete = []  | 
|
| 
1988.2.6
by Robert Collins
 Review feedback.  | 
1350  | 
while to_find_delete:  | 
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1351  | 
ie = to_find_delete.pop()  | 
1352  | 
to_delete.append(ie.file_id)  | 
|
1353  | 
if ie.kind == 'directory':  | 
|
1354  | 
to_find_delete.extend(ie.children.values())  | 
|
1355  | 
for file_id in reversed(to_delete):  | 
|
| 
1988.2.4
by Robert Collins
 Bugfix the unversion implementation - it had a faulty inventory.remove included in it, which the initial test was not rigourous enough to detect.  | 
1356  | 
ie = self[file_id]  | 
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1357  | 
del self._byid[file_id]  | 
| 
1731.2.16
by Aaron Bentley
 Get extract working for standalone trees  | 
1358  | 
if ie.parent_id is not None:  | 
1359  | 
del self[ie.parent_id].children[ie.name]  | 
|
| 
2376.2.3
by Aaron Bentley
 Fix root replacement for apply_inventory_delta  | 
1360  | 
else:  | 
1361  | 
self.root = None  | 
|
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1362  | 
|
| 
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  | 
1363  | 
def rename(self, file_id, new_parent_id, new_name):  | 
1364  | 
"""Move a file within the inventory.  | 
|
1365  | 
||
1366  | 
        This can change either the name, or the parent, or both.
 | 
|
1367  | 
||
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
1368  | 
        This does not move the working file.
 | 
1369  | 
        """
 | 
|
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
1370  | 
new_name = ensure_normalized_name(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  | 
1371  | 
if not is_valid_name(new_name):  | 
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1372  | 
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  | 
1373  | 
|
1374  | 
new_parent = self._byid[new_parent_id]  | 
|
1375  | 
if new_name in new_parent.children:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1376  | 
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  | 
1377  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1378  | 
new_parent_idpath = self.get_idpath(new_parent_id)  | 
1379  | 
if file_id in new_parent_idpath:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1380  | 
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  | 
1381  | 
% (self.id2path(file_id), self.id2path(new_parent_id)))  | 
1382  | 
||
| 
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  | 
1383  | 
file_ie = self._byid[file_id]  | 
1384  | 
old_parent = self._byid[file_ie.parent_id]  | 
|
1385  | 
||
1386  | 
        # TODO: Don't leave things messed up if this fails
 | 
|
1387  | 
||
1388  | 
del old_parent.children[file_ie.name]  | 
|
1389  | 
new_parent.children[new_name] = file_ie  | 
|
1390  | 
||
1391  | 
file_ie.name = new_name  | 
|
1392  | 
file_ie.parent_id = new_parent_id  | 
|
1393  | 
||
| 
1731.1.1
by Aaron Bentley
 Make root entry an InventoryDirectory, make EmptyTree really empty  | 
1394  | 
def is_root(self, file_id):  | 
1395  | 
return self.root is not None and file_id == self.root.file_id  | 
|
1396  | 
||
| 
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  | 
1397  | 
|
| 
2255.2.74
by Robert Collins
 Minor performance optimisation in _generate_inventory by avoiding normalisation checks and just using a factory to create the inventory entries.  | 
1398  | 
entry_factory = {  | 
| 
2255.2.158
by Martin Pool
 Most of the integration of dirstate and subtree  | 
1399  | 
'directory': InventoryDirectory,  | 
1400  | 
'file': InventoryFile,  | 
|
1401  | 
'symlink': InventoryLink,  | 
|
| 
2255.6.8
by Aaron Bentley
 Merge refactoring of add_reference  | 
1402  | 
'tree-reference': TreeReference  | 
| 
2255.2.74
by Robert Collins
 Minor performance optimisation in _generate_inventory by avoiding normalisation checks and just using a factory to create the inventory entries.  | 
1403  | 
}
 | 
1404  | 
||
| 
1713.1.11
by Robert Collins
 refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)  | 
1405  | 
def make_entry(kind, name, parent_id, file_id=None):  | 
1406  | 
"""Create an inventory entry.  | 
|
1407  | 
||
1408  | 
    :param kind: the type of inventory entry to create.
 | 
|
1409  | 
    :param name: the basename of the entry.
 | 
|
1410  | 
    :param parent_id: the parent_id of the entry.
 | 
|
1411  | 
    :param file_id: the file_id to use. if None, one will be created.
 | 
|
1412  | 
    """
 | 
|
1413  | 
if file_id is None:  | 
|
| 
2116.4.1
by John Arbash Meinel
 Update file and revision id generators.  | 
1414  | 
file_id = generate_ids.gen_file_id(name)  | 
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
1415  | 
name = ensure_normalized_name(name)  | 
1416  | 
try:  | 
|
1417  | 
factory = entry_factory[kind]  | 
|
1418  | 
except KeyError:  | 
|
1419  | 
raise BzrError("unknown kind %r" % kind)  | 
|
1420  | 
return factory(file_id, name, parent_id)  | 
|
1421  | 
||
1422  | 
||
1423  | 
def ensure_normalized_name(name):  | 
|
1424  | 
"""Normalize name.  | 
|
1425  | 
||
1426  | 
    :raises InvalidNormalization: When name is not normalized, and cannot be
 | 
|
1427  | 
        accessed on this platform by the normalized path.
 | 
|
1428  | 
    :return: The NFC/NFKC normalised version of name.
 | 
|
1429  | 
    """
 | 
|
| 
2255.2.54
by Robert Collins
 Add in non-normalized filename sanity check to dirstate add().  | 
1430  | 
    #------- This has been copied to bzrlib.dirstate.DirState.add, please
 | 
1431  | 
    # keep them synchronised.
 | 
|
| 
2255.2.58
by Robert Collins
 Fix the way we used osutils.normalized_filename in dirstate to support overriding in tests - and document this in the original location it was used.  | 
1432  | 
    # we dont import normalized_filename directly because we want to be
 | 
1433  | 
    # able to change the implementation at runtime for tests.
 | 
|
| 
1830.3.5
by John Arbash Meinel
 make_entry refuses to create non-normalized entries.  | 
1434  | 
norm_name, can_access = osutils.normalized_filename(name)  | 
1435  | 
if norm_name != name:  | 
|
1436  | 
if can_access:  | 
|
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
1437  | 
return norm_name  | 
| 
1830.3.5
by John Arbash Meinel
 make_entry refuses to create non-normalized entries.  | 
1438  | 
else:  | 
1439  | 
            # TODO: jam 20060701 This would probably be more useful
 | 
|
1440  | 
            #       if the error was raised with the full path
 | 
|
1441  | 
raise errors.InvalidNormalization(name)  | 
|
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
1442  | 
return name  | 
| 
1713.1.11
by Robert Collins
 refactor smart_add to pass around the parent inventory entry and use that, resulting in another 100bzrlib/inventory.py performance improvement, and making inventory writing the dominating factory in add. (Robert Collins)  | 
1443  | 
|
| 
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  | 
1444  | 
|
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
1445  | 
_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  | 
1446  | 
|
1447  | 
def is_valid_name(name):  | 
|
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
1448  | 
global _NAME_RE  | 
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
1449  | 
if _NAME_RE is None:  | 
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
1450  | 
_NAME_RE = re.compile(r'^[^/\\]+$')  | 
1451  | 
||
| 
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  | 
1452  | 
return bool(_NAME_RE.match(name))  |