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
 | 
|
| 
4183.7.1
by Sabin Iacob
 update FSF mailing address  | 
15  | 
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
16  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
17  | 
# FIXME: This refactoring of the workingtree code doesn't seem to keep
 | 
| 
1185.16.72
by Martin Pool
 [merge] from robert and fix up tests  | 
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  | 
from bzrlib.lazy_import import lazy_import  | 
31  | 
lazy_import(globals(), """  | 
|
32  | 
import collections
 | 
|
| 
4496.3.10
by Andrew Bennetts
 Tidy import nits in inventory.py.  | 
33  | 
import copy
 | 
| 
4244.2.1
by Vincent Ladeuil
 inv._get_mutable_inventory() - prepare for CHKInventory  | 
34  | 
import os
 | 
35  | 
import re
 | 
|
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
36  | 
import tarfile
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
37  | 
|
| 
800
by Martin Pool
 Merge John's import-speedup branch:  | 
38  | 
import bzrlib
 | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
39  | 
from bzrlib import (
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
40  | 
    chk_map,
 | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
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,
 | 
|
45  | 
    )
 | 
|
46  | 
""")  | 
|
47  | 
||
48  | 
from bzrlib.errors import (  | 
|
49  | 
BzrCheckError,  | 
|
50  | 
BzrError,  | 
|
51  | 
    )
 | 
|
| 
3577.2.1
by Ian Clatworthy
 deprecate export-related InventoryEntry methods and refactor export code accordingly  | 
52  | 
from bzrlib.symbol_versioning import deprecated_in, deprecated_method  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
53  | 
from bzrlib.trace import mutter  | 
| 
1185.1.41
by Robert Collins
 massive patch from Alexander Belchenko - many PEP8 fixes, removes unused function uuid  | 
54  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
55  | 
|
| 
802
by Martin Pool
 - Remove XMLMixin class in favour of simple pack_xml, unpack_xml functions  | 
56  | 
class InventoryEntry(object):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
57  | 
"""Description of a versioned file.  | 
58  | 
||
59  | 
    An InventoryEntry has the following fields, which are also
 | 
|
60  | 
    present in the XML inventory-entry element:
 | 
|
61  | 
||
| 
1197
by Martin Pool
 doc  | 
62  | 
    file_id
 | 
63  | 
||
64  | 
    name
 | 
|
65  | 
        (within the parent directory)
 | 
|
66  | 
||
67  | 
    parent_id
 | 
|
68  | 
        file_id of the parent directory, or ROOT_ID
 | 
|
69  | 
||
| 
1092.2.21
by Robert Collins
 convert name_version to revision in inventory entries  | 
70  | 
    revision
 | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
71  | 
        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  | 
72  | 
        introduced.
 | 
| 
1197
by Martin Pool
 doc  | 
73  | 
|
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
74  | 
    executable
 | 
75  | 
        Indicates that this file should be executable on systems
 | 
|
76  | 
        that support it.
 | 
|
77  | 
||
| 
1197
by Martin Pool
 doc  | 
78  | 
    text_sha1
 | 
79  | 
        sha-1 of the text of the file
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
80  | 
|
| 
1197
by Martin Pool
 doc  | 
81  | 
    text_size
 | 
82  | 
        size in bytes of the text of the file
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
83  | 
|
| 
1197
by Martin Pool
 doc  | 
84  | 
    (reading a version 4 tree created a text_id field.)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
85  | 
|
86  | 
    >>> i = Inventory()
 | 
|
87  | 
    >>> i.path2id('')
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
88  | 
    'TREE_ROOT'
 | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
89  | 
    >>> i.add(InventoryDirectory('123', 'src', ROOT_ID))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
90  | 
    InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None)
 | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
91  | 
    >>> i.add(InventoryFile('2323', 'hello.c', parent_id='123'))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
92  | 
    InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None, revision=None)
 | 
| 
1996.3.13
by John Arbash Meinel
 Fix the inventory doc tests  | 
93  | 
    >>> shouldbe = {0: '', 1: 'src', 2: 'src/hello.c'}
 | 
| 
1185.16.151
by Martin Pool
 [patch] win32 fix for InventoryEntry doctest (Alexander, patch 21)  | 
94  | 
    >>> for ix, j in enumerate(i.iter_entries()):
 | 
95  | 
    ...   print (j[0] == shouldbe[ix], j[1])
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
96  | 
    ...
 | 
| 
2294.1.8
by John Arbash Meinel
 Fix one doc test in Inventory which expected a plain str  | 
97  | 
    (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.  | 
98  | 
    (True, InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
99  | 
    (True, InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None, revision=None))
 | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
100  | 
    >>> i.add(InventoryFile('2324', 'bye.c', '123'))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
101  | 
    InventoryFile('2324', 'bye.c', parent_id='123', sha1=None, len=None, revision=None)
 | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
102  | 
    >>> i.add(InventoryDirectory('2325', 'wibble', '123'))
 | 
| 
1733.1.6
by Jelmer Vernooij
 Fix a couple of minor issues after review by Martin.  | 
103  | 
    InventoryDirectory('2325', 'wibble', parent_id='123', revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
104  | 
    >>> i.path2id('src/wibble')
 | 
105  | 
    '2325'
 | 
|
106  | 
    >>> '2325' in i
 | 
|
107  | 
    True
 | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
108  | 
    >>> i.add(InventoryFile('2326', 'wibble.c', '2325'))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
109  | 
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None, revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
110  | 
    >>> i['2326']
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
111  | 
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None, revision=None)
 | 
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
112  | 
    >>> 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 \  | 
113  | 
    ...     print path
 | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
114  | 
    ...
 | 
| 
1852.6.6
by Robert Collins
 Finish updating iter_entries change to make all tests pass.  | 
115  | 
    <BLANKLINE>
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
116  | 
    src
 | 
117  | 
    src/bye.c
 | 
|
118  | 
    src/hello.c
 | 
|
119  | 
    src/wibble
 | 
|
120  | 
    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 \  | 
121  | 
    >>> i.id2path('2326')
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
122  | 
    'src/wibble/wibble.c'
 | 
123  | 
    """
 | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
124  | 
|
125  | 
    # Constants returned by describe_change()
 | 
|
126  | 
    #
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
127  | 
    # TODO: These should probably move to some kind of FileChangeDescription
 | 
128  | 
    # class; that's like what's inside a TreeDelta but we want to be able to
 | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
129  | 
    # generate them just for one file at a time.
 | 
130  | 
RENAMED = 'renamed'  | 
|
131  | 
MODIFIED_AND_RENAMED = 'modified and renamed'  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
132  | 
|
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
133  | 
__slots__ = []  | 
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
134  | 
|
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
135  | 
def detect_changes(self, old_entry):  | 
136  | 
"""Return a (text_modified, meta_modified) from this to old_entry.  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
137  | 
|
138  | 
        _read_tree_state must have been called on self and old_entry prior to
 | 
|
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
139  | 
        calling detect_changes.
 | 
140  | 
        """
 | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
141  | 
return False, False  | 
| 
1399.1.3
by Robert Collins
 move change detection for text and metadata from delta to entry.detect_changes  | 
142  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
143  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
144  | 
output_to, reverse=False):  | 
|
145  | 
"""Perform a diff between two entries of the same kind."""  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
146  | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
147  | 
def parent_candidates(self, previous_inventories):  | 
148  | 
"""Find possible per-file graph parents.  | 
|
149  | 
||
150  | 
        This is currently defined by:
 | 
|
151  | 
         - Select the last changed revision in the parent inventory.
 | 
|
152  | 
         - Do deal with a short lived bug in bzr 0.8's development two entries
 | 
|
153  | 
           that have the same last changed but different 'x' bit settings are
 | 
|
154  | 
           changed in-place.
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
155  | 
        """
 | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
156  | 
        # revision:ie mapping for each ie found in previous_inventories.
 | 
157  | 
candidates = {}  | 
|
158  | 
        # identify candidate head revision ids.
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
159  | 
for inv in previous_inventories:  | 
160  | 
if self.file_id in inv:  | 
|
161  | 
ie = inv[self.file_id]  | 
|
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
162  | 
if ie.revision in candidates:  | 
163  | 
                    # same revision value in two different inventories:
 | 
|
164  | 
                    # correct possible inconsistencies:
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
165  | 
                    #     * there was a bug in revision updates with 'x' bit
 | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
166  | 
                    #       support.
 | 
| 
1185.1.51
by Robert Collins
 merge in reweave support  | 
167  | 
try:  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
168  | 
if candidates[ie.revision].executable != ie.executable:  | 
169  | 
candidates[ie.revision].executable = False  | 
|
| 
1185.1.51
by Robert Collins
 merge in reweave support  | 
170  | 
ie.executable = False  | 
171  | 
except AttributeError:  | 
|
172  | 
                        pass
 | 
|
| 
1409
by Robert Collins
 unify previous inventory entry parent logic in preparation for fixing the revision-thrashing bug  | 
173  | 
else:  | 
| 
1596.2.20
by Robert Collins
 optimise commit to only access weaves for merged, or altered files during commit.  | 
174  | 
                    # add this revision as a candidate.
 | 
175  | 
candidates[ie.revision] = ie  | 
|
| 
2776.3.1
by Robert Collins
 * Deprecated method ``find_previous_heads`` on  | 
176  | 
return candidates  | 
177  | 
||
| 
3577.2.1
by Ian Clatworthy
 deprecate export-related InventoryEntry methods and refactor export code accordingly  | 
178  | 
@deprecated_method(deprecated_in((1, 6, 0)))  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
179  | 
def get_tar_item(self, root, dp, now, tree):  | 
| 
1399.1.7
by Robert Collins
 implement symlink exporting to tarballs  | 
180  | 
"""Get a tarfile item and a file stream for its content."""  | 
| 
1996.3.20
by John Arbash Meinel
 [merge] bzr.dev 2063  | 
181  | 
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  | 
182  | 
        # TODO: would be cool to actually set it to the timestamp of the
 | 
183  | 
        # revision it was last changed
 | 
|
184  | 
item.mtime = now  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
185  | 
fileobj = self._put_in_tar(item, tree)  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
186  | 
return item, fileobj  | 
187  | 
||
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
188  | 
def has_text(self):  | 
189  | 
"""Return true if the object this entry represents has textual data.  | 
|
190  | 
||
191  | 
        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  | 
192  | 
|
193  | 
        Also note that all entries get weave files created for them.
 | 
|
194  | 
        This attribute is primarily used when upgrading from old trees that
 | 
|
195  | 
        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  | 
196  | 
        """
 | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
197  | 
return False  | 
| 
1399.1.5
by Robert Collins
 move checking whether an entry stores text into inventory.py from fetch,py  | 
198  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
199  | 
def __init__(self, file_id, name, parent_id, text_id=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
200  | 
"""Create an InventoryEntry  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
201  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
202  | 
        The filename must be a single component, relative to the
 | 
203  | 
        parent directory; it cannot be a whole path or relative name.
 | 
|
204  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
205  | 
        >>> e = InventoryFile('123', 'hello.c', ROOT_ID)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
206  | 
        >>> e.name
 | 
207  | 
        'hello.c'
 | 
|
208  | 
        >>> e.file_id
 | 
|
209  | 
        '123'
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
210  | 
        >>> e = InventoryFile('123', 'src/hello.c', ROOT_ID)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
211  | 
        Traceback (most recent call last):
 | 
| 
1185.16.63
by Martin Pool
 - more error conversion  | 
212  | 
        InvalidEntryName: Invalid entry name: src/hello.c
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
213  | 
        """
 | 
| 
376
by Martin Pool
 - fix slow invariant check when reading in InventoryEntry objects  | 
214  | 
if '/' in name or '\\' in name:  | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
215  | 
raise errors.InvalidEntryName(name=name)  | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
216  | 
self.executable = False  | 
| 
1092.2.21
by Robert Collins
 convert name_version to revision in inventory entries  | 
217  | 
self.revision = None  | 
| 
955
by Martin Pool
 - use __slots__ on InventoryEntry; rather faster  | 
218  | 
self.text_sha1 = None  | 
219  | 
self.text_size = None  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
220  | 
self.file_id = file_id  | 
221  | 
self.name = name  | 
|
222  | 
self.text_id = text_id  | 
|
223  | 
self.parent_id = parent_id  | 
|
| 
1092.2.6
by Robert Collins
 symlink support updated to work  | 
224  | 
self.symlink_target = None  | 
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
225  | 
self.reference_revision = None  | 
| 
237
by mbp at sourcefrog
 - Better assertions in InventoryEntry constructor  | 
226  | 
|
| 
1399.1.2
by Robert Collins
 push kind character creation into InventoryEntry and TreeEntry  | 
227  | 
def kind_character(self):  | 
228  | 
"""Return a short kind indicator useful for appending to names."""  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
229  | 
raise BzrError('unknown kind %r' % self.kind)  | 
| 
1399.1.2
by Robert Collins
 push kind character creation into InventoryEntry and TreeEntry  | 
230  | 
|
| 
1731.1.2
by Aaron Bentley
 Removed all remaining uses of root_directory  | 
231  | 
known_kinds = ('file', 'directory', 'symlink')  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
232  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
233  | 
def _put_in_tar(self, item, tree):  | 
234  | 
"""populate item for stashing in a tar, and return the content stream.  | 
|
235  | 
||
236  | 
        If no content is available, return None.
 | 
|
237  | 
        """
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
238  | 
raise BzrError("don't know how to export {%s} of kind %r" %  | 
239  | 
(self.file_id, self.kind))  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
240  | 
|
| 
3577.2.1
by Ian Clatworthy
 deprecate export-related InventoryEntry methods and refactor export code accordingly  | 
241  | 
@deprecated_method(deprecated_in((1, 6, 0)))  | 
| 
1399.1.6
by Robert Collins
 move exporting functionality into inventory.py - uncovers bug in symlink support  | 
242  | 
def put_on_disk(self, dest, dp, tree):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
243  | 
"""Create a representation of self on disk in the prefix dest.  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
244  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
245  | 
        This is a template method - implement _put_on_disk in subclasses.
 | 
246  | 
        """
 | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
247  | 
fullpath = osutils.pathjoin(dest, dp)  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
248  | 
self._put_on_disk(fullpath, tree)  | 
| 
1711.2.101
by John Arbash Meinel
 Clean up some unnecessary mutter() calls  | 
249  | 
        # mutter("  export {%s} kind %s to %s", self.file_id,
 | 
250  | 
        #         self.kind, fullpath)
 | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
251  | 
|
252  | 
def _put_on_disk(self, fullpath, tree):  | 
|
253  | 
"""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  | 
254  | 
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  | 
255  | 
|
| 
156
by mbp at sourcefrog
 new "directories" command  | 
256  | 
def sorted_children(self):  | 
| 
1757.2.13
by Robert Collins
 Tweak InventoryEntry.sorted_children to be simpler.  | 
257  | 
return sorted(self.children.items())  | 
| 
156
by mbp at sourcefrog
 new "directories" command  | 
258  | 
|
| 
1399.1.1
by Robert Collins
 move checks for versionability of file kinds into InventoryEntry  | 
259  | 
    @staticmethod
 | 
260  | 
def versionable_kind(kind):  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
261  | 
return (kind in ('file', 'directory', 'symlink', 'tree-reference'))  | 
| 
1399.1.1
by Robert Collins
 move checks for versionability of file kinds into InventoryEntry  | 
262  | 
|
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
263  | 
def check(self, checker, rev_id, inv):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
264  | 
"""Check this inventory entry is intact.  | 
265  | 
||
266  | 
        This is a template method, override _check for kind specific
 | 
|
267  | 
        tests.
 | 
|
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
268  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
269  | 
        :param checker: Check object providing context for the checks;
 | 
| 
1616.1.5
by Martin Pool
 Cleanup and document some check code  | 
270  | 
             can be used to find out what parts of the repository have already
 | 
271  | 
             been checked.
 | 
|
272  | 
        :param rev_id: Revision id from which this InventoryEntry was loaded.
 | 
|
273  | 
             Not necessarily the last-changed revision for this file.
 | 
|
274  | 
        :param inv: Inventory from which the entry was loaded.
 | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
275  | 
        """
 | 
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
276  | 
if self.parent_id is not None:  | 
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
277  | 
if not inv.has_id(self.parent_id):  | 
278  | 
raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'  | 
|
279  | 
% (self.parent_id, rev_id))  | 
|
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
280  | 
checker._add_entry_to_text_key_references(inv, self)  | 
281  | 
self._check(checker, rev_id)  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
282  | 
|
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
283  | 
def _check(self, checker, rev_id):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
284  | 
"""Check this inventory entry for kind specific errors."""  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
285  | 
checker._report_items.append(  | 
286  | 
'unknown entry kind %r in revision {%s}' % (self.kind, rev_id))  | 
|
| 
1092.2.20
by Robert Collins
 symlink and weaves, whaddya know  | 
287  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
288  | 
def copy(self):  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
289  | 
"""Clone this inventory entry."""  | 
290  | 
raise NotImplementedError  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
291  | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
292  | 
    @staticmethod
 | 
293  | 
def describe_change(old_entry, new_entry):  | 
|
294  | 
"""Describe the change between old_entry and this.  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
295  | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
296  | 
        This smells of being an InterInventoryEntry situation, but as its
 | 
297  | 
        the first one, we're making it a static method for now.
 | 
|
298  | 
||
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
299  | 
        An entry with a different parent, or different name is considered
 | 
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
300  | 
        to be renamed. Reparenting is an internal detail.
 | 
301  | 
        Note that renaming the parent does not trigger a rename for the
 | 
|
302  | 
        child entry itself.
 | 
|
| 
1669.2.1
by Martin Pool
 verbose commit now specifically identifies modified/renamed/reparented files  | 
303  | 
        """
 | 
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
304  | 
        # TODO: Perhaps return an object rather than just a string
 | 
305  | 
if old_entry is new_entry:  | 
|
306  | 
            # also the case of both being None
 | 
|
307  | 
return 'unchanged'  | 
|
308  | 
elif old_entry is None:  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
309  | 
return 'added'  | 
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
310  | 
elif new_entry is None:  | 
311  | 
return 'removed'  | 
|
| 
1959.4.1
by Aaron Bentley
 Correctly handle all file kind changes  | 
312  | 
if old_entry.kind != new_entry.kind:  | 
313  | 
return 'modified'  | 
|
| 
1668.1.5
by Martin Pool
 [broken] fix up display of files changed by a commit  | 
314  | 
text_modified, meta_modified = new_entry.detect_changes(old_entry)  | 
315  | 
if text_modified or meta_modified:  | 
|
316  | 
modified = True  | 
|
317  | 
else:  | 
|
318  | 
modified = False  | 
|
319  | 
        # TODO 20060511 (mbp, rbc) factor out 'detect_rename' here.
 | 
|
320  | 
if old_entry.parent_id != new_entry.parent_id:  | 
|
321  | 
renamed = True  | 
|
322  | 
elif old_entry.name != new_entry.name:  | 
|
323  | 
renamed = True  | 
|
324  | 
else:  | 
|
325  | 
renamed = False  | 
|
326  | 
if renamed and not modified:  | 
|
327  | 
return InventoryEntry.RENAMED  | 
|
328  | 
if modified and not renamed:  | 
|
329  | 
return 'modified'  | 
|
330  | 
if modified and renamed:  | 
|
331  | 
return InventoryEntry.MODIFIED_AND_RENAMED  | 
|
332  | 
return 'unchanged'  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
333  | 
|
334  | 
def __repr__(self):  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
335  | 
return ("%s(%r, %r, parent_id=%r, revision=%r)"  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
336  | 
% (self.__class__.__name__,  | 
337  | 
self.file_id,  | 
|
338  | 
self.name,  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
339  | 
self.parent_id,  | 
340  | 
self.revision))  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
341  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
342  | 
def __eq__(self, other):  | 
| 
3882.6.16
by John Arbash Meinel
 Update InventoryEntry.__eq__ in case we enable caching without .copy()  | 
343  | 
if other is self:  | 
344  | 
            # For the case when objects are cached
 | 
|
345  | 
return True  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
346  | 
if not isinstance(other, InventoryEntry):  | 
347  | 
return NotImplemented  | 
|
348  | 
||
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
349  | 
return ((self.file_id == other.file_id)  | 
350  | 
and (self.name == other.name)  | 
|
351  | 
and (other.symlink_target == self.symlink_target)  | 
|
352  | 
and (self.text_sha1 == other.text_sha1)  | 
|
353  | 
and (self.text_size == other.text_size)  | 
|
354  | 
and (self.text_id == other.text_id)  | 
|
355  | 
and (self.parent_id == other.parent_id)  | 
|
356  | 
and (self.kind == other.kind)  | 
|
357  | 
and (self.revision == other.revision)  | 
|
358  | 
and (self.executable == other.executable)  | 
|
| 
2255.2.220
by Robert Collins
 Fix failing detection of changes restricted to subtrees causing spurious pointless commit errors.  | 
359  | 
and (self.reference_revision == other.reference_revision)  | 
| 
1398
by Robert Collins
 integrate in Gustavos x-bit patch  | 
360  | 
                )
 | 
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
361  | 
|
362  | 
def __ne__(self, other):  | 
|
363  | 
return not (self == other)  | 
|
364  | 
||
365  | 
def __hash__(self):  | 
|
366  | 
raise ValueError('not hashable')  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
367  | 
|
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
368  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
369  | 
"""Has this entry changed relative to previous_ie.  | 
370  | 
||
| 
1759.2.1
by Jelmer Vernooij
 Fix some types (found using aspell).  | 
371  | 
        This method should be overridden in child classes.
 | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
372  | 
        """
 | 
| 
1092.2.22
by Robert Collins
 text_version and name_version unification looking reasonable  | 
373  | 
compatible = True  | 
374  | 
        # different inv parent
 | 
|
375  | 
if previous_ie.parent_id != self.parent_id:  | 
|
376  | 
compatible = False  | 
|
377  | 
        # renamed
 | 
|
378  | 
elif previous_ie.name != self.name:  | 
|
379  | 
compatible = False  | 
|
| 
2374.2.2
by John Arbash Meinel
 Fix the small bug that ie.snapshot() didn't think about kind changes.  | 
380  | 
elif previous_ie.kind != self.kind:  | 
381  | 
compatible = False  | 
|
| 
1092.2.22
by Robert Collins
 text_version and name_version unification looking reasonable  | 
382  | 
return compatible  | 
383  | 
||
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
384  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
385  | 
"""Populate fields in the inventory entry from the given tree.  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
386  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
387  | 
        Note that this should be modified to be a noop on virtual trees
 | 
388  | 
        as all entries created there are prepopulated.
 | 
|
389  | 
        """
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
390  | 
        # TODO: Rather than running this manually, we should check the
 | 
| 
1185.16.5
by Martin Pool
 doc  | 
391  | 
        # working sha1 and other expensive properties when they're
 | 
392  | 
        # first requested, or preload them if they're already known
 | 
|
393  | 
pass # nothing to do by default  | 
|
| 
1092.2.23
by Robert Collins
 move inventory entry centric snapshot taking logic to inventory.py  | 
394  | 
|
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
395  | 
def _forget_tree_state(self):  | 
396  | 
        pass
 | 
|
397  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
398  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
399  | 
class RootEntry(InventoryEntry):  | 
400  | 
||
401  | 
__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.  | 
402  | 
'text_id', 'parent_id', 'children', 'executable',  | 
403  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
404  | 
|
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
405  | 
def _check(self, checker, rev_id):  | 
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
406  | 
"""See InventoryEntry._check"""  | 
407  | 
||
408  | 
def __init__(self, file_id):  | 
|
409  | 
self.file_id = file_id  | 
|
410  | 
self.children = {}  | 
|
411  | 
self.kind = 'directory'  | 
|
412  | 
self.parent_id = None  | 
|
413  | 
self.name = u''  | 
|
414  | 
self.revision = None  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
415  | 
symbol_versioning.warn('RootEntry is deprecated as of bzr 0.10.'  | 
416  | 
' Please use InventoryDirectory instead.',  | 
|
417  | 
DeprecationWarning, stacklevel=2)  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
418  | 
|
419  | 
def __eq__(self, other):  | 
|
420  | 
if not isinstance(other, RootEntry):  | 
|
421  | 
return NotImplemented  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
422  | 
|
| 
1907.1.4
by Aaron Bentley
 Restore RootEntry, but mark it deprecated, restore EmptyTree.kind  | 
423  | 
return (self.file_id == other.file_id) \  | 
424  | 
and (self.children == other.children)  | 
|
425  | 
||
426  | 
||
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
427  | 
class InventoryDirectory(InventoryEntry):  | 
428  | 
"""A directory in an inventory."""  | 
|
429  | 
||
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
430  | 
__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.  | 
431  | 
'text_id', 'parent_id', 'children', 'executable',  | 
432  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
433  | 
|
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
434  | 
def _check(self, checker, rev_id):  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
435  | 
"""See InventoryEntry._check"""  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
436  | 
if (self.text_sha1 is not None or self.text_size is not None or  | 
437  | 
self.text_id is not None):  | 
|
438  | 
checker._report_items.append('directory {%s} has text in revision {%s}'  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
439  | 
% (self.file_id, rev_id))  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
440  | 
        # Directories are stored as ''.
 | 
441  | 
checker.add_pending_item(rev_id,  | 
|
442  | 
('texts', self.file_id, self.revision), 'text',  | 
|
443  | 
'da39a3ee5e6b4b0d3255bfef95601890afd80709')  | 
|
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
444  | 
|
445  | 
def copy(self):  | 
|
446  | 
other = InventoryDirectory(self.file_id, self.name, self.parent_id)  | 
|
447  | 
other.revision = self.revision  | 
|
448  | 
        # note that children are *not* copied; they're pulled across when
 | 
|
449  | 
        # others are added
 | 
|
450  | 
return other  | 
|
451  | 
||
452  | 
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  | 
453  | 
super(InventoryDirectory, self).__init__(file_id, name, parent_id)  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
454  | 
self.children = {}  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
455  | 
self.kind = 'directory'  | 
| 
1399.1.8
by Robert Collins
 factor out inventory directory logic into 'InventoryDirectory' class  | 
456  | 
|
457  | 
def kind_character(self):  | 
|
458  | 
"""See InventoryEntry.kind_character."""  | 
|
459  | 
return '/'  | 
|
460  | 
||
461  | 
def _put_in_tar(self, item, tree):  | 
|
462  | 
"""See InventoryEntry._put_in_tar."""  | 
|
463  | 
item.type = tarfile.DIRTYPE  | 
|
464  | 
fileobj = None  | 
|
465  | 
item.name += '/'  | 
|
466  | 
item.size = 0  | 
|
467  | 
item.mode = 0755  | 
|
468  | 
return fileobj  | 
|
469  | 
||
470  | 
def _put_on_disk(self, fullpath, tree):  | 
|
471  | 
"""See InventoryEntry._put_on_disk."""  | 
|
472  | 
os.mkdir(fullpath)  | 
|
473  | 
||
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
474  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
475  | 
class InventoryFile(InventoryEntry):  | 
476  | 
"""A file in an inventory."""  | 
|
477  | 
||
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
478  | 
__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.  | 
479  | 
'text_id', 'parent_id', 'children', 'executable',  | 
480  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
481  | 
|
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
482  | 
def _check(self, checker, tree_revision_id):  | 
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
483  | 
"""See InventoryEntry._check"""  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
484  | 
        # TODO: check size too.
 | 
485  | 
checker.add_pending_item(tree_revision_id,  | 
|
486  | 
('texts', self.file_id, self.revision), 'text',  | 
|
487  | 
self.text_sha1)  | 
|
488  | 
if self.text_size is None:  | 
|
489  | 
checker._report_items.append(  | 
|
490  | 
'fileid {%s} in {%s} has None for text_size' % (self.file_id,  | 
|
491  | 
tree_revision_id))  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
492  | 
|
493  | 
def copy(self):  | 
|
494  | 
other = InventoryFile(self.file_id, self.name, self.parent_id)  | 
|
495  | 
other.executable = self.executable  | 
|
496  | 
other.text_id = self.text_id  | 
|
497  | 
other.text_sha1 = self.text_sha1  | 
|
498  | 
other.text_size = self.text_size  | 
|
499  | 
other.revision = self.revision  | 
|
500  | 
return other  | 
|
501  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
502  | 
def detect_changes(self, old_entry):  | 
503  | 
"""See InventoryEntry.detect_changes."""  | 
|
504  | 
text_modified = (self.text_sha1 != old_entry.text_sha1)  | 
|
505  | 
meta_modified = (self.executable != old_entry.executable)  | 
|
506  | 
return text_modified, meta_modified  | 
|
507  | 
||
508  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
509  | 
output_to, reverse=False):  | 
|
510  | 
"""See InventoryEntry._diff."""  | 
|
| 
3009.2.22
by Aaron Bentley
 Update names & docstring  | 
511  | 
from bzrlib.diff import DiffText  | 
| 
3009.2.5
by Aaron Bentley
 Factor symlink and file diffing into differ  | 
512  | 
from_file_id = self.file_id  | 
513  | 
if to_entry:  | 
|
514  | 
to_file_id = to_entry.file_id  | 
|
515  | 
else:  | 
|
516  | 
to_file_id = None  | 
|
517  | 
if reverse:  | 
|
518  | 
to_file_id, from_file_id = from_file_id, to_file_id  | 
|
519  | 
tree, to_tree = to_tree, tree  | 
|
520  | 
from_label, to_label = to_label, from_label  | 
|
| 
3009.2.22
by Aaron Bentley
 Update names & docstring  | 
521  | 
differ = DiffText(tree, to_tree, output_to, 'utf-8', '', '',  | 
522  | 
text_diff)  | 
|
| 
3009.2.5
by Aaron Bentley
 Factor symlink and file diffing into differ  | 
523  | 
return differ.diff_text(from_file_id, to_file_id, from_label, to_label)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
524  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
525  | 
def has_text(self):  | 
526  | 
"""See InventoryEntry.has_text."""  | 
|
527  | 
return True  | 
|
528  | 
||
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
529  | 
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  | 
530  | 
super(InventoryFile, self).__init__(file_id, name, parent_id)  | 
531  | 
self.kind = 'file'  | 
|
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
532  | 
|
533  | 
def kind_character(self):  | 
|
534  | 
"""See InventoryEntry.kind_character."""  | 
|
535  | 
return ''  | 
|
536  | 
||
537  | 
def _put_in_tar(self, item, tree):  | 
|
538  | 
"""See InventoryEntry._put_in_tar."""  | 
|
539  | 
item.type = tarfile.REGTYPE  | 
|
540  | 
fileobj = tree.get_file(self.file_id)  | 
|
541  | 
item.size = self.text_size  | 
|
542  | 
if tree.is_executable(self.file_id):  | 
|
543  | 
item.mode = 0755  | 
|
544  | 
else:  | 
|
545  | 
item.mode = 0644  | 
|
546  | 
return fileobj  | 
|
547  | 
||
548  | 
def _put_on_disk(self, fullpath, tree):  | 
|
549  | 
"""See InventoryEntry._put_on_disk."""  | 
|
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
550  | 
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  | 
551  | 
if tree.is_executable(self.file_id):  | 
552  | 
os.chmod(fullpath, 0755)  | 
|
553  | 
||
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
554  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
555  | 
"""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  | 
556  | 
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.  | 
557  | 
        # FIXME: 20050930 probe for the text size when getting sha1
 | 
558  | 
        # in _read_tree_state
 | 
|
| 
1732.1.19
by John Arbash Meinel
 If you have the path, use it rather than looking it up again  | 
559  | 
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  | 
560  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
561  | 
def __repr__(self):  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
562  | 
return ("%s(%r, %r, parent_id=%r, sha1=%r, len=%s, revision=%s)"  | 
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
563  | 
% (self.__class__.__name__,  | 
564  | 
self.file_id,  | 
|
565  | 
self.name,  | 
|
566  | 
self.parent_id,  | 
|
567  | 
self.text_sha1,  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
568  | 
self.text_size,  | 
569  | 
self.revision))  | 
|
| 
1733.1.4
by Robert Collins
 Cosmetic niceties for debugging, extra comments etc.  | 
570  | 
|
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
571  | 
def _forget_tree_state(self):  | 
572  | 
self.text_sha1 = None  | 
|
573  | 
||
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
574  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
575  | 
"""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  | 
576  | 
compatible = super(InventoryFile, self)._unchanged(previous_ie)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
577  | 
if self.text_sha1 != previous_ie.text_sha1:  | 
578  | 
compatible = False  | 
|
579  | 
else:  | 
|
580  | 
            # FIXME: 20050930 probe for the text size when getting sha1
 | 
|
581  | 
            # in _read_tree_state
 | 
|
582  | 
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  | 
583  | 
if self.executable != previous_ie.executable:  | 
584  | 
compatible = False  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
585  | 
return compatible  | 
586  | 
||
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
587  | 
|
588  | 
class InventoryLink(InventoryEntry):  | 
|
589  | 
"""A file in an inventory."""  | 
|
590  | 
||
| 
1757.2.10
by Robert Collins
 Give all inventory entries __slots__ that are useful with the current codebase.  | 
591  | 
__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.  | 
592  | 
'text_id', 'parent_id', 'children', 'executable',  | 
593  | 
'revision', 'symlink_target', 'reference_revision']  | 
|
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
594  | 
|
| 
4332.3.35
by Robert Collins
 Fix failing tests.  | 
595  | 
def _check(self, checker, tree_revision_id):  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
596  | 
"""See InventoryEntry._check"""  | 
| 
1757.2.11
by Robert Collins
 Correct bzr diff | less= None clauses in inventory.py to be is not None.  | 
597  | 
if self.text_sha1 is not None or self.text_size is not None or self.text_id is not None:  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
598  | 
checker._report_items.append(  | 
599  | 
'symlink {%s} has text in revision {%s}'  | 
|
| 
4332.3.35
by Robert Collins
 Fix failing tests.  | 
600  | 
% (self.file_id, tree_revision_id))  | 
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
601  | 
if self.symlink_target is None:  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
602  | 
checker._report_items.append(  | 
603  | 
'symlink {%s} has no target in revision {%s}'  | 
|
| 
4332.3.35
by Robert Collins
 Fix failing tests.  | 
604  | 
% (self.file_id, tree_revision_id))  | 
| 
4332.3.28
by Robert Collins
 Start checking file texts in a single pass.  | 
605  | 
        # Symlinks are stored as ''
 | 
606  | 
checker.add_pending_item(tree_revision_id,  | 
|
607  | 
('texts', self.file_id, self.revision), 'text',  | 
|
608  | 
'da39a3ee5e6b4b0d3255bfef95601890afd80709')  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
609  | 
|
610  | 
def copy(self):  | 
|
611  | 
other = InventoryLink(self.file_id, self.name, self.parent_id)  | 
|
612  | 
other.symlink_target = self.symlink_target  | 
|
613  | 
other.revision = self.revision  | 
|
614  | 
return other  | 
|
615  | 
||
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
616  | 
def detect_changes(self, old_entry):  | 
617  | 
"""See InventoryEntry.detect_changes."""  | 
|
618  | 
        # FIXME: which _modified field should we use ? RBC 20051003
 | 
|
619  | 
text_modified = (self.symlink_target != old_entry.symlink_target)  | 
|
620  | 
if text_modified:  | 
|
621  | 
mutter(" symlink target changed")  | 
|
622  | 
meta_modified = False  | 
|
623  | 
return text_modified, meta_modified  | 
|
624  | 
||
625  | 
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,  | 
|
626  | 
output_to, reverse=False):  | 
|
627  | 
"""See InventoryEntry._diff."""  | 
|
| 
3009.2.22
by Aaron Bentley
 Update names & docstring  | 
628  | 
from bzrlib.diff import DiffSymlink  | 
| 
3009.2.5
by Aaron Bentley
 Factor symlink and file diffing into differ  | 
629  | 
old_target = self.symlink_target  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
630  | 
if to_entry is not None:  | 
| 
3009.2.5
by Aaron Bentley
 Factor symlink and file diffing into differ  | 
631  | 
new_target = to_entry.symlink_target  | 
632  | 
else:  | 
|
633  | 
new_target = None  | 
|
634  | 
if not reverse:  | 
|
635  | 
old_tree = tree  | 
|
636  | 
new_tree = to_tree  | 
|
637  | 
else:  | 
|
638  | 
old_tree = to_tree  | 
|
639  | 
new_tree = tree  | 
|
640  | 
new_target, old_target = old_target, new_target  | 
|
| 
3009.2.22
by Aaron Bentley
 Update names & docstring  | 
641  | 
differ = DiffSymlink(old_tree, new_tree, output_to)  | 
| 
3009.2.5
by Aaron Bentley
 Factor symlink and file diffing into differ  | 
642  | 
return differ.diff_symlink(old_target, new_target)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
643  | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
644  | 
def __init__(self, file_id, name, parent_id):  | 
645  | 
super(InventoryLink, self).__init__(file_id, name, parent_id)  | 
|
646  | 
self.kind = 'symlink'  | 
|
647  | 
||
648  | 
def kind_character(self):  | 
|
649  | 
"""See InventoryEntry.kind_character."""  | 
|
650  | 
return ''  | 
|
651  | 
||
652  | 
def _put_in_tar(self, item, tree):  | 
|
653  | 
"""See InventoryEntry._put_in_tar."""  | 
|
| 
1185.33.3
by Martin Pool
 [merge] jelmer  | 
654  | 
item.type = tarfile.SYMTYPE  | 
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
655  | 
fileobj = None  | 
656  | 
item.size = 0  | 
|
657  | 
item.mode = 0755  | 
|
658  | 
item.linkname = self.symlink_target  | 
|
659  | 
return fileobj  | 
|
660  | 
||
661  | 
def _put_on_disk(self, fullpath, tree):  | 
|
662  | 
"""See InventoryEntry._put_on_disk."""  | 
|
663  | 
try:  | 
|
664  | 
os.symlink(self.symlink_target, fullpath)  | 
|
665  | 
except OSError,e:  | 
|
666  | 
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  | 
667  | 
|
| 
1185.12.33
by Aaron Bentley
 Fixed symlink reverting  | 
668  | 
def _read_tree_state(self, path, work_tree):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
669  | 
"""See InventoryEntry._read_tree_state."""  | 
670  | 
self.symlink_target = work_tree.get_symlink_target(self.file_id)  | 
|
671  | 
||
| 
1534.7.175
by Aaron Bentley
 Ensured revert writes a normal inventory  | 
672  | 
def _forget_tree_state(self):  | 
673  | 
self.symlink_target = None  | 
|
674  | 
||
| 
1405
by Robert Collins
 remove some of the upgrade code that was duplicated with inventory_entry, and give all inventory entries a weave  | 
675  | 
def _unchanged(self, previous_ie):  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
676  | 
"""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  | 
677  | 
compatible = super(InventoryLink, self)._unchanged(previous_ie)  | 
| 
1399.1.11
by Robert Collins
 finish off nearly all of the kind separations  | 
678  | 
if self.symlink_target != previous_ie.symlink_target:  | 
679  | 
compatible = False  | 
|
680  | 
return compatible  | 
|
681  | 
||
| 
1399.1.9
by Robert Collins
 factor out file related logic from InventoryEntry to InventoryFile  | 
682  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
683  | 
class TreeReference(InventoryEntry):  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
684  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
685  | 
kind = 'tree-reference'  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
686  | 
|
| 
2255.6.8
by Aaron Bentley
 Merge refactoring of add_reference  | 
687  | 
def __init__(self, file_id, name, parent_id, revision=None,  | 
688  | 
reference_revision=None):  | 
|
| 
2100.3.1
by Aaron Bentley
 Start roundtripping tree-reference entries  | 
689  | 
InventoryEntry.__init__(self, file_id, name, parent_id)  | 
690  | 
self.revision = revision  | 
|
691  | 
self.reference_revision = reference_revision  | 
|
692  | 
||
| 
2100.3.18
by Aaron Bentley
 Get commit working for tree references  | 
693  | 
def copy(self):  | 
694  | 
return TreeReference(self.file_id, self.name, self.parent_id,  | 
|
695  | 
self.revision, self.reference_revision)  | 
|
696  | 
||
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
697  | 
def _read_tree_state(self, path, work_tree):  | 
698  | 
"""Populate fields in the inventory entry from the given tree.  | 
|
699  | 
        """
 | 
|
| 
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.  | 
700  | 
self.reference_revision = work_tree.get_reference_revision(  | 
701  | 
self.file_id, path)  | 
|
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
702  | 
|
703  | 
def _forget_tree_state(self):  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
704  | 
self.reference_revision = None  | 
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
705  | 
|
| 
2825.5.2
by Robert Collins
 Review feedback, and fix pointless commits with nested trees to raise PointlessCommit appropriately.  | 
706  | 
def _unchanged(self, previous_ie):  | 
707  | 
"""See InventoryEntry._unchanged."""  | 
|
708  | 
compatible = super(TreeReference, self)._unchanged(previous_ie)  | 
|
709  | 
if self.reference_revision != previous_ie.reference_revision:  | 
|
710  | 
compatible = False  | 
|
711  | 
return compatible  | 
|
712  | 
||
| 
2100.3.19
by Aaron Bentley
 Ensure commit preserves reference revision  | 
713  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
714  | 
class CommonInventory(object):  | 
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
715  | 
"""Basic inventory logic, defined in terms of primitives like has_id.  | 
716  | 
||
717  | 
    An inventory is the metadata about the contents of a tree.
 | 
|
718  | 
||
719  | 
    This is broadly a map from file_id to entries such as directories, files,
 | 
|
720  | 
    symlinks and tree references. Each entry maintains its own metadata like
 | 
|
721  | 
    SHA1 and length for files, or children for a directory.
 | 
|
722  | 
||
723  | 
    Entries can be looked up either by path or by file_id.
 | 
|
724  | 
||
725  | 
    InventoryEntry objects must not be modified after they are
 | 
|
726  | 
    inserted, other than through the Inventory API.
 | 
|
727  | 
    """
 | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
728  | 
|
| 
3735.2.61
by Robert Collins
 Define __contains__ for all Inventories, as otherwise __iter__ gets used for foo in bar, if __iter__ is defined.  | 
729  | 
def __contains__(self, file_id):  | 
730  | 
"""True if this entry contains a file with given id.  | 
|
731  | 
||
732  | 
        >>> inv = Inventory()
 | 
|
733  | 
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
 | 
|
734  | 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 | 
|
735  | 
        >>> '123' in inv
 | 
|
736  | 
        True
 | 
|
737  | 
        >>> '456' in inv
 | 
|
738  | 
        False
 | 
|
739  | 
||
740  | 
        Note that this method along with __iter__ are not encouraged for use as
 | 
|
741  | 
        they are less clear than specific query methods - they may be rmeoved
 | 
|
742  | 
        in the future.
 | 
|
743  | 
        """
 | 
|
744  | 
return self.has_id(file_id)  | 
|
745  | 
||
| 
4593.3.2
by Martin Pool
 has_filename should be in CommonInventory and CHKInventory  | 
746  | 
def has_filename(self, filename):  | 
747  | 
return bool(self.path2id(filename))  | 
|
748  | 
||
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
749  | 
def id2path(self, file_id):  | 
750  | 
"""Return as a string the path to file_id.  | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
751  | 
|
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
752  | 
        >>> i = Inventory()
 | 
753  | 
        >>> e = i.add(InventoryDirectory('src-id', 'src', ROOT_ID))
 | 
|
754  | 
        >>> e = i.add(InventoryFile('foo-id', 'foo.c', parent_id='src-id'))
 | 
|
755  | 
        >>> print i.id2path('foo-id')
 | 
|
756  | 
        src/foo.c
 | 
|
757  | 
        """
 | 
|
758  | 
        # get all names, skipping root
 | 
|
759  | 
return '/'.join(reversed(  | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
760  | 
[parent.name for parent in  | 
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
761  | 
self._iter_file_id_parents(file_id)][:-1]))  | 
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
762  | 
|
| 
4370.5.1
by Ian Clatworthy
 add recursive parameter to iter_entries()  | 
763  | 
def iter_entries(self, from_dir=None, recursive=True):  | 
764  | 
"""Return (path, entry) pairs, in order by name.  | 
|
765  | 
        
 | 
|
766  | 
        :param from_dir: if None, start from the root,
 | 
|
767  | 
          otherwise start from this directory (either file-id or entry)
 | 
|
768  | 
        :param recursive: recurse into directories or not
 | 
|
769  | 
        """
 | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
770  | 
if from_dir is None:  | 
771  | 
if self.root is None:  | 
|
772  | 
                return
 | 
|
773  | 
from_dir = self.root  | 
|
774  | 
yield '', self.root  | 
|
775  | 
elif isinstance(from_dir, basestring):  | 
|
776  | 
from_dir = self[from_dir]  | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
777  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
778  | 
        # unrolling the recursive called changed the time from
 | 
779  | 
        # 440ms/663ms (inline/total) to 116ms/116ms
 | 
|
780  | 
children = from_dir.children.items()  | 
|
781  | 
children.sort()  | 
|
| 
4370.5.1
by Ian Clatworthy
 add recursive parameter to iter_entries()  | 
782  | 
if not recursive:  | 
783  | 
for name, ie in children:  | 
|
784  | 
yield name, ie  | 
|
785  | 
            return
 | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
786  | 
children = collections.deque(children)  | 
787  | 
stack = [(u'', children)]  | 
|
788  | 
while stack:  | 
|
789  | 
from_dir_relpath, children = stack[-1]  | 
|
790  | 
||
791  | 
while children:  | 
|
792  | 
name, ie = children.popleft()  | 
|
793  | 
||
794  | 
                # we know that from_dir_relpath never ends in a slash
 | 
|
795  | 
                # and 'f' doesn't begin with one, we can do a string op, rather
 | 
|
796  | 
                # than the checks of pathjoin(), though this means that all paths
 | 
|
797  | 
                # start with a slash
 | 
|
798  | 
path = from_dir_relpath + '/' + name  | 
|
799  | 
||
800  | 
yield path[1:], ie  | 
|
801  | 
||
802  | 
if ie.kind != 'directory':  | 
|
803  | 
                    continue
 | 
|
804  | 
||
805  | 
                # But do this child first
 | 
|
806  | 
new_children = ie.children.items()  | 
|
807  | 
new_children.sort()  | 
|
808  | 
new_children = collections.deque(new_children)  | 
|
809  | 
stack.append((path, new_children))  | 
|
810  | 
                # Break out of inner loop, so that we start outer loop with child
 | 
|
811  | 
                break
 | 
|
812  | 
else:  | 
|
813  | 
                # if we finished all children, pop it off the stack
 | 
|
814  | 
stack.pop()  | 
|
815  | 
||
816  | 
def iter_entries_by_dir(self, from_dir=None, specific_file_ids=None,  | 
|
817  | 
yield_parents=False):  | 
|
818  | 
"""Iterate over the entries in a directory first order.  | 
|
819  | 
||
820  | 
        This returns all entries for a directory before returning
 | 
|
821  | 
        the entries for children of a directory. This is not
 | 
|
822  | 
        lexicographically sorted order, and is a hybrid between
 | 
|
823  | 
        depth-first and breadth-first.
 | 
|
824  | 
||
825  | 
        :param yield_parents: If True, yield the parents from the root leading
 | 
|
826  | 
            down to specific_file_ids that have been requested. This has no
 | 
|
827  | 
            impact if specific_file_ids is None.
 | 
|
828  | 
        :return: This yields (path, entry) pairs
 | 
|
829  | 
        """
 | 
|
830  | 
if specific_file_ids and not isinstance(specific_file_ids, set):  | 
|
831  | 
specific_file_ids = set(specific_file_ids)  | 
|
832  | 
        # TODO? Perhaps this should return the from_dir so that the root is
 | 
|
833  | 
        # yielded? or maybe an option?
 | 
|
834  | 
if from_dir is None:  | 
|
835  | 
if self.root is None:  | 
|
836  | 
                return
 | 
|
837  | 
            # Optimize a common case
 | 
|
838  | 
if (not yield_parents and specific_file_ids is not None and  | 
|
839  | 
len(specific_file_ids) == 1):  | 
|
840  | 
file_id = list(specific_file_ids)[0]  | 
|
841  | 
if file_id in self:  | 
|
842  | 
yield self.id2path(file_id), self[file_id]  | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
843  | 
                return
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
844  | 
from_dir = self.root  | 
845  | 
if (specific_file_ids is None or yield_parents or  | 
|
846  | 
self.root.file_id in specific_file_ids):  | 
|
847  | 
yield u'', self.root  | 
|
848  | 
elif isinstance(from_dir, basestring):  | 
|
849  | 
from_dir = self[from_dir]  | 
|
850  | 
||
851  | 
if specific_file_ids is not None:  | 
|
852  | 
            # TODO: jam 20070302 This could really be done as a loop rather
 | 
|
853  | 
            #       than a bunch of recursive calls.
 | 
|
854  | 
parents = set()  | 
|
855  | 
byid = self  | 
|
856  | 
def add_ancestors(file_id):  | 
|
857  | 
if file_id not in byid:  | 
|
858  | 
                    return
 | 
|
859  | 
parent_id = byid[file_id].parent_id  | 
|
860  | 
if parent_id is None:  | 
|
861  | 
                    return
 | 
|
862  | 
if parent_id not in parents:  | 
|
863  | 
parents.add(parent_id)  | 
|
864  | 
add_ancestors(parent_id)  | 
|
865  | 
for file_id in specific_file_ids:  | 
|
866  | 
add_ancestors(file_id)  | 
|
867  | 
else:  | 
|
868  | 
parents = None  | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
869  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
870  | 
stack = [(u'', from_dir)]  | 
871  | 
while stack:  | 
|
872  | 
cur_relpath, cur_dir = stack.pop()  | 
|
873  | 
||
874  | 
child_dirs = []  | 
|
875  | 
for child_name, child_ie in sorted(cur_dir.children.iteritems()):  | 
|
876  | 
||
877  | 
child_relpath = cur_relpath + child_name  | 
|
878  | 
||
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
879  | 
if (specific_file_ids is None or  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
880  | 
child_ie.file_id in specific_file_ids or  | 
881  | 
(yield_parents and child_ie.file_id in parents)):  | 
|
882  | 
yield child_relpath, child_ie  | 
|
883  | 
||
884  | 
if child_ie.kind == 'directory':  | 
|
885  | 
if parents is None or child_ie.file_id in parents:  | 
|
886  | 
child_dirs.append((child_relpath+'/', child_ie))  | 
|
887  | 
stack.extend(reversed(child_dirs))  | 
|
888  | 
||
| 
3735.2.47
by Robert Collins
 Move '_make_inv_delta' onto Inventory (UNTESTED).  | 
889  | 
def _make_delta(self, old):  | 
890  | 
"""Make an inventory delta from two inventories."""  | 
|
891  | 
old_ids = set(old)  | 
|
892  | 
new_ids = set(self)  | 
|
893  | 
adds = new_ids - old_ids  | 
|
894  | 
deletes = old_ids - new_ids  | 
|
895  | 
common = old_ids.intersection(new_ids)  | 
|
896  | 
delta = []  | 
|
897  | 
for file_id in deletes:  | 
|
898  | 
delta.append((old.id2path(file_id), None, file_id, None))  | 
|
899  | 
for file_id in adds:  | 
|
900  | 
delta.append((None, self.id2path(file_id), file_id, self[file_id]))  | 
|
901  | 
for file_id in common:  | 
|
902  | 
if old[file_id] != self[file_id]:  | 
|
903  | 
delta.append((old.id2path(file_id), self.id2path(file_id),  | 
|
904  | 
file_id, self[file_id]))  | 
|
905  | 
return delta  | 
|
906  | 
||
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
907  | 
def _get_mutable_inventory(self):  | 
908  | 
"""Returns a mutable copy of the object.  | 
|
909  | 
||
910  | 
        Some inventories are immutable, yet working trees, for example, needs
 | 
|
911  | 
        to mutate exisiting inventories instead of creating a new one.
 | 
|
912  | 
        """
 | 
|
913  | 
raise NotImplementedError(self._get_mutable_inventory)  | 
|
914  | 
||
| 
3735.2.110
by Ian Clatworthy
 move make_entry(), entries() and directories() up to CommonInventory class  | 
915  | 
def make_entry(self, kind, name, parent_id, file_id=None):  | 
916  | 
"""Simple thunk to bzrlib.inventory.make_entry."""  | 
|
917  | 
return make_entry(kind, name, parent_id, file_id)  | 
|
918  | 
||
919  | 
def entries(self):  | 
|
920  | 
"""Return list of (path, ie) for all entries except the root.  | 
|
921  | 
||
922  | 
        This may be faster than iter_entries.
 | 
|
923  | 
        """
 | 
|
924  | 
accum = []  | 
|
925  | 
def descend(dir_ie, dir_path):  | 
|
926  | 
kids = dir_ie.children.items()  | 
|
927  | 
kids.sort()  | 
|
928  | 
for name, ie in kids:  | 
|
929  | 
child_path = osutils.pathjoin(dir_path, name)  | 
|
930  | 
accum.append((child_path, ie))  | 
|
931  | 
if ie.kind == 'directory':  | 
|
932  | 
descend(ie, child_path)  | 
|
933  | 
||
934  | 
descend(self.root, u'')  | 
|
935  | 
return accum  | 
|
936  | 
||
937  | 
def directories(self):  | 
|
938  | 
"""Return (path, entry) pairs for all directories, including the root.  | 
|
939  | 
        """
 | 
|
940  | 
accum = []  | 
|
941  | 
def descend(parent_ie, parent_path):  | 
|
942  | 
accum.append((parent_path, parent_ie))  | 
|
943  | 
||
944  | 
kids = [(ie.name, ie) for ie in parent_ie.children.itervalues() if ie.kind == 'directory']  | 
|
945  | 
kids.sort()  | 
|
946  | 
||
947  | 
for name, child_ie in kids:  | 
|
948  | 
child_path = osutils.pathjoin(parent_path, name)  | 
|
949  | 
descend(child_ie, child_path)  | 
|
950  | 
descend(self.root, u'')  | 
|
951  | 
return accum  | 
|
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
952  | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
953  | 
def path2id(self, name):  | 
954  | 
"""Walk down through directories to return entry of last component.  | 
|
955  | 
||
956  | 
        names may be either a list of path components, or a single
 | 
|
957  | 
        string, in which case it is automatically split.
 | 
|
958  | 
||
959  | 
        This returns the entry of the last component in the path,
 | 
|
960  | 
        which may be either a file or a directory.
 | 
|
961  | 
||
962  | 
        Returns None IFF the path is not found.
 | 
|
963  | 
        """
 | 
|
964  | 
if isinstance(name, basestring):  | 
|
965  | 
name = osutils.splitpath(name)  | 
|
966  | 
||
967  | 
        # mutter("lookup path %r" % name)
 | 
|
968  | 
||
| 
3735.2.149
by Ian Clatworthy
 handle path2id when root not yet known  | 
969  | 
try:  | 
970  | 
parent = self.root  | 
|
971  | 
except errors.NoSuchId:  | 
|
972  | 
            # root doesn't exist yet so nothing else can
 | 
|
973  | 
return None  | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
974  | 
if parent is None:  | 
975  | 
return None  | 
|
976  | 
for f in name:  | 
|
977  | 
try:  | 
|
978  | 
children = getattr(parent, 'children', None)  | 
|
979  | 
if children is None:  | 
|
980  | 
return None  | 
|
981  | 
cie = children[f]  | 
|
982  | 
parent = cie  | 
|
983  | 
except KeyError:  | 
|
984  | 
                # or raise an error?
 | 
|
985  | 
return None  | 
|
986  | 
||
987  | 
return parent.file_id  | 
|
988  | 
||
| 
3735.36.6
by Ian Clatworthy
 get inventory filtering working for CHKInventory  | 
989  | 
def filter(self, specific_fileids):  | 
990  | 
"""Get an inventory view filtered against a set of file-ids.  | 
|
991  | 
||
992  | 
        Children of directories and parents are included.
 | 
|
993  | 
||
994  | 
        The result may or may not reference the underlying inventory
 | 
|
995  | 
        so it should be treated as immutable.
 | 
|
996  | 
        """
 | 
|
997  | 
interesting_parents = set()  | 
|
998  | 
for fileid in specific_fileids:  | 
|
999  | 
try:  | 
|
1000  | 
interesting_parents.update(self.get_idpath(fileid))  | 
|
1001  | 
except errors.NoSuchId:  | 
|
1002  | 
                # This fileid is not in the inventory - that's ok
 | 
|
1003  | 
                pass
 | 
|
1004  | 
entries = self.iter_entries()  | 
|
1005  | 
if self.root is None:  | 
|
1006  | 
return Inventory(root_id=None)  | 
|
1007  | 
other = Inventory(entries.next()[1].file_id)  | 
|
1008  | 
other.root.revision = self.root.revision  | 
|
1009  | 
other.revision_id = self.revision_id  | 
|
1010  | 
directories_to_expand = set()  | 
|
1011  | 
for path, entry in entries:  | 
|
1012  | 
file_id = entry.file_id  | 
|
1013  | 
if (file_id in specific_fileids  | 
|
1014  | 
or entry.parent_id in directories_to_expand):  | 
|
1015  | 
if entry.kind == 'directory':  | 
|
1016  | 
directories_to_expand.add(file_id)  | 
|
1017  | 
elif file_id not in interesting_parents:  | 
|
1018  | 
                continue
 | 
|
1019  | 
other.add(entry.copy())  | 
|
1020  | 
return other  | 
|
1021  | 
||
1022  | 
def get_idpath(self, file_id):  | 
|
1023  | 
"""Return a list of file_ids for the path to an entry.  | 
|
1024  | 
||
1025  | 
        The list contains one element for each directory followed by
 | 
|
1026  | 
        the id of the file itself.  So the length of the returned list
 | 
|
1027  | 
        is equal to the depth of the file in the tree, counting the
 | 
|
1028  | 
        root directory as depth 1.
 | 
|
1029  | 
        """
 | 
|
1030  | 
p = []  | 
|
1031  | 
for parent in self._iter_file_id_parents(file_id):  | 
|
1032  | 
p.insert(0, parent.file_id)  | 
|
1033  | 
return p  | 
|
1034  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1035  | 
|
1036  | 
class Inventory(CommonInventory):  | 
|
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
1037  | 
"""Mutable dict based in-memory inventory.  | 
1038  | 
||
1039  | 
    We never store the full path to a file, because renaming a directory
 | 
|
1040  | 
    implicitly moves all of its contents.  This class internally maintains a
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1041  | 
    lookup tree that allows the children under a directory to be
 | 
1042  | 
    returned quickly.
 | 
|
1043  | 
||
1044  | 
    >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1045  | 
    >>> inv.add(InventoryFile('123-123', 'hello.c', ROOT_ID))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1046  | 
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1047  | 
    >>> inv['123-123'].name
 | 
1048  | 
    'hello.c'
 | 
|
1049  | 
||
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
1050  | 
    Id's may be looked up from paths:
 | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1051  | 
|
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
1052  | 
    >>> inv.path2id('hello.c')
 | 
1053  | 
    '123-123'
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1054  | 
    >>> '123-123' in inv
 | 
1055  | 
    True
 | 
|
1056  | 
||
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
1057  | 
    There are iterators over the contents:
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1058  | 
|
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
1059  | 
    >>> [entry[0] for entry in inv.iter_entries()]
 | 
| 
1852.6.6
by Robert Collins
 Finish updating iter_entries change to make all tests pass.  | 
1060  | 
    ['', u'hello.c']
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1061  | 
    """
 | 
| 
4505.5.8
by Robert Collins
 Fix fallout from the delta checking work, don't error on deltas containing the root inventory item in CHK delta application, and clean up Inventory docs.  | 
1062  | 
|
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
1063  | 
def __init__(self, root_id=ROOT_ID, revision_id=None):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1064  | 
"""Create or read an inventory.  | 
1065  | 
||
1066  | 
        If a working directory is specified, the inventory is read
 | 
|
1067  | 
        from there.  If the file is specified, read from that. If not,
 | 
|
1068  | 
        the inventory is created empty.
 | 
|
| 
155
by mbp at sourcefrog
 add new explicit RootEntry to inventory (in-core only)  | 
1069  | 
|
1070  | 
        The inventory is created with a default root directory, with
 | 
|
1071  | 
        an id of None.
 | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1072  | 
        """
 | 
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
1073  | 
if root_id is not None:  | 
| 
2294.1.5
by John Arbash Meinel
 Fix Inventory.iter_entries_by_dir to return Unicode paths,  | 
1074  | 
self._set_root(InventoryDirectory(root_id, u'', None))  | 
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
1075  | 
else:  | 
1076  | 
self.root = None  | 
|
1077  | 
self._byid = {}  | 
|
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
1078  | 
self.revision_id = revision_id  | 
| 
1910.2.3
by Aaron Bentley
 All tests pass  | 
1079  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1080  | 
def __repr__(self):  | 
| 
4112.1.1
by Vincent Ladeuil
 Fallback to old revision id if the current one doesn't exist in  | 
1081  | 
        # More than one page of ouput is not useful anymore to debug
 | 
1082  | 
max_len = 2048  | 
|
1083  | 
closing = '...}'  | 
|
1084  | 
contents = repr(self._byid)  | 
|
1085  | 
if len(contents) > max_len:  | 
|
1086  | 
contents = contents[:(max_len-len(closing))] + closing  | 
|
1087  | 
return "<Inventory object at %x, contents=%r>" % (id(self), contents)  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1088  | 
|
1089  | 
def apply_delta(self, delta):  | 
|
1090  | 
"""Apply a delta to this inventory.  | 
|
1091  | 
||
| 
4501.1.1
by Robert Collins
 Add documentation describing how and why we use inventory deltas, and what can go wrong with them.  | 
1092  | 
        See the inventory developers documentation for the theory behind
 | 
1093  | 
        inventory deltas.
 | 
|
1094  | 
||
| 
4526.9.3
by Robert Collins
 Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.  | 
1095  | 
        If delta application fails the inventory is left in an indeterminate
 | 
1096  | 
        state and must not be used.
 | 
|
1097  | 
||
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1098  | 
        :param delta: A list of changes to apply. After all the changes are
 | 
1099  | 
            applied the final inventory must be internally consistent, but it
 | 
|
1100  | 
            is ok to supply changes which, if only half-applied would have an
 | 
|
1101  | 
            invalid result - such as supplying two changes which rename two
 | 
|
1102  | 
            files, 'A' and 'B' with each other : [('A', 'B', 'A-id', a_entry),
 | 
|
1103  | 
            ('B', 'A', 'B-id', b_entry)].
 | 
|
1104  | 
||
1105  | 
            Each change is a tuple, of the form (old_path, new_path, file_id,
 | 
|
1106  | 
            new_entry).
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1107  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1108  | 
            When new_path is None, the change indicates the removal of an entry
 | 
1109  | 
            from the inventory and new_entry will be ignored (using None is
 | 
|
1110  | 
            appropriate). If new_path is not None, then new_entry must be an
 | 
|
1111  | 
            InventoryEntry instance, which will be incorporated into the
 | 
|
1112  | 
            inventory (and replace any existing entry with the same file id).
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1113  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1114  | 
            When old_path is None, the change indicates the addition of
 | 
1115  | 
            a new entry to the inventory.
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1116  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1117  | 
            When neither new_path nor old_path are None, the change is a
 | 
1118  | 
            modification to an entry, such as a rename, reparent, kind change
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1119  | 
            etc.
 | 
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1120  | 
|
1121  | 
            The children attribute of new_entry is ignored. This is because
 | 
|
| 
2865.1.3
by Robert Collins
 Review feedback.  | 
1122  | 
            this method preserves children automatically across alterations to
 | 
1123  | 
            the parent of the children, and cases where the parent id of a
 | 
|
1124  | 
            child is changing require the child to be passed in as a separate
 | 
|
1125  | 
            change regardless. E.g. in the recursive deletion of a directory -
 | 
|
1126  | 
            the directory's children must be included in the delta, or the
 | 
|
1127  | 
            final inventory will be invalid.
 | 
|
| 
4090.3.1
by Ian Clatworthy
 check delta is legal in Inventory.apply_delta()  | 
1128  | 
|
1129  | 
            Note that a file_id must only appear once within a given delta.
 | 
|
1130  | 
            An AssertionError is raised otherwise.
 | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1131  | 
        """
 | 
| 
4090.3.2
by Ian Clatworthy
 review tweak from jam  | 
1132  | 
        # Check that the delta is legal. It would be nice if this could be
 | 
1133  | 
        # done within the loops below but it's safer to validate the delta
 | 
|
| 
4505.5.4
by Robert Collins
 Repeated path/id corruption detected.  | 
1134  | 
        # before starting to mutate the inventory, as there isn't a rollback
 | 
1135  | 
        # facility.
 | 
|
1136  | 
list(_check_delta_unique_ids(_check_delta_unique_new_paths(  | 
|
1137  | 
_check_delta_unique_old_paths(_check_delta_ids_match_entry(  | 
|
| 
4526.9.22
by Robert Collins
 Check fileids in inventory deltas are not None and are strings.  | 
1138  | 
_check_delta_ids_are_valid(  | 
| 
4526.9.4
by Robert Collins
 Look for trivial issues with new_path and entry being out of sync in deltas.  | 
1139  | 
_check_delta_new_path_entry_both_or_None(  | 
| 
4526.9.22
by Robert Collins
 Check fileids in inventory deltas are not None and are strings.  | 
1140  | 
delta)))))))  | 
| 
4090.3.1
by Ian Clatworthy
 check delta is legal in Inventory.apply_delta()  | 
1141  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1142  | 
children = {}  | 
1143  | 
        # Remove all affected items which were in the original inventory,
 | 
|
1144  | 
        # starting with the longest paths, thus ensuring parents are examined
 | 
|
1145  | 
        # after their children, which means that everything we examine has no
 | 
|
1146  | 
        # modified children remaining by the time we examine it.
 | 
|
1147  | 
for old_path, file_id in sorted(((op, f) for op, np, f, e in delta  | 
|
1148  | 
if op is not None), reverse=True):  | 
|
1149  | 
            # Preserve unaltered children of file_id for later reinsertion.
 | 
|
| 
3585.2.2
by Robert Collins
 Cause apply_inventory_delta on Inventory objects to fail with deltas that leave dangling children.  | 
1150  | 
file_id_children = getattr(self[file_id], 'children', {})  | 
1151  | 
if len(file_id_children):  | 
|
1152  | 
children[file_id] = file_id_children  | 
|
| 
4526.9.3
by Robert Collins
 Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.  | 
1153  | 
if self.id2path(file_id) != old_path:  | 
1154  | 
raise errors.InconsistentDelta(old_path, file_id,  | 
|
1155  | 
"Entry was at wrong other path %r." % self.id2path(file_id))  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1156  | 
            # Remove file_id and the unaltered children. If file_id is not
 | 
1157  | 
            # being deleted it will be reinserted back later.
 | 
|
1158  | 
self.remove_recursive_id(file_id)  | 
|
1159  | 
        # Insert all affected which should be in the new inventory, reattaching
 | 
|
1160  | 
        # their children if they had any. This is done from shortest path to
 | 
|
1161  | 
        # longest, ensuring that items which were modified and whose parents in
 | 
|
1162  | 
        # the resulting inventory were also modified, are inserted after their
 | 
|
1163  | 
        # parents.
 | 
|
| 
4526.9.4
by Robert Collins
 Look for trivial issues with new_path and entry being out of sync in deltas.  | 
1164  | 
for new_path, f, new_entry in sorted((np, f, e) for op, np, f, e in  | 
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1165  | 
delta if np is not None):  | 
1166  | 
if new_entry.kind == 'directory':  | 
|
| 
3585.2.2
by Robert Collins
 Cause apply_inventory_delta on Inventory objects to fail with deltas that leave dangling children.  | 
1167  | 
                # Pop the child which to allow detection of children whose
 | 
1168  | 
                # parents were deleted and which were not reattached to a new
 | 
|
1169  | 
                # parent.
 | 
|
| 
3735.2.46
by Robert Collins
 Do not alter InventoryDirectory objects provided to Inventory.apply_delta.  | 
1170  | 
replacement = InventoryDirectory(new_entry.file_id,  | 
1171  | 
new_entry.name, new_entry.parent_id)  | 
|
1172  | 
replacement.revision = new_entry.revision  | 
|
1173  | 
replacement.children = children.pop(replacement.file_id, {})  | 
|
1174  | 
new_entry = replacement  | 
|
| 
4505.5.5
by Robert Collins
 Parents used in a delta must be directories.  | 
1175  | 
try:  | 
1176  | 
self.add(new_entry)  | 
|
| 
4526.9.5
by Robert Collins
 Require that added ids in inventory deltas be new.  | 
1177  | 
except errors.DuplicateFileId:  | 
1178  | 
raise errors.InconsistentDelta(new_path, new_entry.file_id,  | 
|
1179  | 
"New id is already present in target.")  | 
|
| 
4505.5.5
by Robert Collins
 Parents used in a delta must be directories.  | 
1180  | 
except AttributeError:  | 
1181  | 
raise errors.InconsistentDelta(new_path, new_entry.file_id,  | 
|
1182  | 
"Parent is not a directory.")  | 
|
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1183  | 
if self.id2path(new_entry.file_id) != new_path:  | 
1184  | 
raise errors.InconsistentDelta(new_path, new_entry.file_id,  | 
|
1185  | 
"New path is not consistent with parent path.")  | 
|
| 
3585.2.2
by Robert Collins
 Cause apply_inventory_delta on Inventory objects to fail with deltas that leave dangling children.  | 
1186  | 
if len(children):  | 
1187  | 
            # Get the parent id that was deleted
 | 
|
1188  | 
parent_id, children = children.popitem()  | 
|
1189  | 
raise errors.InconsistentDelta("<deleted>", parent_id,  | 
|
1190  | 
"The file id was deleted but its children were not deleted.")  | 
|
| 
2865.1.1
by Robert Collins
 Create new mutable tree method update_to_one_parent_via_delta for eventual use by commit.  | 
1191  | 
|
| 
1910.2.3
by Aaron Bentley
 All tests pass  | 
1192  | 
def _set_root(self, ie):  | 
1193  | 
self.root = ie  | 
|
| 
1907.1.2
by Aaron Bentley
 More removal of unique-root stuff  | 
1194  | 
self._byid = {self.root.file_id: self.root}  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1195  | 
|
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
1196  | 
def copy(self):  | 
| 
1638.1.2
by Robert Collins
 Change the basis-inventory file to not have the revision-id in the file name.  | 
1197  | 
        # TODO: jam 20051218 Should copy also copy the revision_id?
 | 
| 
1852.6.3
by Robert Collins
 Make iter(Tree) consistent for all tree types.  | 
1198  | 
entries = self.iter_entries()  | 
| 
2938.2.1
by Jelmer Vernooij
 Handle empty inventories in Inventory.copy().  | 
1199  | 
if self.root is None:  | 
1200  | 
return Inventory(root_id=None)  | 
|
| 
1852.6.3
by Robert Collins
 Make iter(Tree) consistent for all tree types.  | 
1201  | 
other = Inventory(entries.next()[1].file_id)  | 
| 
3616.1.1
by Jelmer Vernooij
 Fix copying of root revision in inventory.  | 
1202  | 
other.root.revision = self.root.revision  | 
| 
1206
by Martin Pool
 - fix bug in Inventory.copy()  | 
1203  | 
        # copy recursively so we know directories will be added before
 | 
1204  | 
        # their children.  There are more efficient ways than this...
 | 
|
| 
2935.2.1
by Jelmer Vernooij
 Fix Inventory.copy() and add a test for it.  | 
1205  | 
for path, entry in entries:  | 
| 
1189
by Martin Pool
 - BROKEN: partial support for commit into weave  | 
1206  | 
other.add(entry.copy())  | 
1207  | 
return other  | 
|
1208  | 
||
| 
4244.2.1
by Vincent Ladeuil
 inv._get_mutable_inventory() - prepare for CHKInventory  | 
1209  | 
def _get_mutable_inventory(self):  | 
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1210  | 
"""See CommonInventory._get_mutable_inventory."""  | 
| 
4496.3.10
by Andrew Bennetts
 Tidy import nits in inventory.py.  | 
1211  | 
return copy.deepcopy(self)  | 
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1212  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1213  | 
def __iter__(self):  | 
| 
3735.2.118
by Ian Clatworthy
 only apply the parent_id_basename delta if there is one  | 
1214  | 
"""Iterate over all file-ids."""  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1215  | 
return iter(self._byid)  | 
1216  | 
||
| 
3735.2.155
by Ian Clatworthy
 Inventory.iter_just_entries() API & test  | 
1217  | 
def iter_just_entries(self):  | 
1218  | 
"""Iterate over all entries.  | 
|
1219  | 
        
 | 
|
1220  | 
        Unlike iter_entries(), just the entries are returned (not (path, ie))
 | 
|
1221  | 
        and the order of entries is undefined.
 | 
|
1222  | 
||
1223  | 
        XXX: We may not want to merge this into bzr.dev.
 | 
|
1224  | 
        """
 | 
|
1225  | 
if self.root is None:  | 
|
1226  | 
            return
 | 
|
1227  | 
for _, ie in self._byid.iteritems():  | 
|
1228  | 
yield ie  | 
|
1229  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1230  | 
def __len__(self):  | 
1231  | 
"""Returns number of entries."""  | 
|
1232  | 
return len(self._byid)  | 
|
1233  | 
||
1234  | 
def __getitem__(self, file_id):  | 
|
1235  | 
"""Return the entry for given file_id.  | 
|
1236  | 
||
1237  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1238  | 
        >>> inv.add(InventoryFile('123123', 'hello.c', ROOT_ID))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1239  | 
        InventoryFile('123123', 'hello.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1240  | 
        >>> inv['123123'].name
 | 
1241  | 
        'hello.c'
 | 
|
1242  | 
        """
 | 
|
| 
178
by mbp at sourcefrog
 - Use a non-null file_id for the branch root directory. At the moment  | 
1243  | 
try:  | 
1244  | 
return self._byid[file_id]  | 
|
1245  | 
except KeyError:  | 
|
| 
2067.3.1
by Martin Pool
 Clean up BzrNewError, other exception classes and users.  | 
1246  | 
            # really we're passing an inventory, not a tree...
 | 
1247  | 
raise errors.NoSuchId(self, file_id)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1248  | 
|
| 
460
by Martin Pool
 - new testing command compare-trees  | 
1249  | 
def get_file_kind(self, file_id):  | 
1250  | 
return self._byid[file_id].kind  | 
|
1251  | 
||
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1252  | 
def get_child(self, parent_id, filename):  | 
| 
1732.1.18
by John Arbash Meinel
 50ms is probably not worth it  | 
1253  | 
return self[parent_id].children.get(filename)  | 
| 
138
by mbp at sourcefrog
 remove parallel tree from inventory;  | 
1254  | 
|
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1255  | 
def _add_child(self, entry):  | 
1256  | 
"""Add an entry to the inventory, without adding it to its parent"""  | 
|
1257  | 
if entry.file_id in self._byid:  | 
|
1258  | 
raise BzrError("inventory already contains entry with id {%s}" %  | 
|
1259  | 
entry.file_id)  | 
|
1260  | 
self._byid[entry.file_id] = entry  | 
|
1261  | 
for child in getattr(entry, 'children', {}).itervalues():  | 
|
1262  | 
self._add_child(child)  | 
|
1263  | 
return entry  | 
|
1264  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1265  | 
def add(self, entry):  | 
1266  | 
"""Add entry to inventory.  | 
|
1267  | 
||
1268  | 
        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  | 
1269  | 
        which calls this.
 | 
1270  | 
||
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1271  | 
        :return: entry
 | 
| 
1180
by Martin Pool
 - start splitting code for xml (de)serialization away from objects  | 
1272  | 
        """
 | 
| 
139
by mbp at sourcefrog
 simplified/faster Inventory.add  | 
1273  | 
if entry.file_id in self._byid:  | 
| 
2255.7.16
by John Arbash Meinel
 Make sure adding a duplicate file_id raises DuplicateFileId.  | 
1274  | 
raise errors.DuplicateFileId(entry.file_id,  | 
1275  | 
self._byid[entry.file_id])  | 
|
| 
1731.1.33
by Aaron Bentley
 Revert no-special-root changes  | 
1276  | 
if entry.parent_id is None:  | 
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1277  | 
self.root = entry  | 
1278  | 
else:  | 
|
1279  | 
try:  | 
|
1280  | 
parent = self._byid[entry.parent_id]  | 
|
1281  | 
except KeyError:  | 
|
| 
4505.5.6
by Robert Collins
 Check for missing parents in deltas.  | 
1282  | 
raise errors.InconsistentDelta("<unknown>", entry.parent_id,  | 
1283  | 
"Parent not in inventory.")  | 
|
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1284  | 
if entry.name in parent.children:  | 
| 
4505.5.4
by Robert Collins
 Repeated path/id corruption detected.  | 
1285  | 
raise errors.InconsistentDelta(  | 
1286  | 
self.id2path(parent.children[entry.name].file_id),  | 
|
1287  | 
entry.file_id,  | 
|
1288  | 
"Path already versioned")  | 
|
| 
2100.3.6
by Aaron Bentley
 Make add recursive for children of added entries  | 
1289  | 
parent.children[entry.name] = entry  | 
1290  | 
return self._add_child(entry)  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1291  | 
|
| 
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)  | 
1292  | 
def add_path(self, relpath, kind, file_id=None, parent_id=None):  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1293  | 
"""Add entry from a path.  | 
1294  | 
||
| 
1180
by Martin Pool
 - start splitting code for xml (de)serialization away from objects  | 
1295  | 
        The immediate parent must already be versioned.
 | 
1296  | 
||
1297  | 
        Returns the new entry object."""
 | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1298  | 
|
| 
1830.3.5
by John Arbash Meinel
 make_entry refuses to create non-normalized entries.  | 
1299  | 
parts = osutils.splitpath(relpath)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1300  | 
|
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1301  | 
if len(parts) == 0:  | 
| 
1713.1.6
by Robert Collins
 Move file id random data selection out of the inner loop for 'bzr add'.  | 
1302  | 
if file_id is None:  | 
| 
2116.4.1
by John Arbash Meinel
 Update file and revision id generators.  | 
1303  | 
file_id = generate_ids.gen_root_id()  | 
| 
1731.1.1
by Aaron Bentley
 Make root entry an InventoryDirectory, make EmptyTree really empty  | 
1304  | 
self.root = InventoryDirectory(file_id, '', None)  | 
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1305  | 
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.  | 
1306  | 
return self.root  | 
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1307  | 
else:  | 
1308  | 
parent_path = parts[:-1]  | 
|
1309  | 
parent_id = self.path2id(parent_path)  | 
|
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
1310  | 
if parent_id is None:  | 
| 
1996.3.10
by John Arbash Meinel
 lazy_import inventory.py, avoids importing tarfile  | 
1311  | 
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)  | 
1312  | 
ie = make_entry(kind, parts[-1], parent_id, file_id)  | 
| 
70
by mbp at sourcefrog
 Prepare for smart recursive add.  | 
1313  | 
return self.add(ie)  | 
1314  | 
||
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1315  | 
def __delitem__(self, file_id):  | 
1316  | 
"""Remove entry by id.  | 
|
1317  | 
||
1318  | 
        >>> inv = Inventory()
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1319  | 
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1320  | 
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1321  | 
        >>> '123' in inv
 | 
1322  | 
        True
 | 
|
1323  | 
        >>> del inv['123']
 | 
|
1324  | 
        >>> '123' in inv
 | 
|
1325  | 
        False
 | 
|
1326  | 
        """
 | 
|
1327  | 
ie = self[file_id]  | 
|
1328  | 
del self._byid[file_id]  | 
|
| 
1534.7.69
by Aaron Bentley
 Got real root moves working  | 
1329  | 
if ie.parent_id is not None:  | 
1330  | 
del self[ie.parent_id].children[ie.name]  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1331  | 
|
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1332  | 
def __eq__(self, other):  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1333  | 
"""Compare two sets by comparing their contents.  | 
1334  | 
||
1335  | 
        >>> i1 = Inventory()
 | 
|
1336  | 
        >>> i2 = Inventory()
 | 
|
1337  | 
        >>> i1 == i2
 | 
|
1338  | 
        True
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1339  | 
        >>> i1.add(InventoryFile('123', 'foo', ROOT_ID))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1340  | 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1341  | 
        >>> i1 == i2
 | 
1342  | 
        False
 | 
|
| 
1399.1.10
by Robert Collins
 remove kind from the InventoryEntry constructor - only child classes should be created now  | 
1343  | 
        >>> i2.add(InventoryFile('123', 'foo', ROOT_ID))
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1344  | 
        InventoryFile('123', 'foo', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
 | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1345  | 
        >>> i1 == i2
 | 
1346  | 
        True
 | 
|
1347  | 
        """
 | 
|
1348  | 
if not isinstance(other, Inventory):  | 
|
1349  | 
return NotImplemented  | 
|
1350  | 
||
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1351  | 
return self._byid == other._byid  | 
1352  | 
||
1353  | 
def __ne__(self, other):  | 
|
| 
1249
by Martin Pool
 - improvements to weave commit [broken]  | 
1354  | 
return not self.__eq__(other)  | 
| 
544
by Martin Pool
 - Define __eq__ and __ne__ for Inventory and InventoryEntry objects,  | 
1355  | 
|
1356  | 
def __hash__(self):  | 
|
1357  | 
raise ValueError('not hashable')  | 
|
1358  | 
||
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1359  | 
def _iter_file_id_parents(self, file_id):  | 
1360  | 
"""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.  | 
1361  | 
while file_id is not None:  | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1362  | 
try:  | 
1363  | 
ie = self._byid[file_id]  | 
|
1364  | 
except KeyError:  | 
|
| 
2255.11.5
by Martin Pool
 Tree.id2path should raise NoSuchId, not return None.  | 
1365  | 
raise errors.NoSuchId(tree=None, file_id=file_id)  | 
| 
1596.2.19
by Robert Collins
 Shave 20% off id2path.  | 
1366  | 
yield ie  | 
1367  | 
file_id = ie.parent_id  | 
|
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1368  | 
|
1369  | 
def has_id(self, file_id):  | 
|
| 
1711.9.11
by John Arbash Meinel
 change return foo in bar to return (foo in bar)  | 
1370  | 
return (file_id in self._byid)  | 
| 
1
by mbp at sourcefrog
 import from baz patch-364  | 
1371  | 
|
| 
3879.2.6
by John Arbash Meinel
 Bring in Inventory._make_delta  | 
1372  | 
def _make_delta(self, old):  | 
1373  | 
"""Make an inventory delta from two inventories."""  | 
|
| 
3882.6.18
by John Arbash Meinel
 Bring in optimizations to Inventory._make_delta.  | 
1374  | 
old_getter = getattr(old, '_byid', old)  | 
1375  | 
new_getter = self._byid  | 
|
1376  | 
old_ids = set(old_getter)  | 
|
1377  | 
new_ids = set(new_getter)  | 
|
| 
3879.2.6
by John Arbash Meinel
 Bring in Inventory._make_delta  | 
1378  | 
adds = new_ids - old_ids  | 
1379  | 
deletes = old_ids - new_ids  | 
|
| 
3882.6.18
by John Arbash Meinel
 Bring in optimizations to Inventory._make_delta.  | 
1380  | 
if not adds and not deletes:  | 
1381  | 
common = new_ids  | 
|
1382  | 
else:  | 
|
1383  | 
common = old_ids.intersection(new_ids)  | 
|
| 
3879.2.6
by John Arbash Meinel
 Bring in Inventory._make_delta  | 
1384  | 
delta = []  | 
1385  | 
for file_id in deletes:  | 
|
1386  | 
delta.append((old.id2path(file_id), None, file_id, None))  | 
|
1387  | 
for file_id in adds:  | 
|
1388  | 
delta.append((None, self.id2path(file_id), file_id, self[file_id]))  | 
|
1389  | 
for file_id in common:  | 
|
| 
3882.6.18
by John Arbash Meinel
 Bring in optimizations to Inventory._make_delta.  | 
1390  | 
new_ie = new_getter[file_id]  | 
1391  | 
old_ie = old_getter[file_id]  | 
|
1392  | 
            # If xml_serializer returns the cached InventoryEntries (rather
 | 
|
1393  | 
            # than always doing .copy()), inlining the 'is' check saves 2.7M
 | 
|
1394  | 
            # calls to __eq__.  Under lsprof this saves 20s => 6s.
 | 
|
1395  | 
            # It is a minor improvement without lsprof.
 | 
|
1396  | 
if old_ie is new_ie or old_ie == new_ie:  | 
|
1397  | 
                continue
 | 
|
1398  | 
else:  | 
|
| 
3879.2.6
by John Arbash Meinel
 Bring in Inventory._make_delta  | 
1399  | 
delta.append((old.id2path(file_id), self.id2path(file_id),  | 
| 
3882.6.18
by John Arbash Meinel
 Bring in optimizations to Inventory._make_delta.  | 
1400  | 
file_id, new_ie))  | 
| 
3879.2.6
by John Arbash Meinel
 Bring in Inventory._make_delta  | 
1401  | 
return delta  | 
1402  | 
||
| 
1988.2.6
by Robert Collins
 Review feedback.  | 
1403  | 
def remove_recursive_id(self, file_id):  | 
1404  | 
"""Remove file_id, and children, from the inventory.  | 
|
| 
3879.2.6
by John Arbash Meinel
 Bring in Inventory._make_delta  | 
1405  | 
|
| 
1988.2.6
by Robert Collins
 Review feedback.  | 
1406  | 
        :param file_id: A file_id to remove.
 | 
1407  | 
        """
 | 
|
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1408  | 
to_find_delete = [self._byid[file_id]]  | 
1409  | 
to_delete = []  | 
|
| 
1988.2.6
by Robert Collins
 Review feedback.  | 
1410  | 
while to_find_delete:  | 
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1411  | 
ie = to_find_delete.pop()  | 
1412  | 
to_delete.append(ie.file_id)  | 
|
1413  | 
if ie.kind == 'directory':  | 
|
1414  | 
to_find_delete.extend(ie.children.values())  | 
|
1415  | 
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.  | 
1416  | 
ie = self[file_id]  | 
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1417  | 
del self._byid[file_id]  | 
| 
1731.2.16
by Aaron Bentley
 Get extract working for standalone trees  | 
1418  | 
if ie.parent_id is not None:  | 
1419  | 
del self[ie.parent_id].children[ie.name]  | 
|
| 
2376.2.3
by Aaron Bentley
 Fix root replacement for apply_inventory_delta  | 
1420  | 
else:  | 
1421  | 
self.root = None  | 
|
| 
1988.2.1
by Robert Collins
 WorkingTree has a new api ``unversion`` which allow the unversioning of  | 
1422  | 
|
| 
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  | 
1423  | 
def rename(self, file_id, new_parent_id, new_name):  | 
1424  | 
"""Move a file within the inventory.  | 
|
1425  | 
||
1426  | 
        This can change either the name, or the parent, or both.
 | 
|
1427  | 
||
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
1428  | 
        This does not move the working file.
 | 
1429  | 
        """
 | 
|
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
1430  | 
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  | 
1431  | 
if not is_valid_name(new_name):  | 
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1432  | 
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  | 
1433  | 
|
1434  | 
new_parent = self._byid[new_parent_id]  | 
|
1435  | 
if new_name in new_parent.children:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1436  | 
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  | 
1437  | 
|
| 
172
by mbp at sourcefrog
 - clearer check against attempts to introduce directory loops in the inventory  | 
1438  | 
new_parent_idpath = self.get_idpath(new_parent_id)  | 
1439  | 
if file_id in new_parent_idpath:  | 
|
| 
694
by Martin Pool
 - weed out all remaining calls to bailout() and remove the function  | 
1440  | 
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  | 
1441  | 
% (self.id2path(file_id), self.id2path(new_parent_id)))  | 
1442  | 
||
| 
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  | 
1443  | 
file_ie = self._byid[file_id]  | 
1444  | 
old_parent = self._byid[file_ie.parent_id]  | 
|
1445  | 
||
1446  | 
        # TODO: Don't leave things messed up if this fails
 | 
|
1447  | 
||
1448  | 
del old_parent.children[file_ie.name]  | 
|
1449  | 
new_parent.children[new_name] = file_ie  | 
|
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
1450  | 
|
| 
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  | 
1451  | 
file_ie.name = new_name  | 
1452  | 
file_ie.parent_id = new_parent_id  | 
|
1453  | 
||
| 
1731.1.1
by Aaron Bentley
 Make root entry an InventoryDirectory, make EmptyTree really empty  | 
1454  | 
def is_root(self, file_id):  | 
1455  | 
return self.root is not None and file_id == self.root.file_id  | 
|
1456  | 
||
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1457  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1458  | 
class CHKInventory(CommonInventory):  | 
| 
3735.20.3
by Ian Clatworthy
 improve CHKInventory docstring  | 
1459  | 
"""An inventory persisted in a CHK store.  | 
1460  | 
||
1461  | 
    By design, a CHKInventory is immutable so many of the methods
 | 
|
1462  | 
    supported by Inventory - add, rename, apply_delta, etc - are *not*
 | 
|
1463  | 
    supported. To create a new CHKInventory, use create_by_apply_delta()
 | 
|
1464  | 
    or from_inventory(), say.
 | 
|
1465  | 
||
1466  | 
    Internally, a CHKInventory has one or two CHKMaps:
 | 
|
1467  | 
||
1468  | 
    * id_to_entry - a map from (file_id,) => InventoryEntry as bytes
 | 
|
1469  | 
    * parent_id_basename_to_file_id - a map from (parent_id, basename_utf8)
 | 
|
1470  | 
        => file_id as bytes
 | 
|
1471  | 
||
1472  | 
    The second map is optional and not present in early CHkRepository's.
 | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
1473  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1474  | 
    No caching is performed: every method call or item access will perform
 | 
| 
3735.20.3
by Ian Clatworthy
 improve CHKInventory docstring  | 
1475  | 
    requests to the storage layer. As such, keep references to objects you
 | 
1476  | 
    want to reuse.
 | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1477  | 
    """
 | 
1478  | 
||
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1479  | 
def __init__(self, search_key_name):  | 
| 
3735.10.1
by Robert Collins
 Create an __init__ for CHKInventory to ensure mandatory attributes are set.  | 
1480  | 
CommonInventory.__init__(self)  | 
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
1481  | 
self._fileid_to_entry_cache = {}  | 
1482  | 
self._path_to_fileid_cache = {}  | 
|
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1483  | 
self._search_key_name = search_key_name  | 
| 
4526.9.17
by Robert Collins
 Teach CHKInventory.path2id to avoid loading inventory entries.  | 
1484  | 
self.root_id = None  | 
| 
3735.10.1
by Robert Collins
 Create an __init__ for CHKInventory to ensure mandatory attributes are set.  | 
1485  | 
|
| 
4413.5.14
by John Arbash Meinel
 The new add_inventory_by_delta is returning a CHKInventory when mapping from NULL  | 
1486  | 
def __eq__(self, other):  | 
1487  | 
"""Compare two sets by comparing their contents."""  | 
|
1488  | 
if not isinstance(other, CHKInventory):  | 
|
1489  | 
return NotImplemented  | 
|
1490  | 
||
1491  | 
this_key = self.id_to_entry.key()  | 
|
1492  | 
other_key = other.id_to_entry.key()  | 
|
1493  | 
this_pid_key = self.parent_id_basename_to_file_id.key()  | 
|
1494  | 
other_pid_key = other.parent_id_basename_to_file_id.key()  | 
|
1495  | 
if None in (this_key, this_pid_key, other_key, other_pid_key):  | 
|
1496  | 
return False  | 
|
1497  | 
return this_key == other_key and this_pid_key == other_pid_key  | 
|
1498  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1499  | 
def _entry_to_bytes(self, entry):  | 
1500  | 
"""Serialise entry as a single bytestring.  | 
|
1501  | 
||
1502  | 
        :param Entry: An inventory entry.
 | 
|
1503  | 
        :return: A bytestring for the entry.
 | 
|
| 
3735.2.99
by John Arbash Meinel
 Merge bzr.dev 4034. Whitespace cleanup  | 
1504  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1505  | 
        The BNF:
 | 
1506  | 
        ENTRY ::= FILE | DIR | SYMLINK | TREE
 | 
|
| 
3735.20.4
by Ian Clatworthy
 correct _entry_to_bytes() docstring  | 
1507  | 
        FILE ::= "file: " COMMON SEP SHA SEP SIZE SEP EXECUTABLE
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1508  | 
        DIR ::= "dir: " COMMON
 | 
| 
3735.20.4
by Ian Clatworthy
 correct _entry_to_bytes() docstring  | 
1509  | 
        SYMLINK ::= "symlink: " COMMON SEP TARGET_UTF8
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1510  | 
        TREE ::= "tree: " COMMON REFERENCE_REVISION
 | 
| 
3735.20.4
by Ian Clatworthy
 correct _entry_to_bytes() docstring  | 
1511  | 
        COMMON ::= FILE_ID SEP PARENT_ID SEP NAME_UTF8 SEP REVISION
 | 
1512  | 
        SEP ::= "\n"
 | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1513  | 
        """
 | 
1514  | 
if entry.parent_id is not None:  | 
|
1515  | 
parent_str = entry.parent_id  | 
|
1516  | 
else:  | 
|
1517  | 
parent_str = ''  | 
|
1518  | 
name_str = entry.name.encode("utf8")  | 
|
1519  | 
if entry.kind == 'file':  | 
|
1520  | 
if entry.executable:  | 
|
1521  | 
exec_str = "Y"  | 
|
1522  | 
else:  | 
|
1523  | 
exec_str = "N"  | 
|
| 
3735.17.11
by John Arbash Meinel
 Actually format the inventories using line-based separation.  | 
1524  | 
return "file: %s\n%s\n%s\n%s\n%s\n%d\n%s" % (  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1525  | 
entry.file_id, parent_str, name_str, entry.revision,  | 
1526  | 
entry.text_sha1, entry.text_size, exec_str)  | 
|
1527  | 
elif entry.kind == 'directory':  | 
|
| 
3735.17.11
by John Arbash Meinel
 Actually format the inventories using line-based separation.  | 
1528  | 
return "dir: %s\n%s\n%s\n%s" % (  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1529  | 
entry.file_id, parent_str, name_str, entry.revision)  | 
1530  | 
elif entry.kind == 'symlink':  | 
|
| 
3735.17.11
by John Arbash Meinel
 Actually format the inventories using line-based separation.  | 
1531  | 
return "symlink: %s\n%s\n%s\n%s\n%s" % (  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1532  | 
entry.file_id, parent_str, name_str, entry.revision,  | 
1533  | 
entry.symlink_target.encode("utf8"))  | 
|
1534  | 
elif entry.kind == 'tree-reference':  | 
|
| 
3735.17.11
by John Arbash Meinel
 Actually format the inventories using line-based separation.  | 
1535  | 
return "tree: %s\n%s\n%s\n%s\n%s" % (  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1536  | 
entry.file_id, parent_str, name_str, entry.revision,  | 
1537  | 
entry.reference_revision)  | 
|
1538  | 
else:  | 
|
1539  | 
raise ValueError("unknown kind %r" % entry.kind)  | 
|
1540  | 
||
| 
3735.36.12
by John Arbash Meinel
 Add some direct tests for CHKInventory._entry_to_bytes  | 
1541  | 
    @staticmethod
 | 
1542  | 
def _bytes_to_utf8name_key(bytes):  | 
|
1543  | 
"""Get the file_id, revision_id key out of bytes."""  | 
|
1544  | 
        # We don't normally care about name, except for times when we want
 | 
|
1545  | 
        # to filter out empty names because of non rich-root...
 | 
|
1546  | 
sections = bytes.split('\n')  | 
|
1547  | 
kind, file_id = sections[0].split(': ')  | 
|
1548  | 
return (sections[2], file_id, sections[3])  | 
|
1549  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1550  | 
def _bytes_to_entry(self, bytes):  | 
1551  | 
"""Deserialise a serialised entry."""  | 
|
| 
3735.17.11
by John Arbash Meinel
 Actually format the inventories using line-based separation.  | 
1552  | 
sections = bytes.split('\n')  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1553  | 
if sections[0].startswith("file: "):  | 
1554  | 
result = InventoryFile(sections[0][6:],  | 
|
1555  | 
sections[2].decode('utf8'),  | 
|
1556  | 
sections[1])  | 
|
1557  | 
result.text_sha1 = sections[4]  | 
|
1558  | 
result.text_size = int(sections[5])  | 
|
1559  | 
result.executable = sections[6] == "Y"  | 
|
1560  | 
elif sections[0].startswith("dir: "):  | 
|
1561  | 
result = CHKInventoryDirectory(sections[0][5:],  | 
|
1562  | 
sections[2].decode('utf8'),  | 
|
1563  | 
sections[1], self)  | 
|
1564  | 
elif sections[0].startswith("symlink: "):  | 
|
1565  | 
result = InventoryLink(sections[0][9:],  | 
|
1566  | 
sections[2].decode('utf8'),  | 
|
1567  | 
sections[1])  | 
|
| 
3735.36.12
by John Arbash Meinel
 Add some direct tests for CHKInventory._entry_to_bytes  | 
1568  | 
result.symlink_target = sections[4].decode('utf8')  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1569  | 
elif sections[0].startswith("tree: "):  | 
1570  | 
result = TreeReference(sections[0][6:],  | 
|
1571  | 
sections[2].decode('utf8'),  | 
|
1572  | 
sections[1])  | 
|
1573  | 
result.reference_revision = sections[4]  | 
|
1574  | 
else:  | 
|
1575  | 
raise ValueError("Not a serialised entry %r" % bytes)  | 
|
1576  | 
result.revision = sections[3]  | 
|
1577  | 
if result.parent_id == '':  | 
|
1578  | 
result.parent_id = None  | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
1579  | 
self._fileid_to_entry_cache[result.file_id] = result  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1580  | 
return result  | 
1581  | 
||
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1582  | 
def _get_mutable_inventory(self):  | 
1583  | 
"""See CommonInventory._get_mutable_inventory."""  | 
|
1584  | 
entries = self.iter_entries()  | 
|
| 
4343.3.23
by John Arbash Meinel
 Change RepositoryCHK1.fileids_altered_by to handle ghosts the way XML does.  | 
1585  | 
inv = Inventory(None, self.revision_id)  | 
| 
3735.20.1
by Ian Clatworthy
 fix bug in get_mutable_inventory  | 
1586  | 
for path, inv_entry in entries:  | 
| 
4343.3.23
by John Arbash Meinel
 Change RepositoryCHK1.fileids_altered_by to handle ghosts the way XML does.  | 
1587  | 
inv.add(inv_entry.copy())  | 
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1588  | 
return inv  | 
1589  | 
||
| 
3735.2.121
by Ian Clatworthy
 add propagate_caches param to create_by_apply_delta, making fast-import 30% faster  | 
1590  | 
def create_by_apply_delta(self, inventory_delta, new_revision_id,  | 
1591  | 
propagate_caches=False):  | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1592  | 
"""Create a new CHKInventory by applying inventory_delta to this one.  | 
1593  | 
||
| 
4501.1.1
by Robert Collins
 Add documentation describing how and why we use inventory deltas, and what can go wrong with them.  | 
1594  | 
        See the inventory developers documentation for the theory behind
 | 
1595  | 
        inventory deltas.
 | 
|
1596  | 
||
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1597  | 
        :param inventory_delta: The inventory delta to apply. See
 | 
1598  | 
            Inventory.apply_delta for details.
 | 
|
1599  | 
        :param new_revision_id: The revision id of the resulting CHKInventory.
 | 
|
| 
3735.2.121
by Ian Clatworthy
 add propagate_caches param to create_by_apply_delta, making fast-import 30% faster  | 
1600  | 
        :param propagate_caches: If True, the caches for this inventory are
 | 
1601  | 
          copied to and updated for the result.
 | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1602  | 
        :return: The new CHKInventory.
 | 
1603  | 
        """
 | 
|
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1604  | 
split = osutils.split  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1605  | 
result = CHKInventory(self._search_key_name)  | 
| 
3735.2.121
by Ian Clatworthy
 add propagate_caches param to create_by_apply_delta, making fast-import 30% faster  | 
1606  | 
if propagate_caches:  | 
1607  | 
            # Just propagate the path-to-fileid cache for now
 | 
|
1608  | 
result._path_to_fileid_cache = dict(self._path_to_fileid_cache.iteritems())  | 
|
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1609  | 
search_key_func = chk_map.search_key_registry.get(self._search_key_name)  | 
| 
3735.20.8
by Ian Clatworthy
 fix max size & key width propagation in create_by_apply_delta()  | 
1610  | 
self.id_to_entry._ensure_root()  | 
1611  | 
maximum_size = self.id_to_entry._root_node.maximum_size  | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1612  | 
result.revision_id = new_revision_id  | 
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1613  | 
result.id_to_entry = chk_map.CHKMap(  | 
1614  | 
self.id_to_entry._store,  | 
|
| 
3735.20.2
by Ian Clatworthy
 fix root key handling in create_by_apply_delta()  | 
1615  | 
self.id_to_entry.key(),  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1616  | 
search_key_func=search_key_func)  | 
| 
3735.20.8
by Ian Clatworthy
 fix max size & key width propagation in create_by_apply_delta()  | 
1617  | 
result.id_to_entry._ensure_root()  | 
1618  | 
result.id_to_entry._root_node.set_maximum_size(maximum_size)  | 
|
| 
4526.9.12
by Robert Collins
 Make CHKInventory generate safer parent_id_basename deltas.  | 
1619  | 
        # Change to apply to the parent_id_basename delta. The dict maps
 | 
1620  | 
        # (parent_id, basename) -> (old_key, new_value). We use a dict because
 | 
|
1621  | 
        # when a path has its id replaced (e.g. the root is changed, or someone
 | 
|
1622  | 
        # does bzr mv a b, bzr mv c a, we should output a single change to this
 | 
|
1623  | 
        # map rather than two.
 | 
|
1624  | 
parent_id_basename_delta = {}  | 
|
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1625  | 
if self.parent_id_basename_to_file_id is not None:  | 
1626  | 
result.parent_id_basename_to_file_id = chk_map.CHKMap(  | 
|
1627  | 
self.parent_id_basename_to_file_id._store,  | 
|
| 
3735.20.2
by Ian Clatworthy
 fix root key handling in create_by_apply_delta()  | 
1628  | 
self.parent_id_basename_to_file_id.key(),  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1629  | 
search_key_func=search_key_func)  | 
| 
3735.20.8
by Ian Clatworthy
 fix max size & key width propagation in create_by_apply_delta()  | 
1630  | 
result.parent_id_basename_to_file_id._ensure_root()  | 
| 
3735.2.111
by John Arbash Meinel
 Merge Ian's updates to chk_map and chk_inventory.create_by_apply_delta.  | 
1631  | 
self.parent_id_basename_to_file_id._ensure_root()  | 
| 
3735.2.113
by Ian Clatworthy
 fix bug in jam's tweaks to create_by_apply_delta  | 
1632  | 
result_p_id_root = result.parent_id_basename_to_file_id._root_node  | 
| 
3735.2.111
by John Arbash Meinel
 Merge Ian's updates to chk_map and chk_inventory.create_by_apply_delta.  | 
1633  | 
p_id_root = self.parent_id_basename_to_file_id._root_node  | 
1634  | 
result_p_id_root.set_maximum_size(p_id_root.maximum_size)  | 
|
1635  | 
result_p_id_root._key_width = p_id_root._key_width  | 
|
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1636  | 
else:  | 
1637  | 
result.parent_id_basename_to_file_id = None  | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1638  | 
result.root_id = self.root_id  | 
1639  | 
id_to_entry_delta = []  | 
|
| 
4505.5.4
by Robert Collins
 Repeated path/id corruption detected.  | 
1640  | 
        # inventory_delta is only traversed once, so we just update the
 | 
1641  | 
        # variable.
 | 
|
1642  | 
        # Check for repeated file ids
 | 
|
1643  | 
inventory_delta = _check_delta_unique_ids(inventory_delta)  | 
|
1644  | 
        # Repeated old paths
 | 
|
1645  | 
inventory_delta = _check_delta_unique_old_paths(inventory_delta)  | 
|
1646  | 
        # Check for repeated new paths
 | 
|
1647  | 
inventory_delta = _check_delta_unique_new_paths(inventory_delta)  | 
|
1648  | 
        # Check for entries that don't match the fileid
 | 
|
1649  | 
inventory_delta = _check_delta_ids_match_entry(inventory_delta)  | 
|
| 
4526.9.22
by Robert Collins
 Check fileids in inventory deltas are not None and are strings.  | 
1650  | 
        # Check for nonsense fileids
 | 
1651  | 
inventory_delta = _check_delta_ids_are_valid(inventory_delta)  | 
|
| 
4526.9.4
by Robert Collins
 Look for trivial issues with new_path and entry being out of sync in deltas.  | 
1652  | 
        # Check for new_path <-> entry consistency
 | 
1653  | 
inventory_delta = _check_delta_new_path_entry_both_or_None(  | 
|
1654  | 
inventory_delta)  | 
|
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1655  | 
        # All changed entries need to have their parents be directories and be
 | 
1656  | 
        # at the right path. This set contains (path, id) tuples.
 | 
|
| 
4505.5.5
by Robert Collins
 Parents used in a delta must be directories.  | 
1657  | 
parents = set()  | 
| 
4526.9.9
by Robert Collins
 Add interface tests for dangling children in inventory deltas.  | 
1658  | 
        # When we delete an item, all the children of it must be either deleted
 | 
1659  | 
        # or altered in their own right. As we batch process the change via
 | 
|
1660  | 
        # CHKMap.apply_delta, we build a set of things to use to validate the
 | 
|
1661  | 
        # delta.
 | 
|
1662  | 
deletes = set()  | 
|
1663  | 
altered = set()  | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1664  | 
for old_path, new_path, file_id, entry in inventory_delta:  | 
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1665  | 
            # file id changes
 | 
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1666  | 
if new_path == '':  | 
1667  | 
result.root_id = file_id  | 
|
1668  | 
if new_path is None:  | 
|
1669  | 
                # Make a delete:
 | 
|
1670  | 
new_key = None  | 
|
1671  | 
new_value = None  | 
|
| 
3735.2.121
by Ian Clatworthy
 add propagate_caches param to create_by_apply_delta, making fast-import 30% faster  | 
1672  | 
                # Update caches
 | 
1673  | 
if propagate_caches:  | 
|
1674  | 
try:  | 
|
1675  | 
del result._path_to_fileid_cache[old_path]  | 
|
1676  | 
except KeyError:  | 
|
1677  | 
                        pass
 | 
|
| 
4526.9.9
by Robert Collins
 Add interface tests for dangling children in inventory deltas.  | 
1678  | 
deletes.add(file_id)  | 
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1679  | 
else:  | 
| 
3735.2.25
by Robert Collins
 CHKInventory core tests passing.  | 
1680  | 
new_key = (file_id,)  | 
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1681  | 
new_value = result._entry_to_bytes(entry)  | 
| 
3735.2.121
by Ian Clatworthy
 add propagate_caches param to create_by_apply_delta, making fast-import 30% faster  | 
1682  | 
                # Update caches. It's worth doing this whether
 | 
1683  | 
                # we're propagating the old caches or not.
 | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
1684  | 
result._path_to_fileid_cache[new_path] = file_id  | 
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1685  | 
parents.add((split(new_path)[0], entry.parent_id))  | 
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1686  | 
if old_path is None:  | 
1687  | 
old_key = None  | 
|
1688  | 
else:  | 
|
| 
3735.2.25
by Robert Collins
 CHKInventory core tests passing.  | 
1689  | 
old_key = (file_id,)  | 
| 
4526.9.3
by Robert Collins
 Handle mismatches between inventory delta paths and actual paths found by traversing parent pointers.  | 
1690  | 
if self.id2path(file_id) != old_path:  | 
1691  | 
raise errors.InconsistentDelta(old_path, file_id,  | 
|
1692  | 
"Entry was at wrong other path %r." %  | 
|
1693  | 
self.id2path(file_id))  | 
|
| 
4526.9.9
by Robert Collins
 Add interface tests for dangling children in inventory deltas.  | 
1694  | 
altered.add(file_id)  | 
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1695  | 
id_to_entry_delta.append((old_key, new_key, new_value))  | 
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1696  | 
if result.parent_id_basename_to_file_id is not None:  | 
1697  | 
                # parent_id, basename changes
 | 
|
1698  | 
if old_path is None:  | 
|
1699  | 
old_key = None  | 
|
1700  | 
else:  | 
|
1701  | 
old_entry = self[file_id]  | 
|
1702  | 
old_key = self._parent_id_basename_key(old_entry)  | 
|
1703  | 
if new_path is None:  | 
|
1704  | 
new_key = None  | 
|
1705  | 
new_value = None  | 
|
1706  | 
else:  | 
|
1707  | 
new_key = self._parent_id_basename_key(entry)  | 
|
1708  | 
new_value = file_id  | 
|
| 
4526.9.12
by Robert Collins
 Make CHKInventory generate safer parent_id_basename deltas.  | 
1709  | 
                # If the two keys are the same, the value will be unchanged
 | 
1710  | 
                # as its always the file id for this entry.
 | 
|
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1711  | 
if old_key != new_key:  | 
| 
4526.9.12
by Robert Collins
 Make CHKInventory generate safer parent_id_basename deltas.  | 
1712  | 
                    # Transform a change into explicit delete/add preserving
 | 
1713  | 
                    # a possible match on the key from a different file id.
 | 
|
1714  | 
if old_key is not None:  | 
|
1715  | 
parent_id_basename_delta.setdefault(  | 
|
1716  | 
old_key, [None, None])[0] = old_key  | 
|
1717  | 
if new_key is not None:  | 
|
1718  | 
parent_id_basename_delta.setdefault(  | 
|
1719  | 
new_key, [None, None])[1] = new_value  | 
|
| 
4526.9.9
by Robert Collins
 Add interface tests for dangling children in inventory deltas.  | 
1720  | 
        # validate that deletes are complete.
 | 
1721  | 
for file_id in deletes:  | 
|
1722  | 
entry = self[file_id]  | 
|
1723  | 
if entry.kind != 'directory':  | 
|
1724  | 
                continue
 | 
|
1725  | 
            # This loop could potentially be better by using the id_basename
 | 
|
1726  | 
            # map to just get the child file ids.
 | 
|
1727  | 
for child in entry.children.values():  | 
|
1728  | 
if child.file_id not in altered:  | 
|
1729  | 
raise errors.InconsistentDelta(self.id2path(child.file_id),  | 
|
1730  | 
child.file_id, "Child not deleted or reparented when "  | 
|
1731  | 
"parent deleted.")  | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1732  | 
result.id_to_entry.apply_delta(id_to_entry_delta)  | 
| 
3735.2.118
by Ian Clatworthy
 only apply the parent_id_basename delta if there is one  | 
1733  | 
if parent_id_basename_delta:  | 
| 
4526.9.12
by Robert Collins
 Make CHKInventory generate safer parent_id_basename deltas.  | 
1734  | 
            # Transform the parent_id_basename delta data into a linear delta
 | 
1735  | 
            # with only one record for a given key. Optimally this would allow
 | 
|
1736  | 
            # re-keying, but its simpler to just output that as a delete+add
 | 
|
1737  | 
            # to spend less time calculating the delta.
 | 
|
1738  | 
delta_list = []  | 
|
1739  | 
for key, (old_key, value) in parent_id_basename_delta.iteritems():  | 
|
| 
4526.9.19
by Robert Collins
 Review feedback.  | 
1740  | 
if value is not None:  | 
| 
4526.9.16
by Robert Collins
 Fix parent_id_basename map update in CHKInventory more.  | 
1741  | 
delta_list.append((old_key, key, value))  | 
1742  | 
else:  | 
|
1743  | 
delta_list.append((old_key, None, None))  | 
|
| 
4526.9.12
by Robert Collins
 Make CHKInventory generate safer parent_id_basename deltas.  | 
1744  | 
result.parent_id_basename_to_file_id.apply_delta(delta_list)  | 
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1745  | 
parents.discard(('', None))  | 
1746  | 
for parent_path, parent in parents:  | 
|
| 
4505.5.6
by Robert Collins
 Check for missing parents in deltas.  | 
1747  | 
try:  | 
1748  | 
if result[parent].kind != 'directory':  | 
|
1749  | 
raise errors.InconsistentDelta(result.id2path(parent), parent,  | 
|
1750  | 
'Not a directory, but given children')  | 
|
1751  | 
except errors.NoSuchId:  | 
|
1752  | 
raise errors.InconsistentDelta("<unknown>", parent,  | 
|
1753  | 
"Parent is not present in resulting inventory.")  | 
|
| 
4526.9.2
by Robert Collins
 Handle deltas with new paths not matching the actual path.  | 
1754  | 
if result.path2id(parent_path) != parent:  | 
1755  | 
raise errors.InconsistentDelta(parent_path, parent,  | 
|
1756  | 
"Parent has wrong path %r." % result.path2id(parent_path))  | 
|
| 
3735.2.10
by Robert Collins
 Teach CHKInventory how to make a new inventory from an inventory delta.  | 
1757  | 
return result  | 
1758  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1759  | 
    @classmethod
 | 
1760  | 
def deserialise(klass, chk_store, bytes, expected_revision_id):  | 
|
1761  | 
"""Deserialise a CHKInventory.  | 
|
1762  | 
||
1763  | 
        :param chk_store: A CHK capable VersionedFiles instance.
 | 
|
1764  | 
        :param bytes: The serialised bytes.
 | 
|
1765  | 
        :param expected_revision_id: The revision ID we think this inventory is
 | 
|
1766  | 
            for.
 | 
|
1767  | 
        :return: A CHKInventory
 | 
|
1768  | 
        """
 | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1769  | 
lines = bytes.split('\n')  | 
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1770  | 
if lines[-1] != '':  | 
1771  | 
raise AssertionError('bytes to deserialize must end with an eol')  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1772  | 
lines.pop()  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1773  | 
if lines[0] != 'chkinventory:':  | 
1774  | 
raise ValueError("not a serialised CHKInventory: %r" % bytes)  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1775  | 
info = {}  | 
| 
3735.24.2
by John Arbash Meinel
 Add a bit more strictness to the formatting, update the test case.  | 
1776  | 
allowed_keys = frozenset(['root_id', 'revision_id', 'search_key_name',  | 
1777  | 
'parent_id_basename_to_file_id',  | 
|
1778  | 
'id_to_entry'])  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1779  | 
for line in lines[1:]:  | 
1780  | 
key, value = line.split(': ', 1)  | 
|
| 
3735.24.2
by John Arbash Meinel
 Add a bit more strictness to the formatting, update the test case.  | 
1781  | 
if key not in allowed_keys:  | 
1782  | 
raise errors.BzrError('Unknown key in inventory: %r\n%r'  | 
|
1783  | 
% (key, bytes))  | 
|
1784  | 
if key in info:  | 
|
1785  | 
raise errors.BzrError('Duplicate key in inventory: %r\n%r'  | 
|
1786  | 
% (key, bytes))  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1787  | 
info[key] = value  | 
1788  | 
revision_id = info['revision_id']  | 
|
1789  | 
root_id = info['root_id']  | 
|
1790  | 
search_key_name = info.get('search_key_name', 'plain')  | 
|
1791  | 
parent_id_basename_to_file_id = info.get(  | 
|
1792  | 
'parent_id_basename_to_file_id', None)  | 
|
1793  | 
id_to_entry = info['id_to_entry']  | 
|
1794  | 
||
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1795  | 
result = CHKInventory(search_key_name)  | 
1796  | 
result.revision_id = revision_id  | 
|
1797  | 
result.root_id = root_id  | 
|
1798  | 
search_key_func = chk_map.search_key_registry.get(  | 
|
1799  | 
result._search_key_name)  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1800  | 
if parent_id_basename_to_file_id is not None:  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1801  | 
result.parent_id_basename_to_file_id = chk_map.CHKMap(  | 
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1802  | 
chk_store, (parent_id_basename_to_file_id,),  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1803  | 
search_key_func=search_key_func)  | 
1804  | 
else:  | 
|
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1805  | 
result.parent_id_basename_to_file_id = None  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1806  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
1807  | 
result.id_to_entry = chk_map.CHKMap(chk_store, (id_to_entry,),  | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1808  | 
search_key_func=search_key_func)  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1809  | 
if (result.revision_id,) != expected_revision_id:  | 
1810  | 
raise ValueError("Mismatched revision id and expected: %r, %r" %  | 
|
1811  | 
(result.revision_id, expected_revision_id))  | 
|
1812  | 
return result  | 
|
1813  | 
||
1814  | 
    @classmethod
 | 
|
| 
3735.2.132
by John Arbash Meinel
 Remove references to parent_id_basename_index, now that we know we want it.  | 
1815  | 
def from_inventory(klass, chk_store, inventory, maximum_size=0, search_key_name='plain'):  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1816  | 
"""Create a CHKInventory from an existing inventory.  | 
1817  | 
||
1818  | 
        The content of inventory is copied into the chk_store, and a
 | 
|
1819  | 
        CHKInventory referencing that is returned.
 | 
|
1820  | 
||
1821  | 
        :param chk_store: A CHK capable VersionedFiles instance.
 | 
|
1822  | 
        :param inventory: The inventory to copy.
 | 
|
| 
3735.2.40
by Robert Collins
 Add development4 which has a parent_id to basename index on CHKInventory objects.  | 
1823  | 
        :param maximum_size: The CHKMap node size limit.
 | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
1824  | 
        :param search_key_name: The identifier for the search key function
 | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1825  | 
        """
 | 
| 
4413.5.11
by John Arbash Meinel
 Pull out the common 'populate this CHKInventory' code out into a helper  | 
1826  | 
result = klass(search_key_name)  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1827  | 
result.revision_id = inventory.revision_id  | 
1828  | 
result.root_id = inventory.root.file_id  | 
|
| 
4413.5.10
by John Arbash Meinel
 Clean upt the test_inv tests that assumed _root_node was real and not just a key.  | 
1829  | 
|
1830  | 
entry_to_bytes = result._entry_to_bytes  | 
|
1831  | 
parent_id_basename_key = result._parent_id_basename_key  | 
|
1832  | 
id_to_entry_dict = {}  | 
|
1833  | 
parent_id_basename_dict = {}  | 
|
1834  | 
for path, entry in inventory.iter_entries():  | 
|
1835  | 
id_to_entry_dict[(entry.file_id,)] = entry_to_bytes(entry)  | 
|
1836  | 
p_id_key = parent_id_basename_key(entry)  | 
|
1837  | 
parent_id_basename_dict[p_id_key] = entry.file_id  | 
|
1838  | 
||
| 
4413.5.11
by John Arbash Meinel
 Pull out the common 'populate this CHKInventory' code out into a helper  | 
1839  | 
result._populate_from_dicts(chk_store, id_to_entry_dict,  | 
1840  | 
parent_id_basename_dict, maximum_size=maximum_size)  | 
|
1841  | 
return result  | 
|
1842  | 
||
1843  | 
def _populate_from_dicts(self, chk_store, id_to_entry_dict,  | 
|
1844  | 
parent_id_basename_dict, maximum_size):  | 
|
1845  | 
search_key_func = chk_map.search_key_registry.get(self._search_key_name)  | 
|
| 
4413.5.10
by John Arbash Meinel
 Clean upt the test_inv tests that assumed _root_node was real and not just a key.  | 
1846  | 
root_key = chk_map.CHKMap.from_dict(chk_store, id_to_entry_dict,  | 
1847  | 
maximum_size=maximum_size, key_width=1,  | 
|
1848  | 
search_key_func=search_key_func)  | 
|
| 
4413.5.11
by John Arbash Meinel
 Pull out the common 'populate this CHKInventory' code out into a helper  | 
1849  | 
self.id_to_entry = chk_map.CHKMap(chk_store, root_key,  | 
1850  | 
search_key_func)  | 
|
| 
4413.5.10
by John Arbash Meinel
 Clean upt the test_inv tests that assumed _root_node was real and not just a key.  | 
1851  | 
root_key = chk_map.CHKMap.from_dict(chk_store,  | 
1852  | 
parent_id_basename_dict,  | 
|
1853  | 
maximum_size=maximum_size, key_width=2,  | 
|
1854  | 
search_key_func=search_key_func)  | 
|
| 
4413.5.11
by John Arbash Meinel
 Pull out the common 'populate this CHKInventory' code out into a helper  | 
1855  | 
self.parent_id_basename_to_file_id = chk_map.CHKMap(chk_store,  | 
1856  | 
root_key, search_key_func)  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1857  | 
|
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
1858  | 
def _parent_id_basename_key(self, entry):  | 
1859  | 
"""Create a key for a entry in a parent_id_basename_to_file_id index."""  | 
|
1860  | 
if entry.parent_id is not None:  | 
|
1861  | 
parent_id = entry.parent_id  | 
|
1862  | 
else:  | 
|
1863  | 
parent_id = ''  | 
|
1864  | 
return parent_id, entry.name.encode('utf8')  | 
|
1865  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1866  | 
def __getitem__(self, file_id):  | 
1867  | 
"""map a single file_id -> InventoryEntry."""  | 
|
| 
3735.2.125
by Ian Clatworthy
 looking up an inventory with file_id=None should throw NoSuchId, not some low level error in crc32  | 
1868  | 
if file_id is None:  | 
1869  | 
raise errors.NoSuchId(self, file_id)  | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
1870  | 
result = self._fileid_to_entry_cache.get(file_id, None)  | 
| 
3735.2.51
by Robert Collins
 Trivial cache of inventory entries after they are read by a specific inventory.  | 
1871  | 
if result is not None:  | 
1872  | 
return result  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1873  | 
try:  | 
1874  | 
return self._bytes_to_entry(  | 
|
| 
3735.2.25
by Robert Collins
 CHKInventory core tests passing.  | 
1875  | 
self.id_to_entry.iteritems([(file_id,)]).next()[1])  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1876  | 
except StopIteration:  | 
| 
3735.2.53
by Robert Collins
 Support Inventory.__getitem__ more consistently.  | 
1877  | 
            # really we're passing an inventory, not a tree...
 | 
1878  | 
raise errors.NoSuchId(self, file_id)  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1879  | 
|
1880  | 
def has_id(self, file_id):  | 
|
1881  | 
        # Perhaps have an explicit 'contains' method on CHKMap ?
 | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
1882  | 
if self._fileid_to_entry_cache.get(file_id, None) is not None:  | 
| 
3735.20.5
by Ian Clatworthy
 more efficient CHKInventory.has_id()  | 
1883  | 
return True  | 
| 
3735.2.25
by Robert Collins
 CHKInventory core tests passing.  | 
1884  | 
return len(list(self.id_to_entry.iteritems([(file_id,)]))) == 1  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1885  | 
|
| 
3735.2.49
by Robert Collins
 Support is_root on CHKInventory objects.  | 
1886  | 
def is_root(self, file_id):  | 
1887  | 
return file_id == self.root_id  | 
|
1888  | 
||
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
1889  | 
def _iter_file_id_parents(self, file_id):  | 
1890  | 
"""Yield the parents of file_id up to the root."""  | 
|
1891  | 
while file_id is not None:  | 
|
| 
4137.3.1
by Ian Clatworthy
 Inventory.filter() API with tests  | 
1892  | 
try:  | 
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
1893  | 
ie = self[file_id]  | 
1894  | 
except KeyError:  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1895  | 
raise errors.NoSuchId(tree=self, file_id=file_id)  | 
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
1896  | 
yield ie  | 
1897  | 
file_id = ie.parent_id  | 
|
1898  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1899  | 
def __iter__(self):  | 
| 
3735.2.118
by Ian Clatworthy
 only apply the parent_id_basename delta if there is one  | 
1900  | 
"""Iterate over all file-ids."""  | 
| 
3735.2.25
by Robert Collins
 CHKInventory core tests passing.  | 
1901  | 
for key, _ in self.id_to_entry.iteritems():  | 
1902  | 
yield key[-1]  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1903  | 
|
| 
3735.2.155
by Ian Clatworthy
 Inventory.iter_just_entries() API & test  | 
1904  | 
def iter_just_entries(self):  | 
1905  | 
"""Iterate over all entries.  | 
|
1906  | 
        
 | 
|
1907  | 
        Unlike iter_entries(), just the entries are returned (not (path, ie))
 | 
|
1908  | 
        and the order of entries is undefined.
 | 
|
1909  | 
||
1910  | 
        XXX: We may not want to merge this into bzr.dev.
 | 
|
1911  | 
        """
 | 
|
1912  | 
for key, entry in self.id_to_entry.iteritems():  | 
|
1913  | 
file_id = key[0]  | 
|
| 
3735.2.165
by Ian Clatworthy
 fix iter_just_entries() in CHKInventories  | 
1914  | 
ie = self._fileid_to_entry_cache.get(file_id, None)  | 
| 
3735.2.155
by Ian Clatworthy
 Inventory.iter_just_entries() API & test  | 
1915  | 
if ie is None:  | 
1916  | 
ie = self._bytes_to_entry(entry)  | 
|
| 
3735.2.165
by Ian Clatworthy
 fix iter_just_entries() in CHKInventories  | 
1917  | 
self._fileid_to_entry_cache[file_id] = ie  | 
| 
3735.2.155
by Ian Clatworthy
 Inventory.iter_just_entries() API & test  | 
1918  | 
yield ie  | 
1919  | 
||
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1920  | 
def iter_changes(self, basis):  | 
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1921  | 
"""Generate a Tree.iter_changes change list between this and basis.  | 
1922  | 
||
1923  | 
        :param basis: Another CHKInventory.
 | 
|
1924  | 
        :return: An iterator over the changes between self and basis, as per
 | 
|
1925  | 
            tree.iter_changes().
 | 
|
1926  | 
        """
 | 
|
1927  | 
        # We want: (file_id, (path_in_source, path_in_target),
 | 
|
1928  | 
        # changed_content, versioned, parent, name, kind,
 | 
|
1929  | 
        # executable)
 | 
|
1930  | 
for key, basis_value, self_value in \  | 
|
1931  | 
self.id_to_entry.iter_changes(basis.id_to_entry):  | 
|
1932  | 
file_id = key[0]  | 
|
1933  | 
if basis_value is not None:  | 
|
1934  | 
basis_entry = basis._bytes_to_entry(basis_value)  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1935  | 
path_in_source = basis.id2path(file_id)  | 
1936  | 
basis_parent = basis_entry.parent_id  | 
|
1937  | 
basis_name = basis_entry.name  | 
|
1938  | 
basis_executable = basis_entry.executable  | 
|
1939  | 
else:  | 
|
1940  | 
path_in_source = None  | 
|
1941  | 
basis_parent = None  | 
|
1942  | 
basis_name = None  | 
|
1943  | 
basis_executable = None  | 
|
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1944  | 
if self_value is not None:  | 
1945  | 
self_entry = self._bytes_to_entry(self_value)  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1946  | 
path_in_target = self.id2path(file_id)  | 
1947  | 
self_parent = self_entry.parent_id  | 
|
1948  | 
self_name = self_entry.name  | 
|
1949  | 
self_executable = self_entry.executable  | 
|
1950  | 
else:  | 
|
1951  | 
path_in_target = None  | 
|
1952  | 
self_parent = None  | 
|
1953  | 
self_name = None  | 
|
1954  | 
self_executable = None  | 
|
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1955  | 
if basis_value is None:  | 
1956  | 
                # add
 | 
|
1957  | 
kind = (None, self_entry.kind)  | 
|
1958  | 
versioned = (False, True)  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1959  | 
elif self_value is None:  | 
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1960  | 
                # delete
 | 
1961  | 
kind = (basis_entry.kind, None)  | 
|
1962  | 
versioned = (True, False)  | 
|
1963  | 
else:  | 
|
1964  | 
kind = (basis_entry.kind, self_entry.kind)  | 
|
1965  | 
versioned = (True, True)  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1966  | 
changed_content = False  | 
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1967  | 
if kind[0] != kind[1]:  | 
1968  | 
changed_content = True  | 
|
1969  | 
elif kind[0] == 'file':  | 
|
1970  | 
if (self_entry.text_size != basis_entry.text_size or  | 
|
1971  | 
self_entry.text_sha1 != basis_entry.text_sha1):  | 
|
1972  | 
changed_content = True  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1973  | 
elif kind[0] == 'symlink':  | 
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1974  | 
if self_entry.symlink_target != basis_entry.symlink_target:  | 
1975  | 
changed_content = True  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1976  | 
elif kind[0] == 'tree-reference':  | 
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1977  | 
if (self_entry.reference_revision !=  | 
1978  | 
basis_entry.reference_revision):  | 
|
1979  | 
changed_content = True  | 
|
| 
3735.2.34
by Robert Collins
 Mega-hack; hook in a nasty iter_changes based on CHKInventory.  | 
1980  | 
parent = (basis_parent, self_parent)  | 
1981  | 
name = (basis_name, self_name)  | 
|
1982  | 
executable = (basis_executable, self_executable)  | 
|
| 
4241.6.5
by Robert Collins, John Arbash Meinel
 CHKInventory support from brisbane-core.  | 
1983  | 
if (not changed_content  | 
1984  | 
and parent[0] == parent[1]  | 
|
1985  | 
and name[0] == name[1]  | 
|
1986  | 
and executable[0] == executable[1]):  | 
|
1987  | 
                # Could happen when only the revision changed for a directory
 | 
|
1988  | 
                # for instance.
 | 
|
| 
4137.3.1
by Ian Clatworthy
 Inventory.filter() API with tests  | 
1989  | 
                continue
 | 
| 
3735.2.33
by Robert Collins
 Create a smoke-tested CHKInventory.iter_changes(CHKInventory) - incomplete in general but enough to start working with.  | 
1990  | 
yield (file_id, (path_in_source, path_in_target), changed_content,  | 
1991  | 
versioned, parent, name, kind, executable)  | 
|
1992  | 
||
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1993  | 
def __len__(self):  | 
1994  | 
"""Return the number of entries in the inventory."""  | 
|
| 
3735.2.17
by Robert Collins
 Cache node length to avoid full iteration on __len__ calls.  | 
1995  | 
return len(self.id_to_entry)  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
1996  | 
|
| 
3735.2.47
by Robert Collins
 Move '_make_inv_delta' onto Inventory (UNTESTED).  | 
1997  | 
def _make_delta(self, old):  | 
1998  | 
"""Make an inventory delta from two inventories."""  | 
|
1999  | 
if type(old) != CHKInventory:  | 
|
2000  | 
return CommonInventory._make_delta(self, old)  | 
|
2001  | 
delta = []  | 
|
2002  | 
for key, old_value, self_value in \  | 
|
2003  | 
self.id_to_entry.iter_changes(old.id_to_entry):  | 
|
2004  | 
file_id = key[0]  | 
|
2005  | 
if old_value is not None:  | 
|
2006  | 
old_path = old.id2path(file_id)  | 
|
2007  | 
else:  | 
|
2008  | 
old_path = None  | 
|
2009  | 
if self_value is not None:  | 
|
2010  | 
entry = self._bytes_to_entry(self_value)  | 
|
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
2011  | 
self._fileid_to_entry_cache[file_id] = entry  | 
| 
3735.2.47
by Robert Collins
 Move '_make_inv_delta' onto Inventory (UNTESTED).  | 
2012  | 
new_path = self.id2path(file_id)  | 
2013  | 
else:  | 
|
2014  | 
entry = None  | 
|
2015  | 
new_path = None  | 
|
2016  | 
delta.append((old_path, new_path, file_id, entry))  | 
|
2017  | 
return delta  | 
|
2018  | 
||
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
2019  | 
def path2id(self, name):  | 
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
2020  | 
"""See CommonInventory.path2id()."""  | 
| 
4526.9.17
by Robert Collins
 Teach CHKInventory.path2id to avoid loading inventory entries.  | 
2021  | 
        # TODO: perhaps support negative hits?
 | 
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
2022  | 
result = self._path_to_fileid_cache.get(name, None)  | 
| 
4526.9.17
by Robert Collins
 Teach CHKInventory.path2id to avoid loading inventory entries.  | 
2023  | 
if result is not None:  | 
2024  | 
return result  | 
|
2025  | 
if isinstance(name, basestring):  | 
|
2026  | 
names = osutils.splitpath(name)  | 
|
2027  | 
else:  | 
|
2028  | 
names = name  | 
|
2029  | 
current_id = self.root_id  | 
|
2030  | 
if current_id is None:  | 
|
2031  | 
return None  | 
|
2032  | 
parent_id_index = self.parent_id_basename_to_file_id  | 
|
2033  | 
for basename in names:  | 
|
2034  | 
            # TODO: Cache each path we figure out in this function.
 | 
|
2035  | 
basename_utf8 = basename.encode('utf8')  | 
|
2036  | 
key_filter = [(current_id, basename_utf8)]  | 
|
2037  | 
file_id = None  | 
|
2038  | 
for (parent_id, name_utf8), file_id in parent_id_index.iteritems(  | 
|
2039  | 
key_filter=key_filter):  | 
|
2040  | 
if parent_id != current_id or name_utf8 != basename_utf8:  | 
|
| 
4526.9.19
by Robert Collins
 Review feedback.  | 
2041  | 
raise errors.BzrError("corrupt inventory lookup! "  | 
| 
4526.9.17
by Robert Collins
 Teach CHKInventory.path2id to avoid loading inventory entries.  | 
2042  | 
"%r %r %r %r" % (parent_id, current_id, name_utf8,  | 
2043  | 
basename_utf8))  | 
|
2044  | 
if file_id is None:  | 
|
2045  | 
return None  | 
|
2046  | 
current_id = file_id  | 
|
2047  | 
self._path_to_fileid_cache[name] = current_id  | 
|
2048  | 
return current_id  | 
|
| 
3735.2.12
by Robert Collins
 Implement commit-via-deltas for split inventory repositories.  | 
2049  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2050  | 
def to_lines(self):  | 
2051  | 
"""Serialise the inventory to lines."""  | 
|
2052  | 
lines = ["chkinventory:\n"]  | 
|
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
2053  | 
if self._search_key_name != 'plain':  | 
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
2054  | 
            # custom ordering grouping things that don't change together
 | 
| 
3735.16.7
by John Arbash Meinel
 Start parameterizing CHKInventory and CHKSerializer so that we can  | 
2055  | 
lines.append('search_key_name: %s\n' % (self._search_key_name,))  | 
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
2056  | 
lines.append("root_id: %s\n" % self.root_id)  | 
| 
3735.2.41
by Robert Collins
 Make the parent_id_basename index be updated during CHKInventory.apply_delta.  | 
2057  | 
lines.append('parent_id_basename_to_file_id: %s\n' %  | 
2058  | 
self.parent_id_basename_to_file_id.key())  | 
|
| 
3735.24.1
by John Arbash Meinel
 Change how the ordering of the inventory metablock is written.  | 
2059  | 
lines.append("revision_id: %s\n" % self.revision_id)  | 
2060  | 
lines.append("id_to_entry: %s\n" % self.id_to_entry.key())  | 
|
2061  | 
else:  | 
|
2062  | 
lines.append("revision_id: %s\n" % self.revision_id)  | 
|
2063  | 
lines.append("root_id: %s\n" % self.root_id)  | 
|
2064  | 
if self.parent_id_basename_to_file_id is not None:  | 
|
2065  | 
lines.append('parent_id_basename_to_file_id: %s\n' %  | 
|
2066  | 
self.parent_id_basename_to_file_id.key())  | 
|
2067  | 
lines.append("id_to_entry: %s\n" % self.id_to_entry.key())  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2068  | 
return lines  | 
2069  | 
||
2070  | 
    @property
 | 
|
2071  | 
def root(self):  | 
|
2072  | 
"""Get the root entry."""  | 
|
2073  | 
return self[self.root_id]  | 
|
2074  | 
||
2075  | 
||
2076  | 
class CHKInventoryDirectory(InventoryDirectory):  | 
|
2077  | 
"""A directory in an inventory."""  | 
|
2078  | 
||
2079  | 
__slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',  | 
|
2080  | 
'text_id', 'parent_id', '_children', 'executable',  | 
|
2081  | 
'revision', 'symlink_target', 'reference_revision',  | 
|
2082  | 
'_chk_inventory']  | 
|
2083  | 
||
2084  | 
def __init__(self, file_id, name, parent_id, chk_inventory):  | 
|
2085  | 
        # Don't call InventoryDirectory.__init__ - it isn't right for this
 | 
|
2086  | 
        # class.
 | 
|
2087  | 
InventoryEntry.__init__(self, file_id, name, parent_id)  | 
|
2088  | 
self._children = None  | 
|
2089  | 
self.kind = 'directory'  | 
|
2090  | 
self._chk_inventory = chk_inventory  | 
|
2091  | 
||
2092  | 
    @property
 | 
|
2093  | 
def children(self):  | 
|
| 
3735.2.118
by Ian Clatworthy
 only apply the parent_id_basename delta if there is one  | 
2094  | 
"""Access the list of children of this directory.  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2095  | 
|
| 
3735.2.44
by Robert Collins
 Teach CHKInventory with a parent_id_basename index how to load partial index contents.  | 
2096  | 
        With a parent_id_basename_to_file_id index, loads all the children,
 | 
2097  | 
        without loads the entire index. Without is bad. A more sophisticated
 | 
|
2098  | 
        proxy object might be nice, to allow partial loading of children as
 | 
|
2099  | 
        well when specific names are accessed. (So path traversal can be
 | 
|
2100  | 
        written in the obvious way but not examine siblings.).
 | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2101  | 
        """
 | 
2102  | 
if self._children is not None:  | 
|
2103  | 
return self._children  | 
|
| 
3735.21.1
by John Arbash Meinel
 Fix the file_id versus file_id_key confusion in CHKInventoryDirectory.children()  | 
2104  | 
        # No longer supported
 | 
| 
3735.2.129
by Andrew Bennetts
 Fix some trivial test failures.  | 
2105  | 
if self._chk_inventory.parent_id_basename_to_file_id is None:  | 
| 
3735.2.132
by John Arbash Meinel
 Remove references to parent_id_basename_index, now that we know we want it.  | 
2106  | 
raise AssertionError("Inventories without"  | 
2107  | 
" parent_id_basename_to_file_id are no longer supported")  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2108  | 
result = {}  | 
| 
3735.2.44
by Robert Collins
 Teach CHKInventory with a parent_id_basename index how to load partial index contents.  | 
2109  | 
        # XXX: Todo - use proxy objects for the children rather than loading
 | 
2110  | 
        # all when the attribute is referenced.
 | 
|
2111  | 
parent_id_index = self._chk_inventory.parent_id_basename_to_file_id  | 
|
| 
3735.21.1
by John Arbash Meinel
 Fix the file_id versus file_id_key confusion in CHKInventoryDirectory.children()  | 
2112  | 
child_keys = set()  | 
| 
3735.2.44
by Robert Collins
 Teach CHKInventory with a parent_id_basename index how to load partial index contents.  | 
2113  | 
for (parent_id, name_utf8), file_id in parent_id_index.iteritems(  | 
2114  | 
key_filter=[(self.file_id,)]):  | 
|
| 
3735.21.1
by John Arbash Meinel
 Fix the file_id versus file_id_key confusion in CHKInventoryDirectory.children()  | 
2115  | 
child_keys.add((file_id,))  | 
| 
3735.2.51
by Robert Collins
 Trivial cache of inventory entries after they are read by a specific inventory.  | 
2116  | 
cached = set()  | 
| 
3735.21.1
by John Arbash Meinel
 Fix the file_id versus file_id_key confusion in CHKInventoryDirectory.children()  | 
2117  | 
for file_id_key in child_keys:  | 
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
2118  | 
entry = self._chk_inventory._fileid_to_entry_cache.get(  | 
2119  | 
file_id_key[0], None)  | 
|
| 
3735.2.51
by Robert Collins
 Trivial cache of inventory entries after they are read by a specific inventory.  | 
2120  | 
if entry is not None:  | 
2121  | 
result[entry.name] = entry  | 
|
| 
3735.21.1
by John Arbash Meinel
 Fix the file_id versus file_id_key confusion in CHKInventoryDirectory.children()  | 
2122  | 
cached.add(file_id_key)  | 
2123  | 
child_keys.difference_update(cached)  | 
|
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2124  | 
        # populate; todo: do by name
 | 
| 
3735.2.44
by Robert Collins
 Teach CHKInventory with a parent_id_basename index how to load partial index contents.  | 
2125  | 
id_to_entry = self._chk_inventory.id_to_entry  | 
| 
3735.21.1
by John Arbash Meinel
 Fix the file_id versus file_id_key confusion in CHKInventoryDirectory.children()  | 
2126  | 
for file_id_key, bytes in id_to_entry.iteritems(child_keys):  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2127  | 
entry = self._chk_inventory._bytes_to_entry(bytes)  | 
| 
3735.2.44
by Robert Collins
 Teach CHKInventory with a parent_id_basename index how to load partial index contents.  | 
2128  | 
result[entry.name] = entry  | 
| 
3735.2.119
by Ian Clatworthy
 add a cache for CHKInventory.path2id()  | 
2129  | 
self._chk_inventory._fileid_to_entry_cache[file_id_key[0]] = entry  | 
| 
3735.2.9
by Robert Collins
 Get a working chk_map using inventory implementation bootstrapped.  | 
2130  | 
self._children = result  | 
2131  | 
return result  | 
|
| 
4137.3.1
by Ian Clatworthy
 Inventory.filter() API with tests  | 
2132  | 
|
| 
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.  | 
2133  | 
entry_factory = {  | 
| 
2255.2.158
by Martin Pool
 Most of the integration of dirstate and subtree  | 
2134  | 
'directory': InventoryDirectory,  | 
2135  | 
'file': InventoryFile,  | 
|
2136  | 
'symlink': InventoryLink,  | 
|
| 
2255.6.8
by Aaron Bentley
 Merge refactoring of add_reference  | 
2137  | 
'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.  | 
2138  | 
}
 | 
2139  | 
||
| 
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)  | 
2140  | 
def make_entry(kind, name, parent_id, file_id=None):  | 
2141  | 
"""Create an inventory entry.  | 
|
2142  | 
||
2143  | 
    :param kind: the type of inventory entry to create.
 | 
|
2144  | 
    :param name: the basename of the entry.
 | 
|
2145  | 
    :param parent_id: the parent_id of the entry.
 | 
|
2146  | 
    :param file_id: the file_id to use. if None, one will be created.
 | 
|
2147  | 
    """
 | 
|
2148  | 
if file_id is None:  | 
|
| 
2116.4.1
by John Arbash Meinel
 Update file and revision id generators.  | 
2149  | 
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  | 
2150  | 
name = ensure_normalized_name(name)  | 
2151  | 
try:  | 
|
2152  | 
factory = entry_factory[kind]  | 
|
2153  | 
except KeyError:  | 
|
2154  | 
raise BzrError("unknown kind %r" % kind)  | 
|
2155  | 
return factory(file_id, name, parent_id)  | 
|
2156  | 
||
2157  | 
||
2158  | 
def ensure_normalized_name(name):  | 
|
2159  | 
"""Normalize name.  | 
|
2160  | 
||
2161  | 
    :raises InvalidNormalization: When name is not normalized, and cannot be
 | 
|
2162  | 
        accessed on this platform by the normalized path.
 | 
|
| 
3201.1.1
by jameinel
 Fix bug #185458, switch from NFKC to NFC and add tests for filenames that would be broken under NFKC  | 
2163  | 
    :return: The NFC normalised version of name.
 | 
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
2164  | 
    """
 | 
| 
2255.2.54
by Robert Collins
 Add in non-normalized filename sanity check to dirstate add().  | 
2165  | 
    #------- This has been copied to bzrlib.dirstate.DirState.add, please
 | 
2166  | 
    # 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.  | 
2167  | 
    # we dont import normalized_filename directly because we want to be
 | 
2168  | 
    # able to change the implementation at runtime for tests.
 | 
|
| 
1830.3.5
by John Arbash Meinel
 make_entry refuses to create non-normalized entries.  | 
2169  | 
norm_name, can_access = osutils.normalized_filename(name)  | 
2170  | 
if norm_name != name:  | 
|
2171  | 
if can_access:  | 
|
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
2172  | 
return norm_name  | 
| 
1830.3.5
by John Arbash Meinel
 make_entry refuses to create non-normalized entries.  | 
2173  | 
else:  | 
2174  | 
            # TODO: jam 20060701 This would probably be more useful
 | 
|
2175  | 
            #       if the error was raised with the full path
 | 
|
2176  | 
raise errors.InvalidNormalization(name)  | 
|
| 
2825.6.1
by Robert Collins
 * ``WorkingTree.rename_one`` will now raise an error if normalisation of the  | 
2177  | 
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)  | 
2178  | 
|
| 
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  | 
2179  | 
|
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
2180  | 
_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  | 
2181  | 
|
2182  | 
def is_valid_name(name):  | 
|
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
2183  | 
global _NAME_RE  | 
| 
1753.1.4
by Robert Collins
 Fixup '== None' usage in inventory.py.  | 
2184  | 
if _NAME_RE is None:  | 
| 
1077
by Martin Pool
 - avoid compiling REs at module load time  | 
2185  | 
_NAME_RE = re.compile(r'^[^/\\]+$')  | 
| 
3943.8.1
by Marius Kruger
 remove all trailing whitespace from bzr source  | 
2186  | 
|
| 
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  | 
2187  | 
return bool(_NAME_RE.match(name))  | 
| 
4505.5.4
by Robert Collins
 Repeated path/id corruption detected.  | 
2188  | 
|
2189  | 
||
2190  | 
def _check_delta_unique_ids(delta):  | 
|
2191  | 
"""Decorate a delta and check that the file ids in it are unique.  | 
|
2192  | 
||
2193  | 
    :return: A generator over delta.
 | 
|
2194  | 
    """
 | 
|
2195  | 
ids = set()  | 
|
2196  | 
for item in delta:  | 
|
2197  | 
length = len(ids) + 1  | 
|
2198  | 
ids.add(item[2])  | 
|
2199  | 
if len(ids) != length:  | 
|
2200  | 
raise errors.InconsistentDelta(item[0] or item[1], item[2],  | 
|
2201  | 
"repeated file_id")  | 
|
2202  | 
yield item  | 
|
2203  | 
||
2204  | 
||
2205  | 
def _check_delta_unique_new_paths(delta):  | 
|
2206  | 
"""Decorate a delta and check that the new paths in it are unique.  | 
|
2207  | 
||
2208  | 
    :return: A generator over delta.
 | 
|
2209  | 
    """
 | 
|
2210  | 
paths = set()  | 
|
2211  | 
for item in delta:  | 
|
2212  | 
length = len(paths) + 1  | 
|
2213  | 
path = item[1]  | 
|
2214  | 
if path is not None:  | 
|
2215  | 
paths.add(path)  | 
|
2216  | 
if len(paths) != length:  | 
|
2217  | 
raise errors.InconsistentDelta(path, item[2], "repeated path")  | 
|
2218  | 
yield item  | 
|
2219  | 
||
2220  | 
||
2221  | 
def _check_delta_unique_old_paths(delta):  | 
|
2222  | 
"""Decorate a delta and check that the old paths in it are unique.  | 
|
2223  | 
||
2224  | 
    :return: A generator over delta.
 | 
|
2225  | 
    """
 | 
|
2226  | 
paths = set()  | 
|
2227  | 
for item in delta:  | 
|
2228  | 
length = len(paths) + 1  | 
|
2229  | 
path = item[0]  | 
|
2230  | 
if path is not None:  | 
|
2231  | 
paths.add(path)  | 
|
2232  | 
if len(paths) != length:  | 
|
2233  | 
raise errors.InconsistentDelta(path, item[2], "repeated path")  | 
|
2234  | 
yield item  | 
|
2235  | 
||
2236  | 
||
| 
4526.9.22
by Robert Collins
 Check fileids in inventory deltas are not None and are strings.  | 
2237  | 
def _check_delta_ids_are_valid(delta):  | 
2238  | 
"""Decorate a delta and check that the ids in it are valid.  | 
|
2239  | 
||
2240  | 
    :return: A generator over delta.
 | 
|
2241  | 
    """
 | 
|
2242  | 
for item in delta:  | 
|
2243  | 
entry = item[3]  | 
|
2244  | 
if item[2] is None:  | 
|
2245  | 
raise errors.InconsistentDelta(item[0] or item[1], item[2],  | 
|
2246  | 
"entry with file_id None %r" % entry)  | 
|
2247  | 
if type(item[2]) != str:  | 
|
2248  | 
raise errors.InconsistentDelta(item[0] or item[1], item[2],  | 
|
2249  | 
"entry with non bytes file_id %r" % entry)  | 
|
2250  | 
yield item  | 
|
2251  | 
||
2252  | 
||
| 
4505.5.4
by Robert Collins
 Repeated path/id corruption detected.  | 
2253  | 
def _check_delta_ids_match_entry(delta):  | 
2254  | 
"""Decorate a delta and check that the ids in it match the entry.file_id.  | 
|
2255  | 
||
2256  | 
    :return: A generator over delta.
 | 
|
2257  | 
    """
 | 
|
2258  | 
for item in delta:  | 
|
2259  | 
entry = item[3]  | 
|
2260  | 
if entry is not None:  | 
|
2261  | 
if entry.file_id != item[2]:  | 
|
2262  | 
raise errors.InconsistentDelta(item[0] or item[1], item[2],  | 
|
2263  | 
"mismatched id with %r" % entry)  | 
|
2264  | 
yield item  | 
|
| 
4526.9.4
by Robert Collins
 Look for trivial issues with new_path and entry being out of sync in deltas.  | 
2265  | 
|
2266  | 
||
2267  | 
def _check_delta_new_path_entry_both_or_None(delta):  | 
|
2268  | 
"""Decorate a delta and check that the new_path and entry are paired.  | 
|
2269  | 
||
2270  | 
    :return: A generator over delta.
 | 
|
2271  | 
    """
 | 
|
2272  | 
for item in delta:  | 
|
2273  | 
new_path = item[1]  | 
|
2274  | 
entry = item[3]  | 
|
2275  | 
if new_path is None and entry is not None:  | 
|
2276  | 
raise errors.InconsistentDelta(item[0], item[1],  | 
|
2277  | 
"Entry with no new_path")  | 
|
2278  | 
if new_path is not None and entry is None:  | 
|
2279  | 
raise errors.InconsistentDelta(new_path, item[1],  | 
|
2280  | 
"new_path with no entry")  | 
|
2281  | 
yield item  |