~bzr-pqm/bzr/bzr.dev

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