/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/revisiontree.py

  • Committer: John Arbash Meinel
  • Date: 2008-08-18 22:34:21 UTC
  • mto: (3606.5.6 1.6)
  • mto: This revision was merged to the branch mainline in revision 3641.
  • Revision ID: john@arbash-meinel.com-20080818223421-todjny24vj4faj4t
Add tests for the fetching behavior.

The proper parameter passed is 'unordered' add an assert for it, and
fix callers that were passing 'unsorted' instead.
Add tests that we make the right get_record_stream call based
on the value of _fetch_uses_deltas.
Fix the fetch request for signatures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2007 Canonical Ltd
 
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
"""RevisionTree - a Tree implementation backed by repository data for a revision."""
 
18
 
 
19
from cStringIO import StringIO
 
20
 
 
21
from bzrlib import (
 
22
    errors,
 
23
    osutils,
 
24
    revision,
 
25
    symbol_versioning,
 
26
    )
 
27
from bzrlib.tree import Tree
 
28
 
 
29
 
 
30
class RevisionTree(Tree):
 
31
    """Tree viewing a previous revision.
 
32
 
 
33
    File text can be retrieved from the text store.
 
34
    """
 
35
 
 
36
    def __init__(self, branch, inv, revision_id):
 
37
        # for compatability the 'branch' parameter has not been renamed to 
 
38
        # repository at this point. However, we should change RevisionTree's
 
39
        # construction to always be via Repository and not via direct 
 
40
        # construction - this will mean that we can change the constructor
 
41
        # with much less chance of breaking client code.
 
42
        self._repository = branch
 
43
        self._inventory = inv
 
44
        self._revision_id = revision_id
 
45
        self._rules_searcher = None
 
46
 
 
47
    def supports_tree_reference(self):
 
48
        return True
 
49
 
 
50
    def get_parent_ids(self):
 
51
        """See Tree.get_parent_ids.
 
52
 
 
53
        A RevisionTree's parents match the revision graph.
 
54
        """
 
55
        if self._revision_id in (None, revision.NULL_REVISION):
 
56
            parent_ids = []
 
57
        else:
 
58
            parent_ids = self._repository.get_revision(
 
59
                self._revision_id).parent_ids
 
60
        return parent_ids
 
61
        
 
62
    def get_revision_id(self):
 
63
        """Return the revision id associated with this tree."""
 
64
        return self._revision_id
 
65
 
 
66
    def get_file_lines(self, file_id):
 
67
        return osutils.split_lines(self.get_file_text(file_id))
 
68
 
 
69
    def get_file_text(self, file_id):
 
70
        return list(self.iter_files_bytes([(file_id, None)]))[0][1]
 
71
 
 
72
    def get_file(self, file_id, path=None):
 
73
        return StringIO(self.get_file_text(file_id))
 
74
 
 
75
    def iter_files_bytes(self, desired_files):
 
76
        """See Tree.iter_files_bytes.
 
77
 
 
78
        This version is implemented on top of Repository.extract_files_bytes"""
 
79
        repo_desired_files = [(f, self.inventory[f].revision, i)
 
80
                              for f, i in desired_files]
 
81
        try:
 
82
            for result in self._repository.iter_files_bytes(repo_desired_files):
 
83
                yield result
 
84
        except errors.RevisionNotPresent, e:
 
85
            raise errors.NoSuchFile(e.revision_id)
 
86
 
 
87
    def annotate_iter(self, file_id,
 
88
                      default_revision=revision.CURRENT_REVISION):
 
89
        """See Tree.annotate_iter"""
 
90
        text_key = (file_id, self.inventory[file_id].revision)
 
91
        annotations = self._repository.texts.annotate(text_key)
 
92
        return [(key[-1], line) for key, line in annotations]
 
93
 
 
94
    def get_file_size(self, file_id):
 
95
        """See Tree.get_file_size"""
 
96
        return self._inventory[file_id].text_size
 
97
 
 
98
    def get_file_sha1(self, file_id, path=None, stat_value=None):
 
99
        ie = self._inventory[file_id]
 
100
        if ie.kind == "file":
 
101
            return ie.text_sha1
 
102
        return None
 
103
 
 
104
    def get_file_mtime(self, file_id, path=None):
 
105
        ie = self._inventory[file_id]
 
106
        revision = self._repository.get_revision(ie.revision)
 
107
        return revision.timestamp
 
108
 
 
109
    def is_executable(self, file_id, path=None):
 
110
        ie = self._inventory[file_id]
 
111
        if ie.kind != "file":
 
112
            return None
 
113
        return ie.executable
 
114
 
 
115
    def has_filename(self, filename):
 
116
        return bool(self.inventory.path2id(filename))
 
117
 
 
118
    def list_files(self, include_root=False):
 
119
        # The only files returned by this are those from the version
 
120
        entries = self.inventory.iter_entries()
 
121
        # skip the root for compatability with the current apis.
 
122
        if self.inventory.root is not None and not include_root:
 
123
            # skip the root for compatability with the current apis.
 
124
            entries.next()
 
125
        for path, entry in entries:
 
126
            yield path, 'V', entry.kind, entry.file_id, entry
 
127
 
 
128
    def get_symlink_target(self, file_id):
 
129
        ie = self._inventory[file_id]
 
130
        return ie.symlink_target;
 
131
 
 
132
    def get_reference_revision(self, file_id, path=None):
 
133
        return self.inventory[file_id].reference_revision
 
134
 
 
135
    def get_root_id(self):
 
136
        if self.inventory.root:
 
137
            return self.inventory.root.file_id
 
138
 
 
139
    def kind(self, file_id):
 
140
        return self._inventory[file_id].kind
 
141
 
 
142
    def path_content_summary(self, path):
 
143
        """See Tree.path_content_summary."""
 
144
        id = self.inventory.path2id(path)
 
145
        if id is None:
 
146
            return ('missing', None, None, None)
 
147
        entry = self._inventory[id]
 
148
        kind = entry.kind
 
149
        if kind == 'file':
 
150
            return (kind, entry.text_size, entry.executable, entry.text_sha1)
 
151
        elif kind == 'symlink':
 
152
            return (kind, None, None, entry.symlink_target)
 
153
        else:
 
154
            return (kind, None, None, None)
 
155
 
 
156
    def _comparison_data(self, entry, path):
 
157
        if entry is None:
 
158
            return None, False, None
 
159
        return entry.kind, entry.executable, None
 
160
 
 
161
    def _file_size(self, entry, stat_value):
 
162
        return entry.text_size
 
163
 
 
164
    def _get_ancestors(self, default_revision):
 
165
        return set(self._repository.get_ancestry(self._revision_id,
 
166
                                                 topo_sorted=False))
 
167
 
 
168
    def lock_read(self):
 
169
        self._repository.lock_read()
 
170
 
 
171
    def __repr__(self):
 
172
        return '<%s instance at %x, rev_id=%r>' % (
 
173
            self.__class__.__name__, id(self), self._revision_id)
 
174
 
 
175
    def unlock(self):
 
176
        self._repository.unlock()
 
177
 
 
178
    def walkdirs(self, prefix=""):
 
179
        _directory = 'directory'
 
180
        inv = self.inventory
 
181
        top_id = inv.path2id(prefix)
 
182
        if top_id is None:
 
183
            pending = []
 
184
        else:
 
185
            pending = [(prefix, '', _directory, None, top_id, None)]
 
186
        while pending:
 
187
            dirblock = []
 
188
            currentdir = pending.pop()
 
189
            # 0 - relpath, 1- basename, 2- kind, 3- stat, id, v-kind
 
190
            if currentdir[0]:
 
191
                relroot = currentdir[0] + '/'
 
192
            else:
 
193
                relroot = ""
 
194
            # FIXME: stash the node in pending
 
195
            entry = inv[currentdir[4]]
 
196
            for name, child in entry.sorted_children():
 
197
                toppath = relroot + name
 
198
                dirblock.append((toppath, name, child.kind, None,
 
199
                    child.file_id, child.kind
 
200
                    ))
 
201
            yield (currentdir[0], entry.file_id), dirblock
 
202
            # push the user specified dirs from dirblock
 
203
            for dir in reversed(dirblock):
 
204
                if dir[2] == _directory:
 
205
                    pending.append(dir)
 
206
 
 
207
    def _get_rules_searcher(self, default_searcher):
 
208
        """See Tree._get_rules_searcher."""
 
209
        if self._rules_searcher is None:
 
210
            self._rules_searcher = super(RevisionTree,
 
211
                self)._get_rules_searcher(default_searcher)
 
212
        return self._rules_searcher