/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.14.26 by Aaron Bentley
Update copyright
1
# Copyright (C) 2008 Canonical Ltd
0.12.12 by Aaron Bentley
Implement shelf creator
2
#
0.12.80 by Aaron Bentley
Re-format GPL notifications
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
0.12.12 by Aaron Bentley
Implement shelf creator
16
17
0.12.50 by Aaron Bentley
Improve error handling for non-existant shelf-ids
18
import errno
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
19
import re
0.12.13 by Aaron Bentley
Implement shelving content
20
0.14.19 by Aaron Bentley
Convert bzrlib import to split-line
21
from bzrlib import (
0.15.15 by Aaron Bentley
Merge prepare-shelf into unshelve
22
    errors,
23
    merge,
0.14.19 by Aaron Bentley
Convert bzrlib import to split-line
24
    merge3,
25
    osutils,
26
    pack,
27
    transform,
0.15.15 by Aaron Bentley
Merge prepare-shelf into unshelve
28
    ui,
0.16.102 by Aaron Bentley
Minor updates
29
    workingtree,
0.14.19 by Aaron Bentley
Convert bzrlib import to split-line
30
)
0.15.19 by Aaron Bentley
Generalize first record as metadata.
31
from bzrlib.util import bencode
0.12.19 by Aaron Bentley
Add support for writing shelves
32
0.12.12 by Aaron Bentley
Implement shelf creator
33
34
class ShelfCreator(object):
0.14.27 by Aaron Bentley
Update docs
35
    """Create a transform to shelve objects and its inverse."""
0.12.12 by Aaron Bentley
Implement shelf creator
36
0.14.21 by Aaron Bentley
Update to accept a list of files.
37
    def __init__(self, work_tree, target_tree, file_list=None):
0.14.27 by Aaron Bentley
Update docs
38
        """Constructor.
39
40
        :param work_tree: The working tree to apply changes to
41
        :param target_tree: The tree to make the working tree more similar to.
42
        :param file_list: The files to make more similar to the target.
43
        """
0.12.12 by Aaron Bentley
Implement shelf creator
44
        self.work_tree = work_tree
45
        self.work_transform = transform.TreeTransform(work_tree)
3873.2.1 by Benoît Pierre
Clean-up when an error occurs during the creation of a ShelfCreator: fix
46
        try:
4123.1.3 by Aaron Bentley
Properly handle exceptions during __init__
47
            self.target_tree = target_tree
48
            self.shelf_transform = transform.TransformPreview(self.target_tree)
49
            try:
50
                self.renames = {}
51
                self.creation = {}
52
                self.deletion = {}
53
                self.iter_changes = work_tree.iter_changes(
54
                    self.target_tree, specific_files=file_list)
55
            except:
56
                self.shelf_transform.finalize()
57
                raise
58
        except:
59
            self.work_transform.finalize()
60
            raise
0.12.12 by Aaron Bentley
Implement shelf creator
61
0.14.32 by Aaron Bentley
Replace ShelfCreator.__iter__ with ShelfCreator.iter_shelvable
62
    def iter_shelvable(self):
0.14.27 by Aaron Bentley
Update docs
63
        """Iterable of tuples describing shelvable changes.
64
65
        As well as generating the tuples, this updates several members.
66
        Tuples may be:
67
           ('add file', file_id, work_kind, work_path)
68
           ('delete file', file_id, target_kind, target_path)
69
           ('rename', file_id, target_path, work_path)
70
           ('change kind', file_id, target_kind, work_kind, target_path)
71
           ('modify text', file_id)
72
        """
0.12.12 by Aaron Bentley
Implement shelf creator
73
        for (file_id, paths, changed, versioned, parents, names, kind,
74
             executable) in self.iter_changes:
0.12.14 by Aaron Bentley
Add shelving of created files
75
            if kind[0] is None or versioned[0] == False:
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
76
                self.creation[file_id] = (kind[1], names[1], parents[1],
77
                                          versioned)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
78
                yield ('add file', file_id, kind[1], paths[1])
0.14.4 by Aaron Bentley
Implement shelving deletion
79
            elif kind[1] is None or versioned[0] == False:
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
80
                self.deletion[file_id] = (kind[0], names[0], parents[0],
81
                                          versioned)
0.14.13 by Aaron Bentley
Provide path and kind when deletes/adds are detected.
82
                yield ('delete file', file_id, kind[0], paths[0])
0.12.14 by Aaron Bentley
Add shelving of created files
83
            else:
84
                if names[0] != names[1] or parents[0] != parents[1]:
85
                    self.renames[file_id] = (names, parents)
86
                    yield ('rename', file_id) + paths
0.14.23 by Aaron Bentley
Allow shelving kind change
87
88
                if kind[0] != kind [1]:
89
                    yield ('change kind', file_id, kind[0], kind[1], paths[0])
90
                elif changed:
0.12.14 by Aaron Bentley
Add shelving of created files
91
                    yield ('modify text', file_id)
0.12.12 by Aaron Bentley
Implement shelf creator
92
93
    def shelve_rename(self, file_id):
0.14.27 by Aaron Bentley
Update docs
94
        """Shelve a file rename.
95
96
        :param file_id: The file id of the file to shelve the renaming of.
97
        """
0.12.12 by Aaron Bentley
Implement shelf creator
98
        names, parents = self.renames[file_id]
99
        w_trans_id = self.work_transform.trans_id_file_id(file_id)
100
        work_parent = self.work_transform.trans_id_file_id(parents[0])
101
        self.work_transform.adjust_path(names[0], work_parent, w_trans_id)
102
103
        s_trans_id = self.shelf_transform.trans_id_file_id(file_id)
104
        shelf_parent = self.shelf_transform.trans_id_file_id(parents[1])
105
        self.shelf_transform.adjust_path(names[1], shelf_parent, s_trans_id)
106
0.14.14 by Aaron Bentley
Change shelf_text to shelve_lines
107
    def shelve_lines(self, file_id, new_lines):
0.14.27 by Aaron Bentley
Update docs
108
        """Shelve text changes to a file, using provided lines.
109
110
        :param file_id: The file id of the file to shelve the text of.
111
        :param new_lines: The lines that the file should have due to shelving.
112
        """
0.12.13 by Aaron Bentley
Implement shelving content
113
        w_trans_id = self.work_transform.trans_id_file_id(file_id)
114
        self.work_transform.delete_contents(w_trans_id)
115
        self.work_transform.create_file(new_lines, w_trans_id)
116
117
        s_trans_id = self.shelf_transform.trans_id_file_id(file_id)
118
        self.shelf_transform.delete_contents(s_trans_id)
119
        inverse_lines = self._inverse_lines(new_lines, file_id)
120
        self.shelf_transform.create_file(inverse_lines, s_trans_id)
121
0.14.23 by Aaron Bentley
Allow shelving kind change
122
    @staticmethod
123
    def _content_from_tree(tt, tree, file_id):
124
        trans_id = tt.trans_id_file_id(file_id)
125
        tt.delete_contents(trans_id)
126
        transform.create_from_tree(tt, trans_id, tree, file_id)
127
128
    def shelve_content_change(self, file_id):
0.14.27 by Aaron Bentley
Update docs
129
        """Shelve a kind change or binary file content change.
130
131
        :param file_id: The file id of the file to shelve the content change
132
            of.
133
        """
0.14.23 by Aaron Bentley
Allow shelving kind change
134
        self._content_from_tree(self.work_transform, self.target_tree, file_id)
135
        self._content_from_tree(self.shelf_transform, self.work_tree, file_id)
136
0.14.2 by Aaron Bentley
Somewhat clean up shelving
137
    def shelve_creation(self, file_id):
0.14.27 by Aaron Bentley
Update docs
138
        """Shelve creation of a file.
139
140
        This handles content and inventory id.
141
        :param file_id: The file_id of the file to shelve creation of.
142
        """
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
143
        kind, name, parent, versioned = self.creation[file_id]
144
        version = not versioned[0]
0.14.4 by Aaron Bentley
Implement shelving deletion
145
        self._shelve_creation(self.work_tree, file_id, self.work_transform,
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
146
                              self.shelf_transform, kind, name, parent,
147
                              version)
0.14.4 by Aaron Bentley
Implement shelving deletion
148
149
    def shelve_deletion(self, file_id):
0.14.27 by Aaron Bentley
Update docs
150
        """Shelve deletion of a file.
151
152
        This handles content and inventory id.
153
        :param file_id: The file_id of the file to shelve deletion of.
154
        """
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
155
        kind, name, parent, versioned = self.deletion[file_id]
156
        existing_path = self.target_tree.id2path(file_id)
157
        if not self.work_tree.has_filename(existing_path):
158
            existing_path = None
159
        version = not versioned[1]
0.14.4 by Aaron Bentley
Implement shelving deletion
160
        self._shelve_creation(self.target_tree, file_id, self.shelf_transform,
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
161
                              self.work_transform, kind, name, parent,
162
                              version, existing_path=existing_path)
0.14.4 by Aaron Bentley
Implement shelving deletion
163
164
    def _shelve_creation(self, tree, file_id, from_transform, to_transform,
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
165
                         kind, name, parent, version, existing_path=None):
0.14.4 by Aaron Bentley
Implement shelving deletion
166
        w_trans_id = from_transform.trans_id_file_id(file_id)
0.14.12 by Aaron Bentley
Handle new dangling ids
167
        if parent is not None and kind is not None:
0.14.4 by Aaron Bentley
Implement shelving deletion
168
            from_transform.delete_contents(w_trans_id)
169
        from_transform.unversion_file(w_trans_id)
170
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
171
        if existing_path is not None:
172
            s_trans_id = to_transform.trans_id_tree_path(existing_path)
173
        else:
174
            s_trans_id = to_transform.trans_id_file_id(file_id)
0.14.4 by Aaron Bentley
Implement shelving deletion
175
        if parent is not None:
176
            s_parent_id = to_transform.trans_id_file_id(parent)
0.14.9 by Aaron Bentley
Shelve deleted files properly
177
            to_transform.adjust_path(name, s_parent_id, s_trans_id)
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
178
            if existing_path is None:
0.14.18 by Aaron Bentley
Simplify creating files
179
                if kind is None:
0.14.12 by Aaron Bentley
Handle new dangling ids
180
                    to_transform.create_file('', s_trans_id)
0.14.18 by Aaron Bentley
Simplify creating files
181
                else:
182
                    transform.create_from_tree(to_transform, s_trans_id,
183
                                               tree, file_id)
0.14.10 by Aaron Bentley
Fix behavior with deletions, unversioning, ...
184
        if version:
185
            to_transform.version_file(file_id, s_trans_id)
0.12.14 by Aaron Bentley
Add shelving of created files
186
187
    def _inverse_lines(self, new_lines, file_id):
188
        """Produce a version with only those changes removed from new_lines."""
0.14.1 by Aaron Bentley
Use explicit target in ShelfCreator
189
        target_lines = self.target_tree.get_file_lines(file_id)
0.14.37 by Aaron Bentley
Switch from read_tree_lines to tree.get_file_lines.
190
        work_lines = self.work_tree.get_file_lines(file_id)
0.14.1 by Aaron Bentley
Use explicit target in ShelfCreator
191
        return merge3.Merge3(new_lines, target_lines, work_lines).merge_lines()
0.12.13 by Aaron Bentley
Implement shelving content
192
0.12.12 by Aaron Bentley
Implement shelf creator
193
    def finalize(self):
0.14.27 by Aaron Bentley
Update docs
194
        """Release all resources used by this ShelfCreator."""
0.12.12 by Aaron Bentley
Implement shelf creator
195
        self.work_transform.finalize()
196
        self.shelf_transform.finalize()
0.12.13 by Aaron Bentley
Implement shelving content
197
198
    def transform(self):
0.14.27 by Aaron Bentley
Update docs
199
        """Shelve changes from working tree."""
0.12.13 by Aaron Bentley
Implement shelving content
200
        self.work_transform.apply()
0.12.19 by Aaron Bentley
Add support for writing shelves
201
0.12.51 by Aaron Bentley
Merge unshelve into shelf-manager
202
    def write_shelf(self, shelf_file, message=None):
0.14.27 by Aaron Bentley
Update docs
203
        """Serialize the shelved changes to a file.
204
0.12.66 by Aaron Bentley
Merge with unshelve
205
        :param shelf_file: A file-like object to write the shelf to.
0.15.29 by Aaron Bentley
Merge with prepare-shelf
206
        :param message: An optional message describing the shelved changes.
0.14.27 by Aaron Bentley
Update docs
207
        :return: the filename of the written file.
208
        """
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
209
        transform.resolve_conflicts(self.shelf_transform)
0.12.28 by Aaron Bentley
Update for shelf manager
210
        serializer = pack.ContainerSerialiser()
211
        shelf_file.write(serializer.begin())
0.12.51 by Aaron Bentley
Merge unshelve into shelf-manager
212
        metadata = {
213
            'revision_id': self.target_tree.get_revision_id(),
214
        }
215
        if message is not None:
0.12.52 by Aaron Bentley
Merge unshelve into shelf-manager
216
            metadata['message'] = message.encode('utf-8')
0.12.28 by Aaron Bentley
Update for shelf manager
217
        shelf_file.write(serializer.bytes_record(
0.12.51 by Aaron Bentley
Merge unshelve into shelf-manager
218
            bencode.bencode(metadata), (('metadata',),)))
0.12.63 by Aaron Bentley
Merge with unshelve
219
        for bytes in self.shelf_transform.serialize(serializer):
0.12.28 by Aaron Bentley
Update for shelf manager
220
            shelf_file.write(bytes)
221
        shelf_file.write(serializer.end())
0.12.21 by Aaron Bentley
Add failing test of unshelver
222
223
224
class Unshelver(object):
0.15.30 by Aaron Bentley
Update docs.
225
    """Unshelve shelved changes."""
0.12.21 by Aaron Bentley
Add failing test of unshelver
226
0.15.19 by Aaron Bentley
Generalize first record as metadata.
227
    def __init__(self, tree, base_tree, transform, message):
0.15.30 by Aaron Bentley
Update docs.
228
        """Constructor.
229
230
        :param tree: The tree to apply the changes to.
231
        :param base_tree: The basis to apply the tranform to.
232
        :param message: A message from the shelved transform.
233
        """
0.12.21 by Aaron Bentley
Add failing test of unshelver
234
        self.tree = tree
0.12.24 by Aaron Bentley
Get unshelve using merge codepath, not applying transform directly
235
        self.base_tree = base_tree
0.12.21 by Aaron Bentley
Add failing test of unshelver
236
        self.transform = transform
0.15.19 by Aaron Bentley
Generalize first record as metadata.
237
        self.message = message
0.12.21 by Aaron Bentley
Add failing test of unshelver
238
0.16.110 by Aaron Bentley
Implement ls-shelf command
239
    @staticmethod
240
    def iter_records(shelf_file):
0.12.21 by Aaron Bentley
Add failing test of unshelver
241
        parser = pack.ContainerPushParser()
0.12.28 by Aaron Bentley
Update for shelf manager
242
        parser.accept_bytes(shelf_file.read())
0.16.110 by Aaron Bentley
Implement ls-shelf command
243
        return iter(parser.read_pending_records())
244
245
    @staticmethod
246
    def parse_metadata(records):
0.15.19 by Aaron Bentley
Generalize first record as metadata.
247
        names, metadata_bytes = records.next()
0.15.41 by Aaron Bentley
Replace assert with proper error handling
248
        if names[0] != ('metadata',):
249
            raise errors.ShelfCorrupt
0.15.19 by Aaron Bentley
Generalize first record as metadata.
250
        metadata = bencode.bdecode(metadata_bytes)
251
        message = metadata.get('message')
252
        if message is not None:
0.16.111 by Aaron Bentley
Return metadata as a dict.
253
            metadata['message'] = message.decode('utf-8')
254
        return metadata
0.16.110 by Aaron Bentley
Implement ls-shelf command
255
256
    @classmethod
257
    def from_tree_and_shelf(klass, tree, shelf_file):
258
        """Create an Unshelver from a tree and a shelf file.
259
260
        :param tree: The tree to apply shelved changes to.
261
        :param shelf_file: A file-like object containing shelved changes.
262
        :return: The Unshelver.
263
        """
264
        records = klass.iter_records(shelf_file)
0.16.111 by Aaron Bentley
Return metadata as a dict.
265
        metadata = klass.parse_metadata(records)
266
        base_revision_id = metadata['revision_id']
0.12.26 by Aaron Bentley
Use correct base for shelving
267
        try:
268
            base_tree = tree.revision_tree(base_revision_id)
269
        except errors.NoSuchRevisionInTree:
270
            base_tree = tree.branch.repository.revision_tree(base_revision_id)
0.15.23 by Aaron Bentley
Use correct tree for desrializing transform
271
        tt = transform.TransformPreview(base_tree)
0.15.26 by Aaron Bentley
Merge with prepare-shelf
272
        tt.deserialize(records)
0.16.111 by Aaron Bentley
Return metadata as a dict.
273
        return klass(tree, base_tree, tt, metadata.get('message'))
0.12.21 by Aaron Bentley
Add failing test of unshelver
274
1551.21.7 by Aaron Bentley
Fix progress warning
275
    def make_merger(self, task=None):
0.15.30 by Aaron Bentley
Update docs.
276
        """Return a merger that can unshelve the changes."""
1551.21.7 by Aaron Bentley
Fix progress warning
277
        target_tree = self.transform.get_preview_tree()
278
        merger = merge.Merger.from_uncommitted(self.tree, target_tree,
279
            task, self.base_tree)
280
        merger.merge_type = merge.Merge3Merger
281
        return merger
0.12.25 by Aaron Bentley
Update to use new from_uncommitted API
282
283
    def finalize(self):
0.15.30 by Aaron Bentley
Update docs.
284
        """Release all resources held by this Unshelver."""
0.12.25 by Aaron Bentley
Update to use new from_uncommitted API
285
        self.transform.finalize()
0.12.27 by Aaron Bentley
Implement shelf manager
286
287
288
class ShelfManager(object):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
289
    """Maintain a list of shelved changes."""
0.12.27 by Aaron Bentley
Implement shelf manager
290
0.12.42 by Aaron Bentley
Get shelf from tree
291
    def __init__(self, tree, transport):
292
        self.tree = tree
0.12.41 by Aaron Bentley
Change shelf to use WT control dir for shelves
293
        self.transport = transport.clone('shelf')
0.12.27 by Aaron Bentley
Implement shelf manager
294
        self.transport.ensure_base()
295
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
296
    def get_shelf_filename(self, shelf_id):
297
        return 'shelf-%d' % shelf_id
298
299
    def get_shelf_ids(self, filenames):
300
        matcher = re.compile('shelf-([1-9][0-9]*)')
301
        shelf_ids = []
302
        for filename in filenames:
303
            match = matcher.match(filename)
304
            if match is not None:
305
                shelf_ids.append(int(match.group(1)))
306
        return shelf_ids
307
0.12.27 by Aaron Bentley
Implement shelf manager
308
    def new_shelf(self):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
309
        """Return a file object and id for a new set of shelved changes."""
0.12.27 by Aaron Bentley
Implement shelf manager
310
        last_shelf = self.last_shelf()
311
        if last_shelf is None:
312
            next_shelf = 1
313
        else:
314
            next_shelf = last_shelf + 1
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
315
        filename = self.get_shelf_filename(next_shelf)
316
        shelf_file = open(self.transport.local_abspath(filename), 'wb')
0.12.27 by Aaron Bentley
Implement shelf manager
317
        return next_shelf, shelf_file
318
0.12.53 by Aaron Bentley
Allow adding message to shelf
319
    def shelve_changes(self, creator, message=None):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
320
        """Store the changes in a ShelfCreator on a shelf."""
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
321
        next_shelf, shelf_file = self.new_shelf()
322
        try:
0.12.53 by Aaron Bentley
Allow adding message to shelf
323
            creator.write_shelf(shelf_file, message)
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
324
        finally:
325
            shelf_file.close()
0.12.44 by Aaron Bentley
Give manager responsibility for applying transform
326
        creator.transform()
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
327
        return next_shelf
328
0.12.27 by Aaron Bentley
Implement shelf manager
329
    def read_shelf(self, shelf_id):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
330
        """Return the file associated with a shelf_id for reading.
331
332
        :param shelf_id: The id of the shelf to retrive the file for.
333
        """
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
334
        filename = self.get_shelf_filename(shelf_id)
0.12.50 by Aaron Bentley
Improve error handling for non-existant shelf-ids
335
        try:
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
336
            return open(self.transport.local_abspath(filename), 'rb')
0.12.50 by Aaron Bentley
Improve error handling for non-existant shelf-ids
337
        except IOError, e:
338
            if e.errno != errno.ENOENT:
339
                raise
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
340
            from bzrlib import errors
341
            raise errors.NoSuchShelfId(shelf_id)
0.12.27 by Aaron Bentley
Implement shelf manager
342
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
343
    def get_unshelver(self, shelf_id):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
344
        """Return an unshelver for a given shelf_id.
345
346
        :param shelf_id: The shelf id to return the unshelver for.
347
        """
0.12.43 by Aaron Bentley
Make ShelfManager consume ShelfCreator and produce Unshelver
348
        shelf_file = self.read_shelf(shelf_id)
349
        try:
350
            return Unshelver.from_tree_and_shelf(self.tree, shelf_file)
351
        finally:
352
            shelf_file.close()
353
0.16.112 by Aaron Bentley
Add tests
354
    def get_metadata(self, shelf_id):
355
        """Return the metadata associated with a given shelf_id."""
0.16.110 by Aaron Bentley
Implement ls-shelf command
356
        shelf_file = self.read_shelf(shelf_id)
357
        try:
358
            records = Unshelver.iter_records(shelf_file)
359
        finally:
360
            shelf_file.close()
361
        return Unshelver.parse_metadata(records)
362
0.12.27 by Aaron Bentley
Implement shelf manager
363
    def delete_shelf(self, shelf_id):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
364
        """Delete the shelved changes for a given id.
365
366
        :param shelf_id: id of the shelved changes to delete.
367
        """
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
368
        filename = self.get_shelf_filename(shelf_id)
369
        self.transport.delete(filename)
0.12.27 by Aaron Bentley
Implement shelf manager
370
371
    def active_shelves(self):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
372
        """Return a list of shelved changes."""
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
373
        active = self.get_shelf_ids(self.transport.list_dir('.'))
374
        active.sort()
375
        return active
0.12.27 by Aaron Bentley
Implement shelf manager
376
377
    def last_shelf(self):
0.12.68 by Aaron Bentley
Update docs, move items to proper files.
378
        """Return the id of the last-created shelved change."""
0.12.27 by Aaron Bentley
Implement shelf manager
379
        active = self.active_shelves()
380
        if len(active) > 0:
0.12.77 by Aaron Bentley
Use names of the form shelf-5 for shelves
381
            return active[-1]
0.12.27 by Aaron Bentley
Implement shelf manager
382
        else:
383
            return None