60
56
def init_workspace(location, model=None, format=None, create_parent_dirs=False,
61
trunk_name='trunk', work_name='work', outf=None):
57
outf=None, model_params=None):
62
58
"""Initialise a workspace.
64
60
:param location: base location of the workspace
65
:param model: one of the following:
66
* feature-branches - create a shared repository at location
67
then create a trunk branch inside it (default)
68
* shared-tree - create a (no-trees) shared repository at location,
69
then create a trunk branch and separate working tree
70
(lightweight checkout) inside it
71
* plain-branch - create a plain branch at location; if inside a
72
shared repository, that will be used, otherwise the branch will
73
be a standalone branch
74
* shared-repo - create a shared repository at location
75
* shared-repo-no-trees - create a shared repository at location
76
and configure it so branches have no trees
61
:param model: the workspace model to use
77
62
:param format: storage format to use
78
63
:param create_parent_dirs: create parent directories of location if
79
64
they don't already exist
80
:param trunk_name: name of trunk branch for feature-branches and
82
:param work_name: name of trunk branch for feature-branches and
84
65
:param outf: output stream; if None, standard output is used
66
:param model_params: a dictionary of model-specific parameters
86
# Assign defaults to parameters
88
model = MODEL_FEATURE_BRANCHES
70
model = workspace_model_registry.get()
90
72
format = bzrdir.format_registry.make_bzrdir('default')
95
77
# Create the parent directories if required
96
78
_ensure_base_of_location(location, create_parent_dirs)
98
# For feature branching, we need to start with a trunk
99
# branch in a shared repository
100
if model == MODEL_FEATURE_BRANCHES:
101
trunk_location = osutils.pathjoin(location, trunk_name)
102
_init_repository(outf, location, format)
103
_init_branch(outf, trunk_location, format)
105
# For the shared tree model, we start with a treeless shared repository,
106
# create a trunk branch and then a work checkout pointing to that trunk
107
elif model == MODEL_SHARED_TREE:
108
trunk_location = osutils.pathjoin(location, trunk_name)
109
work_location = osutils.pathjoin(location, work_name)
110
_init_repository(outf, location, format, no_trees=True)
111
_init_branch(outf, trunk_location, format)
112
_init_working_tree(outf, trunk_location, work_location)
114
elif model == MODEL_PLAIN_BRANCH:
115
_init_branch(outf, location, format)
116
elif model == MODEL_SHARED_REPO:
117
_init_repository(outf, location, format)
118
elif model == MODEL_SHARED_REPO_NO_TREES:
119
_init_repository(outf, location, format, no_trees=True)
83
model_params = dict([(k.replace('-', '_'), v)
84
for k, v in model_params.items()])
121
raise UnknownWorkspaceModel(model)
87
repo_dir, branch_dir, tree_dir = ws_model.build(outf, location,
88
format, **model_params)
90
# Move existing files if this is required
91
#if tree_dir != location:
92
# mutter("moving files from %s to %s" % (location, tree_dir))
124
95
def _ensure_base_of_location(location, create_parent_dirs):
179
152
# setup a fresh one here
180
153
cmd_obj.outf = outf
157
## The workspace model registry ##
159
class WorkspaceModel(object):
160
"""Abstract workspace model.
162
The following attributes may be defined:
164
* title - the label for this model in the GUI
165
* just_repository - if True, this model only creates a repository
166
* parameters - a list of model-specific options
170
just_repository = False
173
def build(self, outf, location, format, **model_params):
174
"""Build a workspace.
176
:param outf: the output file for reporting actions
177
:param location: the location of the workspace
178
:param format: the format to use
179
:param model_params: model-specific parameters
180
:return: repo_dir, branch_dir, tree_dir - the directories
181
created for the various parts, if any.
183
raise NotImplementedError(WorkspaceModel.build)
186
class WorkspaceModelRegistry(registry.Registry):
187
"""Registry for workspace models.
189
The registered object should be a WorkspaceModel.
190
The doc-string for the registered object will be used as help by default.
193
def get_help(self, key=None):
194
result = registry.Registry.get_help(self, key)
196
from inspect import getdoc
197
model = self.get(key)
198
result = getdoc(model)
202
workspace_model_registry = WorkspaceModelRegistry()
205
## Standard workspace models ##
207
class FeatureBranchesWorkspaceModel(WorkspaceModel):
208
"""Create a shared repository at location then create a trunk branch inside it."""
210
title = "Feature branches"
212
Option('with-shared-tree',
213
help='Create a work checkout to share across branches.'),
216
def build(self, outf, location, format, with_shared_tree=False):
217
trunk_location = osutils.pathjoin(location, 'trunk')
219
work_location = osutils.pathjoin(location, 'work')
220
init_repository(outf, location, format, no_trees=True)
221
init_branch(outf, trunk_location, format)
222
init_working_tree(outf, trunk_location, work_location)
224
init_repository(outf, location, format)
225
init_branch(outf, trunk_location, format)
226
work_location = trunk_location
227
return location, trunk_location, work_location
230
_repo_in_registry = registry.Registry()
231
_repo_in_registry.register(".bzrbranches", ".bzrbranches",
232
help="Put repository in .bzrbranches")
233
_repo_in_registry.register(".bzr/branches", ".bzr/branches",
234
help="Put repository in .bzr/branches")
235
_repo_in_registry.default_key = ".bzrbranches"
238
class ColocatedBranchesWorkspaceModel(WorkspaceModel):
239
"""Create a working tree at location pointing to a trunk branch
240
in an embedded (no-trees) shared repository.
243
title = "Colocated branches"
245
RegistryOption('repository-location',
246
registry=_repo_in_registry,
247
help="Location for the shared repository."),
250
def build(self, outf, location, format, repository_location=None):
251
if repository_location is None:
252
repository_location = _repo_in_registry.get()
253
if repository_location == '.bzrbranches':
254
repo_location = osutils.pathjoin(location, ".bzrbranches")
255
trunk_location = osutils.pathjoin(repo_location, 'trunk')
256
init_repository(outf, repo_location, format, no_trees=True)
257
init_branch(outf, trunk_location, format)
258
init_working_tree(outf, trunk_location, location)
260
# Note: These os calls should become transport calls to
261
# ensure this works on non-local transports ...
262
bzr_location = osutils.pathjoin(location, ".bzr")
263
os.mkdir(bzr_location)
264
repo_location = osutils.pathjoin(bzr_location, "branches")
265
trunk_location = osutils.pathjoin(repo_location, 'trunk')
266
init_repository(outf, repo_location, format, no_trees=True)
267
init_branch(outf, trunk_location, format)
268
# Move the .bzr directory aside so we can create the checkout
269
tmp_location = osutils.pathjoin(location, ".bzr-tmp")
270
os.rename(bzr_location, tmp_location)
272
tmp_repo = osutils.pathjoin(tmp_location, "branches")
273
tmp_trunk = osutils.pathjoin(tmp_repo, "trunk")
274
init_working_tree(outf, tmp_trunk, location)
275
# Now move the repository into the .bzr directory.
276
os.rename(tmp_repo, repo_location)
278
os.rmdir(tmp_location)
279
# Update the checkout reference
280
self._switch_checkout(location, trunk_location)
281
return repo_location, trunk_location, location
283
def _switch_checkout(self, checkout_location, branch_location):
284
from bzrlib.branch import Branch
285
control = bzrdir.BzrDir.open(checkout_location)
286
to_branch = Branch.open(branch_location)
287
control.find_branch_format().set_reference(control, to_branch)
290
class PlainBranchWorkspaceModel(WorkspaceModel):
291
"""Create a plain branch at location;
292
if inside a shared repository, that will be used,
293
otherwise the branch will be a standalone branch.
296
title = "Plain branch"
298
def build(self, outf, location, format):
299
init_branch(outf, location, format)
300
return None, location, location
303
class SharedRepoWorkspaceModel(WorkspaceModel):
304
"""Create a shared repository at location."""
306
title = "Shared repository"
307
just_repository = True
310
help='Branches in the repository will default to'
311
' not having a working tree.'),
314
def build(self, outf, location, format, no_trees=False):
315
init_repository(outf, location, format, no_trees=no_trees)
316
return location, None, None
319
workspace_model_registry.register("feature-branches",
320
FeatureBranchesWorkspaceModel)
321
workspace_model_registry.register("colocated-branches",
322
ColocatedBranchesWorkspaceModel)
323
workspace_model_registry.register("plain-branch", PlainBranchWorkspaceModel)
324
workspace_model_registry.register("shared-repository", SharedRepoWorkspaceModel)
325
workspace_model_registry.default_key = "feature-branches"