bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
2052.3.2
by John Arbash Meinel
 Change Copyright .. by Canonical to Copyright ... Canonical  | 
1  | 
# Copyright (C) 2006 Canonical Ltd
 | 
| 
1711.3.2
by John Arbash Meinel
 Add the read_bundle_from_url command, which handles lots of exceptions  | 
2  | 
#
 | 
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.
 | 
|
7  | 
#
 | 
|
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.
 | 
|
12  | 
#
 | 
|
13  | 
# You should have received a copy of the GNU General Public License
 | 
|
14  | 
# along with this program; if not, write to the Free Software
 | 
|
15  | 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
|
16  | 
||
17  | 
"""Read in a bundle stream, and process it into a BundleReader object."""
 | 
|
| 
0.5.7
by John Arbash Meinel
 Added a bunch more information about changesets. Can now read back in all of the meta information.  | 
18  | 
|
| 
1185.82.96
by Aaron Bentley
 Got first binary test passing  | 
19  | 
import base64  | 
| 
1185.82.78
by Aaron Bentley
 Cleanups  | 
20  | 
from cStringIO import StringIO  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
21  | 
import os  | 
22  | 
import pprint  | 
|
23  | 
||
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
24  | 
from bzrlib import (  | 
25  | 
osutils,  | 
|
| 
2520.4.33
by Aaron Bentley
 remove test dependencies on serialization minutia  | 
26  | 
timestamp,  | 
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
27  | 
    )
 | 
| 
1711.3.2
by John Arbash Meinel
 Add the read_bundle_from_url command, which handles lots of exceptions  | 
28  | 
import bzrlib.errors  | 
| 
1551.14.4
by Aaron Bentley
 Change bundle reader and merge directive to both be 'mergeables'  | 
29  | 
from bzrlib.bundle import apply_bundle  | 
| 
1185.82.131
by Aaron Bentley
 Move BadBundle error (and subclasses) to errors.py  | 
30  | 
from bzrlib.errors import (TestamentMismatch, BzrError,  | 
| 
1185.82.139
by Aaron Bentley
 Raise NotABundle when a non-bundle is supplied  | 
31  | 
MalformedHeader, MalformedPatches, NotABundle)  | 
| 
0.5.116
by John Arbash Meinel
 Fixed a bug based on the new InventoryEntry separation.  | 
32  | 
from bzrlib.inventory import (Inventory, InventoryEntry,  | 
33  | 
InventoryDirectory, InventoryFile,  | 
|
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
34  | 
InventoryLink)  | 
| 
1711.4.19
by John Arbash Meinel
 Bundles were still using os.path.join to compute paths rather than osutils.pathjoin  | 
35  | 
from bzrlib.osutils import sha_file, sha_string, pathjoin  | 
| 
1185.82.78
by Aaron Bentley
 Cleanups  | 
36  | 
from bzrlib.revision import Revision, NULL_REVISION  | 
| 
1185.82.116
by Aaron Bentley
 Introduce StrictTestament, get test failing for the right reasons  | 
37  | 
from bzrlib.testament import StrictTestament  | 
| 
1185.82.78
by Aaron Bentley
 Cleanups  | 
38  | 
from bzrlib.trace import mutter, warning  | 
| 
1711.3.2
by John Arbash Meinel
 Add the read_bundle_from_url command, which handles lots of exceptions  | 
39  | 
import bzrlib.transport  | 
| 
1185.82.78
by Aaron Bentley
 Cleanups  | 
40  | 
from bzrlib.tree import Tree  | 
| 
1711.3.2
by John Arbash Meinel
 Add the read_bundle_from_url command, which handles lots of exceptions  | 
41  | 
import bzrlib.urlutils  | 
| 
1185.82.78
by Aaron Bentley
 Cleanups  | 
42  | 
from bzrlib.xml5 import serializer_v5  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
43  | 
|
| 
0.5.57
by John Arbash Meinel
 Simplified the header, only output base if it is not the expected one.  | 
44  | 
|
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
45  | 
class RevisionInfo(object):  | 
46  | 
"""Gets filled out for each revision object that is read.  | 
|
47  | 
    """
 | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
48  | 
def __init__(self, revision_id):  | 
49  | 
self.revision_id = revision_id  | 
|
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
50  | 
self.sha1 = None  | 
51  | 
self.committer = None  | 
|
| 
0.5.39
by John Arbash Meinel
 (broken) Working on changing the processing to use a ChangesetTree.  | 
52  | 
self.date = None  | 
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
53  | 
self.timestamp = None  | 
54  | 
self.timezone = None  | 
|
55  | 
self.inventory_sha1 = None  | 
|
56  | 
||
| 
1185.82.27
by Aaron Bentley
 Fixed most revision attribute handling  | 
57  | 
self.parent_ids = None  | 
| 
1185.82.74
by Aaron Bentley
 Allow custom base for any revision  | 
58  | 
self.base_id = None  | 
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
59  | 
self.message = None  | 
| 
1185.82.27
by Aaron Bentley
 Fixed most revision attribute handling  | 
60  | 
self.properties = None  | 
| 
1185.82.77
by Aaron Bentley
 Move tree actions to RevisionInfo  | 
61  | 
self.tree_actions = None  | 
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
62  | 
|
63  | 
def __str__(self):  | 
|
64  | 
return pprint.pformat(self.__dict__)  | 
|
65  | 
||
| 
0.5.37
by John Arbash Meinel
 Made read_changeset able to spit out 'Revision' entities.  | 
66  | 
def as_revision(self):  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
67  | 
rev = Revision(revision_id=self.revision_id,  | 
| 
0.5.37
by John Arbash Meinel
 Made read_changeset able to spit out 'Revision' entities.  | 
68  | 
committer=self.committer,  | 
69  | 
timestamp=float(self.timestamp),  | 
|
70  | 
timezone=int(self.timezone),  | 
|
71  | 
inventory_sha1=self.inventory_sha1,  | 
|
72  | 
message='\n'.join(self.message))  | 
|
73  | 
||
| 
1185.82.28
by Aaron Bentley
 Got parent_id handling working  | 
74  | 
if self.parent_ids:  | 
75  | 
rev.parent_ids.extend(self.parent_ids)  | 
|
| 
1185.82.35
by Aaron Bentley
 Read revision properties  | 
76  | 
|
| 
1185.82.59
by Aaron Bentley
 Behave properly when there are no properties in a revision  | 
77  | 
if self.properties:  | 
78  | 
for property in self.properties:  | 
|
79  | 
key_end = property.find(': ')  | 
|
| 
2447.1.2
by John Arbash Meinel
 Add tests that we handle empty values whether they end in ': \n' or ':\n'.  | 
80  | 
if key_end == -1:  | 
81  | 
assert property.endswith(':')  | 
|
82  | 
key = str(property[:-1])  | 
|
83  | 
value = ''  | 
|
84  | 
else:  | 
|
| 
2447.1.4
by John Arbash Meinel
 Add a test that we properly round-trip unicode properties.  | 
85  | 
key = str(property[:key_end])  | 
86  | 
value = property[key_end+2:]  | 
|
| 
1185.82.59
by Aaron Bentley
 Behave properly when there are no properties in a revision  | 
87  | 
rev.properties[key] = value  | 
| 
1185.82.35
by Aaron Bentley
 Read revision properties  | 
88  | 
|
| 
0.5.37
by John Arbash Meinel
 Made read_changeset able to spit out 'Revision' entities.  | 
89  | 
return rev  | 
90  | 
||
| 
2520.4.33
by Aaron Bentley
 remove test dependencies on serialization minutia  | 
91  | 
    @staticmethod
 | 
92  | 
def from_revision(revision):  | 
|
93  | 
revision_info = RevisionInfo(revision.revision_id)  | 
|
94  | 
date = timestamp.format_highres_date(revision.timestamp,  | 
|
95  | 
revision.timezone)  | 
|
96  | 
revision_info.date = date  | 
|
97  | 
revision_info.timezone = revision.timezone  | 
|
98  | 
revision_info.timestamp = revision.timestamp  | 
|
99  | 
revision_info.message = revision.message.split('\n')  | 
|
100  | 
revision_info.properties = [': '.join(p) for p in  | 
|
101  | 
revision.properties.iteritems()]  | 
|
102  | 
return revision_info  | 
|
103  | 
||
| 
1185.82.123
by Aaron Bentley
 Cleanups to prepare for review  | 
104  | 
|
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
105  | 
class BundleInfo(object):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
106  | 
"""This contains the meta information. Stuff that allows you to  | 
107  | 
    recreate the revision or inventory XML.
 | 
|
| 
0.5.7
by John Arbash Meinel
 Added a bunch more information about changesets. Can now read back in all of the meta information.  | 
108  | 
    """
 | 
| 
2520.4.35
by Aaron Bentley
 zap obsolete changeset commands, add bundle-info command  | 
109  | 
def __init__(self, bundle_format=None):  | 
110  | 
self.bundle_format = None  | 
|
| 
0.5.7
by John Arbash Meinel
 Added a bunch more information about changesets. Can now read back in all of the meta information.  | 
111  | 
self.committer = None  | 
112  | 
self.date = None  | 
|
| 
0.5.17
by John Arbash Meinel
 adding apply-changset, plus more meta information.  | 
113  | 
self.message = None  | 
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
114  | 
|
| 
0.5.39
by John Arbash Meinel
 (broken) Working on changing the processing to use a ChangesetTree.  | 
115  | 
        # A list of RevisionInfo objects
 | 
| 
0.5.36
by John Arbash Meinel
 Updated so that read_changeset is able to parse the output  | 
116  | 
self.revisions = []  | 
| 
0.5.56
by John Arbash Meinel
 A couple more fixups, it seems actually capable now of writing out a changeset, and reading it back.  | 
117  | 
|
118  | 
        # The next entries are created during complete_info() and
 | 
|
119  | 
        # other post-read functions.
 | 
|
120  | 
||
121  | 
        # A list of real Revision objects
 | 
|
122  | 
self.real_revisions = []  | 
|
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
123  | 
|
124  | 
self.timestamp = None  | 
|
125  | 
self.timezone = None  | 
|
| 
0.5.15
by John Arbash Meinel
 Created an apply-changeset function, and modified output for better parsing.  | 
126  | 
|
| 
2476.2.1
by John Arbash Meinel
 Vastly improve bundle install performance by only validating the bundle one time  | 
127  | 
        # Have we checked the repository yet?
 | 
128  | 
self._validated_revisions_against_repo = False  | 
|
129  | 
||
| 
0.5.7
by John Arbash Meinel
 Added a bunch more information about changesets. Can now read back in all of the meta information.  | 
130  | 
def __str__(self):  | 
131  | 
return pprint.pformat(self.__dict__)  | 
|
132  | 
||
| 
0.5.39
by John Arbash Meinel
 (broken) Working on changing the processing to use a ChangesetTree.  | 
133  | 
def complete_info(self):  | 
134  | 
"""This makes sure that all information is properly  | 
|
135  | 
        split up, based on the assumptions that can be made
 | 
|
136  | 
        when information is missing.
 | 
|
137  | 
        """
 | 
|
| 
1551.12.29
by Aaron Bentley
 Copy and extend patch date formatting code, add patch-date parsing  | 
138  | 
from bzrlib.timestamp import unpack_highres_date  | 
| 
0.5.56
by John Arbash Meinel
 A couple more fixups, it seems actually capable now of writing out a changeset, and reading it back.  | 
139  | 
        # Put in all of the guessable information.
 | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
140  | 
if not self.timestamp and self.date:  | 
| 
0.5.81
by John Arbash Meinel
 Cleaning up from pychecker.  | 
141  | 
self.timestamp, self.timezone = unpack_highres_date(self.date)  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
142  | 
|
| 
0.5.56
by John Arbash Meinel
 A couple more fixups, it seems actually capable now of writing out a changeset, and reading it back.  | 
143  | 
self.real_revisions = []  | 
| 
0.5.39
by John Arbash Meinel
 (broken) Working on changing the processing to use a ChangesetTree.  | 
144  | 
for rev in self.revisions:  | 
| 
0.5.60
by John Arbash Meinel
 read_changeset now parses the date: subheader of revisions correctly.  | 
145  | 
if rev.timestamp is None:  | 
146  | 
if rev.date is not None:  | 
|
147  | 
rev.timestamp, rev.timezone = \  | 
|
| 
0.5.81
by John Arbash Meinel
 Cleaning up from pychecker.  | 
148  | 
unpack_highres_date(rev.date)  | 
| 
0.5.60
by John Arbash Meinel
 read_changeset now parses the date: subheader of revisions correctly.  | 
149  | 
else:  | 
150  | 
rev.timestamp = self.timestamp  | 
|
151  | 
rev.timezone = self.timezone  | 
|
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
152  | 
if rev.message is None and self.message:  | 
153  | 
rev.message = self.message  | 
|
154  | 
if rev.committer is None and self.committer:  | 
|
155  | 
rev.committer = self.committer  | 
|
| 
0.5.56
by John Arbash Meinel
 A couple more fixups, it seems actually capable now of writing out a changeset, and reading it back.  | 
156  | 
self.real_revisions.append(rev.as_revision())  | 
157  | 
||
| 
1185.82.48
by Aaron Bentley
 Inching closer to supporting multiple revisions per changeset  | 
158  | 
def get_base(self, revision):  | 
| 
1185.82.74
by Aaron Bentley
 Allow custom base for any revision  | 
159  | 
revision_info = self.get_revision_info(revision.revision_id)  | 
160  | 
if revision_info.base_id is not None:  | 
|
161  | 
if revision_info.base_id == NULL_REVISION:  | 
|
162  | 
return None  | 
|
163  | 
else:  | 
|
164  | 
return revision_info.base_id  | 
|
| 
1185.82.48
by Aaron Bentley
 Inching closer to supporting multiple revisions per changeset  | 
165  | 
if len(revision.parent_ids) == 0:  | 
166  | 
            # There is no base listed, and
 | 
|
167  | 
            # the lowest revision doesn't have a parent
 | 
|
168  | 
            # so this is probably against the empty tree
 | 
|
169  | 
            # and thus base truly is None
 | 
|
170  | 
return None  | 
|
171  | 
else:  | 
|
| 
1185.82.73
by Aaron Bentley
 Use rightmost parent always  | 
172  | 
return revision.parent_ids[-1]  | 
| 
0.5.56
by John Arbash Meinel
 A couple more fixups, it seems actually capable now of writing out a changeset, and reading it back.  | 
173  | 
|
| 
0.5.67
by John Arbash Meinel
 Working on apply_changeset  | 
174  | 
def _get_target(self):  | 
| 
0.5.81
by John Arbash Meinel
 Cleaning up from pychecker.  | 
175  | 
"""Return the target revision."""  | 
| 
0.5.67
by John Arbash Meinel
 Working on apply_changeset  | 
176  | 
if len(self.real_revisions) > 0:  | 
| 
1185.82.48
by Aaron Bentley
 Inching closer to supporting multiple revisions per changeset  | 
177  | 
return self.real_revisions[0].revision_id  | 
| 
0.5.67
by John Arbash Meinel
 Working on apply_changeset  | 
178  | 
elif len(self.revisions) > 0:  | 
| 
1185.82.48
by Aaron Bentley
 Inching closer to supporting multiple revisions per changeset  | 
179  | 
return self.revisions[0].revision_id  | 
| 
0.5.67
by John Arbash Meinel
 Working on apply_changeset  | 
180  | 
return None  | 
181  | 
||
182  | 
target = property(_get_target, doc='The target revision id')  | 
|
183  | 
||
| 
1185.82.49
by Aaron Bentley
 SPOT fixes, fix inventory validation  | 
184  | 
def get_revision(self, revision_id):  | 
185  | 
for r in self.real_revisions:  | 
|
186  | 
if r.revision_id == revision_id:  | 
|
187  | 
return r  | 
|
188  | 
raise KeyError(revision_id)  | 
|
189  | 
||
190  | 
def get_revision_info(self, revision_id):  | 
|
191  | 
for r in self.revisions:  | 
|
192  | 
if r.revision_id == revision_id:  | 
|
193  | 
return r  | 
|
194  | 
raise KeyError(revision_id)  | 
|
195  | 
||
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
196  | 
def revision_tree(self, repository, revision_id, base=None):  | 
| 
2309.4.5
by John Arbash Meinel
 Change bundle_data to use the sanitizing form of safe_*_id  | 
197  | 
revision_id = osutils.safe_revision_id(revision_id)  | 
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
198  | 
revision = self.get_revision(revision_id)  | 
199  | 
base = self.get_base(revision)  | 
|
200  | 
assert base != revision_id  | 
|
| 
2476.2.1
by John Arbash Meinel
 Vastly improve bundle install performance by only validating the bundle one time  | 
201  | 
if not self._validated_revisions_against_repo:  | 
202  | 
self._validate_references_from_repository(repository)  | 
|
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
203  | 
revision_info = self.get_revision_info(revision_id)  | 
204  | 
inventory_revision_id = revision_id  | 
|
205  | 
bundle_tree = BundleTree(repository.revision_tree(base),  | 
|
206  | 
inventory_revision_id)  | 
|
207  | 
self._update_tree(bundle_tree, revision_id)  | 
|
208  | 
||
209  | 
inv = bundle_tree.inventory  | 
|
210  | 
self._validate_inventory(inv, revision_id)  | 
|
211  | 
self._validate_revision(inv, revision_id)  | 
|
212  | 
||
213  | 
return bundle_tree  | 
|
| 
0.5.62
by John Arbash Meinel
 Doing some internal validation before allowing processing to continue, additional checks at the command level.  | 
214  | 
|
| 
1185.82.15
by Aaron Bentley
 Disabled validate_revisions (needs info it doesn't have), updated API to repos  | 
215  | 
def _validate_references_from_repository(self, repository):  | 
216  | 
"""Now that we have a repository which should have some of the  | 
|
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
217  | 
        revisions we care about, go through and validate all of them
 | 
218  | 
        that we can.
 | 
|
219  | 
        """
 | 
|
220  | 
rev_to_sha = {}  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
221  | 
inv_to_sha = {}  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
222  | 
def add_sha(d, revision_id, sha1):  | 
223  | 
if revision_id is None:  | 
|
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
224  | 
if sha1 is not None:  | 
225  | 
raise BzrError('A Null revision should always'  | 
|
226  | 
'have a null sha1 hash')  | 
|
227  | 
                return
 | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
228  | 
if revision_id in d:  | 
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
229  | 
                # This really should have been validated as part
 | 
230  | 
                # of _validate_revisions but lets do it again
 | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
231  | 
if sha1 != d[revision_id]:  | 
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
232  | 
raise BzrError('** Revision %r referenced with 2 different'  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
233  | 
' sha hashes %s != %s' % (revision_id,  | 
234  | 
sha1, d[revision_id]))  | 
|
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
235  | 
else:  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
236  | 
d[revision_id] = sha1  | 
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
237  | 
|
238  | 
        # All of the contained revisions were checked
 | 
|
239  | 
        # in _validate_revisions
 | 
|
240  | 
checked = {}  | 
|
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
241  | 
for rev_info in self.revisions:  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
242  | 
checked[rev_info.revision_id] = True  | 
243  | 
add_sha(rev_to_sha, rev_info.revision_id, rev_info.sha1)  | 
|
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
244  | 
|
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
245  | 
for (rev, rev_info) in zip(self.real_revisions, self.revisions):  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
246  | 
add_sha(inv_to_sha, rev_info.revision_id, rev_info.inventory_sha1)  | 
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
247  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
248  | 
count = 0  | 
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
249  | 
missing = {}  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
250  | 
for revision_id, sha1 in rev_to_sha.iteritems():  | 
| 
1185.82.15
by Aaron Bentley
 Disabled validate_revisions (needs info it doesn't have), updated API to repos  | 
251  | 
if repository.has_revision(revision_id):  | 
| 
1185.82.121
by Aaron Bentley
 Move calculation of Testament sha1s to Testament  | 
252  | 
testament = StrictTestament.from_revision(repository,  | 
253  | 
revision_id)  | 
|
| 
1910.2.55
by Aaron Bentley
 Bundle 0.9 uses Testament 3 strict  | 
254  | 
local_sha1 = self._testament_sha1_from_revision(repository,  | 
255  | 
revision_id)  | 
|
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
256  | 
if sha1 != local_sha1:  | 
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
257  | 
raise BzrError('sha1 mismatch. For revision id {%s}'  | 
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
258  | 
'local: %s, bundle: %s' % (revision_id, local_sha1, sha1))  | 
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
259  | 
else:  | 
260  | 
count += 1  | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
261  | 
elif revision_id not in checked:  | 
262  | 
missing[revision_id] = sha1  | 
|
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
263  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
264  | 
for inv_id, sha1 in inv_to_sha.iteritems():  | 
| 
1185.82.15
by Aaron Bentley
 Disabled validate_revisions (needs info it doesn't have), updated API to repos  | 
265  | 
if repository.has_revision(inv_id):  | 
| 
1185.82.123
by Aaron Bentley
 Cleanups to prepare for review  | 
266  | 
                # Note: branch.get_inventory_sha1() just returns the value that
 | 
267  | 
                # is stored in the revision text, and that value may be out
 | 
|
268  | 
                # of date. This is bogus, because that means we aren't
 | 
|
269  | 
                # validating the actual text, just that we wrote and read the
 | 
|
270  | 
                # string. But for now, what the hell.
 | 
|
| 
1185.82.15
by Aaron Bentley
 Disabled validate_revisions (needs info it doesn't have), updated API to repos  | 
271  | 
local_sha1 = repository.get_inventory_sha1(inv_id)  | 
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
272  | 
if sha1 != local_sha1:  | 
273  | 
raise BzrError('sha1 mismatch. For inventory id {%s}'  | 
|
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
274  | 
'local: %s, bundle: %s' %  | 
275  | 
(inv_id, local_sha1, sha1))  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
276  | 
else:  | 
277  | 
count += 1  | 
|
278  | 
||
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
279  | 
if len(missing) > 0:  | 
280  | 
            # I don't know if this is an error yet
 | 
|
281  | 
warning('Not all revision hashes could be validated.'  | 
|
282  | 
' Unable validate %d hashes' % len(missing))  | 
|
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
283  | 
mutter('Verified %d sha hashes for the bundle.' % count)  | 
| 
2476.2.1
by John Arbash Meinel
 Vastly improve bundle install performance by only validating the bundle one time  | 
284  | 
self._validated_revisions_against_repo = True  | 
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
285  | 
|
| 
1185.82.49
by Aaron Bentley
 SPOT fixes, fix inventory validation  | 
286  | 
def _validate_inventory(self, inv, revision_id):  | 
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
287  | 
"""At this point we should have generated the BundleTree,  | 
| 
0.5.63
by John Arbash Meinel
 Moving the validation into part of the reading.  | 
288  | 
        so build up an inventory, and make sure the hashes match.
 | 
289  | 
        """
 | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
290  | 
|
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
291  | 
assert inv is not None  | 
292  | 
||
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
293  | 
        # Now we should have a complete inventory entry.
 | 
| 
0.5.117
by John Arbash Meinel
 Almost there. Just need to track down a few remaining bugs.  | 
294  | 
s = serializer_v5.write_inventory_to_string(inv)  | 
295  | 
sha1 = sha_string(s)  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
296  | 
        # Target revision is the last entry in the real_revisions list
 | 
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
297  | 
rev = self.get_revision(revision_id)  | 
| 
1185.82.49
by Aaron Bentley
 SPOT fixes, fix inventory validation  | 
298  | 
assert rev.revision_id == revision_id  | 
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
299  | 
if sha1 != rev.inventory_sha1:  | 
| 
0.5.117
by John Arbash Meinel
 Almost there. Just need to track down a few remaining bugs.  | 
300  | 
open(',,bogus-inv', 'wb').write(s)  | 
| 
1185.82.61
by Aaron Bentley
 Downgrade inventory mismatch to warning (source can be inaccurate)  | 
301  | 
warning('Inventory sha hash mismatch for revision %s. %s'  | 
302  | 
' != %s' % (revision_id, sha1, rev.inventory_sha1))  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
303  | 
|
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
304  | 
def _validate_revision(self, inventory, revision_id):  | 
305  | 
"""Make sure all revision entries match their checksum."""  | 
|
306  | 
||
307  | 
        # This is a mapping from each revision id to it's sha hash
 | 
|
308  | 
rev_to_sha1 = {}  | 
|
309  | 
||
310  | 
rev = self.get_revision(revision_id)  | 
|
311  | 
rev_info = self.get_revision_info(revision_id)  | 
|
312  | 
assert rev.revision_id == rev_info.revision_id  | 
|
313  | 
assert rev.revision_id == revision_id  | 
|
| 
1910.2.55
by Aaron Bentley
 Bundle 0.9 uses Testament 3 strict  | 
314  | 
sha1 = self._testament_sha1(rev, inventory)  | 
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
315  | 
if sha1 != rev_info.sha1:  | 
316  | 
raise TestamentMismatch(rev.revision_id, rev_info.sha1, sha1)  | 
|
| 
1963.2.1
by Robey Pointer
 remove usage of has_key()  | 
317  | 
if rev.revision_id in rev_to_sha1:  | 
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
318  | 
raise BzrError('Revision {%s} given twice in the list'  | 
319  | 
% (rev.revision_id))  | 
|
320  | 
rev_to_sha1[rev.revision_id] = sha1  | 
|
321  | 
||
322  | 
def _update_tree(self, bundle_tree, revision_id):  | 
|
323  | 
"""This fills out a BundleTree based on the information  | 
|
324  | 
        that was read in.
 | 
|
325  | 
||
326  | 
        :param bundle_tree: A BundleTree to update with the new information.
 | 
|
327  | 
        """
 | 
|
328  | 
||
329  | 
def get_rev_id(last_changed, path, kind):  | 
|
330  | 
if last_changed is not None:  | 
|
| 
2309.4.5
by John Arbash Meinel
 Change bundle_data to use the sanitizing form of safe_*_id  | 
331  | 
                # last_changed will be a Unicode string because of how it was
 | 
332  | 
                # read. Convert it back to utf8.
 | 
|
333  | 
changed_revision_id = osutils.safe_revision_id(last_changed,  | 
|
334  | 
warn=False)  | 
|
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
335  | 
else:  | 
336  | 
changed_revision_id = revision_id  | 
|
337  | 
bundle_tree.note_last_changed(path, changed_revision_id)  | 
|
338  | 
return changed_revision_id  | 
|
339  | 
||
340  | 
def extra_info(info, new_path):  | 
|
341  | 
last_changed = None  | 
|
342  | 
encoding = None  | 
|
343  | 
for info_item in info:  | 
|
344  | 
try:  | 
|
345  | 
name, value = info_item.split(':', 1)  | 
|
346  | 
except ValueError:  | 
|
347  | 
raise 'Value %r has no colon' % info_item  | 
|
348  | 
if name == 'last-changed':  | 
|
349  | 
last_changed = value  | 
|
350  | 
elif name == 'executable':  | 
|
351  | 
assert value in ('yes', 'no'), value  | 
|
352  | 
val = (value == 'yes')  | 
|
353  | 
bundle_tree.note_executable(new_path, val)  | 
|
354  | 
elif name == 'target':  | 
|
355  | 
bundle_tree.note_target(new_path, value)  | 
|
356  | 
elif name == 'encoding':  | 
|
357  | 
encoding = value  | 
|
358  | 
return last_changed, encoding  | 
|
359  | 
||
360  | 
def do_patch(path, lines, encoding):  | 
|
361  | 
if encoding is not None:  | 
|
362  | 
assert encoding == 'base64'  | 
|
363  | 
patch = base64.decodestring(''.join(lines))  | 
|
364  | 
else:  | 
|
365  | 
patch = ''.join(lines)  | 
|
366  | 
bundle_tree.note_patch(path, patch)  | 
|
367  | 
||
368  | 
def renamed(kind, extra, lines):  | 
|
369  | 
info = extra.split(' // ')  | 
|
370  | 
if len(info) < 2:  | 
|
371  | 
raise BzrError('renamed action lines need both a from and to'  | 
|
372  | 
': %r' % extra)  | 
|
373  | 
old_path = info[0]  | 
|
374  | 
if info[1].startswith('=> '):  | 
|
375  | 
new_path = info[1][3:]  | 
|
376  | 
else:  | 
|
377  | 
new_path = info[1]  | 
|
378  | 
||
379  | 
bundle_tree.note_rename(old_path, new_path)  | 
|
380  | 
last_modified, encoding = extra_info(info[2:], new_path)  | 
|
381  | 
revision = get_rev_id(last_modified, new_path, kind)  | 
|
382  | 
if lines:  | 
|
383  | 
do_patch(new_path, lines, encoding)  | 
|
384  | 
||
385  | 
def removed(kind, extra, lines):  | 
|
386  | 
info = extra.split(' // ')  | 
|
387  | 
if len(info) > 1:  | 
|
388  | 
                # TODO: in the future we might allow file ids to be
 | 
|
389  | 
                # given for removed entries
 | 
|
390  | 
raise BzrError('removed action lines should only have the path'  | 
|
391  | 
': %r' % extra)  | 
|
392  | 
path = info[0]  | 
|
393  | 
bundle_tree.note_deletion(path)  | 
|
394  | 
||
395  | 
def added(kind, extra, lines):  | 
|
396  | 
info = extra.split(' // ')  | 
|
397  | 
if len(info) <= 1:  | 
|
398  | 
raise BzrError('add action lines require the path and file id'  | 
|
399  | 
': %r' % extra)  | 
|
400  | 
elif len(info) > 5:  | 
|
401  | 
raise BzrError('add action lines have fewer than 5 entries.'  | 
|
402  | 
': %r' % extra)  | 
|
403  | 
path = info[0]  | 
|
404  | 
if not info[1].startswith('file-id:'):  | 
|
405  | 
raise BzrError('The file-id should follow the path for an add'  | 
|
406  | 
': %r' % extra)  | 
|
| 
2294.1.10
by John Arbash Meinel
 Switch all apis over to utf8 file ids. All tests pass  | 
407  | 
            # This will be Unicode because of how the stream is read. Turn it
 | 
408  | 
            # back into a utf8 file_id
 | 
|
| 
2309.4.5
by John Arbash Meinel
 Change bundle_data to use the sanitizing form of safe_*_id  | 
409  | 
file_id = osutils.safe_file_id(info[1][8:], warn=False)  | 
| 
1793.2.1
by Aaron Bentley
 Move revision_tree into BundleInfo  | 
410  | 
|
411  | 
bundle_tree.note_id(file_id, path, kind)  | 
|
412  | 
            # this will be overridden in extra_info if executable is specified.
 | 
|
413  | 
bundle_tree.note_executable(path, False)  | 
|
414  | 
last_changed, encoding = extra_info(info[2:], path)  | 
|
415  | 
revision = get_rev_id(last_changed, path, kind)  | 
|
416  | 
if kind == 'directory':  | 
|
417  | 
                return
 | 
|
418  | 
do_patch(path, lines, encoding)  | 
|
419  | 
||
420  | 
def modified(kind, extra, lines):  | 
|
421  | 
info = extra.split(' // ')  | 
|
422  | 
if len(info) < 1:  | 
|
423  | 
raise BzrError('modified action lines have at least'  | 
|
424  | 
'the path in them: %r' % extra)  | 
|
425  | 
path = info[0]  | 
|
426  | 
||
427  | 
last_modified, encoding = extra_info(info[1:], path)  | 
|
428  | 
revision = get_rev_id(last_modified, path, kind)  | 
|
429  | 
if lines:  | 
|
430  | 
do_patch(path, lines, encoding)  | 
|
431  | 
||
432  | 
valid_actions = {  | 
|
433  | 
'renamed':renamed,  | 
|
434  | 
'removed':removed,  | 
|
435  | 
'added':added,  | 
|
436  | 
'modified':modified  | 
|
437  | 
        }
 | 
|
438  | 
for action_line, lines in \  | 
|
439  | 
self.get_revision_info(revision_id).tree_actions:  | 
|
440  | 
first = action_line.find(' ')  | 
|
441  | 
if first == -1:  | 
|
442  | 
raise BzrError('Bogus action line'  | 
|
443  | 
' (no opening space): %r' % action_line)  | 
|
444  | 
second = action_line.find(' ', first+1)  | 
|
445  | 
if second == -1:  | 
|
446  | 
raise BzrError('Bogus action line'  | 
|
447  | 
' (missing second space): %r' % action_line)  | 
|
448  | 
action = action_line[:first]  | 
|
449  | 
kind = action_line[first+1:second]  | 
|
450  | 
if kind not in ('file', 'directory', 'symlink'):  | 
|
451  | 
raise BzrError('Bogus action line'  | 
|
452  | 
' (invalid object kind %r): %r' % (kind, action_line))  | 
|
453  | 
extra = action_line[second+1:]  | 
|
454  | 
||
455  | 
if action not in valid_actions:  | 
|
456  | 
raise BzrError('Bogus action line'  | 
|
457  | 
' (unrecognized action): %r' % action_line)  | 
|
458  | 
valid_actions[action](kind, extra, lines)  | 
|
459  | 
||
| 
2520.4.148
by Aaron Bentley
 Updates from review  | 
460  | 
def install_revisions(self, target_repo, stream_input=True):  | 
461  | 
"""Install revisions and return the target revision  | 
|
462  | 
||
463  | 
        :param target_repo: The repository to install into
 | 
|
464  | 
        :param stream_input: Ignored by this implementation.
 | 
|
465  | 
        """
 | 
|
| 
1551.14.4
by Aaron Bentley
 Change bundle reader and merge directive to both be 'mergeables'  | 
466  | 
apply_bundle.install_bundle(target_repo, self)  | 
467  | 
return self.target  | 
|
468  | 
||
| 
2520.4.109
by Aaron Bentley
 start work on directive cherry-picking  | 
469  | 
def get_merge_request(self, target_repo):  | 
470  | 
"""Provide data for performing a merge  | 
|
471  | 
||
472  | 
        Returns suggested base, suggested target, and patch verification status
 | 
|
473  | 
        """
 | 
|
474  | 
return None, self.target, 'inapplicable'  | 
|
475  | 
||
| 
1551.14.4
by Aaron Bentley
 Change bundle reader and merge directive to both be 'mergeables'  | 
476  | 
|
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
477  | 
class BundleTree(Tree):  | 
| 
1185.82.16
by Aaron Bentley
 Ensured revision ID is stored in ChangesetTree inventories  | 
478  | 
def __init__(self, base_tree, revision_id):  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
479  | 
self.base_tree = base_tree  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
480  | 
self._renamed = {} # Mapping from old_path => new_path  | 
481  | 
self._renamed_r = {} # new_path => old_path  | 
|
482  | 
self._new_id = {} # new_path => new_id  | 
|
483  | 
self._new_id_r = {} # new_id => new_path  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
484  | 
self._kinds = {} # new_id => kind  | 
| 
0.5.118
by John Arbash Meinel
 Got most of test_changeset to work. Still needs work for Aaron's test code.  | 
485  | 
self._last_changed = {} # new_id => revision_id  | 
| 
1185.82.66
by Aaron Bentley
 Handle new executable files  | 
486  | 
self._executable = {} # new_id => executable value  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
487  | 
self.patches = {}  | 
| 
1185.82.87
by Aaron Bentley
 Got symlink adding working  | 
488  | 
self._targets = {} # new path => new symlink target  | 
| 
0.5.48
by aaron.bentley at utoronto
 Implemented deletion for ChangesetTrees  | 
489  | 
self.deleted = []  | 
| 
0.5.52
by aaron.bentley at utoronto
 Make contents-addressing configurable  | 
490  | 
self.contents_by_id = True  | 
| 
1185.82.16
by Aaron Bentley
 Ensured revision ID is stored in ChangesetTree inventories  | 
491  | 
self.revision_id = revision_id  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
492  | 
self._inventory = None  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
493  | 
|
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
494  | 
def __str__(self):  | 
495  | 
return pprint.pformat(self.__dict__)  | 
|
496  | 
||
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
497  | 
def note_rename(self, old_path, new_path):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
498  | 
"""A file/directory has been renamed from old_path => new_path"""  | 
| 
1963.2.1
by Robey Pointer
 remove usage of has_key()  | 
499  | 
assert new_path not in self._renamed  | 
500  | 
assert old_path not in self._renamed_r  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
501  | 
self._renamed[new_path] = old_path  | 
502  | 
self._renamed_r[old_path] = new_path  | 
|
503  | 
||
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
504  | 
def note_id(self, new_id, new_path, kind='file'):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
505  | 
"""Files that don't exist in base need a new id."""  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
506  | 
self._new_id[new_path] = new_id  | 
507  | 
self._new_id_r[new_id] = new_path  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
508  | 
self._kinds[new_id] = kind  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
509  | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
510  | 
def note_last_changed(self, file_id, revision_id):  | 
| 
1963.2.1
by Robey Pointer
 remove usage of has_key()  | 
511  | 
if (file_id in self._last_changed  | 
| 
0.5.118
by John Arbash Meinel
 Got most of test_changeset to work. Still needs work for Aaron's test code.  | 
512  | 
and self._last_changed[file_id] != revision_id):  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
513  | 
raise BzrError('Mismatched last-changed revision for file_id {%s}'  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
514  | 
': %s != %s' % (file_id,  | 
| 
0.5.118
by John Arbash Meinel
 Got most of test_changeset to work. Still needs work for Aaron's test code.  | 
515  | 
self._last_changed[file_id],  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
516  | 
revision_id))  | 
| 
0.5.118
by John Arbash Meinel
 Got most of test_changeset to work. Still needs work for Aaron's test code.  | 
517  | 
self._last_changed[file_id] = revision_id  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
518  | 
|
| 
0.5.44
by aaron.bentley at utoronto
 Got get_file working for new files  | 
519  | 
def note_patch(self, new_path, patch):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
520  | 
"""There is a patch for a given filename."""  | 
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
521  | 
self.patches[new_path] = patch  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
522  | 
|
| 
1185.82.87
by Aaron Bentley
 Got symlink adding working  | 
523  | 
def note_target(self, new_path, target):  | 
524  | 
"""The symlink at the new path has the given target"""  | 
|
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
525  | 
self._targets[new_path] = target  | 
| 
1185.82.87
by Aaron Bentley
 Got symlink adding working  | 
526  | 
|
| 
0.5.48
by aaron.bentley at utoronto
 Implemented deletion for ChangesetTrees  | 
527  | 
def note_deletion(self, old_path):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
528  | 
"""The file at old_path has been deleted."""  | 
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
529  | 
self.deleted.append(old_path)  | 
| 
0.5.48
by aaron.bentley at utoronto
 Implemented deletion for ChangesetTrees  | 
530  | 
|
| 
1185.82.66
by Aaron Bentley
 Handle new executable files  | 
531  | 
def note_executable(self, new_path, executable):  | 
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
532  | 
self._executable[new_path] = executable  | 
| 
1185.82.66
by Aaron Bentley
 Handle new executable files  | 
533  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
534  | 
def old_path(self, new_path):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
535  | 
"""Get the old_path (path in the base_tree) for the file at new_path"""  | 
| 
0.6.1
by Aaron Bentley
 Fleshed out MockTree, fixed all test failures  | 
536  | 
assert new_path[:1] not in ('\\', '/')  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
537  | 
old_path = self._renamed.get(new_path)  | 
538  | 
if old_path is not None:  | 
|
539  | 
return old_path  | 
|
540  | 
dirname,basename = os.path.split(new_path)  | 
|
| 
0.5.56
by John Arbash Meinel
 A couple more fixups, it seems actually capable now of writing out a changeset, and reading it back.  | 
541  | 
        # dirname is not '' doesn't work, because
 | 
542  | 
        # dirname may be a unicode entry, and is
 | 
|
543  | 
        # requires the objects to be identical
 | 
|
544  | 
if dirname != '':  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
545  | 
old_dir = self.old_path(dirname)  | 
546  | 
if old_dir is None:  | 
|
| 
0.5.42
by aaron.bentley at utoronto
 Improved rename handling  | 
547  | 
old_path = None  | 
548  | 
else:  | 
|
| 
1711.4.19
by John Arbash Meinel
 Bundles were still using os.path.join to compute paths rather than osutils.pathjoin  | 
549  | 
old_path = pathjoin(old_dir, basename)  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
550  | 
else:  | 
| 
0.5.42
by aaron.bentley at utoronto
 Improved rename handling  | 
551  | 
old_path = new_path  | 
552  | 
        #If the new path wasn't in renamed, the old one shouldn't be in
 | 
|
553  | 
        #renamed_r
 | 
|
| 
1963.2.1
by Robey Pointer
 remove usage of has_key()  | 
554  | 
if old_path in self._renamed_r:  | 
| 
0.5.42
by aaron.bentley at utoronto
 Improved rename handling  | 
555  | 
return None  | 
556  | 
return old_path  | 
|
557  | 
||
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
558  | 
def new_path(self, old_path):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
559  | 
"""Get the new_path (path in the target_tree) for the file at old_path  | 
560  | 
        in the base tree.
 | 
|
561  | 
        """
 | 
|
| 
0.6.1
by Aaron Bentley
 Fleshed out MockTree, fixed all test failures  | 
562  | 
assert old_path[:1] not in ('\\', '/')  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
563  | 
new_path = self._renamed_r.get(old_path)  | 
564  | 
if new_path is not None:  | 
|
565  | 
return new_path  | 
|
| 
1963.2.1
by Robey Pointer
 remove usage of has_key()  | 
566  | 
if new_path in self._renamed:  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
567  | 
return None  | 
568  | 
dirname,basename = os.path.split(old_path)  | 
|
| 
0.5.81
by John Arbash Meinel
 Cleaning up from pychecker.  | 
569  | 
if dirname != '':  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
570  | 
new_dir = self.new_path(dirname)  | 
571  | 
if new_dir is None:  | 
|
| 
0.5.42
by aaron.bentley at utoronto
 Improved rename handling  | 
572  | 
new_path = None  | 
573  | 
else:  | 
|
| 
1711.4.19
by John Arbash Meinel
 Bundles were still using os.path.join to compute paths rather than osutils.pathjoin  | 
574  | 
new_path = pathjoin(new_dir, basename)  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
575  | 
else:  | 
| 
0.5.42
by aaron.bentley at utoronto
 Improved rename handling  | 
576  | 
new_path = old_path  | 
577  | 
        #If the old path wasn't in renamed, the new one shouldn't be in
 | 
|
578  | 
        #renamed_r
 | 
|
| 
1963.2.1
by Robey Pointer
 remove usage of has_key()  | 
579  | 
if new_path in self._renamed:  | 
| 
0.5.42
by aaron.bentley at utoronto
 Improved rename handling  | 
580  | 
return None  | 
581  | 
return new_path  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
582  | 
|
583  | 
def path2id(self, path):  | 
|
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
584  | 
"""Return the id of the file present at path in the target tree."""  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
585  | 
file_id = self._new_id.get(path)  | 
586  | 
if file_id is not None:  | 
|
587  | 
return file_id  | 
|
| 
0.5.43
by aaron.bentley at utoronto
 Handled moves and adds properly  | 
588  | 
old_path = self.old_path(path)  | 
589  | 
if old_path is None:  | 
|
590  | 
return None  | 
|
| 
0.5.48
by aaron.bentley at utoronto
 Implemented deletion for ChangesetTrees  | 
591  | 
if old_path in self.deleted:  | 
592  | 
return None  | 
|
| 
1963.2.6
by Robey Pointer
 pychecker is on crack; go back to using 'is None'.  | 
593  | 
if getattr(self.base_tree, 'path2id', None) is not None:  | 
| 
0.5.66
by John Arbash Meinel
 Refactoring, moving test code into test (switching back to assert is None)  | 
594  | 
return self.base_tree.path2id(old_path)  | 
595  | 
else:  | 
|
596  | 
return self.base_tree.inventory.path2id(old_path)  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
597  | 
|
598  | 
def id2path(self, file_id):  | 
|
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
599  | 
"""Return the new path in the target tree of the file with id file_id"""  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
600  | 
path = self._new_id_r.get(file_id)  | 
601  | 
if path is not None:  | 
|
602  | 
return path  | 
|
| 
0.5.43
by aaron.bentley at utoronto
 Handled moves and adds properly  | 
603  | 
old_path = self.base_tree.id2path(file_id)  | 
604  | 
if old_path is None:  | 
|
605  | 
return None  | 
|
| 
0.5.48
by aaron.bentley at utoronto
 Implemented deletion for ChangesetTrees  | 
606  | 
if old_path in self.deleted:  | 
607  | 
return None  | 
|
| 
0.5.43
by aaron.bentley at utoronto
 Handled moves and adds properly  | 
608  | 
return self.new_path(old_path)  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
609  | 
|
| 
0.5.52
by aaron.bentley at utoronto
 Make contents-addressing configurable  | 
610  | 
def old_contents_id(self, file_id):  | 
| 
1185.82.94
by Aaron Bentley
 Remove old chatter  | 
611  | 
"""Return the id in the base_tree for the given file_id.  | 
612  | 
        Return None if the file did not exist in base.
 | 
|
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
613  | 
        """
 | 
| 
0.5.52
by aaron.bentley at utoronto
 Make contents-addressing configurable  | 
614  | 
if self.contents_by_id:  | 
615  | 
if self.base_tree.has_id(file_id):  | 
|
616  | 
return file_id  | 
|
617  | 
else:  | 
|
618  | 
return None  | 
|
619  | 
new_path = self.id2path(file_id)  | 
|
620  | 
return self.base_tree.path2id(new_path)  | 
|
621  | 
||
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
622  | 
def get_file(self, file_id):  | 
| 
0.5.55
by John Arbash Meinel
 Lots of updates. Using a minimized annotations for changesets.  | 
623  | 
"""Return a file-like object containing the new contents of the  | 
624  | 
        file given by file_id.
 | 
|
625  | 
||
626  | 
        TODO:   It might be nice if this actually generated an entry
 | 
|
627  | 
                in the text-store, so that the file contents would
 | 
|
628  | 
                then be cached.
 | 
|
629  | 
        """
 | 
|
| 
0.5.52
by aaron.bentley at utoronto
 Make contents-addressing configurable  | 
630  | 
base_id = self.old_contents_id(file_id)  | 
| 
1910.2.64
by Aaron Bentley
 Changes from review  | 
631  | 
if (base_id is not None and  | 
| 
1910.2.58
by Aaron Bentley
 Stop using get_revision_id to make bundles  | 
632  | 
base_id != self.base_tree.inventory.root.file_id):  | 
| 
0.5.50
by aaron.bentley at utoronto
 Evaluate patches against file paths, not file ids  | 
633  | 
patch_original = self.base_tree.get_file(base_id)  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
634  | 
else:  | 
635  | 
patch_original = None  | 
|
| 
0.5.52
by aaron.bentley at utoronto
 Make contents-addressing configurable  | 
636  | 
file_patch = self.patches.get(self.id2path(file_id))  | 
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
637  | 
if file_patch is None:  | 
| 
1185.82.42
by Aaron Bentley
 Handle new directories properly  | 
638  | 
if (patch_original is None and  | 
639  | 
self.get_kind(file_id) == 'directory'):  | 
|
640  | 
return StringIO()  | 
|
641  | 
assert patch_original is not None, "None: %s" % file_id  | 
|
| 
0.5.44
by aaron.bentley at utoronto
 Got get_file working for new files  | 
642  | 
return patch_original  | 
| 
0.5.94
by Aaron Bentley
 Switched to native patch application, added tests for terminating newlines  | 
643  | 
|
644  | 
assert not file_patch.startswith('\\'), \  | 
|
645  | 
'Malformed patch for %s, %r' % (file_id, file_patch)  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
646  | 
return patched_file(file_patch, patch_original)  | 
647  | 
||
| 
1185.82.87
by Aaron Bentley
 Got symlink adding working  | 
648  | 
def get_symlink_target(self, file_id):  | 
649  | 
new_path = self.id2path(file_id)  | 
|
650  | 
try:  | 
|
651  | 
return self._targets[new_path]  | 
|
652  | 
except KeyError:  | 
|
653  | 
return self.base_tree.get_symlink_target(file_id)  | 
|
654  | 
||
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
655  | 
def get_kind(self, file_id):  | 
656  | 
if file_id in self._kinds:  | 
|
657  | 
return self._kinds[file_id]  | 
|
658  | 
return self.base_tree.inventory[file_id].kind  | 
|
659  | 
||
| 
1185.82.66
by Aaron Bentley
 Handle new executable files  | 
660  | 
def is_executable(self, file_id):  | 
| 
1185.82.93
by Aaron Bentley
 Code cleanup  | 
661  | 
path = self.id2path(file_id)  | 
662  | 
if path in self._executable:  | 
|
663  | 
return self._executable[path]  | 
|
| 
1185.82.66
by Aaron Bentley
 Handle new executable files  | 
664  | 
else:  | 
665  | 
return self.base_tree.inventory[file_id].executable  | 
|
666  | 
||
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
667  | 
def get_last_changed(self, file_id):  | 
| 
1185.82.95
by Aaron Bentley
 Restore path-orientation of ChangesetTree  | 
668  | 
path = self.id2path(file_id)  | 
669  | 
if path in self._last_changed:  | 
|
670  | 
return self._last_changed[path]  | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
671  | 
return self.base_tree.inventory[file_id].revision  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
672  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
673  | 
def get_size_and_sha1(self, file_id):  | 
674  | 
"""Return the size and sha1 hash of the given file id.  | 
|
675  | 
        If the file was not locally modified, this is extracted
 | 
|
676  | 
        from the base_tree. Rather than re-reading the file.
 | 
|
677  | 
        """
 | 
|
678  | 
new_path = self.id2path(file_id)  | 
|
679  | 
if new_path is None:  | 
|
680  | 
return None, None  | 
|
681  | 
if new_path not in self.patches:  | 
|
682  | 
            # If the entry does not have a patch, then the
 | 
|
683  | 
            # contents must be the same as in the base_tree
 | 
|
684  | 
ie = self.base_tree.inventory[file_id]  | 
|
| 
0.5.69
by John Arbash Meinel
 Applying patch from Robey Pointer to clean up apply_changeset.  | 
685  | 
if ie.text_size is None:  | 
686  | 
return ie.text_size, ie.text_sha1  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
687  | 
return int(ie.text_size), ie.text_sha1  | 
| 
0.5.94
by Aaron Bentley
 Switched to native patch application, added tests for terminating newlines  | 
688  | 
fileobj = self.get_file(file_id)  | 
689  | 
content = fileobj.read()  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
690  | 
return len(content), sha_string(content)  | 
691  | 
||
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
692  | 
def _get_inventory(self):  | 
| 
1185.82.130
by Aaron Bentley
 Rename changesets to revision bundles  | 
693  | 
"""Build up the inventory entry for the BundleTree.  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
694  | 
|
695  | 
        This need to be called before ever accessing self.inventory
 | 
|
696  | 
        """
 | 
|
697  | 
from os.path import dirname, basename  | 
|
698  | 
||
699  | 
assert self.base_tree is not None  | 
|
700  | 
base_inv = self.base_tree.inventory  | 
|
| 
1731.1.62
by Aaron Bentley
 Changes from review comments  | 
701  | 
inv = Inventory(None, self.revision_id)  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
702  | 
|
703  | 
def add_entry(file_id):  | 
|
704  | 
path = self.id2path(file_id)  | 
|
705  | 
if path is None:  | 
|
706  | 
                return
 | 
|
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
707  | 
if path == '':  | 
708  | 
parent_id = None  | 
|
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
709  | 
else:  | 
| 
1731.1.55
by Aaron Bentley
 Fix bundle handling  | 
710  | 
parent_path = dirname(path)  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
711  | 
parent_id = self.path2id(parent_path)  | 
712  | 
||
713  | 
kind = self.get_kind(file_id)  | 
|
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
714  | 
revision_id = self.get_last_changed(file_id)  | 
| 
0.5.83
by John Arbash Meinel
 Tests pass. Now ChangesetTree has it's own inventory.  | 
715  | 
|
716  | 
name = basename(path)  | 
|
| 
0.5.116
by John Arbash Meinel
 Fixed a bug based on the new InventoryEntry separation.  | 
717  | 
if kind == 'directory':  | 
718  | 
ie = InventoryDirectory(file_id, name, parent_id)  | 
|
719  | 
elif kind == 'file':  | 
|
720  | 
ie = InventoryFile(file_id, name, parent_id)  | 
|
| 
1185.82.66
by Aaron Bentley
 Handle new executable files  | 
721  | 
ie.executable = self.is_executable(file_id)  | 
| 
0.5.116
by John Arbash Meinel
 Fixed a bug based on the new InventoryEntry separation.  | 
722  | 
elif kind == 'symlink':  | 
723  | 
ie = InventoryLink(file_id, name, parent_id)  | 
|
| 
1185.82.87
by Aaron Bentley
 Got symlink adding working  | 
724  | 
ie.symlink_target = self.get_symlink_target(file_id)  | 
| 
0.5.115
by John Arbash Meinel
 Getting closer to being able to read back the changesets, still broken, though.  | 
725  | 
ie.revision = revision_id  | 
726  | 
||
| 
1185.82.88
by Aaron Bentley
 Get symlink modification, renames and deletion under test  | 
727  | 
if kind in ('directory', 'symlink'):  | 
| 
0.5.83
by John Arbash Meinel
 Tests pass. Now ChangesetTree has it's own inventory.  | 
728  | 
ie.text_size, ie.text_sha1 = None, None  | 
729  | 
else:  | 
|
730  | 
ie.text_size, ie.text_sha1 = self.get_size_and_sha1(file_id)  | 
|
| 
1185.82.88
by Aaron Bentley
 Get symlink modification, renames and deletion under test  | 
731  | 
if (ie.text_size is None) and (kind == 'file'):  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
732  | 
raise BzrError('Got a text_size of None for file_id %r' % file_id)  | 
733  | 
inv.add(ie)  | 
|
734  | 
||
| 
0.6.1
by Aaron Bentley
 Fleshed out MockTree, fixed all test failures  | 
735  | 
sorted_entries = self.sorted_path_id()  | 
736  | 
for path, file_id in sorted_entries:  | 
|
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
737  | 
add_entry(file_id)  | 
738  | 
||
739  | 
return inv  | 
|
740  | 
||
741  | 
    # Have to overload the inherited inventory property
 | 
|
742  | 
    # because _get_inventory is only called in the parent.
 | 
|
743  | 
    # Reading the docs, property() objects do not use
 | 
|
744  | 
    # overloading, they use the function as it was defined
 | 
|
745  | 
    # at that instant
 | 
|
746  | 
inventory = property(_get_inventory)  | 
|
| 
0.5.64
by John Arbash Meinel
 SUCCESS, we now are able to validate the inventory XML.  | 
747  | 
|
| 
0.5.49
by aaron.bentley at utoronto
 Implemented iteration over ids  | 
748  | 
def __iter__(self):  | 
| 
0.5.82
by John Arbash Meinel
 Lots of changes, changing separators, updating tests, updated ChangesetTree to include text_ids  | 
749  | 
for path, entry in self.inventory.iter_entries():  | 
| 
0.5.69
by John Arbash Meinel
 Applying patch from Robey Pointer to clean up apply_changeset.  | 
750  | 
yield entry.file_id  | 
| 
0.5.49
by aaron.bentley at utoronto
 Implemented iteration over ids  | 
751  | 
|
| 
0.6.1
by Aaron Bentley
 Fleshed out MockTree, fixed all test failures  | 
752  | 
def sorted_path_id(self):  | 
753  | 
paths = []  | 
|
754  | 
for result in self._new_id.iteritems():  | 
|
755  | 
paths.append(result)  | 
|
756  | 
for id in self.base_tree:  | 
|
757  | 
path = self.id2path(id)  | 
|
758  | 
if path is None:  | 
|
759  | 
                continue
 | 
|
760  | 
paths.append((path, id))  | 
|
761  | 
paths.sort()  | 
|
762  | 
return paths  | 
|
763  | 
||
| 
1185.82.123
by Aaron Bentley
 Cleanups to prepare for review  | 
764  | 
|
| 
0.5.41
by aaron.bentley at utoronto
 Added non-working ChangesetTree  | 
765  | 
def patched_file(file_patch, original):  | 
| 
0.5.94
by Aaron Bentley
 Switched to native patch application, added tests for terminating newlines  | 
766  | 
"""Produce a file-like object with the patched version of a text"""  | 
| 
1185.82.13
by Aaron Bentley
 Got old changeset tests running  | 
767  | 
from bzrlib.patches import iter_patched  | 
768  | 
from bzrlib.iterablefile import IterableFile  | 
|
| 
0.5.94
by Aaron Bentley
 Switched to native patch application, added tests for terminating newlines  | 
769  | 
if file_patch == "":  | 
770  | 
return IterableFile(())  | 
|
| 
1848.1.1
by John Arbash Meinel
 fix bug in bundle handling of binary files with just '\r' in them.  | 
771  | 
    # string.splitlines(True) also splits on '\r', but the iter_patched code
 | 
772  | 
    # only expects to iterate over '\n' style lines
 | 
|
773  | 
return IterableFile(iter_patched(original,  | 
|
774  | 
StringIO(file_patch).readlines()))  |