17
17
"""Utility for create branches with particular contents."""
19
from bzrlib import bzrdir, errors, memorytree
22
27
class BranchBuilder(object):
23
"""A BranchBuilder aids creating Branches with particular shapes.
28
r"""A BranchBuilder aids creating Branches with particular shapes.
25
30
The expected way to use BranchBuilder is to construct a
26
31
BranchBuilder on the transport you want your branch on, and then call
33
builder = BranchBuilder(self.get_transport().clone('relpath'))
34
builder.start_series()
35
builder.build_snapshot('rev-id', [],
36
[('add', ('filename', 'f-id', 'file', 'content\n'))])
37
builder.build_snapshot('rev2-id', ['rev-id'],
38
[('modify', ('f-id', 'new-content\n'))])
39
builder.finish_series()
40
branch = builder.get_branch()
39
>>> from bzrlib.transport.memory import MemoryTransport
40
>>> builder = BranchBuilder(MemoryTransport("memory:///"))
41
>>> builder.start_series()
42
>>> builder.build_snapshot('rev-id', None, [
43
... ('add', ('', 'root-id', 'directory', '')),
44
... ('add', ('filename', 'f-id', 'file', 'content\n'))])
46
>>> builder.build_snapshot('rev2-id', ['rev-id'],
47
... [('modify', ('f-id', 'new-content\n'))])
49
>>> builder.finish_series()
50
>>> branch = builder.get_branch()
42
52
:ivar _tree: This is a private member which is not meant to be modified by
43
53
users of this class. While a 'series' is in progress, it should hold a
74
return tree.commit('commit %d' % (self._branch.revno() + 1))
84
return self._do_commit(tree)
88
def _do_commit(self, tree, message=None, **kwargs):
89
reporter = commit.NullCommitReporter()
91
message = u'commit %d' % (self._branch.revno() + 1,)
92
return tree.commit(message,
78
96
def _move_branch_pointer(self, new_revision_id):
79
97
"""Point self._branch to a different revision id."""
80
98
self._branch.lock_write()
129
147
('add', ('path', 'file-id', 'kind', 'content' or None))
130
148
('modify', ('file-id', 'new-content'))
131
149
('unversion', 'file-id')
132
# not supported yet: ('rename', ('orig-path', 'new-path'))
150
('rename', ('orig-path', 'new-path'))
133
151
:param message: An optional commit message, if not supplied, a default
134
152
commit message will be written.
135
153
:return: The revision_id of the new commit
157
175
to_add_kinds = []
158
176
new_contents = {}
159
177
to_unversion_ids = []
160
# TODO: MemoryTree doesn't support rename() or
161
# apply_inventory_delta, so we'll postpone allowing renames
164
179
for action, info in actions:
165
180
if action == 'add':
166
181
path, file_id, kind, content = info
177
192
new_contents[file_id] = content
178
193
elif action == 'unversion':
179
194
to_unversion_ids.append(info)
195
elif action == 'rename':
196
from_relpath, to_relpath = info
197
to_rename.append((from_relpath, to_relpath))
181
199
raise ValueError('Unknown build action: "%s"' % (action,))
182
200
if to_unversion_ids:
187
205
tree.add([path], [file_id], ['directory'])
189
207
tree.mkdir(path, file_id)
208
for from_relpath, to_relpath in to_rename:
209
tree.rename_one(from_relpath, to_relpath)
190
210
tree.add(to_add_files, to_add_file_ids, to_add_kinds)
191
211
for file_id, content in new_contents.iteritems():
192
212
tree.put_file_bytes_non_atomic(file_id, content)
195
message = u'commit %d' % (self._branch.revno() + 1,)
196
return tree.commit(message, rev_id=revision_id)
213
return self._do_commit(tree, message=message, rev_id=revision_id)