Merge lp:~jelmer/bzr/weave-plugin into lp:bzr

Proposed by Jelmer Vernooij
Status: Superseded
Proposed branch: lp:~jelmer/bzr/weave-plugin
Merge into: lp:bzr
Prerequisite: lp:~jelmer/bzr/blackbox-upgrade-formats
Diff against target: 4068 lines (+1953/-1726)
23 files modified
bzrlib/branch.py (+0/-4)
bzrlib/bzrdir.py (+0/-933)
bzrlib/plugins/weave_fmt/__init__.py (+114/-0)
bzrlib/plugins/weave_fmt/branch.py (+4/-2)
bzrlib/plugins/weave_fmt/bzrdir.py (+969/-0)
bzrlib/plugins/weave_fmt/repository.py (+11/-5)
bzrlib/plugins/weave_fmt/test_bzrdir.py (+512/-0)
bzrlib/plugins/weave_fmt/test_repository.py (+329/-0)
bzrlib/plugins/weave_fmt/test_workingtree.py (+1/-1)
bzrlib/plugins/weave_fmt/workingtree.py (+1/-1)
bzrlib/repository.py (+1/-32)
bzrlib/serializer.py (+0/-1)
bzrlib/tests/__init__.py (+0/-1)
bzrlib/tests/blackbox/test_break_lock.py (+0/-9)
bzrlib/tests/blackbox/test_info.py (+0/-83)
bzrlib/tests/per_repository/test_repository.py (+0/-18)
bzrlib/tests/test_bzrdir.py (+0/-64)
bzrlib/tests/test_repository.py (+11/-220)
bzrlib/tests/test_serializer.py (+0/-3)
bzrlib/tests/test_sftp_transport.py (+0/-14)
bzrlib/tests/test_upgrade.py (+0/-287)
bzrlib/tests/test_xml.py (+0/-43)
bzrlib/workingtree.py (+0/-5)
To merge this branch: bzr merge lp:~jelmer/bzr/weave-plugin
Reviewer Review Type Date Requested Status
bzr-core Pending
Review via email: mp+51301@code.launchpad.net

This proposal has been superseded by a proposal from 2011-03-10.

Description of the change

Move the weave-era formats into a plugin. This should make avoid some unnecessary overhead loading these formats unless they're actually used and make it easier for users to disable the weave formats completely.

To post a comment you must log in.
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

This branch looks scary but it's mainly moving code around to bzrlib.plugins.weave_fmt...

Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Unfortunately I can only set one prerequisite branch, another prerequisite is lp:~jelmer/bzr/repository-format-deprecation

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bzrlib/branch.py'
2--- bzrlib/branch.py 2011-03-08 00:04:05 +0000
3+++ bzrlib/branch.py 2011-03-09 01:37:04 +0000
4@@ -2349,10 +2349,6 @@
5 format_registry.register(__format7)
6 format_registry.register(__format8)
7 format_registry.set_default(__format7)
8-format_registry.register_extra_lazy("bzrlib.branch_weave",
9- "BzrBranchFormat4")
10-network_format_registry.register_lazy("Bazaar-NG branch, format 6\n",
11- "bzrlib.branch_weave", "BzrBranchFormat4")
12
13
14 class BranchWriteLockResult(LogicalLockResult):
15
16=== modified file 'bzrlib/bzrdir.py'
17--- bzrlib/bzrdir.py 2011-03-08 17:40:26 +0000
18+++ bzrlib/bzrdir.py 2011-03-09 01:37:04 +0000
19@@ -27,9 +27,7 @@
20
21 # TODO: Move old formats into a plugin to make this file smaller.
22
23-import os
24 import sys
25-import warnings
26
27 from bzrlib.lazy_import import lazy_import
28 lazy_import(globals(), """
29@@ -55,13 +53,9 @@
30 win32utils,
31 workingtree,
32 workingtree_4,
33- xml4,
34- xml5,
35 )
36 from bzrlib.repofmt import pack_repo
37 from bzrlib.smart.client import _SmartClient
38-from bzrlib.store.versioned import VersionedFileStore
39-from bzrlib.transactions import WriteTransaction
40 from bzrlib.transport import (
41 do_catching_redirections,
42 local,
43@@ -73,9 +67,7 @@
44 """)
45
46 from bzrlib.trace import (
47- mutter,
48 note,
49- warning,
50 )
51
52 from bzrlib import (
53@@ -1016,268 +1008,6 @@
54 self.bzrdir)
55
56
57-class BzrDirPreSplitOut(BzrDir):
58- """A common class for the all-in-one formats."""
59-
60- def __init__(self, _transport, _format):
61- """See BzrDir.__init__."""
62- super(BzrDirPreSplitOut, self).__init__(_transport, _format)
63- self._control_files = lockable_files.LockableFiles(
64- self.get_branch_transport(None),
65- self._format._lock_file_name,
66- self._format._lock_class)
67-
68- def break_lock(self):
69- """Pre-splitout bzrdirs do not suffer from stale locks."""
70- raise NotImplementedError(self.break_lock)
71-
72- def cloning_metadir(self, require_stacking=False):
73- """Produce a metadir suitable for cloning with."""
74- if require_stacking:
75- return controldir.format_registry.make_bzrdir('1.6')
76- return self._format.__class__()
77-
78- def clone(self, url, revision_id=None, force_new_repo=False,
79- preserve_stacking=False):
80- """See BzrDir.clone().
81-
82- force_new_repo has no effect, since this family of formats always
83- require a new repository.
84- preserve_stacking has no effect, since no source branch using this
85- family of formats can be stacked, so there is no stacking to preserve.
86- """
87- self._make_tail(url)
88- result = self._format._initialize_for_clone(url)
89- self.open_repository().clone(result, revision_id=revision_id)
90- from_branch = self.open_branch()
91- from_branch.clone(result, revision_id=revision_id)
92- try:
93- tree = self.open_workingtree()
94- except errors.NotLocalUrl:
95- # make a new one, this format always has to have one.
96- result._init_workingtree()
97- else:
98- tree.clone(result)
99- return result
100-
101- def create_branch(self, name=None, repository=None):
102- """See BzrDir.create_branch."""
103- if repository is not None:
104- raise NotImplementedError(
105- "create_branch(repository=<not None>) on %r" % (self,))
106- return self._format.get_branch_format().initialize(self, name=name)
107-
108- def destroy_branch(self, name=None):
109- """See BzrDir.destroy_branch."""
110- raise errors.UnsupportedOperation(self.destroy_branch, self)
111-
112- def create_repository(self, shared=False):
113- """See BzrDir.create_repository."""
114- if shared:
115- raise errors.IncompatibleFormat('shared repository', self._format)
116- return self.open_repository()
117-
118- def destroy_repository(self):
119- """See BzrDir.destroy_repository."""
120- raise errors.UnsupportedOperation(self.destroy_repository, self)
121-
122- def create_workingtree(self, revision_id=None, from_branch=None,
123- accelerator_tree=None, hardlink=False):
124- """See BzrDir.create_workingtree."""
125- # The workingtree is sometimes created when the bzrdir is created,
126- # but not when cloning.
127-
128- # this looks buggy but is not -really-
129- # because this format creates the workingtree when the bzrdir is
130- # created
131- # clone and sprout will have set the revision_id
132- # and that will have set it for us, its only
133- # specific uses of create_workingtree in isolation
134- # that can do wonky stuff here, and that only
135- # happens for creating checkouts, which cannot be
136- # done on this format anyway. So - acceptable wart.
137- if hardlink:
138- warning("can't support hardlinked working trees in %r"
139- % (self,))
140- try:
141- result = self.open_workingtree(recommend_upgrade=False)
142- except errors.NoSuchFile:
143- result = self._init_workingtree()
144- if revision_id is not None:
145- if revision_id == _mod_revision.NULL_REVISION:
146- result.set_parent_ids([])
147- else:
148- result.set_parent_ids([revision_id])
149- return result
150-
151- def _init_workingtree(self):
152- from bzrlib.workingtree_2 import WorkingTreeFormat2
153- try:
154- return WorkingTreeFormat2().initialize(self)
155- except errors.NotLocalUrl:
156- # Even though we can't access the working tree, we need to
157- # create its control files.
158- return WorkingTreeFormat2()._stub_initialize_on_transport(
159- self.transport, self._control_files._file_mode)
160-
161- def destroy_workingtree(self):
162- """See BzrDir.destroy_workingtree."""
163- raise errors.UnsupportedOperation(self.destroy_workingtree, self)
164-
165- def destroy_workingtree_metadata(self):
166- """See BzrDir.destroy_workingtree_metadata."""
167- raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
168- self)
169-
170- def get_branch_transport(self, branch_format, name=None):
171- """See BzrDir.get_branch_transport()."""
172- if name is not None:
173- raise errors.NoColocatedBranchSupport(self)
174- if branch_format is None:
175- return self.transport
176- try:
177- branch_format.get_format_string()
178- except NotImplementedError:
179- return self.transport
180- raise errors.IncompatibleFormat(branch_format, self._format)
181-
182- def get_repository_transport(self, repository_format):
183- """See BzrDir.get_repository_transport()."""
184- if repository_format is None:
185- return self.transport
186- try:
187- repository_format.get_format_string()
188- except NotImplementedError:
189- return self.transport
190- raise errors.IncompatibleFormat(repository_format, self._format)
191-
192- def get_workingtree_transport(self, workingtree_format):
193- """See BzrDir.get_workingtree_transport()."""
194- if workingtree_format is None:
195- return self.transport
196- try:
197- workingtree_format.get_format_string()
198- except NotImplementedError:
199- return self.transport
200- raise errors.IncompatibleFormat(workingtree_format, self._format)
201-
202- def needs_format_conversion(self, format):
203- """See BzrDir.needs_format_conversion()."""
204- return not isinstance(self._format, format.__class__)
205-
206- def open_branch(self, name=None, unsupported=False,
207- ignore_fallbacks=False):
208- """See BzrDir.open_branch."""
209- from bzrlib.branch_weave import BzrBranchFormat4
210- format = BzrBranchFormat4()
211- self._check_supported(format, unsupported)
212- return format.open(self, name, _found=True)
213-
214- def sprout(self, url, revision_id=None, force_new_repo=False,
215- possible_transports=None, accelerator_tree=None,
216- hardlink=False, stacked=False, create_tree_if_local=True,
217- source_branch=None):
218- """See BzrDir.sprout()."""
219- if source_branch is not None:
220- my_branch = self.open_branch()
221- if source_branch.base != my_branch.base:
222- raise AssertionError(
223- "source branch %r is not within %r with branch %r" %
224- (source_branch, self, my_branch))
225- if stacked:
226- raise errors.UnstackableBranchFormat(
227- self._format, self.root_transport.base)
228- if not create_tree_if_local:
229- raise errors.MustHaveWorkingTree(
230- self._format, self.root_transport.base)
231- from bzrlib.workingtree_2 import WorkingTreeFormat2
232- self._make_tail(url)
233- result = self._format._initialize_for_clone(url)
234- try:
235- self.open_repository().clone(result, revision_id=revision_id)
236- except errors.NoRepositoryPresent:
237- pass
238- try:
239- self.open_branch().sprout(result, revision_id=revision_id)
240- except errors.NotBranchError:
241- pass
242-
243- # we always want a working tree
244- WorkingTreeFormat2().initialize(result,
245- accelerator_tree=accelerator_tree,
246- hardlink=hardlink)
247- return result
248-
249-
250-class BzrDir4(BzrDirPreSplitOut):
251- """A .bzr version 4 control object.
252-
253- This is a deprecated format and may be removed after sept 2006.
254- """
255-
256- def create_repository(self, shared=False):
257- """See BzrDir.create_repository."""
258- return self._format.repository_format.initialize(self, shared)
259-
260- def needs_format_conversion(self, format):
261- """Format 4 dirs are always in need of conversion."""
262- return True
263-
264- def open_repository(self):
265- """See BzrDir.open_repository."""
266- from bzrlib.repofmt.weaverepo import RepositoryFormat4
267- return RepositoryFormat4().open(self, _found=True)
268-
269-
270-class BzrDir5(BzrDirPreSplitOut):
271- """A .bzr version 5 control object.
272-
273- This is a deprecated format and may be removed after sept 2006.
274- """
275-
276- def has_workingtree(self):
277- """See BzrDir.has_workingtree."""
278- return True
279-
280- def open_repository(self):
281- """See BzrDir.open_repository."""
282- from bzrlib.repofmt.weaverepo import RepositoryFormat5
283- return RepositoryFormat5().open(self, _found=True)
284-
285- def open_workingtree(self, _unsupported=False,
286- recommend_upgrade=True):
287- """See BzrDir.create_workingtree."""
288- from bzrlib.workingtree_2 import WorkingTreeFormat2
289- wt_format = WorkingTreeFormat2()
290- # we don't warn here about upgrades; that ought to be handled for the
291- # bzrdir as a whole
292- return wt_format.open(self, _found=True)
293-
294-
295-class BzrDir6(BzrDirPreSplitOut):
296- """A .bzr version 6 control object.
297-
298- This is a deprecated format and may be removed after sept 2006.
299- """
300-
301- def has_workingtree(self):
302- """See BzrDir.has_workingtree."""
303- return True
304-
305- def open_repository(self):
306- """See BzrDir.open_repository."""
307- from bzrlib.repofmt.weaverepo import RepositoryFormat6
308- return RepositoryFormat6().open(self, _found=True)
309-
310- def open_workingtree(self, _unsupported=False,
311- recommend_upgrade=True):
312- """See BzrDir.create_workingtree."""
313- # we don't warn here about upgrades; that ought to be handled for the
314- # bzrdir as a whole
315- from bzrlib.workingtree_2 import WorkingTreeFormat2
316- return WorkingTreeFormat2().open(self, _found=True)
317-
318-
319 class BzrDirMeta1(BzrDir):
320 """A .bzr meta version 1 control object.
321
322@@ -1752,213 +1482,6 @@
323 controldir.network_format_registry.remove(format.get_format_string())
324
325
326-class BzrDirFormat4(BzrDirFormat):
327- """Bzr dir format 4.
328-
329- This format is a combined format for working tree, branch and repository.
330- It has:
331- - Format 1 working trees [always]
332- - Format 4 branches [always]
333- - Format 4 repositories [always]
334-
335- This format is deprecated: it indexes texts using a text it which is
336- removed in format 5; write support for this format has been removed.
337- """
338-
339- _lock_class = lockable_files.TransportLock
340-
341- fixed_components = True
342-
343- def get_format_string(self):
344- """See BzrDirFormat.get_format_string()."""
345- return "Bazaar-NG branch, format 0.0.4\n"
346-
347- def get_format_description(self):
348- """See BzrDirFormat.get_format_description()."""
349- return "All-in-one format 4"
350-
351- def get_converter(self, format=None):
352- """See BzrDirFormat.get_converter()."""
353- # there is one and only one upgrade path here.
354- return ConvertBzrDir4To5()
355-
356- def initialize_on_transport(self, transport):
357- """Format 4 branches cannot be created."""
358- raise errors.UninitializableFormat(self)
359-
360- def is_supported(self):
361- """Format 4 is not supported.
362-
363- It is not supported because the model changed from 4 to 5 and the
364- conversion logic is expensive - so doing it on the fly was not
365- feasible.
366- """
367- return False
368-
369- def network_name(self):
370- return self.get_format_string()
371-
372- def _open(self, transport):
373- """See BzrDirFormat._open."""
374- return BzrDir4(transport, self)
375-
376- def __return_repository_format(self):
377- """Circular import protection."""
378- from bzrlib.repofmt.weaverepo import RepositoryFormat4
379- return RepositoryFormat4()
380- repository_format = property(__return_repository_format)
381-
382-
383-class BzrDirFormatAllInOne(BzrDirFormat):
384- """Common class for formats before meta-dirs."""
385-
386- fixed_components = True
387-
388- def initialize_on_transport_ex(self, transport, use_existing_dir=False,
389- create_prefix=False, force_new_repo=False, stacked_on=None,
390- stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
391- shared_repo=False):
392- """See BzrDirFormat.initialize_on_transport_ex."""
393- require_stacking = (stacked_on is not None)
394- # Format 5 cannot stack, but we've been asked to - actually init
395- # a Meta1Dir
396- if require_stacking:
397- format = BzrDirMetaFormat1()
398- return format.initialize_on_transport_ex(transport,
399- use_existing_dir=use_existing_dir, create_prefix=create_prefix,
400- force_new_repo=force_new_repo, stacked_on=stacked_on,
401- stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
402- make_working_trees=make_working_trees, shared_repo=shared_repo)
403- return BzrDirFormat.initialize_on_transport_ex(self, transport,
404- use_existing_dir=use_existing_dir, create_prefix=create_prefix,
405- force_new_repo=force_new_repo, stacked_on=stacked_on,
406- stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
407- make_working_trees=make_working_trees, shared_repo=shared_repo)
408-
409-
410-class BzrDirFormat5(BzrDirFormatAllInOne):
411- """Bzr control format 5.
412-
413- This format is a combined format for working tree, branch and repository.
414- It has:
415- - Format 2 working trees [always]
416- - Format 4 branches [always]
417- - Format 5 repositories [always]
418- Unhashed stores in the repository.
419- """
420-
421- _lock_class = lockable_files.TransportLock
422-
423- def get_format_string(self):
424- """See BzrDirFormat.get_format_string()."""
425- return "Bazaar-NG branch, format 5\n"
426-
427- def get_branch_format(self):
428- from bzrlib import branch_weave
429- return branch_weave.BzrBranchFormat4()
430-
431- def get_format_description(self):
432- """See BzrDirFormat.get_format_description()."""
433- return "All-in-one format 5"
434-
435- def get_converter(self, format=None):
436- """See BzrDirFormat.get_converter()."""
437- # there is one and only one upgrade path here.
438- return ConvertBzrDir5To6()
439-
440- def _initialize_for_clone(self, url):
441- return self.initialize_on_transport(
442- _mod_transport.get_transport(url), _cloning=True)
443-
444- def initialize_on_transport(self, transport, _cloning=False):
445- """Format 5 dirs always have working tree, branch and repository.
446-
447- Except when they are being cloned.
448- """
449- from bzrlib.branch_weave import BzrBranchFormat4
450- from bzrlib.repofmt.weaverepo import RepositoryFormat5
451- result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
452- RepositoryFormat5().initialize(result, _internal=True)
453- if not _cloning:
454- branch = BzrBranchFormat4().initialize(result)
455- result._init_workingtree()
456- return result
457-
458- def network_name(self):
459- return self.get_format_string()
460-
461- def _open(self, transport):
462- """See BzrDirFormat._open."""
463- return BzrDir5(transport, self)
464-
465- def __return_repository_format(self):
466- """Circular import protection."""
467- from bzrlib.repofmt.weaverepo import RepositoryFormat5
468- return RepositoryFormat5()
469- repository_format = property(__return_repository_format)
470-
471-
472-class BzrDirFormat6(BzrDirFormatAllInOne):
473- """Bzr control format 6.
474-
475- This format is a combined format for working tree, branch and repository.
476- It has:
477- - Format 2 working trees [always]
478- - Format 4 branches [always]
479- - Format 6 repositories [always]
480- """
481-
482- _lock_class = lockable_files.TransportLock
483-
484- def get_format_string(self):
485- """See BzrDirFormat.get_format_string()."""
486- return "Bazaar-NG branch, format 6\n"
487-
488- def get_format_description(self):
489- """See BzrDirFormat.get_format_description()."""
490- return "All-in-one format 6"
491-
492- def get_branch_format(self):
493- from bzrlib import branch_weave
494- return branch_weave.BzrBranchFormat4()
495-
496- def get_converter(self, format=None):
497- """See BzrDirFormat.get_converter()."""
498- # there is one and only one upgrade path here.
499- return ConvertBzrDir6ToMeta()
500-
501- def _initialize_for_clone(self, url):
502- return self.initialize_on_transport(
503- _mod_transport.get_transport(url), _cloning=True)
504-
505- def initialize_on_transport(self, transport, _cloning=False):
506- """Format 6 dirs always have working tree, branch and repository.
507-
508- Except when they are being cloned.
509- """
510- from bzrlib.branch_weave import BzrBranchFormat4
511- from bzrlib.repofmt.weaverepo import RepositoryFormat6
512- result = super(BzrDirFormat6, self).initialize_on_transport(transport)
513- RepositoryFormat6().initialize(result, _internal=True)
514- if not _cloning:
515- branch = BzrBranchFormat4().initialize(result)
516- result._init_workingtree()
517- return result
518-
519- def network_name(self):
520- return self.get_format_string()
521-
522- def _open(self, transport):
523- """See BzrDirFormat._open."""
524- return BzrDir6(transport, self)
525-
526- def __return_repository_format(self):
527- """Circular import protection."""
528- from bzrlib.repofmt.weaverepo import RepositoryFormat6
529- return RepositoryFormat6()
530- repository_format = property(__return_repository_format)
531-
532-
533 class BzrDirMetaFormat1(BzrDirFormat):
534 """Bzr meta control format 1
535
536@@ -2170,452 +1693,11 @@
537
538
539 # Register bzr formats
540-BzrDirFormat.register_format(BzrDirFormat4())
541-BzrDirFormat.register_format(BzrDirFormat5())
542-BzrDirFormat.register_format(BzrDirFormat6())
543 __default_format = BzrDirMetaFormat1()
544 BzrDirFormat.register_format(__default_format)
545 controldir.ControlDirFormat._default_format = __default_format
546
547
548-class ConvertBzrDir4To5(controldir.Converter):
549- """Converts format 4 bzr dirs to format 5."""
550-
551- def __init__(self):
552- super(ConvertBzrDir4To5, self).__init__()
553- self.converted_revs = set()
554- self.absent_revisions = set()
555- self.text_count = 0
556- self.revisions = {}
557-
558- def convert(self, to_convert, pb):
559- """See Converter.convert()."""
560- self.bzrdir = to_convert
561- if pb is not None:
562- warnings.warn("pb parameter to convert() is deprecated")
563- self.pb = ui.ui_factory.nested_progress_bar()
564- try:
565- ui.ui_factory.note('starting upgrade from format 4 to 5')
566- if isinstance(self.bzrdir.transport, local.LocalTransport):
567- self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
568- self._convert_to_weaves()
569- return BzrDir.open(self.bzrdir.user_url)
570- finally:
571- self.pb.finished()
572-
573- def _convert_to_weaves(self):
574- ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
575- try:
576- # TODO permissions
577- stat = self.bzrdir.transport.stat('weaves')
578- if not S_ISDIR(stat.st_mode):
579- self.bzrdir.transport.delete('weaves')
580- self.bzrdir.transport.mkdir('weaves')
581- except errors.NoSuchFile:
582- self.bzrdir.transport.mkdir('weaves')
583- # deliberately not a WeaveFile as we want to build it up slowly.
584- self.inv_weave = Weave('inventory')
585- # holds in-memory weaves for all files
586- self.text_weaves = {}
587- self.bzrdir.transport.delete('branch-format')
588- self.branch = self.bzrdir.open_branch()
589- self._convert_working_inv()
590- rev_history = self.branch.revision_history()
591- # to_read is a stack holding the revisions we still need to process;
592- # appending to it adds new highest-priority revisions
593- self.known_revisions = set(rev_history)
594- self.to_read = rev_history[-1:]
595- while self.to_read:
596- rev_id = self.to_read.pop()
597- if (rev_id not in self.revisions
598- and rev_id not in self.absent_revisions):
599- self._load_one_rev(rev_id)
600- self.pb.clear()
601- to_import = self._make_order()
602- for i, rev_id in enumerate(to_import):
603- self.pb.update('converting revision', i, len(to_import))
604- self._convert_one_rev(rev_id)
605- self.pb.clear()
606- self._write_all_weaves()
607- self._write_all_revs()
608- ui.ui_factory.note('upgraded to weaves:')
609- ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
610- ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
611- ui.ui_factory.note(' %6d texts' % self.text_count)
612- self._cleanup_spare_files_after_format4()
613- self.branch._transport.put_bytes(
614- 'branch-format',
615- BzrDirFormat5().get_format_string(),
616- mode=self.bzrdir._get_file_mode())
617-
618- def _cleanup_spare_files_after_format4(self):
619- # FIXME working tree upgrade foo.
620- for n in 'merged-patches', 'pending-merged-patches':
621- try:
622- ## assert os.path.getsize(p) == 0
623- self.bzrdir.transport.delete(n)
624- except errors.NoSuchFile:
625- pass
626- self.bzrdir.transport.delete_tree('inventory-store')
627- self.bzrdir.transport.delete_tree('text-store')
628-
629- def _convert_working_inv(self):
630- inv = xml4.serializer_v4.read_inventory(
631- self.branch._transport.get('inventory'))
632- new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
633- self.branch._transport.put_bytes('inventory', new_inv_xml,
634- mode=self.bzrdir._get_file_mode())
635-
636- def _write_all_weaves(self):
637- controlweaves = VersionedFileStore(self.bzrdir.transport, prefixed=False,
638- versionedfile_class=WeaveFile)
639- weave_transport = self.bzrdir.transport.clone('weaves')
640- weaves = VersionedFileStore(weave_transport, prefixed=False,
641- versionedfile_class=WeaveFile)
642- transaction = WriteTransaction()
643-
644- try:
645- i = 0
646- for file_id, file_weave in self.text_weaves.items():
647- self.pb.update('writing weave', i, len(self.text_weaves))
648- weaves._put_weave(file_id, file_weave, transaction)
649- i += 1
650- self.pb.update('inventory', 0, 1)
651- controlweaves._put_weave('inventory', self.inv_weave, transaction)
652- self.pb.update('inventory', 1, 1)
653- finally:
654- self.pb.clear()
655-
656- def _write_all_revs(self):
657- """Write all revisions out in new form."""
658- self.bzrdir.transport.delete_tree('revision-store')
659- self.bzrdir.transport.mkdir('revision-store')
660- revision_transport = self.bzrdir.transport.clone('revision-store')
661- # TODO permissions
662- from bzrlib.xml5 import serializer_v5
663- from bzrlib.repofmt.weaverepo import RevisionTextStore
664- revision_store = RevisionTextStore(revision_transport,
665- serializer_v5, False, versionedfile.PrefixMapper(),
666- lambda:True, lambda:True)
667- try:
668- for i, rev_id in enumerate(self.converted_revs):
669- self.pb.update('write revision', i, len(self.converted_revs))
670- text = serializer_v5.write_revision_to_string(
671- self.revisions[rev_id])
672- key = (rev_id,)
673- revision_store.add_lines(key, None, osutils.split_lines(text))
674- finally:
675- self.pb.clear()
676-
677- def _load_one_rev(self, rev_id):
678- """Load a revision object into memory.
679-
680- Any parents not either loaded or abandoned get queued to be
681- loaded."""
682- self.pb.update('loading revision',
683- len(self.revisions),
684- len(self.known_revisions))
685- if not self.branch.repository.has_revision(rev_id):
686- self.pb.clear()
687- ui.ui_factory.note('revision {%s} not present in branch; '
688- 'will be converted as a ghost' %
689- rev_id)
690- self.absent_revisions.add(rev_id)
691- else:
692- rev = self.branch.repository.get_revision(rev_id)
693- for parent_id in rev.parent_ids:
694- self.known_revisions.add(parent_id)
695- self.to_read.append(parent_id)
696- self.revisions[rev_id] = rev
697-
698- def _load_old_inventory(self, rev_id):
699- f = self.branch.repository.inventory_store.get(rev_id)
700- try:
701- old_inv_xml = f.read()
702- finally:
703- f.close()
704- inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
705- inv.revision_id = rev_id
706- rev = self.revisions[rev_id]
707- return inv
708-
709- def _load_updated_inventory(self, rev_id):
710- inv_xml = self.inv_weave.get_text(rev_id)
711- inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
712- return inv
713-
714- def _convert_one_rev(self, rev_id):
715- """Convert revision and all referenced objects to new format."""
716- rev = self.revisions[rev_id]
717- inv = self._load_old_inventory(rev_id)
718- present_parents = [p for p in rev.parent_ids
719- if p not in self.absent_revisions]
720- self._convert_revision_contents(rev, inv, present_parents)
721- self._store_new_inv(rev, inv, present_parents)
722- self.converted_revs.add(rev_id)
723-
724- def _store_new_inv(self, rev, inv, present_parents):
725- new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
726- new_inv_sha1 = osutils.sha_string(new_inv_xml)
727- self.inv_weave.add_lines(rev.revision_id,
728- present_parents,
729- new_inv_xml.splitlines(True))
730- rev.inventory_sha1 = new_inv_sha1
731-
732- def _convert_revision_contents(self, rev, inv, present_parents):
733- """Convert all the files within a revision.
734-
735- Also upgrade the inventory to refer to the text revision ids."""
736- rev_id = rev.revision_id
737- mutter('converting texts of revision {%s}',
738- rev_id)
739- parent_invs = map(self._load_updated_inventory, present_parents)
740- entries = inv.iter_entries()
741- entries.next()
742- for path, ie in entries:
743- self._convert_file_version(rev, ie, parent_invs)
744-
745- def _convert_file_version(self, rev, ie, parent_invs):
746- """Convert one version of one file.
747-
748- The file needs to be added into the weave if it is a merge
749- of >=2 parents or if it's changed from its parent.
750- """
751- file_id = ie.file_id
752- rev_id = rev.revision_id
753- w = self.text_weaves.get(file_id)
754- if w is None:
755- w = Weave(file_id)
756- self.text_weaves[file_id] = w
757- text_changed = False
758- parent_candiate_entries = ie.parent_candidates(parent_invs)
759- heads = graph.Graph(self).heads(parent_candiate_entries.keys())
760- # XXX: Note that this is unordered - and this is tolerable because
761- # the previous code was also unordered.
762- previous_entries = dict((head, parent_candiate_entries[head]) for head
763- in heads)
764- self.snapshot_ie(previous_entries, ie, w, rev_id)
765-
766- def get_parent_map(self, revision_ids):
767- """See graph.StackedParentsProvider.get_parent_map"""
768- return dict((revision_id, self.revisions[revision_id])
769- for revision_id in revision_ids
770- if revision_id in self.revisions)
771-
772- def snapshot_ie(self, previous_revisions, ie, w, rev_id):
773- # TODO: convert this logic, which is ~= snapshot to
774- # a call to:. This needs the path figured out. rather than a work_tree
775- # a v4 revision_tree can be given, or something that looks enough like
776- # one to give the file content to the entry if it needs it.
777- # and we need something that looks like a weave store for snapshot to
778- # save against.
779- #ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
780- if len(previous_revisions) == 1:
781- previous_ie = previous_revisions.values()[0]
782- if ie._unchanged(previous_ie):
783- ie.revision = previous_ie.revision
784- return
785- if ie.has_text():
786- f = self.branch.repository._text_store.get(ie.text_id)
787- try:
788- file_lines = f.readlines()
789- finally:
790- f.close()
791- w.add_lines(rev_id, previous_revisions, file_lines)
792- self.text_count += 1
793- else:
794- w.add_lines(rev_id, previous_revisions, [])
795- ie.revision = rev_id
796-
797- def _make_order(self):
798- """Return a suitable order for importing revisions.
799-
800- The order must be such that an revision is imported after all
801- its (present) parents.
802- """
803- todo = set(self.revisions.keys())
804- done = self.absent_revisions.copy()
805- order = []
806- while todo:
807- # scan through looking for a revision whose parents
808- # are all done
809- for rev_id in sorted(list(todo)):
810- rev = self.revisions[rev_id]
811- parent_ids = set(rev.parent_ids)
812- if parent_ids.issubset(done):
813- # can take this one now
814- order.append(rev_id)
815- todo.remove(rev_id)
816- done.add(rev_id)
817- return order
818-
819-
820-class ConvertBzrDir5To6(controldir.Converter):
821- """Converts format 5 bzr dirs to format 6."""
822-
823- def convert(self, to_convert, pb):
824- """See Converter.convert()."""
825- self.bzrdir = to_convert
826- pb = ui.ui_factory.nested_progress_bar()
827- try:
828- ui.ui_factory.note('starting upgrade from format 5 to 6')
829- self._convert_to_prefixed()
830- return BzrDir.open(self.bzrdir.user_url)
831- finally:
832- pb.finished()
833-
834- def _convert_to_prefixed(self):
835- from bzrlib.store import TransportStore
836- self.bzrdir.transport.delete('branch-format')
837- for store_name in ["weaves", "revision-store"]:
838- ui.ui_factory.note("adding prefixes to %s" % store_name)
839- store_transport = self.bzrdir.transport.clone(store_name)
840- store = TransportStore(store_transport, prefixed=True)
841- for urlfilename in store_transport.list_dir('.'):
842- filename = urlutils.unescape(urlfilename)
843- if (filename.endswith(".weave") or
844- filename.endswith(".gz") or
845- filename.endswith(".sig")):
846- file_id, suffix = os.path.splitext(filename)
847- else:
848- file_id = filename
849- suffix = ''
850- new_name = store._mapper.map((file_id,)) + suffix
851- # FIXME keep track of the dirs made RBC 20060121
852- try:
853- store_transport.move(filename, new_name)
854- except errors.NoSuchFile: # catches missing dirs strangely enough
855- store_transport.mkdir(osutils.dirname(new_name))
856- store_transport.move(filename, new_name)
857- self.bzrdir.transport.put_bytes(
858- 'branch-format',
859- BzrDirFormat6().get_format_string(),
860- mode=self.bzrdir._get_file_mode())
861-
862-
863-class ConvertBzrDir6ToMeta(controldir.Converter):
864- """Converts format 6 bzr dirs to metadirs."""
865-
866- def convert(self, to_convert, pb):
867- """See Converter.convert()."""
868- from bzrlib.repofmt.weaverepo import RepositoryFormat7
869- from bzrlib.branch import BzrBranchFormat5
870- self.bzrdir = to_convert
871- self.pb = ui.ui_factory.nested_progress_bar()
872- self.count = 0
873- self.total = 20 # the steps we know about
874- self.garbage_inventories = []
875- self.dir_mode = self.bzrdir._get_dir_mode()
876- self.file_mode = self.bzrdir._get_file_mode()
877-
878- ui.ui_factory.note('starting upgrade from format 6 to metadir')
879- self.bzrdir.transport.put_bytes(
880- 'branch-format',
881- "Converting to format 6",
882- mode=self.file_mode)
883- # its faster to move specific files around than to open and use the apis...
884- # first off, nuke ancestry.weave, it was never used.
885- try:
886- self.step('Removing ancestry.weave')
887- self.bzrdir.transport.delete('ancestry.weave')
888- except errors.NoSuchFile:
889- pass
890- # find out whats there
891- self.step('Finding branch files')
892- last_revision = self.bzrdir.open_branch().last_revision()
893- bzrcontents = self.bzrdir.transport.list_dir('.')
894- for name in bzrcontents:
895- if name.startswith('basis-inventory.'):
896- self.garbage_inventories.append(name)
897- # create new directories for repository, working tree and branch
898- repository_names = [('inventory.weave', True),
899- ('revision-store', True),
900- ('weaves', True)]
901- self.step('Upgrading repository ')
902- self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
903- self.make_lock('repository')
904- # we hard code the formats here because we are converting into
905- # the meta format. The meta format upgrader can take this to a
906- # future format within each component.
907- self.put_format('repository', RepositoryFormat7())
908- for entry in repository_names:
909- self.move_entry('repository', entry)
910-
911- self.step('Upgrading branch ')
912- self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
913- self.make_lock('branch')
914- self.put_format('branch', BzrBranchFormat5())
915- branch_files = [('revision-history', True),
916- ('branch-name', True),
917- ('parent', False)]
918- for entry in branch_files:
919- self.move_entry('branch', entry)
920-
921- checkout_files = [('pending-merges', True),
922- ('inventory', True),
923- ('stat-cache', False)]
924- # If a mandatory checkout file is not present, the branch does not have
925- # a functional checkout. Do not create a checkout in the converted
926- # branch.
927- for name, mandatory in checkout_files:
928- if mandatory and name not in bzrcontents:
929- has_checkout = False
930- break
931- else:
932- has_checkout = True
933- if not has_checkout:
934- ui.ui_factory.note('No working tree.')
935- # If some checkout files are there, we may as well get rid of them.
936- for name, mandatory in checkout_files:
937- if name in bzrcontents:
938- self.bzrdir.transport.delete(name)
939- else:
940- from bzrlib.workingtree import WorkingTreeFormat3
941- self.step('Upgrading working tree')
942- self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
943- self.make_lock('checkout')
944- self.put_format(
945- 'checkout', WorkingTreeFormat3())
946- self.bzrdir.transport.delete_multi(
947- self.garbage_inventories, self.pb)
948- for entry in checkout_files:
949- self.move_entry('checkout', entry)
950- if last_revision is not None:
951- self.bzrdir.transport.put_bytes(
952- 'checkout/last-revision', last_revision)
953- self.bzrdir.transport.put_bytes(
954- 'branch-format',
955- BzrDirMetaFormat1().get_format_string(),
956- mode=self.file_mode)
957- self.pb.finished()
958- return BzrDir.open(self.bzrdir.user_url)
959-
960- def make_lock(self, name):
961- """Make a lock for the new control dir name."""
962- self.step('Make %s lock' % name)
963- ld = lockdir.LockDir(self.bzrdir.transport,
964- '%s/lock' % name,
965- file_modebits=self.file_mode,
966- dir_modebits=self.dir_mode)
967- ld.create()
968-
969- def move_entry(self, new_dir, entry):
970- """Move then entry name into new_dir."""
971- name = entry[0]
972- mandatory = entry[1]
973- self.step('Moving %s' % name)
974- try:
975- self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
976- except errors.NoSuchFile:
977- if mandatory:
978- raise
979-
980- def put_format(self, dirname, format):
981- self.bzrdir.transport.put_bytes('%s/format' % dirname,
982- format.get_format_string(),
983- self.file_mode)
984-
985-
986 class ConvertMetaToMeta(controldir.Converter):
987 """Converts the components of metadirs."""
988
989@@ -3139,21 +2221,6 @@
990 registry.register(key, helper, help, native, deprecated, hidden,
991 experimental, alias)
992
993-# The pre-0.8 formats have their repository format network name registered in
994-# repository.py. MetaDir formats have their repository format network name
995-# inferred from their disk format string.
996-controldir.format_registry.register('weave', BzrDirFormat6,
997- 'Pre-0.8 format. Slower than knit and does not'
998- ' support checkouts or shared repositories.',
999- hidden=True,
1000- deprecated=True)
1001-register_metadir(controldir.format_registry, 'metaweave',
1002- 'bzrlib.repofmt.weaverepo.RepositoryFormat7',
1003- 'Transitional format in 0.8. Slower than knit.',
1004- branch_format='bzrlib.branch.BzrBranchFormat5',
1005- tree_format='bzrlib.workingtree.WorkingTreeFormat3',
1006- hidden=True,
1007- deprecated=True)
1008 register_metadir(controldir.format_registry, 'knit',
1009 'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
1010 'Format using knits. Recommended for interoperation with bzr <= 0.14.',
1011
1012=== added directory 'bzrlib/plugins/weave_fmt'
1013=== added file 'bzrlib/plugins/weave_fmt/__init__.py'
1014--- bzrlib/plugins/weave_fmt/__init__.py 1970-01-01 00:00:00 +0000
1015+++ bzrlib/plugins/weave_fmt/__init__.py 2011-03-09 01:37:04 +0000
1016@@ -0,0 +1,114 @@
1017+# Copyright (C) 2010 Canonical Ltd
1018+#
1019+# This program is free software; you can redistribute it and/or modify
1020+# it under the terms of the GNU General Public License as published by
1021+# the Free Software Foundation; either version 2 of the License, or
1022+# (at your option) any later version.
1023+#
1024+# This program is distributed in the hope that it will be useful,
1025+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1026+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1027+# GNU General Public License for more details.
1028+#
1029+# You should have received a copy of the GNU General Public License
1030+# along with this program; if not, write to the Free Software
1031+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1032+
1033+"""Weave formats.
1034+
1035+These were formats present in pre-1.0 version of Bazaar.
1036+"""
1037+
1038+from bzrlib import (
1039+ branch,
1040+ bzrdir,
1041+ controldir,
1042+ repository,
1043+ serializer,
1044+ workingtree,
1045+ )
1046+
1047+# Pre-0.8 formats that don't have a disk format string (because they are
1048+# versioned by the matching control directory). We use the control directories
1049+# disk format string as a key for the network_name because they meet the
1050+# constraints (simple string, unique, immutable).
1051+repository.network_format_registry.register_lazy(
1052+ "Bazaar-NG branch, format 5\n",
1053+ 'bzrlib.plugins.weave_fmt.repository',
1054+ 'RepositoryFormat5',
1055+)
1056+repository.network_format_registry.register_lazy(
1057+ "Bazaar-NG branch, format 6\n",
1058+ 'bzrlib.plugins.weave_fmt.repository',
1059+ 'RepositoryFormat6',
1060+)
1061+
1062+# weave formats which has no format string and are not discoverable or independently
1063+# creatable on disk, so are not registered in format_registry. They're
1064+# all in bzrlib.plugins.weave_fmt.repository now. When an instance of one of these is
1065+# needed, it's constructed directly by the BzrDir. Non-native formats where
1066+# the repository is not separately opened are similar.
1067+
1068+repository.format_registry.register_lazy(
1069+ 'Bazaar-NG Repository format 7',
1070+ 'bzrlib.plugins.weave_fmt.repository',
1071+ 'RepositoryFormat7'
1072+ )
1073+
1074+repository.format_registry.register_extra_lazy(
1075+ 'bzrlib.plugins.weave_fmt.repository',
1076+ 'RepositoryFormat4')
1077+repository.format_registry.register_extra_lazy(
1078+ 'bzrlib.plugins.weave_fmt.repository',
1079+ 'RepositoryFormat5')
1080+repository.format_registry.register_extra_lazy(
1081+ 'bzrlib.plugins.weave_fmt.repository',
1082+ 'RepositoryFormat6')
1083+
1084+
1085+# The pre-0.8 formats have their repository format network name registered in
1086+# repository.py. MetaDir formats have their repository format network name
1087+# inferred from their disk format string.
1088+controldir.format_registry.register_lazy('weave',
1089+ "bzrlib.plugins.weave_fmt.bzrdir", "BzrDirFormat6",
1090+ 'Pre-0.8 format. Slower than knit and does not'
1091+ ' support checkouts or shared repositories.',
1092+ hidden=True,
1093+ deprecated=True)
1094+bzrdir.register_metadir(controldir.format_registry, 'metaweave',
1095+ 'bzrlib.plugins.weave_fmt.repository.RepositoryFormat7',
1096+ 'Transitional format in 0.8. Slower than knit.',
1097+ branch_format='bzrlib.branch.BzrBranchFormat5',
1098+ tree_format='bzrlib.workingtree.WorkingTreeFormat3',
1099+ hidden=True,
1100+ deprecated=True)
1101+
1102+
1103+from bzrlib.plugins.weave_fmt.bzrdir import BzrDirFormat4, BzrDirFormat5, BzrDirFormat6
1104+bzrdir.BzrDirFormat.register_format(BzrDirFormat4())
1105+bzrdir.BzrDirFormat.register_format(BzrDirFormat5())
1106+bzrdir.BzrDirFormat.register_format(BzrDirFormat6())
1107+
1108+branch.format_registry.register_extra_lazy(
1109+ 'bzrlib.plugins.weave_fmt.branch', 'BzrBranchFormat4')
1110+branch.network_format_registry.register_lazy(
1111+ "Bazaar-NG branch, format 6\n",
1112+ 'bzrlib.plugins.weave_fmt.branch', "BzrBranchFormat4")
1113+
1114+
1115+workingtree.format_registry.register_extra_lazy(
1116+ 'bzrlib.plugins.weave_fmt.workingtree',
1117+ 'WorkingTreeFormat2')
1118+
1119+serializer.format_registry.register_lazy('4', 'bzrlib.plugins.weave_fmt.xml4',
1120+ 'serializer_v4')
1121+
1122+def load_tests(basic_tests, module, loader):
1123+ testmod_names = [
1124+ 'test_bzrdir',
1125+ 'test_repository',
1126+ 'test_workingtree',
1127+ ]
1128+ basic_tests.addTest(loader.loadTestsFromModuleNames(
1129+ ["%s.%s" % (__name__, tmn) for tmn in testmod_names]))
1130+ return basic_tests
1131
1132=== renamed file 'bzrlib/branch_weave.py' => 'bzrlib/plugins/weave_fmt/branch.py'
1133--- bzrlib/branch_weave.py 2011-03-08 20:07:41 +0000
1134+++ bzrlib/plugins/weave_fmt/branch.py 2011-03-09 01:37:04 +0000
1135@@ -34,7 +34,7 @@
1136 def _get_checkout_format(self):
1137 """Return the most suitable metadir for a checkout of this branch.
1138 """
1139- from bzrlib.repofmt.weaverepo import RepositoryFormat7
1140+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat7
1141 from bzrlib.bzrdir import BzrDirMetaFormat1
1142 format = BzrDirMetaFormat1()
1143 format.repository_format = RepositoryFormat7()
1144@@ -91,7 +91,9 @@
1145
1146 def __init__(self):
1147 super(BzrBranchFormat4, self).__init__()
1148- from bzrlib.bzrdir import BzrDirFormat4, BzrDirFormat5, BzrDirFormat6
1149+ from bzrlib.plugins.weave_fmt.bzrdir import (
1150+ BzrDirFormat4, BzrDirFormat5, BzrDirFormat6,
1151+ )
1152 self._matchingbzrdir = BzrDirFormat6()
1153 self._compatible_bzrdirs = [BzrDirFormat4, BzrDirFormat5,
1154 BzrDirFormat6]
1155
1156=== added file 'bzrlib/plugins/weave_fmt/bzrdir.py'
1157--- bzrlib/plugins/weave_fmt/bzrdir.py 1970-01-01 00:00:00 +0000
1158+++ bzrlib/plugins/weave_fmt/bzrdir.py 2011-03-09 01:37:04 +0000
1159@@ -0,0 +1,969 @@
1160+# Copyright (C) 2006-2010 Canonical Ltd
1161+#
1162+# This program is free software; you can redistribute it and/or modify
1163+# it under the terms of the GNU General Public License as published by
1164+# the Free Software Foundation; either version 2 of the License, or
1165+# (at your option) any later version.
1166+#
1167+# This program is distributed in the hope that it will be useful,
1168+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1169+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1170+# GNU General Public License for more details.
1171+#
1172+# You should have received a copy of the GNU General Public License
1173+# along with this program; if not, write to the Free Software
1174+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1175+
1176+"""Weave-era BzrDir formats."""
1177+
1178+from bzrlib.bzrdir import (
1179+ BzrDir,
1180+ BzrDirFormat,
1181+ BzrDirMetaFormat1,
1182+ )
1183+from bzrlib.controldir import (
1184+ Converter,
1185+ format_registry,
1186+ )
1187+from bzrlib.lazy_import import lazy_import
1188+lazy_import(globals(), """
1189+import os
1190+import warnings
1191+
1192+from bzrlib import (
1193+ errors,
1194+ graph,
1195+ lockable_files,
1196+ lockdir,
1197+ osutils,
1198+ revision as _mod_revision,
1199+ trace,
1200+ ui,
1201+ urlutils,
1202+ versionedfile,
1203+ weave,
1204+ xml5,
1205+ )
1206+from bzrlib.store.versioned import VersionedFileStore
1207+from bzrlib.transactions import WriteTransaction
1208+from bzrlib.transport import (
1209+ get_transport,
1210+ local,
1211+ )
1212+from bzrlib.plugins.weave_fmt import xml4
1213+""")
1214+
1215+
1216+class BzrDirFormatAllInOne(BzrDirFormat):
1217+ """Common class for formats before meta-dirs."""
1218+
1219+ fixed_components = True
1220+
1221+ def initialize_on_transport_ex(self, transport, use_existing_dir=False,
1222+ create_prefix=False, force_new_repo=False, stacked_on=None,
1223+ stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
1224+ shared_repo=False):
1225+ """See BzrDirFormat.initialize_on_transport_ex."""
1226+ require_stacking = (stacked_on is not None)
1227+ # Format 5 cannot stack, but we've been asked to - actually init
1228+ # a Meta1Dir
1229+ if require_stacking:
1230+ format = BzrDirMetaFormat1()
1231+ return format.initialize_on_transport_ex(transport,
1232+ use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1233+ force_new_repo=force_new_repo, stacked_on=stacked_on,
1234+ stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1235+ make_working_trees=make_working_trees, shared_repo=shared_repo)
1236+ return BzrDirFormat.initialize_on_transport_ex(self, transport,
1237+ use_existing_dir=use_existing_dir, create_prefix=create_prefix,
1238+ force_new_repo=force_new_repo, stacked_on=stacked_on,
1239+ stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
1240+ make_working_trees=make_working_trees, shared_repo=shared_repo)
1241+
1242+
1243+class BzrDirFormat5(BzrDirFormatAllInOne):
1244+ """Bzr control format 5.
1245+
1246+ This format is a combined format for working tree, branch and repository.
1247+ It has:
1248+ - Format 2 working trees [always]
1249+ - Format 4 branches [always]
1250+ - Format 5 repositories [always]
1251+ Unhashed stores in the repository.
1252+ """
1253+
1254+ _lock_class = lockable_files.TransportLock
1255+
1256+ def get_format_string(self):
1257+ """See BzrDirFormat.get_format_string()."""
1258+ return "Bazaar-NG branch, format 5\n"
1259+
1260+ def get_branch_format(self):
1261+ from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
1262+ return BzrBranchFormat4()
1263+
1264+ def get_format_description(self):
1265+ """See BzrDirFormat.get_format_description()."""
1266+ return "All-in-one format 5"
1267+
1268+ def get_converter(self, format=None):
1269+ """See BzrDirFormat.get_converter()."""
1270+ # there is one and only one upgrade path here.
1271+ return ConvertBzrDir5To6()
1272+
1273+ def _initialize_for_clone(self, url):
1274+ return self.initialize_on_transport(get_transport(url), _cloning=True)
1275+
1276+ def initialize_on_transport(self, transport, _cloning=False):
1277+ """Format 5 dirs always have working tree, branch and repository.
1278+
1279+ Except when they are being cloned.
1280+ """
1281+ from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
1282+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat5
1283+ result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1284+ RepositoryFormat5().initialize(result, _internal=True)
1285+ if not _cloning:
1286+ branch = BzrBranchFormat4().initialize(result)
1287+ result._init_workingtree()
1288+ return result
1289+
1290+ def network_name(self):
1291+ return self.get_format_string()
1292+
1293+ def _open(self, transport):
1294+ """See BzrDirFormat._open."""
1295+ return BzrDir5(transport, self)
1296+
1297+ def __return_repository_format(self):
1298+ """Circular import protection."""
1299+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat5
1300+ return RepositoryFormat5()
1301+ repository_format = property(__return_repository_format)
1302+
1303+
1304+class BzrDirFormat6(BzrDirFormatAllInOne):
1305+ """Bzr control format 6.
1306+
1307+ This format is a combined format for working tree, branch and repository.
1308+ It has:
1309+ - Format 2 working trees [always]
1310+ - Format 4 branches [always]
1311+ - Format 6 repositories [always]
1312+ """
1313+
1314+ _lock_class = lockable_files.TransportLock
1315+
1316+ def get_format_string(self):
1317+ """See BzrDirFormat.get_format_string()."""
1318+ return "Bazaar-NG branch, format 6\n"
1319+
1320+ def get_format_description(self):
1321+ """See BzrDirFormat.get_format_description()."""
1322+ return "All-in-one format 6"
1323+
1324+ def get_branch_format(self):
1325+ from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
1326+ return BzrBranchFormat4()
1327+
1328+ def get_converter(self, format=None):
1329+ """See BzrDirFormat.get_converter()."""
1330+ # there is one and only one upgrade path here.
1331+ return ConvertBzrDir6ToMeta()
1332+
1333+ def _initialize_for_clone(self, url):
1334+ return self.initialize_on_transport(get_transport(url), _cloning=True)
1335+
1336+ def initialize_on_transport(self, transport, _cloning=False):
1337+ """Format 6 dirs always have working tree, branch and repository.
1338+
1339+ Except when they are being cloned.
1340+ """
1341+ from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
1342+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat6
1343+ result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1344+ RepositoryFormat6().initialize(result, _internal=True)
1345+ if not _cloning:
1346+ branch = BzrBranchFormat4().initialize(result)
1347+ result._init_workingtree()
1348+ return result
1349+
1350+ def network_name(self):
1351+ return self.get_format_string()
1352+
1353+ def _open(self, transport):
1354+ """See BzrDirFormat._open."""
1355+ return BzrDir6(transport, self)
1356+
1357+ def __return_repository_format(self):
1358+ """Circular import protection."""
1359+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat6
1360+ return RepositoryFormat6()
1361+ repository_format = property(__return_repository_format)
1362+
1363+
1364+class ConvertBzrDir4To5(Converter):
1365+ """Converts format 4 bzr dirs to format 5."""
1366+
1367+ def __init__(self):
1368+ super(ConvertBzrDir4To5, self).__init__()
1369+ self.converted_revs = set()
1370+ self.absent_revisions = set()
1371+ self.text_count = 0
1372+ self.revisions = {}
1373+
1374+ def convert(self, to_convert, pb):
1375+ """See Converter.convert()."""
1376+ self.bzrdir = to_convert
1377+ if pb is not None:
1378+ warnings.warn("pb parameter to convert() is deprecated")
1379+ self.pb = ui.ui_factory.nested_progress_bar()
1380+ try:
1381+ ui.ui_factory.note('starting upgrade from format 4 to 5')
1382+ if isinstance(self.bzrdir.transport, local.LocalTransport):
1383+ self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
1384+ self._convert_to_weaves()
1385+ return BzrDir.open(self.bzrdir.user_url)
1386+ finally:
1387+ self.pb.finished()
1388+
1389+ def _convert_to_weaves(self):
1390+ ui.ui_factory.note('note: upgrade may be faster if all store files are ungzipped first')
1391+ try:
1392+ # TODO permissions
1393+ stat = self.bzrdir.transport.stat('weaves')
1394+ if not S_ISDIR(stat.st_mode):
1395+ self.bzrdir.transport.delete('weaves')
1396+ self.bzrdir.transport.mkdir('weaves')
1397+ except errors.NoSuchFile:
1398+ self.bzrdir.transport.mkdir('weaves')
1399+ # deliberately not a WeaveFile as we want to build it up slowly.
1400+ self.inv_weave = weave.Weave('inventory')
1401+ # holds in-memory weaves for all files
1402+ self.text_weaves = {}
1403+ self.bzrdir.transport.delete('branch-format')
1404+ self.branch = self.bzrdir.open_branch()
1405+ self._convert_working_inv()
1406+ rev_history = self.branch.revision_history()
1407+ # to_read is a stack holding the revisions we still need to process;
1408+ # appending to it adds new highest-priority revisions
1409+ self.known_revisions = set(rev_history)
1410+ self.to_read = rev_history[-1:]
1411+ while self.to_read:
1412+ rev_id = self.to_read.pop()
1413+ if (rev_id not in self.revisions
1414+ and rev_id not in self.absent_revisions):
1415+ self._load_one_rev(rev_id)
1416+ self.pb.clear()
1417+ to_import = self._make_order()
1418+ for i, rev_id in enumerate(to_import):
1419+ self.pb.update('converting revision', i, len(to_import))
1420+ self._convert_one_rev(rev_id)
1421+ self.pb.clear()
1422+ self._write_all_weaves()
1423+ self._write_all_revs()
1424+ ui.ui_factory.note('upgraded to weaves:')
1425+ ui.ui_factory.note(' %6d revisions and inventories' % len(self.revisions))
1426+ ui.ui_factory.note(' %6d revisions not present' % len(self.absent_revisions))
1427+ ui.ui_factory.note(' %6d texts' % self.text_count)
1428+ self._cleanup_spare_files_after_format4()
1429+ self.branch._transport.put_bytes(
1430+ 'branch-format',
1431+ BzrDirFormat5().get_format_string(),
1432+ mode=self.bzrdir._get_file_mode())
1433+
1434+ def _cleanup_spare_files_after_format4(self):
1435+ # FIXME working tree upgrade foo.
1436+ for n in 'merged-patches', 'pending-merged-patches':
1437+ try:
1438+ ## assert os.path.getsize(p) == 0
1439+ self.bzrdir.transport.delete(n)
1440+ except errors.NoSuchFile:
1441+ pass
1442+ self.bzrdir.transport.delete_tree('inventory-store')
1443+ self.bzrdir.transport.delete_tree('text-store')
1444+
1445+ def _convert_working_inv(self):
1446+ inv = xml4.serializer_v4.read_inventory(
1447+ self.branch._transport.get('inventory'))
1448+ new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv, working=True)
1449+ self.branch._transport.put_bytes('inventory', new_inv_xml,
1450+ mode=self.bzrdir._get_file_mode())
1451+
1452+ def _write_all_weaves(self):
1453+ controlweaves = VersionedFileStore(self.bzrdir.transport, prefixed=False,
1454+ versionedfile_class=weave.WeaveFile)
1455+ weave_transport = self.bzrdir.transport.clone('weaves')
1456+ weaves = VersionedFileStore(weave_transport, prefixed=False,
1457+ versionedfile_class=weave.WeaveFile)
1458+ transaction = WriteTransaction()
1459+
1460+ try:
1461+ i = 0
1462+ for file_id, file_weave in self.text_weaves.items():
1463+ self.pb.update('writing weave', i, len(self.text_weaves))
1464+ weaves._put_weave(file_id, file_weave, transaction)
1465+ i += 1
1466+ self.pb.update('inventory', 0, 1)
1467+ controlweaves._put_weave('inventory', self.inv_weave, transaction)
1468+ self.pb.update('inventory', 1, 1)
1469+ finally:
1470+ self.pb.clear()
1471+
1472+ def _write_all_revs(self):
1473+ """Write all revisions out in new form."""
1474+ self.bzrdir.transport.delete_tree('revision-store')
1475+ self.bzrdir.transport.mkdir('revision-store')
1476+ revision_transport = self.bzrdir.transport.clone('revision-store')
1477+ # TODO permissions
1478+ from bzrlib.xml5 import serializer_v5
1479+ from bzrlib.plugins.weave_fmt.repository import RevisionTextStore
1480+ revision_store = RevisionTextStore(revision_transport,
1481+ serializer_v5, False, versionedfile.PrefixMapper(),
1482+ lambda:True, lambda:True)
1483+ try:
1484+ for i, rev_id in enumerate(self.converted_revs):
1485+ self.pb.update('write revision', i, len(self.converted_revs))
1486+ text = serializer_v5.write_revision_to_string(
1487+ self.revisions[rev_id])
1488+ key = (rev_id,)
1489+ revision_store.add_lines(key, None, osutils.split_lines(text))
1490+ finally:
1491+ self.pb.clear()
1492+
1493+ def _load_one_rev(self, rev_id):
1494+ """Load a revision object into memory.
1495+
1496+ Any parents not either loaded or abandoned get queued to be
1497+ loaded."""
1498+ self.pb.update('loading revision',
1499+ len(self.revisions),
1500+ len(self.known_revisions))
1501+ if not self.branch.repository.has_revision(rev_id):
1502+ self.pb.clear()
1503+ ui.ui_factory.note('revision {%s} not present in branch; '
1504+ 'will be converted as a ghost' %
1505+ rev_id)
1506+ self.absent_revisions.add(rev_id)
1507+ else:
1508+ rev = self.branch.repository.get_revision(rev_id)
1509+ for parent_id in rev.parent_ids:
1510+ self.known_revisions.add(parent_id)
1511+ self.to_read.append(parent_id)
1512+ self.revisions[rev_id] = rev
1513+
1514+ def _load_old_inventory(self, rev_id):
1515+ f = self.branch.repository.inventory_store.get(rev_id)
1516+ try:
1517+ old_inv_xml = f.read()
1518+ finally:
1519+ f.close()
1520+ inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
1521+ inv.revision_id = rev_id
1522+ rev = self.revisions[rev_id]
1523+ return inv
1524+
1525+ def _load_updated_inventory(self, rev_id):
1526+ inv_xml = self.inv_weave.get_text(rev_id)
1527+ inv = xml5.serializer_v5.read_inventory_from_string(inv_xml, rev_id)
1528+ return inv
1529+
1530+ def _convert_one_rev(self, rev_id):
1531+ """Convert revision and all referenced objects to new format."""
1532+ rev = self.revisions[rev_id]
1533+ inv = self._load_old_inventory(rev_id)
1534+ present_parents = [p for p in rev.parent_ids
1535+ if p not in self.absent_revisions]
1536+ self._convert_revision_contents(rev, inv, present_parents)
1537+ self._store_new_inv(rev, inv, present_parents)
1538+ self.converted_revs.add(rev_id)
1539+
1540+ def _store_new_inv(self, rev, inv, present_parents):
1541+ new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1542+ new_inv_sha1 = osutils.sha_string(new_inv_xml)
1543+ self.inv_weave.add_lines(rev.revision_id,
1544+ present_parents,
1545+ new_inv_xml.splitlines(True))
1546+ rev.inventory_sha1 = new_inv_sha1
1547+
1548+ def _convert_revision_contents(self, rev, inv, present_parents):
1549+ """Convert all the files within a revision.
1550+
1551+ Also upgrade the inventory to refer to the text revision ids."""
1552+ rev_id = rev.revision_id
1553+ trace.mutter('converting texts of revision {%s}', rev_id)
1554+ parent_invs = map(self._load_updated_inventory, present_parents)
1555+ entries = inv.iter_entries()
1556+ entries.next()
1557+ for path, ie in entries:
1558+ self._convert_file_version(rev, ie, parent_invs)
1559+
1560+ def _convert_file_version(self, rev, ie, parent_invs):
1561+ """Convert one version of one file.
1562+
1563+ The file needs to be added into the weave if it is a merge
1564+ of >=2 parents or if it's changed from its parent.
1565+ """
1566+ file_id = ie.file_id
1567+ rev_id = rev.revision_id
1568+ w = self.text_weaves.get(file_id)
1569+ if w is None:
1570+ w = weave.Weave(file_id)
1571+ self.text_weaves[file_id] = w
1572+ text_changed = False
1573+ parent_candiate_entries = ie.parent_candidates(parent_invs)
1574+ heads = graph.Graph(self).heads(parent_candiate_entries.keys())
1575+ # XXX: Note that this is unordered - and this is tolerable because
1576+ # the previous code was also unordered.
1577+ previous_entries = dict((head, parent_candiate_entries[head]) for head
1578+ in heads)
1579+ self.snapshot_ie(previous_entries, ie, w, rev_id)
1580+
1581+ def get_parent_map(self, revision_ids):
1582+ """See graph.StackedParentsProvider.get_parent_map"""
1583+ return dict((revision_id, self.revisions[revision_id])
1584+ for revision_id in revision_ids
1585+ if revision_id in self.revisions)
1586+
1587+ def snapshot_ie(self, previous_revisions, ie, w, rev_id):
1588+ # TODO: convert this logic, which is ~= snapshot to
1589+ # a call to:. This needs the path figured out. rather than a work_tree
1590+ # a v4 revision_tree can be given, or something that looks enough like
1591+ # one to give the file content to the entry if it needs it.
1592+ # and we need something that looks like a weave store for snapshot to
1593+ # save against.
1594+ #ie.snapshot(rev, PATH, previous_revisions, REVISION_TREE, InMemoryWeaveStore(self.text_weaves))
1595+ if len(previous_revisions) == 1:
1596+ previous_ie = previous_revisions.values()[0]
1597+ if ie._unchanged(previous_ie):
1598+ ie.revision = previous_ie.revision
1599+ return
1600+ if ie.has_text():
1601+ f = self.branch.repository._text_store.get(ie.text_id)
1602+ try:
1603+ file_lines = f.readlines()
1604+ finally:
1605+ f.close()
1606+ w.add_lines(rev_id, previous_revisions, file_lines)
1607+ self.text_count += 1
1608+ else:
1609+ w.add_lines(rev_id, previous_revisions, [])
1610+ ie.revision = rev_id
1611+
1612+ def _make_order(self):
1613+ """Return a suitable order for importing revisions.
1614+
1615+ The order must be such that an revision is imported after all
1616+ its (present) parents.
1617+ """
1618+ todo = set(self.revisions.keys())
1619+ done = self.absent_revisions.copy()
1620+ order = []
1621+ while todo:
1622+ # scan through looking for a revision whose parents
1623+ # are all done
1624+ for rev_id in sorted(list(todo)):
1625+ rev = self.revisions[rev_id]
1626+ parent_ids = set(rev.parent_ids)
1627+ if parent_ids.issubset(done):
1628+ # can take this one now
1629+ order.append(rev_id)
1630+ todo.remove(rev_id)
1631+ done.add(rev_id)
1632+ return order
1633+
1634+
1635+
1636+
1637+class ConvertBzrDir5To6(Converter):
1638+ """Converts format 5 bzr dirs to format 6."""
1639+
1640+ def convert(self, to_convert, pb):
1641+ """See Converter.convert()."""
1642+ self.bzrdir = to_convert
1643+ pb = ui.ui_factory.nested_progress_bar()
1644+ try:
1645+ ui.ui_factory.note('starting upgrade from format 5 to 6')
1646+ self._convert_to_prefixed()
1647+ return BzrDir.open(self.bzrdir.user_url)
1648+ finally:
1649+ pb.finished()
1650+
1651+ def _convert_to_prefixed(self):
1652+ from bzrlib.store import TransportStore
1653+ self.bzrdir.transport.delete('branch-format')
1654+ for store_name in ["weaves", "revision-store"]:
1655+ ui.ui_factory.note("adding prefixes to %s" % store_name)
1656+ store_transport = self.bzrdir.transport.clone(store_name)
1657+ store = TransportStore(store_transport, prefixed=True)
1658+ for urlfilename in store_transport.list_dir('.'):
1659+ filename = urlutils.unescape(urlfilename)
1660+ if (filename.endswith(".weave") or
1661+ filename.endswith(".gz") or
1662+ filename.endswith(".sig")):
1663+ file_id, suffix = os.path.splitext(filename)
1664+ else:
1665+ file_id = filename
1666+ suffix = ''
1667+ new_name = store._mapper.map((file_id,)) + suffix
1668+ # FIXME keep track of the dirs made RBC 20060121
1669+ try:
1670+ store_transport.move(filename, new_name)
1671+ except errors.NoSuchFile: # catches missing dirs strangely enough
1672+ store_transport.mkdir(osutils.dirname(new_name))
1673+ store_transport.move(filename, new_name)
1674+ self.bzrdir.transport.put_bytes(
1675+ 'branch-format',
1676+ BzrDirFormat6().get_format_string(),
1677+ mode=self.bzrdir._get_file_mode())
1678+
1679+
1680+class ConvertBzrDir6ToMeta(Converter):
1681+ """Converts format 6 bzr dirs to metadirs."""
1682+
1683+ def convert(self, to_convert, pb):
1684+ """See Converter.convert()."""
1685+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat7
1686+ from bzrlib.branch import BzrBranchFormat5
1687+ self.bzrdir = to_convert
1688+ self.pb = ui.ui_factory.nested_progress_bar()
1689+ self.count = 0
1690+ self.total = 20 # the steps we know about
1691+ self.garbage_inventories = []
1692+ self.dir_mode = self.bzrdir._get_dir_mode()
1693+ self.file_mode = self.bzrdir._get_file_mode()
1694+
1695+ ui.ui_factory.note('starting upgrade from format 6 to metadir')
1696+ self.bzrdir.transport.put_bytes(
1697+ 'branch-format',
1698+ "Converting to format 6",
1699+ mode=self.file_mode)
1700+ # its faster to move specific files around than to open and use the apis...
1701+ # first off, nuke ancestry.weave, it was never used.
1702+ try:
1703+ self.step('Removing ancestry.weave')
1704+ self.bzrdir.transport.delete('ancestry.weave')
1705+ except errors.NoSuchFile:
1706+ pass
1707+ # find out whats there
1708+ self.step('Finding branch files')
1709+ last_revision = self.bzrdir.open_branch().last_revision()
1710+ bzrcontents = self.bzrdir.transport.list_dir('.')
1711+ for name in bzrcontents:
1712+ if name.startswith('basis-inventory.'):
1713+ self.garbage_inventories.append(name)
1714+ # create new directories for repository, working tree and branch
1715+ repository_names = [('inventory.weave', True),
1716+ ('revision-store', True),
1717+ ('weaves', True)]
1718+ self.step('Upgrading repository ')
1719+ self.bzrdir.transport.mkdir('repository', mode=self.dir_mode)
1720+ self.make_lock('repository')
1721+ # we hard code the formats here because we are converting into
1722+ # the meta format. The meta format upgrader can take this to a
1723+ # future format within each component.
1724+ self.put_format('repository', RepositoryFormat7())
1725+ for entry in repository_names:
1726+ self.move_entry('repository', entry)
1727+
1728+ self.step('Upgrading branch ')
1729+ self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
1730+ self.make_lock('branch')
1731+ self.put_format('branch', BzrBranchFormat5())
1732+ branch_files = [('revision-history', True),
1733+ ('branch-name', True),
1734+ ('parent', False)]
1735+ for entry in branch_files:
1736+ self.move_entry('branch', entry)
1737+
1738+ checkout_files = [('pending-merges', True),
1739+ ('inventory', True),
1740+ ('stat-cache', False)]
1741+ # If a mandatory checkout file is not present, the branch does not have
1742+ # a functional checkout. Do not create a checkout in the converted
1743+ # branch.
1744+ for name, mandatory in checkout_files:
1745+ if mandatory and name not in bzrcontents:
1746+ has_checkout = False
1747+ break
1748+ else:
1749+ has_checkout = True
1750+ if not has_checkout:
1751+ ui.ui_factory.note('No working tree.')
1752+ # If some checkout files are there, we may as well get rid of them.
1753+ for name, mandatory in checkout_files:
1754+ if name in bzrcontents:
1755+ self.bzrdir.transport.delete(name)
1756+ else:
1757+ from bzrlib.workingtree import WorkingTreeFormat3
1758+ self.step('Upgrading working tree')
1759+ self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1760+ self.make_lock('checkout')
1761+ self.put_format(
1762+ 'checkout', WorkingTreeFormat3())
1763+ self.bzrdir.transport.delete_multi(
1764+ self.garbage_inventories, self.pb)
1765+ for entry in checkout_files:
1766+ self.move_entry('checkout', entry)
1767+ if last_revision is not None:
1768+ self.bzrdir.transport.put_bytes(
1769+ 'checkout/last-revision', last_revision)
1770+ self.bzrdir.transport.put_bytes(
1771+ 'branch-format',
1772+ BzrDirMetaFormat1().get_format_string(),
1773+ mode=self.file_mode)
1774+ self.pb.finished()
1775+ return BzrDir.open(self.bzrdir.user_url)
1776+
1777+ def make_lock(self, name):
1778+ """Make a lock for the new control dir name."""
1779+ self.step('Make %s lock' % name)
1780+ ld = lockdir.LockDir(self.bzrdir.transport,
1781+ '%s/lock' % name,
1782+ file_modebits=self.file_mode,
1783+ dir_modebits=self.dir_mode)
1784+ ld.create()
1785+
1786+ def move_entry(self, new_dir, entry):
1787+ """Move then entry name into new_dir."""
1788+ name = entry[0]
1789+ mandatory = entry[1]
1790+ self.step('Moving %s' % name)
1791+ try:
1792+ self.bzrdir.transport.move(name, '%s/%s' % (new_dir, name))
1793+ except errors.NoSuchFile:
1794+ if mandatory:
1795+ raise
1796+
1797+ def put_format(self, dirname, format):
1798+ self.bzrdir.transport.put_bytes('%s/format' % dirname,
1799+ format.get_format_string(),
1800+ self.file_mode)
1801+
1802+
1803+class BzrDirFormat4(BzrDirFormat):
1804+ """Bzr dir format 4.
1805+
1806+ This format is a combined format for working tree, branch and repository.
1807+ It has:
1808+ - Format 1 working trees [always]
1809+ - Format 4 branches [always]
1810+ - Format 4 repositories [always]
1811+
1812+ This format is deprecated: it indexes texts using a text it which is
1813+ removed in format 5; write support for this format has been removed.
1814+ """
1815+
1816+ _lock_class = lockable_files.TransportLock
1817+
1818+ def get_format_string(self):
1819+ """See BzrDirFormat.get_format_string()."""
1820+ return "Bazaar-NG branch, format 0.0.4\n"
1821+
1822+ def get_format_description(self):
1823+ """See BzrDirFormat.get_format_description()."""
1824+ return "All-in-one format 4"
1825+
1826+ def get_converter(self, format=None):
1827+ """See BzrDirFormat.get_converter()."""
1828+ # there is one and only one upgrade path here.
1829+ return ConvertBzrDir4To5()
1830+
1831+ def initialize_on_transport(self, transport):
1832+ """Format 4 branches cannot be created."""
1833+ raise errors.UninitializableFormat(self)
1834+
1835+ def is_supported(self):
1836+ """Format 4 is not supported.
1837+
1838+ It is not supported because the model changed from 4 to 5 and the
1839+ conversion logic is expensive - so doing it on the fly was not
1840+ feasible.
1841+ """
1842+ return False
1843+
1844+ def network_name(self):
1845+ return self.get_format_string()
1846+
1847+ def _open(self, transport):
1848+ """See BzrDirFormat._open."""
1849+ return BzrDir4(transport, self)
1850+
1851+ def __return_repository_format(self):
1852+ """Circular import protection."""
1853+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat4
1854+ return RepositoryFormat4()
1855+ repository_format = property(__return_repository_format)
1856+
1857+
1858+class BzrDirPreSplitOut(BzrDir):
1859+ """A common class for the all-in-one formats."""
1860+
1861+ def __init__(self, _transport, _format):
1862+ """See BzrDir.__init__."""
1863+ super(BzrDirPreSplitOut, self).__init__(_transport, _format)
1864+ self._control_files = lockable_files.LockableFiles(
1865+ self.get_branch_transport(None),
1866+ self._format._lock_file_name,
1867+ self._format._lock_class)
1868+
1869+ def break_lock(self):
1870+ """Pre-splitout bzrdirs do not suffer from stale locks."""
1871+ raise NotImplementedError(self.break_lock)
1872+
1873+ def cloning_metadir(self, require_stacking=False):
1874+ """Produce a metadir suitable for cloning with."""
1875+ if require_stacking:
1876+ return format_registry.make_bzrdir('1.6')
1877+ return self._format.__class__()
1878+
1879+ def clone(self, url, revision_id=None, force_new_repo=False,
1880+ preserve_stacking=False):
1881+ """See BzrDir.clone().
1882+
1883+ force_new_repo has no effect, since this family of formats always
1884+ require a new repository.
1885+ preserve_stacking has no effect, since no source branch using this
1886+ family of formats can be stacked, so there is no stacking to preserve.
1887+ """
1888+ self._make_tail(url)
1889+ result = self._format._initialize_for_clone(url)
1890+ self.open_repository().clone(result, revision_id=revision_id)
1891+ from_branch = self.open_branch()
1892+ from_branch.clone(result, revision_id=revision_id)
1893+ try:
1894+ tree = self.open_workingtree()
1895+ except errors.NotLocalUrl:
1896+ # make a new one, this format always has to have one.
1897+ result._init_workingtree()
1898+ else:
1899+ tree.clone(result)
1900+ return result
1901+
1902+ def create_branch(self, name=None, repository=None):
1903+ """See BzrDir.create_branch."""
1904+ if repository is not None:
1905+ raise NotImplementedError(
1906+ "create_branch(repository=<not None>) on %r" % (self,))
1907+ return self._format.get_branch_format().initialize(self, name=name)
1908+
1909+ def destroy_branch(self, name=None):
1910+ """See BzrDir.destroy_branch."""
1911+ raise errors.UnsupportedOperation(self.destroy_branch, self)
1912+
1913+ def create_repository(self, shared=False):
1914+ """See BzrDir.create_repository."""
1915+ if shared:
1916+ raise errors.IncompatibleFormat('shared repository', self._format)
1917+ return self.open_repository()
1918+
1919+ def destroy_repository(self):
1920+ """See BzrDir.destroy_repository."""
1921+ raise errors.UnsupportedOperation(self.destroy_repository, self)
1922+
1923+ def create_workingtree(self, revision_id=None, from_branch=None,
1924+ accelerator_tree=None, hardlink=False):
1925+ """See BzrDir.create_workingtree."""
1926+ # The workingtree is sometimes created when the bzrdir is created,
1927+ # but not when cloning.
1928+
1929+ # this looks buggy but is not -really-
1930+ # because this format creates the workingtree when the bzrdir is
1931+ # created
1932+ # clone and sprout will have set the revision_id
1933+ # and that will have set it for us, its only
1934+ # specific uses of create_workingtree in isolation
1935+ # that can do wonky stuff here, and that only
1936+ # happens for creating checkouts, which cannot be
1937+ # done on this format anyway. So - acceptable wart.
1938+ if hardlink:
1939+ warning("can't support hardlinked working trees in %r"
1940+ % (self,))
1941+ try:
1942+ result = self.open_workingtree(recommend_upgrade=False)
1943+ except errors.NoSuchFile:
1944+ result = self._init_workingtree()
1945+ if revision_id is not None:
1946+ if revision_id == _mod_revision.NULL_REVISION:
1947+ result.set_parent_ids([])
1948+ else:
1949+ result.set_parent_ids([revision_id])
1950+ return result
1951+
1952+ def _init_workingtree(self):
1953+ from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
1954+ try:
1955+ return WorkingTreeFormat2().initialize(self)
1956+ except errors.NotLocalUrl:
1957+ # Even though we can't access the working tree, we need to
1958+ # create its control files.
1959+ return WorkingTreeFormat2()._stub_initialize_on_transport(
1960+ self.transport, self._control_files._file_mode)
1961+
1962+ def destroy_workingtree(self):
1963+ """See BzrDir.destroy_workingtree."""
1964+ raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1965+
1966+ def destroy_workingtree_metadata(self):
1967+ """See BzrDir.destroy_workingtree_metadata."""
1968+ raise errors.UnsupportedOperation(self.destroy_workingtree_metadata,
1969+ self)
1970+
1971+ def get_branch_transport(self, branch_format, name=None):
1972+ """See BzrDir.get_branch_transport()."""
1973+ if name is not None:
1974+ raise errors.NoColocatedBranchSupport(self)
1975+ if branch_format is None:
1976+ return self.transport
1977+ try:
1978+ branch_format.get_format_string()
1979+ except NotImplementedError:
1980+ return self.transport
1981+ raise errors.IncompatibleFormat(branch_format, self._format)
1982+
1983+ def get_repository_transport(self, repository_format):
1984+ """See BzrDir.get_repository_transport()."""
1985+ if repository_format is None:
1986+ return self.transport
1987+ try:
1988+ repository_format.get_format_string()
1989+ except NotImplementedError:
1990+ return self.transport
1991+ raise errors.IncompatibleFormat(repository_format, self._format)
1992+
1993+ def get_workingtree_transport(self, workingtree_format):
1994+ """See BzrDir.get_workingtree_transport()."""
1995+ if workingtree_format is None:
1996+ return self.transport
1997+ try:
1998+ workingtree_format.get_format_string()
1999+ except NotImplementedError:
2000+ return self.transport
2001+ raise errors.IncompatibleFormat(workingtree_format, self._format)
2002+
2003+ def needs_format_conversion(self, format=None):
2004+ """See BzrDir.needs_format_conversion()."""
2005+ # if the format is not the same as the system default,
2006+ # an upgrade is needed.
2007+ if format is None:
2008+ symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
2009+ % 'needs_format_conversion(format=None)')
2010+ format = BzrDirFormat.get_default_format()
2011+ return not isinstance(self._format, format.__class__)
2012+
2013+ def open_branch(self, name=None, unsupported=False,
2014+ ignore_fallbacks=False):
2015+ """See BzrDir.open_branch."""
2016+ from bzrlib.plugins.weave_fmt.branch import BzrBranchFormat4
2017+ format = BzrBranchFormat4()
2018+ self._check_supported(format, unsupported)
2019+ return format.open(self, name, _found=True)
2020+
2021+ def sprout(self, url, revision_id=None, force_new_repo=False,
2022+ possible_transports=None, accelerator_tree=None,
2023+ hardlink=False, stacked=False, create_tree_if_local=True,
2024+ source_branch=None):
2025+ """See BzrDir.sprout()."""
2026+ if source_branch is not None:
2027+ my_branch = self.open_branch()
2028+ if source_branch.base != my_branch.base:
2029+ raise AssertionError(
2030+ "source branch %r is not within %r with branch %r" %
2031+ (source_branch, self, my_branch))
2032+ if stacked:
2033+ raise errors.UnstackableBranchFormat(
2034+ self._format, self.root_transport.base)
2035+ if not create_tree_if_local:
2036+ raise errors.MustHaveWorkingTree(
2037+ self._format, self.root_transport.base)
2038+ from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
2039+ self._make_tail(url)
2040+ result = self._format._initialize_for_clone(url)
2041+ try:
2042+ self.open_repository().clone(result, revision_id=revision_id)
2043+ except errors.NoRepositoryPresent:
2044+ pass
2045+ try:
2046+ self.open_branch().sprout(result, revision_id=revision_id)
2047+ except errors.NotBranchError:
2048+ pass
2049+
2050+ # we always want a working tree
2051+ WorkingTreeFormat2().initialize(result,
2052+ accelerator_tree=accelerator_tree,
2053+ hardlink=hardlink)
2054+ return result
2055+
2056+
2057+class BzrDir4(BzrDirPreSplitOut):
2058+ """A .bzr version 4 control object.
2059+
2060+ This is a deprecated format and may be removed after sept 2006.
2061+ """
2062+
2063+ def create_repository(self, shared=False):
2064+ """See BzrDir.create_repository."""
2065+ return self._format.repository_format.initialize(self, shared)
2066+
2067+ def needs_format_conversion(self, format=None):
2068+ """Format 4 dirs are always in need of conversion."""
2069+ if format is None:
2070+ symbol_versioning.warn(symbol_versioning.deprecated_in((1, 13, 0))
2071+ % 'needs_format_conversion(format=None)')
2072+ return True
2073+
2074+ def open_repository(self):
2075+ """See BzrDir.open_repository."""
2076+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat4
2077+ return RepositoryFormat4().open(self, _found=True)
2078+
2079+
2080+
2081+
2082+class BzrDir5(BzrDirPreSplitOut):
2083+ """A .bzr version 5 control object.
2084+
2085+ This is a deprecated format and may be removed after sept 2006.
2086+ """
2087+
2088+ def has_workingtree(self):
2089+ """See BzrDir.has_workingtree."""
2090+ return True
2091+
2092+ def open_repository(self):
2093+ """See BzrDir.open_repository."""
2094+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat5
2095+ return RepositoryFormat5().open(self, _found=True)
2096+
2097+ def open_workingtree(self, _unsupported=False,
2098+ recommend_upgrade=True):
2099+ """See BzrDir.create_workingtree."""
2100+ from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
2101+ wt_format = WorkingTreeFormat2()
2102+ # we don't warn here about upgrades; that ought to be handled for the
2103+ # bzrdir as a whole
2104+ return wt_format.open(self, _found=True)
2105+
2106+
2107+class BzrDir6(BzrDirPreSplitOut):
2108+ """A .bzr version 6 control object.
2109+
2110+ This is a deprecated format and may be removed after sept 2006.
2111+ """
2112+
2113+ def has_workingtree(self):
2114+ """See BzrDir.has_workingtree."""
2115+ return True
2116+
2117+ def open_repository(self):
2118+ """See BzrDir.open_repository."""
2119+ from bzrlib.plugins.weave_fmt.repository import RepositoryFormat6
2120+ return RepositoryFormat6().open(self, _found=True)
2121+
2122+ def open_workingtree(self, _unsupported=False,
2123+ recommend_upgrade=True):
2124+ """See BzrDir.create_workingtree."""
2125+ # we don't warn here about upgrades; that ought to be handled for the
2126+ # bzrdir as a whole
2127+ from bzrlib.plugins.weave_fmt.workingtree import WorkingTreeFormat2
2128+ return WorkingTreeFormat2().open(self, _found=True)
2129
2130=== renamed file 'bzrlib/repofmt/weaverepo.py' => 'bzrlib/plugins/weave_fmt/repository.py'
2131--- bzrlib/repofmt/weaverepo.py 2011-03-05 04:10:42 +0000
2132+++ bzrlib/plugins/weave_fmt/repository.py 2011-03-09 01:37:04 +0000
2133@@ -34,7 +34,6 @@
2134 )
2135 """)
2136 from bzrlib import (
2137- bzrdir,
2138 debug,
2139 errors,
2140 lockable_files,
2141@@ -65,6 +64,8 @@
2142 VersionedFiles,
2143 )
2144
2145+from bzrlib.plugins.weave_fmt import bzrdir as weave_bzrdir
2146+
2147
2148 class AllInOneRepository(Repository):
2149 """Legacy support - the repository behaviour for all-in-one branches."""
2150@@ -348,7 +349,7 @@
2151
2152 supports_funky_characters = False
2153
2154- _matchingbzrdir = bzrdir.BzrDirFormat4()
2155+ _matchingbzrdir = weave_bzrdir.BzrDirFormat4()
2156
2157 def get_format_description(self):
2158 """See RepositoryFormat.get_format_description()."""
2159@@ -372,7 +373,7 @@
2160 return None
2161
2162 def _get_revisions(self, repo_transport, repo):
2163- from bzrlib.xml4 import serializer_v4
2164+ from bzrlib.plugins.weave_fmt.xml4 import serializer_v4
2165 return RevisionTextStore(repo_transport.clone('revision-store'),
2166 serializer_v4, True, versionedfile.PrefixMapper(),
2167 repo.is_locked, repo.is_write_locked)
2168@@ -396,7 +397,7 @@
2169 """
2170
2171 _versionedfile_class = weave.WeaveFile
2172- _matchingbzrdir = bzrdir.BzrDirFormat5()
2173+ _matchingbzrdir = weave_bzrdir.BzrDirFormat5()
2174 supports_funky_characters = False
2175
2176 @property
2177@@ -432,6 +433,11 @@
2178 return versionedfile.ThunkedVersionedFiles(base_transport,
2179 weave.WeaveFile, mapper, repo.is_locked)
2180
2181+ def _get_extra_interrepo_test_combinations(self):
2182+ from bzrlib.repofmt import knitrepo
2183+ return [(InterRepository, RepositoryFormat5(),
2184+ knitrepo.RepositoryFormatKnit3())]
2185+
2186
2187 class RepositoryFormat6(PreSplitOutRepositoryFormat):
2188 """Bzr control format 6.
2189@@ -443,7 +449,7 @@
2190 """
2191
2192 _versionedfile_class = weave.WeaveFile
2193- _matchingbzrdir = bzrdir.BzrDirFormat6()
2194+ _matchingbzrdir = weave_bzrdir.BzrDirFormat6()
2195 supports_funky_characters = False
2196 @property
2197 def _serializer(self):
2198
2199=== added file 'bzrlib/plugins/weave_fmt/test_bzrdir.py'
2200--- bzrlib/plugins/weave_fmt/test_bzrdir.py 1970-01-01 00:00:00 +0000
2201+++ bzrlib/plugins/weave_fmt/test_bzrdir.py 2011-03-09 01:37:04 +0000
2202@@ -0,0 +1,512 @@
2203+# Copyright (C) 2006-2010 Canonical Ltd
2204+#
2205+# This program is free software; you can redistribute it and/or modify
2206+# it under the terms of the GNU General Public License as published by
2207+# the Free Software Foundation; either version 2 of the License, or
2208+# (at your option) any later version.
2209+#
2210+# This program is distributed in the hope that it will be useful,
2211+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2212+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2213+# GNU General Public License for more details.
2214+#
2215+# You should have received a copy of the GNU General Public License
2216+# along with this program; if not, write to the Free Software
2217+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2218+
2219+"""Tests for the weave-era BzrDir formats.
2220+
2221+For interface contract tests, see tests/per_bzr_dir.
2222+"""
2223+
2224+import sys
2225+
2226+from bzrlib import (
2227+ branch,
2228+ bzrdir,
2229+ repository,
2230+ upgrade,
2231+ workingtree,
2232+ )
2233+from bzrlib.osutils import (
2234+ lexists,
2235+ )
2236+from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
2237+from bzrlib.tests import (
2238+ TestCaseWithTransport,
2239+ )
2240+
2241+from bzrlib.plugins.weave_fmt.bzrdir import (
2242+ BzrDirFormat5,
2243+ BzrDirFormat6,
2244+ )
2245+
2246+
2247+class TestFormat5(TestCaseWithTransport):
2248+ """Tests specific to the version 5 bzrdir format."""
2249+
2250+ def test_same_lockfiles_between_tree_repo_branch(self):
2251+ # this checks that only a single lockfiles instance is created
2252+ # for format 5 objects
2253+ dir = BzrDirFormat5().initialize(self.get_url())
2254+ def check_dir_components_use_same_lock(dir):
2255+ ctrl_1 = dir.open_repository().control_files
2256+ ctrl_2 = dir.open_branch().control_files
2257+ ctrl_3 = dir.open_workingtree()._control_files
2258+ self.assertTrue(ctrl_1 is ctrl_2)
2259+ self.assertTrue(ctrl_2 is ctrl_3)
2260+ check_dir_components_use_same_lock(dir)
2261+ # and if we open it normally.
2262+ dir = bzrdir.BzrDir.open(self.get_url())
2263+ check_dir_components_use_same_lock(dir)
2264+
2265+ def test_can_convert(self):
2266+ # format 5 dirs are convertable
2267+ dir = BzrDirFormat5().initialize(self.get_url())
2268+ self.assertTrue(dir.can_convert_format())
2269+
2270+ def test_needs_conversion(self):
2271+ # format 5 dirs need a conversion if they are not the default,
2272+ # and they aren't
2273+ dir = BzrDirFormat5().initialize(self.get_url())
2274+ # don't need to convert it to itself
2275+ self.assertFalse(dir.needs_format_conversion(BzrDirFormat5()))
2276+ # do need to convert it to the current default
2277+ self.assertTrue(dir.needs_format_conversion(
2278+ bzrdir.BzrDirFormat.get_default_format()))
2279+
2280+
2281+class TestFormat6(TestCaseWithTransport):
2282+ """Tests specific to the version 6 bzrdir format."""
2283+
2284+ def test_same_lockfiles_between_tree_repo_branch(self):
2285+ # this checks that only a single lockfiles instance is created
2286+ # for format 6 objects
2287+ dir = BzrDirFormat6().initialize(self.get_url())
2288+ def check_dir_components_use_same_lock(dir):
2289+ ctrl_1 = dir.open_repository().control_files
2290+ ctrl_2 = dir.open_branch().control_files
2291+ ctrl_3 = dir.open_workingtree()._control_files
2292+ self.assertTrue(ctrl_1 is ctrl_2)
2293+ self.assertTrue(ctrl_2 is ctrl_3)
2294+ check_dir_components_use_same_lock(dir)
2295+ # and if we open it normally.
2296+ dir = bzrdir.BzrDir.open(self.get_url())
2297+ check_dir_components_use_same_lock(dir)
2298+
2299+ def test_can_convert(self):
2300+ # format 6 dirs are convertable
2301+ dir = BzrDirFormat6().initialize(self.get_url())
2302+ self.assertTrue(dir.can_convert_format())
2303+
2304+ def test_needs_conversion(self):
2305+ # format 6 dirs need an conversion if they are not the default.
2306+ dir = BzrDirFormat6().initialize(self.get_url())
2307+ self.assertTrue(dir.needs_format_conversion(
2308+ bzrdir.BzrDirFormat.get_default_format()))
2309+
2310+
2311+class TestBreakLockOldBranch(TestCaseWithTransport):
2312+
2313+ def test_break_lock_format_5_bzrdir(self):
2314+ # break lock on a format 5 bzrdir should just return
2315+ self.make_branch_and_tree('foo', format=BzrDirFormat5())
2316+ out, err = self.run_bzr('break-lock foo')
2317+ self.assertEqual('', out)
2318+ self.assertEqual('', err)
2319+
2320+
2321+_upgrade1_template = \
2322+ [
2323+ ('foo', 'new contents\n'),
2324+ ('.bzr/',),
2325+ ('.bzr/README',
2326+ 'This is a Bazaar control directory.\n'
2327+ 'Do not change any files in this directory.\n'
2328+ 'See http://bazaar.canonical.com/ for more information about Bazaar.\n'),
2329+ ('.bzr/branch-format', 'Bazaar-NG branch, format 0.0.4\n'),
2330+ ('.bzr/revision-history',
2331+ 'mbp@sourcefrog.net-20051004035611-176b16534b086b3c\n'
2332+ 'mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd\n'),
2333+ ('.bzr/merged-patches', ''),
2334+ ('.bzr/pending-merged-patches', ''),
2335+ ('.bzr/branch-name', ''),
2336+ ('.bzr/branch-lock', ''),
2337+ ('.bzr/pending-merges', ''),
2338+ ('.bzr/inventory',
2339+ '<inventory>\n'
2340+ '<entry file_id="foo-20051004035605-91e788d1875603ae" kind="file" name="foo" />\n'
2341+ '</inventory>\n'),
2342+ ('.bzr/stat-cache',
2343+ '### bzr hashcache v5\n'
2344+ 'foo// be9f309239729f69a6309e970ef24941d31e042c 13 1128398176 1128398176 303464 770\n'),
2345+ ('.bzr/text-store/',),
2346+ ('.bzr/text-store/foo-20051004035611-1591048e9dc7c2d4.gz',
2347+ '\x1f\x8b\x08\x00[\xfdAC\x02\xff\xcb\xcc\xcb,\xc9L\xccQH\xce\xcf+I\xcd+)\xe6\x02\x00\xdd\xcc\xf90\x11\x00\x00\x00'),
2348+ ('.bzr/text-store/foo-20051004035756-4081373d897c3453.gz',
2349+ '\x1f\x8b\x08\x00\xc4\xfdAC\x02\xff\xcbK-WH\xce\xcf+I\xcd+)\xe6\x02\x00g\xc3\xdf\xc9\r\x00\x00\x00'),
2350+ ('.bzr/inventory-store/',),
2351+ ('.bzr/inventory-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz',
2352+ '\x1f\x8b\x08\x00[\xfdAC\x02\xffm\x8f\xcd\n\xc20\x10\x84\xef>E\xc8\xbdt7?M\x02\xad\xaf"\xa1\x99`P[\xa8E\xacOo\x14\x05\x0f\xdef\xe1\xfbv\x98\xbeL7L\xeb\xbcl\xfb]_\xc3\xb2\x89\\\xce8\x944\xc8<\xcf\x8d"\xb2LdH\xdb\x8el\x13\x18\xce\xfb\xc4\xde\xd5SGHq*\xd3\x0b\xad\x8e\x14S\xbc\xe0\xadI\xb1\xe2\xbe\xfe}\xc2\xdc\xb0\rL\xc6#\xa4\xd1\x8d*\x99\x0f}=F\x1e$8G\x9d\xa0\x02\xa1rP9\x01c`FV\xda1qg\x98"\x02}\xa5\xf2\xa8\x95\xec\xa4h\xeb\x80\xf6g\xcd\x13\xb3\x01\xcc\x98\xda\x00\x00\x00'),
2353+ ('.bzr/inventory-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz',
2354+ '\x1f\x8b\x08\x00\xc4\xfdAC\x02\xffm\x8f\xc1\n\xc20\x10D\xef~E\xc8\xbd\xb8\x9bM\x9a,\xb4\xfe\x8a\xc4f\x83Am\xa1\x16\xb1~\xbdQ\x14<x\x9b\x81y3LW\xc6\x9b\x8c\xcb4\xaf\xbbMW\xc5\xbc\xaa\\\xce\xb2/\xa9\xd7y\x9a\x1a\x03\xe0\x10\xc0\x02\xb9\x16\\\xc3(>\x84\x84\xc1WKQ\xb4:\x95\xf1\x15\xad\x8cVc\xbc\xc8\x1b\xd3j\x91\xfb\xf2\xaf\xa4r\x8d\x85\x80\xe4)\x05\xf6\x03YG\x9f\xf4\xf5\x18\xb1\xd7\x07\xe1L\xc0\x86\xd8\x1b\xce-\xc7\xb6:a\x0f\x92\x8de\x8b\x89P\xc0\x9a\xe1\x0b\x95G\x9d\xc4\xda\xb1\xad\x07\xb6?o\x9e\xb5\xff\xf0\xf9\xda\x00\x00\x00'),
2355+ ('.bzr/revision-store/',),
2356+ ('.bzr/revision-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz',
2357+ '\x1f\x8b\x08\x00[\xfdAC\x02\xff\x9d\x8eKj\xc30\x14E\xe7^\x85\xd0 \xb3$\xefI\xd1\x8f\xd8\xa6\x1b(t\x07E?\xbb\x82H\n\xb2\x1ahW\xdfB1\x14:\xeb\xf4r\xee\xbdgl\xf1\x91\xb6T\x0b\xf15\xe7\xd4{l\x13}\xb6\xad\xa7B^j\xbd\x91\xc3\xad_\xb3\xbb?m\xf5\xbd\xf9\xb8\xb4\xba\x9eJ\xec\x87\xb5_)I\xe5\x11K\xaf\xed\xe35\x85\x89\xfe\xa5\x8e\x0c@ \xc0\x05\xb8\x90\x88GT\xd2\xa1\x14\xfc\xe2@K\xc7\xfd\xef\x85\xed\xcd\xe2D\x95\x8d\x1a\xa47<\x02c2\xb0 \xbc\xd0\x8ay\xa3\xbcp\x8a\x83\x12A3\xb7XJv\xef\x7f_\xf7\x94\xe3\xd6m\xbeO\x14\x91in4*<\x812\x88\xc60\xfc\x01>k\x89\x13\xe5\x12\x00\xe8<\x8c\xdf\x8d\xcd\xaeq\xb6!\x90\xa5\xd6\xf1\xbc\x07\xc3x\xde\x85\xe6\xe1\x0b\xc8\x8a\x98\x03T\x01\x00\x00'),
2358+ ('.bzr/revision-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz',
2359+ '\x1f\x8b\x08\x00\xc4\xfdAC\x02\xff\x9d\x90Kj\x031\x0c\x86\xf79\xc5\xe0Ev\xe9\xc8o\x9b\xcc\x84^\xa0\xd0\x1b\x14\xbf&5d\xec`\xbb\x81\xf6\xf45\x84\xa4\x81\xaeZ\xa1\x85\x84^\xdf\xaf\xa9\x84K\xac1\xa7\xc1\xe5u\x8d\xad\x852\xa3\x17SZL\xc3k\xce\xa7a{j\xfb\xd5\x9e\x9fk\xfe(.,%\x1f\x9fRh\xdbc\xdb\xa3!\xa6KH-\x97\xcf\xb7\xe8g\xf4\xbbkG\x008\x06`@\xb9\xe4bG(_\x88\x95\xde\xf9n\xca\xfb\xc7\r\xf5\xdd\xe0\x19\xa9\x85)\x81\xf5"\xbd\x04j\xb8\x02b\xa8W\\\x0b\xc9\x14\xf4\xbc\xbb\xd7\xd6H4\xdc\xb8\xff}\xba\xc55\xd4f\xd6\xf3\x8c0&\x8ajE\xa4x\xe2@\xa5\xa6\x9a\xf3k\xc3WNaFT\x00\x00:l\xa6>Q\xcd1\x1cjp9\xf9;\xc34\xde\n\x9b\xe9lJWT{t\',a\xf9\x0b\xae\xc0x\x87\xa5\xb0Xp\xca,(a\xa9{\xd0{}\xd4\x12\x04(\xc5\xbb$\xc5$V\xceaI\x19\x01\xa2\x1dh\xed\x82d\x8c.\xccr@\xc3\xd8Q\xc6\x1f\xaa\xf1\xb6\xe8\xb0\xf9\x06QR\r\xf9\xfc\x01\x00\x00')]
2360+
2361+
2362+_ghost_template = [
2363+ ( './foo',
2364+ 'hello\n'
2365+ ),
2366+ ( './.bzr/', ),
2367+ ( './.bzr/README',
2368+ 'This is a Bazaar control directory.\n'
2369+ 'Do not change any files in this directory.\n'
2370+ 'See http://bazaar.canonical.com/ for more information about Bazaar.\n'
2371+ ),
2372+ ( './.bzr/branch-format',
2373+ 'Bazaar-NG branch, format 0.0.4\n'
2374+ ),
2375+ ( './.bzr/branch-lock',
2376+ ''
2377+ ),
2378+ ( './.bzr/branch-name',
2379+ ''
2380+ ),
2381+ ( './.bzr/inventory',
2382+ '<inventory>\n'
2383+ '<entry file_id="foo-20051004104918-0379cb7c76354cde" kind="file" name="foo" />\n'
2384+ '</inventory>\n'
2385+ ),
2386+ ( './.bzr/merged-patches',
2387+ ''
2388+ ),
2389+ ( './.bzr/pending-merged-patches',
2390+ ''
2391+ ),
2392+ ( './.bzr/pending-merges',
2393+ ''
2394+ ),
2395+ ( './.bzr/revision-history',
2396+ 'mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b\n'
2397+ 'mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d\n'
2398+ ),
2399+ ( './.bzr/stat-cache',
2400+ '### bzr hashcache v5\n'
2401+ 'foo// f572d396fae9206628714fb2ce00f72e94f2258f 6 1128422956 1128422956 306900 770\n'
2402+ ),
2403+ ( './.bzr/text-store/', ),
2404+ ( './.bzr/text-store/foo-20051004104921-8de8118a71be45ba.gz',
2405+ '\x1f\x8b\x08\x081^BC\x00\x03foo-20051004104921-8de8118a71be45ba\x00\xcbH\xcd\xc9\xc9\xe7\x02\x00 0:6\x06\x00\x00\x00'
2406+ ),
2407+ ( './.bzr/inventory-store/', ),
2408+ ( './.bzr/inventory-store/mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b.gz',
2409+ '\x1f\x8b\x08\x081^BC\x00\x03mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b\x00m\x8f\xcb\n'
2410+ '\xc20\x10E\xf7~E\xc8\xbe83\xcd\x13\xaa\xbf"yL0\xa8-\xd4"\xd6\xaf7\x8a\x82\x0bw\xb38\xe7\xde;C\x1do<.\xd3\xbc\xee7C;\xe6U\x94z\xe6C\xcd;Y\xa6\xa9#\x00\x8d\x00\n'
2411+ 'Ayt\x1d\xf4\xd6\xa7h\x935\xbdV)\xb3\x14\xa7:\xbe\xd0\xe6H1\x86\x0b\xbf5)\x16\xbe/\x7fC\x08;\x97\xd9!\xba`1\xb2\xd21|\xe8\xeb1`\xe3\xb5\xa5\xdc{S\x02{\x02c\xc8YT%Rb\x80b\x89\xbd*D\xda\x95\xafT\x1f\xad\xd2H\xb1m\xfb\xb7?\xcf<\x01W}\xb5\x8b\xd9\x00\x00\x00'
2412+ ),
2413+ ( './.bzr/inventory-store/mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d.gz',
2414+ '\x1f\x8b\x08\x08A^BC\x00\x03mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d\x00m\x8f\xcb\n'
2415+ '\xc20\x10E\xf7~E\xc8\xbe83\xcd\x13\xaa\xbf"yL0\xa8-\xd4"\xd6\xaf7\x8a\x82\x0bw\xb38\xe7\xde;C\x1do<.\xd3\xbc\xee7C;\xe6U\x94z\xe6C\xcd;Y\xa6\xa9#\x00\x8d\x00\n'
2416+ 'Ayt\x1d\xf4\xd6\xa7h\x935\xbdV)\xb3\x14\xa7:\xbe\xd0\xe6H1\x86\x0b\xbf5)\x16\xbe/\x7fC\x08;\x97\xd9!\xba`1\xb2\xd21|\xe8\xeb1`\xe3\xb5\xa5\xdc{S\x02{\x02c\xc8YT%Rb\x80b\x89\xbd*D\xda\x95\xafT\x1f\xad\xd2H\xb1m\xfb\xb7?\xcf<\x01W}\xb5\x8b\xd9\x00\x00\x00'
2417+ ),
2418+ ( './.bzr/revision-store/', ),
2419+ ( './.bzr/revision-store/mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b.gz',
2420+ '\x1f\x8b\x08\x081^BC\x00\x03mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b\x00\x9d\x8eMj\xc30\x14\x84\xf7>\x85\xd0"\xbb$\xef\xc9\xb6,\x11\xdb\xf4\x02\x85\xde\xa0\xe8\xe7\xd9\x11\xc4R\x90\xd4@{\xfa\x06\x8a\xa1\xd0]\x97\x03\xdf\xcc|c\xa6G(!E\xe6\xd2\xb6\x85Z)O\xfc\xd5\xe4\x1a"{K\xe9\xc6\x0e\xb7z\xd9\xec\xfd\xa5\xa4\x8f\xech\xc9i=E\xaa\x87\xb5^8\x0b\xf1A\xb1\xa6\xfc\xf9\x1e\xfc\xc4\xffRG\x01\xd0#@\x87\xd0i\x81G\xa3\x95%!\x06\xe5}\x0bv\xb0\xbf\x17\xca\xd5\xe0\xc4-\xa0\xb1\x8b\xb6`\xc0I\xa4\xc5\xf4\x9el\xef\x95v [\x94\xcf\x8e\xd5\xcay\xe4l\xf7\xfe\xf7u\r'
2421+ '\x1b\x95j\xb6\xfb\xc4\x11\x85\xea\x84\xd0\x12O\x03t\x83D\xad\xc4\x0f\xf0\x95"M\xbc\x95\x00\xc0\xe7f|6\x8aYi^B.u<\xef\xb1\x19\xcf\xbb\xce\xdc|\x038=\xc7\xe6R\x01\x00\x00'
2422+ ),
2423+ ( './.bzr/revision-store/mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d.gz',
2424+ '\x1f\x8b\x08\x08A^BC\x00\x03mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d\x00\x9d\x90\xc1j\xc30\x0c\x86\xef}\n'
2425+ "\xe3Coie'\xb1c\x9a\x94\xbe\xc0`o0,[N\x03M\\\x1c\xafe{\xfae\x94n\x85\xc1`;Y\x88O\xd2\xff\xb9Mt\x19\xe6!N\xcc\xc5q\x1cr\xa6\xd4\xf1'\x9b\xf20\xb1\xe7\x18Ol}\xca\xbb\x11\xcf\x879\xbe&G!\xc5~3Q^\xf7y\xc7\xd90]h\xca1\xbd\xbd\x0c\xbe\xe3?\xa9B\x02\xd4\x02\xa0\x12P\x99R\x17\xce\xa0\xb6\x1a\x83s\x80(\xa5\x7f\xdc0\x1f\xad\xe88\x82\xb0\x18\x0c\x82\x05\xa7\x04\x05[{\xc2\xda7\xc6\x81*\x85B\x8dh\x1a\xe7\x05g\xf7\xdc\xff>\x9d\x87\x91\xe6l\xc7s\xc7\x85\x90M%\xa5\xd1z#\x85\xa8\x9b\x1a\xaa\xfa\x06\xbc\xc7\x89:^*\x00\xe0\xfbU\xbbL\xcc\xb6\xa7\xfdH\xa9'\x16\x03\xeb\x8fq\xce\xed\xf6\xde_\xb5g\x9b\x16\xa1y\xa9\xbe\x02&\n"
2426+ '\x7fJ+EaM\x83$\xa5n\xbc/a\x91~\xd0\xbd\xfd\x135\n'
2427+ '\xd0\x9a`\x0c*W\x1aR\xc1\x94du\x08(\t\xb0\x91\xdeZ\xa3\x9cU\x9cm\x7f\x8dr\x1d\x10Ot\xb8\xc6\xcf\xa7\x907|\xfb-\xb1\xbd\xd3\xfb\xd5\x07\xeeD\xee\x08*\x02\x00\x00'
2428+ ),
2429+]
2430+
2431+_upgrade_dir_template = [
2432+ ( './.bzr/', ),
2433+ ( './.bzr/README',
2434+ 'This is a Bazaar control directory.\n'
2435+ 'Do not change any files in this directory.\n'
2436+ 'See http://bazaar.canonical.com/ for more information about Bazaar.\n'
2437+ ),
2438+ ( './.bzr/branch-format',
2439+ 'Bazaar-NG branch, format 0.0.4\n'
2440+ ),
2441+ ( './.bzr/branch-lock',
2442+ ''
2443+ ),
2444+ ( './.bzr/branch-name',
2445+ ''
2446+ ),
2447+ ( './.bzr/inventory',
2448+ '<inventory>\n'
2449+ '<entry file_id="dir-20051005095101-da1441ea3fa6917a" kind="directory" name="dir" />\n'
2450+ '</inventory>\n'
2451+ ),
2452+ ( './.bzr/merged-patches',
2453+ ''
2454+ ),
2455+ ( './.bzr/pending-merged-patches',
2456+ ''
2457+ ),
2458+ ( './.bzr/pending-merges',
2459+ ''
2460+ ),
2461+ ( './.bzr/revision-history',
2462+ 'robertc@robertcollins.net-20051005095108-6065fbd8e7d8617e\n'
2463+ ),
2464+ ( './.bzr/stat-cache',
2465+ '### bzr hashcache v5\n'
2466+ ),
2467+ ( './.bzr/text-store/', ),
2468+ ( './.bzr/inventory-store/', ),
2469+ ( './.bzr/inventory-store/robertc@robertcollins.net-20051005095108-6065fbd8e7d8617e.gz',
2470+ '\x1f\x8b\x08\x00\x0c\xa2CC\x02\xff\xb3\xc9\xcc+K\xcd+\xc9/\xaa\xb4\xe3\xb2\x012\x8a*\x15\xd22sR\xe33Sl\x95R2\x8bt\x8d\x0c\x0cL\r'
2471+ "\x81\xd8\xc0\x12H\x19\xea\xa6$\x1a\x9a\x98\x18\xa6&\x1a\xa7%\x9aY\x1a\x9a'*)dg\xe6A\x94\xa6&\x83LQR\xc8K\xccM\x05\x0b()\xe8\x03\xcd\xd4G\xb2\x00\x00\xc2<\x94\xb1m\x00\x00\x00"
2472+ ),
2473+ ( './.bzr/revision-store/', ),
2474+ ( './.bzr/revision-store/robertc@robertcollins.net-20051005095108-6065fbd8e7d8617e.gz',
2475+ '\x1f\x8b\x08\x00\x0c\xa2CC\x02\xff\xa5OKj\xc30\x14\xdc\xfb\x14B\x8b\xec\x92<I\xd6\xc7\xc42\x85\xde\xa0\x17(\xb6\xf4\x9c\n'
2476+ 'l\xa9H"\x90\x9c\xbe\xa6\xa9\xa1\x9b\xae\xbax\x0c\xcc\xe71\xd3g\xbc\x85\x12R$.\xadk\xa8\x15\xb3\xa5oi\xc2\\\xc9kZ\x96\x10\x0b9,\xf5\x92\xbf)\xf7\xf2\x83O\xe5\x14\xb1\x1e\xae\xf5BI\x887\x8c5\xe5\xfb{\xf0\x96\xfei>r\x00\xc9\xb6\x83n\x03sT\xa0\xe4<y\x83\xda\x1b\xc54\xfe~T>Ff\xe9\xcc:\xdd\x8e\xa6E\xc7@\xa2\x82I\xaaNL\xbas\\313)\x00\xb9\xe6\xe0(\xd9\x87\xfc\xb7A\r'
2477+ "+\x96:\xae\x9f\x962\xc6\x8d\x04i\x949\x01\x97R\xb7\x1d\x17O\xc3#E\xb4T(\x00\xa0C\xd3o\x892^q\x18\xbd'>\xe4\xfe\xbc\x13M\x7f\xde{\r"
2478+ '\xcd\x17\x85\xea\xba\x03l\x01\x00\x00'
2479+ ),
2480+ ( './dir/', ),
2481+]
2482+
2483+
2484+class TestUpgrade(TestCaseWithTransport):
2485+
2486+ def test_upgrade_v6_to_meta_no_workingtree(self):
2487+ # Some format6 branches do not have checkout files. Upgrading
2488+ # such a branch to metadir must not setup a working tree.
2489+ self.build_tree_contents(_upgrade1_template)
2490+ upgrade.upgrade('.', BzrDirFormat6())
2491+ t = self.get_transport('.')
2492+ t.delete_multi(['.bzr/pending-merges', '.bzr/inventory'])
2493+ self.assertFalse(t.has('.bzr/stat-cache'))
2494+ # XXX: upgrade fails if a backup.bzr is already present
2495+ # -- David Allouche 2006-08-11
2496+ t.delete_tree('backup.bzr.~1~')
2497+ # At this point, we have a format6 branch without checkout files.
2498+ upgrade.upgrade('.', bzrdir.BzrDirMetaFormat1())
2499+ # The upgrade should not have set up a working tree.
2500+ control = bzrdir.BzrDir.open('.')
2501+ self.assertFalse(control.has_workingtree())
2502+ # We have covered the scope of this test, we may as well check that
2503+ # upgrade has not eaten our data, even if it's a bit redundant with
2504+ # other tests.
2505+ self.failUnless(isinstance(control._format, bzrdir.BzrDirMetaFormat1))
2506+ b = control.open_branch()
2507+ self.assertEquals(b.revision_history(),
2508+ ['mbp@sourcefrog.net-20051004035611-176b16534b086b3c',
2509+ 'mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd'])
2510+
2511+ def test_upgrade_simple(self):
2512+ """Upgrade simple v0.0.4 format to latest format"""
2513+ eq = self.assertEquals
2514+ self.build_tree_contents(_upgrade1_template)
2515+ upgrade.upgrade(u'.')
2516+ control = bzrdir.BzrDir.open('.')
2517+ b = control.open_branch()
2518+ # tsk, peeking under the covers.
2519+ self.failUnless(
2520+ isinstance(
2521+ control._format,
2522+ bzrdir.BzrDirFormat.get_default_format().__class__))
2523+ rh = b.revision_history()
2524+ eq(rh,
2525+ ['mbp@sourcefrog.net-20051004035611-176b16534b086b3c',
2526+ 'mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd'])
2527+ rt = b.repository.revision_tree(rh[0])
2528+ foo_id = 'foo-20051004035605-91e788d1875603ae'
2529+ rt.lock_read()
2530+ try:
2531+ eq(rt.get_file_text(foo_id), 'initial contents\n')
2532+ finally:
2533+ rt.unlock()
2534+ rt = b.repository.revision_tree(rh[1])
2535+ rt.lock_read()
2536+ try:
2537+ eq(rt.get_file_text(foo_id), 'new contents\n')
2538+ finally:
2539+ rt.unlock()
2540+ # check a backup was made:
2541+ backup_dir = 'backup.bzr.~1~'
2542+ t = self.get_transport('.')
2543+ t.stat(backup_dir)
2544+ t.stat(backup_dir + '/README')
2545+ t.stat(backup_dir + '/branch-format')
2546+ t.stat(backup_dir + '/revision-history')
2547+ t.stat(backup_dir + '/merged-patches')
2548+ t.stat(backup_dir + '/pending-merged-patches')
2549+ t.stat(backup_dir + '/pending-merges')
2550+ t.stat(backup_dir + '/branch-name')
2551+ t.stat(backup_dir + '/branch-lock')
2552+ t.stat(backup_dir + '/inventory')
2553+ t.stat(backup_dir + '/stat-cache')
2554+ t.stat(backup_dir + '/text-store')
2555+ t.stat(backup_dir + '/text-store/foo-20051004035611-1591048e9dc7c2d4.gz')
2556+ t.stat(backup_dir + '/text-store/foo-20051004035756-4081373d897c3453.gz')
2557+ t.stat(backup_dir + '/inventory-store/')
2558+ t.stat(backup_dir + '/inventory-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz')
2559+ t.stat(backup_dir + '/inventory-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz')
2560+ t.stat(backup_dir + '/revision-store/')
2561+ t.stat(backup_dir + '/revision-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz')
2562+ t.stat(backup_dir + '/revision-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz')
2563+
2564+ def test_upgrade_with_ghosts(self):
2565+ """Upgrade v0.0.4 tree containing ghost references.
2566+
2567+ That is, some of the parents of revisions mentioned in the branch
2568+ aren't present in the branch's storage.
2569+
2570+ This shouldn't normally happen in branches created entirely in
2571+ bzr, but can happen in branches imported from baz and arch, or from
2572+ other systems, where the importer knows about a revision but not
2573+ its contents."""
2574+ eq = self.assertEquals
2575+ self.build_tree_contents(_ghost_template)
2576+ upgrade.upgrade(u'.')
2577+ b = branch.Branch.open(u'.')
2578+ revision_id = b.revision_history()[1]
2579+ rev = b.repository.get_revision(revision_id)
2580+ eq(len(rev.parent_ids), 2)
2581+ eq(rev.parent_ids[1], 'wibble@wobble-2')
2582+
2583+ def test_upgrade_makes_dir_weaves(self):
2584+ self.build_tree_contents(_upgrade_dir_template)
2585+ old_repodir = bzrdir.BzrDir.open_unsupported('.')
2586+ old_repo_format = old_repodir.open_repository()._format
2587+ upgrade.upgrade('.')
2588+ # this is the path to the literal file. As format changes
2589+ # occur it needs to be updated. FIXME: ask the store for the
2590+ # path.
2591+ repo = repository.Repository.open('.')
2592+ # it should have changed the format
2593+ self.assertNotEqual(old_repo_format.__class__, repo._format.__class__)
2594+ # and we should be able to read the names for the file id
2595+ # 'dir-20051005095101-da1441ea3fa6917a'
2596+ repo.lock_read()
2597+ self.addCleanup(repo.unlock)
2598+ text_keys = repo.texts.keys()
2599+ dir_keys = [key for key in text_keys if key[0] ==
2600+ 'dir-20051005095101-da1441ea3fa6917a']
2601+ self.assertNotEqual([], dir_keys)
2602+
2603+ def test_upgrade_to_meta_sets_workingtree_last_revision(self):
2604+ self.build_tree_contents(_upgrade_dir_template)
2605+ upgrade.upgrade('.', bzrdir.BzrDirMetaFormat1())
2606+ tree = workingtree.WorkingTree.open('.')
2607+ self.assertEqual([tree.branch.revision_history()[-1]],
2608+ tree.get_parent_ids())
2609+
2610+
2611+class SFTPBranchTest(TestCaseWithSFTPServer):
2612+ """Test some stuff when accessing a bzr Branch over sftp"""
2613+
2614+ def test_lock_file(self):
2615+ # old format branches use a special lock file on sftp.
2616+ b = self.make_branch('', format=BzrDirFormat6())
2617+ b = branch.Branch.open(self.get_url())
2618+ self.failUnlessExists('.bzr/')
2619+ self.failUnlessExists('.bzr/branch-format')
2620+ self.failUnlessExists('.bzr/branch-lock')
2621+
2622+ self.failIf(lexists('.bzr/branch-lock.write-lock'))
2623+ b.lock_write()
2624+ self.failUnlessExists('.bzr/branch-lock.write-lock')
2625+ b.unlock()
2626+ self.failIf(lexists('.bzr/branch-lock.write-lock'))
2627+
2628+
2629+class TestInfo(TestCaseWithTransport):
2630+
2631+ def test_info_locking_oslocks(self):
2632+ if sys.platform == "win32":
2633+ self.skip("don't use oslocks on win32 in unix manner")
2634+ # This test tests old (all-in-one, OS lock using) behaviour which
2635+ # simply cannot work on windows (and is indeed why we changed our
2636+ # design. As such, don't try to remove the thisFailsStrictLockCheck
2637+ # call here.
2638+ self.thisFailsStrictLockCheck()
2639+
2640+ tree = self.make_branch_and_tree('branch',
2641+ format=BzrDirFormat6())
2642+
2643+ # Test all permutations of locking the working tree, branch and repository
2644+ # XXX: Well not yet, as we can't query oslocks yet. Currently, it's
2645+ # implemented by raising NotImplementedError and get_physical_lock_status()
2646+ # always returns false. This makes bzr info hide the lock status. (Olaf)
2647+ # W B R
2648+
2649+ # U U U
2650+ out, err = self.run_bzr('info -v branch')
2651+ self.assertEqualDiff(
2652+"""Standalone tree (format: weave)
2653+Location:
2654+ branch root: %s
2655+
2656+Format:
2657+ control: All-in-one format 6
2658+ working tree: Working tree format 2
2659+ branch: Branch format 4
2660+ repository: %s
2661+
2662+In the working tree:
2663+ 0 unchanged
2664+ 0 modified
2665+ 0 added
2666+ 0 removed
2667+ 0 renamed
2668+ 0 unknown
2669+ 0 ignored
2670+ 0 versioned subdirectories
2671+
2672+Branch history:
2673+ 0 revisions
2674+
2675+Repository:
2676+ 0 revisions
2677+""" % ('branch', tree.branch.repository._format.get_format_description(),
2678+ ), out)
2679+ self.assertEqual('', err)
2680+ # L L L
2681+ tree.lock_write()
2682+ out, err = self.run_bzr('info -v branch')
2683+ self.assertEqualDiff(
2684+"""Standalone tree (format: weave)
2685+Location:
2686+ branch root: %s
2687+
2688+Format:
2689+ control: All-in-one format 6
2690+ working tree: Working tree format 2
2691+ branch: Branch format 4
2692+ repository: %s
2693+
2694+In the working tree:
2695+ 0 unchanged
2696+ 0 modified
2697+ 0 added
2698+ 0 removed
2699+ 0 renamed
2700+ 0 unknown
2701+ 0 ignored
2702+ 0 versioned subdirectories
2703+
2704+Branch history:
2705+ 0 revisions
2706+
2707+Repository:
2708+ 0 revisions
2709+""" % ('branch', tree.branch.repository._format.get_format_description(),
2710+ ), out)
2711+ self.assertEqual('', err)
2712+ tree.unlock()
2713+
2714+
2715
2716=== added file 'bzrlib/plugins/weave_fmt/test_repository.py'
2717--- bzrlib/plugins/weave_fmt/test_repository.py 1970-01-01 00:00:00 +0000
2718+++ bzrlib/plugins/weave_fmt/test_repository.py 2011-03-09 01:37:04 +0000
2719@@ -0,0 +1,329 @@
2720+# Copyright (C) 2006-2010 Canonical Ltd
2721+#
2722+# This program is free software; you can redistribute it and/or modify
2723+# it under the terms of the GNU General Public License as published by
2724+# the Free Software Foundation; either version 2 of the License, or
2725+# (at your option) any later version.
2726+#
2727+# This program is distributed in the hope that it will be useful,
2728+# but WITHOUT ANY WARRANTY; without even the implied warranty of
2729+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2730+# GNU General Public License for more details.
2731+#
2732+# You should have received a copy of the GNU General Public License
2733+# along with this program; if not, write to the Free Software
2734+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2735+
2736+"""Tests for weave repositories.
2737+
2738+For interface tests see tests/per_repository/*.py.
2739+
2740+"""
2741+
2742+from cStringIO import StringIO
2743+from stat import S_ISDIR
2744+import sys
2745+
2746+from bzrlib.bzrdir import (
2747+ BzrDirMetaFormat1,
2748+ )
2749+from bzrlib.errors import (
2750+ IllegalPath,
2751+ NoSuchFile,
2752+ )
2753+from bzrlib.repository import (
2754+ InterRepository,
2755+ Repository,
2756+ )
2757+from bzrlib.serializer import (
2758+ format_registry as serializer_format_registry,
2759+ )
2760+from bzrlib.tests import (
2761+ TestCase,
2762+ TestCaseWithTransport,
2763+ )
2764+
2765+from bzrlib.plugins.weave_fmt import xml4
2766+from bzrlib.plugins.weave_fmt.bzrdir import (
2767+ BzrDirFormat6,
2768+ )
2769+from bzrlib.plugins.weave_fmt.repository import (
2770+ InterWeaveRepo,
2771+ RepositoryFormat4,
2772+ RepositoryFormat5,
2773+ RepositoryFormat6,
2774+ RepositoryFormat7,
2775+ )
2776+
2777+
2778+class TestFormat6(TestCaseWithTransport):
2779+
2780+ def test_attribute__fetch_order(self):
2781+ """Weaves need topological data insertion."""
2782+ control = BzrDirFormat6().initialize(self.get_url())
2783+ repo = RepositoryFormat6().initialize(control)
2784+ self.assertEqual('topological', repo._format._fetch_order)
2785+
2786+ def test_attribute__fetch_uses_deltas(self):
2787+ """Weaves do not reuse deltas."""
2788+ control = BzrDirFormat6().initialize(self.get_url())
2789+ repo = RepositoryFormat6().initialize(control)
2790+ self.assertEqual(False, repo._format._fetch_uses_deltas)
2791+
2792+ def test_attribute__fetch_reconcile(self):
2793+ """Weave repositories need a reconcile after fetch."""
2794+ control = BzrDirFormat6().initialize(self.get_url())
2795+ repo = RepositoryFormat6().initialize(control)
2796+ self.assertEqual(True, repo._format._fetch_reconcile)
2797+
2798+ def test_no_ancestry_weave(self):
2799+ control = BzrDirFormat6().initialize(self.get_url())
2800+ repo = RepositoryFormat6().initialize(control)
2801+ # We no longer need to create the ancestry.weave file
2802+ # since it is *never* used.
2803+ self.assertRaises(NoSuchFile,
2804+ control.transport.get,
2805+ 'ancestry.weave')
2806+
2807+ def test_supports_external_lookups(self):
2808+ control = BzrDirFormat6().initialize(self.get_url())
2809+ repo = RepositoryFormat6().initialize(control)
2810+ self.assertFalse(repo._format.supports_external_lookups)
2811+
2812+
2813+
2814+
2815+class TestFormat7(TestCaseWithTransport):
2816+
2817+ def test_attribute__fetch_order(self):
2818+ """Weaves need topological data insertion."""
2819+ control = BzrDirMetaFormat1().initialize(self.get_url())
2820+ repo = RepositoryFormat7().initialize(control)
2821+ self.assertEqual('topological', repo._format._fetch_order)
2822+
2823+ def test_attribute__fetch_uses_deltas(self):
2824+ """Weaves do not reuse deltas."""
2825+ control = BzrDirMetaFormat1().initialize(self.get_url())
2826+ repo = RepositoryFormat7().initialize(control)
2827+ self.assertEqual(False, repo._format._fetch_uses_deltas)
2828+
2829+ def test_attribute__fetch_reconcile(self):
2830+ """Weave repositories need a reconcile after fetch."""
2831+ control = BzrDirMetaFormat1().initialize(self.get_url())
2832+ repo = RepositoryFormat7().initialize(control)
2833+ self.assertEqual(True, repo._format._fetch_reconcile)
2834+
2835+ def test_disk_layout(self):
2836+ control = BzrDirMetaFormat1().initialize(self.get_url())
2837+ repo = RepositoryFormat7().initialize(control)
2838+ # in case of side effects of locking.
2839+ repo.lock_write()
2840+ repo.unlock()
2841+ # we want:
2842+ # format 'Bazaar-NG Repository format 7'
2843+ # lock ''
2844+ # inventory.weave == empty_weave
2845+ # empty revision-store directory
2846+ # empty weaves directory
2847+ t = control.get_repository_transport(None)
2848+ self.assertEqualDiff('Bazaar-NG Repository format 7',
2849+ t.get('format').read())
2850+ self.assertTrue(S_ISDIR(t.stat('revision-store').st_mode))
2851+ self.assertTrue(S_ISDIR(t.stat('weaves').st_mode))
2852+ self.assertEqualDiff('# bzr weave file v5\n'
2853+ 'w\n'
2854+ 'W\n',
2855+ t.get('inventory.weave').read())
2856+ # Creating a file with id Foo:Bar results in a non-escaped file name on
2857+ # disk.
2858+ control.create_branch()
2859+ tree = control.create_workingtree()
2860+ tree.add(['foo'], ['Foo:Bar'], ['file'])
2861+ tree.put_file_bytes_non_atomic('Foo:Bar', 'content\n')
2862+ try:
2863+ tree.commit('first post', rev_id='first')
2864+ except IllegalPath:
2865+ if sys.platform != 'win32':
2866+ raise
2867+ self.knownFailure('Foo:Bar cannot be used as a file-id on windows'
2868+ ' in repo format 7')
2869+ return
2870+ self.assertEqualDiff(
2871+ '# bzr weave file v5\n'
2872+ 'i\n'
2873+ '1 7fe70820e08a1aac0ef224d9c66ab66831cc4ab1\n'
2874+ 'n first\n'
2875+ '\n'
2876+ 'w\n'
2877+ '{ 0\n'
2878+ '. content\n'
2879+ '}\n'
2880+ 'W\n',
2881+ t.get('weaves/74/Foo%3ABar.weave').read())
2882+
2883+ def test_shared_disk_layout(self):
2884+ control = BzrDirMetaFormat1().initialize(self.get_url())
2885+ repo = RepositoryFormat7().initialize(control, shared=True)
2886+ # we want:
2887+ # format 'Bazaar-NG Repository format 7'
2888+ # inventory.weave == empty_weave
2889+ # empty revision-store directory
2890+ # empty weaves directory
2891+ # a 'shared-storage' marker file.
2892+ # lock is not present when unlocked
2893+ t = control.get_repository_transport(None)
2894+ self.assertEqualDiff('Bazaar-NG Repository format 7',
2895+ t.get('format').read())
2896+ self.assertEqualDiff('', t.get('shared-storage').read())
2897+ self.assertTrue(S_ISDIR(t.stat('revision-store').st_mode))
2898+ self.assertTrue(S_ISDIR(t.stat('weaves').st_mode))
2899+ self.assertEqualDiff('# bzr weave file v5\n'
2900+ 'w\n'
2901+ 'W\n',
2902+ t.get('inventory.weave').read())
2903+ self.assertFalse(t.has('branch-lock'))
2904+
2905+ def test_creates_lockdir(self):
2906+ """Make sure it appears to be controlled by a LockDir existence"""
2907+ control = BzrDirMetaFormat1().initialize(self.get_url())
2908+ repo = RepositoryFormat7().initialize(control, shared=True)
2909+ t = control.get_repository_transport(None)
2910+ # TODO: Should check there is a 'lock' toplevel directory,
2911+ # regardless of contents
2912+ self.assertFalse(t.has('lock/held/info'))
2913+ repo.lock_write()
2914+ try:
2915+ self.assertTrue(t.has('lock/held/info'))
2916+ finally:
2917+ # unlock so we don't get a warning about failing to do so
2918+ repo.unlock()
2919+
2920+ def test_uses_lockdir(self):
2921+ """repo format 7 actually locks on lockdir"""
2922+ base_url = self.get_url()
2923+ control = BzrDirMetaFormat1().initialize(base_url)
2924+ repo = RepositoryFormat7().initialize(control, shared=True)
2925+ t = control.get_repository_transport(None)
2926+ repo.lock_write()
2927+ repo.unlock()
2928+ del repo
2929+ # make sure the same lock is created by opening it
2930+ repo = Repository.open(base_url)
2931+ repo.lock_write()
2932+ self.assertTrue(t.has('lock/held/info'))
2933+ repo.unlock()
2934+ self.assertFalse(t.has('lock/held/info'))
2935+
2936+ def test_shared_no_tree_disk_layout(self):
2937+ control = BzrDirMetaFormat1().initialize(self.get_url())
2938+ repo = RepositoryFormat7().initialize(control, shared=True)
2939+ repo.set_make_working_trees(False)
2940+ # we want:
2941+ # format 'Bazaar-NG Repository format 7'
2942+ # lock ''
2943+ # inventory.weave == empty_weave
2944+ # empty revision-store directory
2945+ # empty weaves directory
2946+ # a 'shared-storage' marker file.
2947+ t = control.get_repository_transport(None)
2948+ self.assertEqualDiff('Bazaar-NG Repository format 7',
2949+ t.get('format').read())
2950+ ## self.assertEqualDiff('', t.get('lock').read())
2951+ self.assertEqualDiff('', t.get('shared-storage').read())
2952+ self.assertEqualDiff('', t.get('no-working-trees').read())
2953+ repo.set_make_working_trees(True)
2954+ self.assertFalse(t.has('no-working-trees'))
2955+ self.assertTrue(S_ISDIR(t.stat('revision-store').st_mode))
2956+ self.assertTrue(S_ISDIR(t.stat('weaves').st_mode))
2957+ self.assertEqualDiff('# bzr weave file v5\n'
2958+ 'w\n'
2959+ 'W\n',
2960+ t.get('inventory.weave').read())
2961+
2962+ def test_supports_external_lookups(self):
2963+ control = BzrDirMetaFormat1().initialize(self.get_url())
2964+ repo = RepositoryFormat7().initialize(control)
2965+ self.assertFalse(repo._format.supports_external_lookups)
2966+
2967+
2968+class TestInterWeaveRepo(TestCaseWithTransport):
2969+
2970+ def test_is_compatible_and_registered(self):
2971+ # InterWeaveRepo is compatible when either side
2972+ # is a format 5/6/7 branch
2973+ from bzrlib.repofmt import knitrepo
2974+ formats = [RepositoryFormat5(),
2975+ RepositoryFormat6(),
2976+ RepositoryFormat7()]
2977+ incompatible_formats = [RepositoryFormat4(),
2978+ knitrepo.RepositoryFormatKnit1(),
2979+ ]
2980+ repo_a = self.make_repository('a')
2981+ repo_b = self.make_repository('b')
2982+ is_compatible = InterWeaveRepo.is_compatible
2983+ for source in incompatible_formats:
2984+ # force incompatible left then right
2985+ repo_a._format = source
2986+ repo_b._format = formats[0]
2987+ self.assertFalse(is_compatible(repo_a, repo_b))
2988+ self.assertFalse(is_compatible(repo_b, repo_a))
2989+ for source in formats:
2990+ repo_a._format = source
2991+ for target in formats:
2992+ repo_b._format = target
2993+ self.assertTrue(is_compatible(repo_a, repo_b))
2994+ self.assertEqual(InterWeaveRepo,
2995+ InterRepository.get(repo_a, repo_b).__class__)
2996+
2997+
2998+_working_inventory_v4 = """<inventory file_id="TREE_ROOT">
2999+<entry file_id="bar-20050901064931-73b4b1138abc9cd2" kind="file" name="bar" parent_id="TREE_ROOT" />
3000+<entry file_id="foo-20050801201819-4139aa4a272f4250" kind="directory" name="foo" parent_id="TREE_ROOT" />
3001+<entry file_id="bar-20050824000535-6bc48cfad47ed134" kind="file" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" />
3002+</inventory>"""
3003+
3004+
3005+_revision_v4 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;"
3006+ inventory_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
3007+ inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
3008+ revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
3009+ timestamp="1125907235.212"
3010+ timezone="36000">
3011+<message>- start splitting code for xml (de)serialization away from objects
3012+ preparatory to supporting multiple formats by a single library
3013+</message>
3014+<parents>
3015+<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92" revision_sha1="7bdf4cc8c5bdac739f8cf9b10b78cf4b68f915ff" />
3016+</parents>
3017+</revision>
3018+"""
3019+
3020+
3021+class TestSerializer(TestCase):
3022+ """Test serializer"""
3023+
3024+ def test_registry(self):
3025+ self.assertIs(xml4.serializer_v4,
3026+ serializer_format_registry.get('4'))
3027+
3028+ def test_canned_inventory(self):
3029+ """Test unpacked a canned inventory v4 file."""
3030+ inp = StringIO(_working_inventory_v4)
3031+ inv = xml4.serializer_v4.read_inventory(inp)
3032+ self.assertEqual(len(inv), 4)
3033+ self.assert_('bar-20050901064931-73b4b1138abc9cd2' in inv)
3034+
3035+ def test_unpack_revision(self):
3036+ """Test unpacking a canned revision v4"""
3037+ inp = StringIO(_revision_v4)
3038+ rev = xml4.serializer_v4.read_revision(inp)
3039+ eq = self.assertEqual
3040+ eq(rev.committer,
3041+ "Martin Pool <mbp@sourcefrog.net>")
3042+ eq(rev.inventory_id,
3043+ "mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9")
3044+ eq(len(rev.parent_ids), 1)
3045+ eq(rev.parent_ids[0],
3046+ "mbp@sourcefrog.net-20050905063503-43948f59fa127d92")
3047+
3048+
3049
3050=== renamed file 'bzrlib/tests/test_workingtree_2.py' => 'bzrlib/plugins/weave_fmt/test_workingtree.py'
3051--- bzrlib/tests/test_workingtree_2.py 2011-03-03 11:32:03 +0000
3052+++ bzrlib/plugins/weave_fmt/test_workingtree.py 2011-03-09 01:37:04 +0000
3053@@ -28,7 +28,7 @@
3054 TestCaseWithTransport,
3055 )
3056
3057-from bzrlib.bzrdir import BzrDirFormat6
3058+from bzrlib.plugins.weave_fmt.bzrdir import BzrDirFormat6
3059
3060
3061 class TestFormat2WorkingTree(TestCaseWithTransport):
3062
3063=== added directory 'bzrlib/plugins/weave_fmt/tests'
3064=== renamed file 'bzrlib/workingtree_2.py' => 'bzrlib/plugins/weave_fmt/workingtree.py'
3065--- bzrlib/workingtree_2.py 2011-03-03 11:32:03 +0000
3066+++ bzrlib/plugins/weave_fmt/workingtree.py 2011-03-09 01:37:04 +0000
3067@@ -111,7 +111,7 @@
3068
3069 def __init__(self):
3070 super(WorkingTreeFormat2, self).__init__()
3071- from bzrlib.bzrdir import BzrDirFormat6
3072+ from bzrlib.plugins.weave_fmt.bzrdir import BzrDirFormat6
3073 self._matchingbzrdir = BzrDirFormat6()
3074
3075 def open(self, a_bzrdir, _found=False):
3076
3077=== renamed file 'bzrlib/xml4.py' => 'bzrlib/plugins/weave_fmt/xml4.py'
3078=== modified file 'bzrlib/repository.py'
3079--- bzrlib/repository.py 2011-03-05 04:10:42 +0000
3080+++ bzrlib/repository.py 2011-03-09 01:37:04 +0000
3081@@ -3218,44 +3218,13 @@
3082 return self.get_format_string()
3083
3084
3085-# Pre-0.8 formats that don't have a disk format string (because they are
3086-# versioned by the matching control directory). We use the control directories
3087-# disk format string as a key for the network_name because they meet the
3088-# constraints (simple string, unique, immutable).
3089-network_format_registry.register_lazy(
3090- "Bazaar-NG branch, format 5\n",
3091- 'bzrlib.repofmt.weaverepo',
3092- 'RepositoryFormat5',
3093-)
3094-network_format_registry.register_lazy(
3095- "Bazaar-NG branch, format 6\n",
3096- 'bzrlib.repofmt.weaverepo',
3097- 'RepositoryFormat6',
3098-)
3099-
3100-format_registry.register_extra_lazy(
3101- 'bzrlib.repofmt.weaverepo',
3102- 'RepositoryFormat4')
3103-format_registry.register_extra_lazy(
3104- 'bzrlib.repofmt.weaverepo',
3105- 'RepositoryFormat5')
3106-format_registry.register_extra_lazy(
3107- 'bzrlib.repofmt.weaverepo',
3108- 'RepositoryFormat6')
3109-
3110 # formats which have no format string are not discoverable or independently
3111 # creatable on disk, so are not registered in format_registry. They're
3112-# all in bzrlib.repofmt.weaverepo now. When an instance of one of these is
3113+# all in bzrlib.repofmt.knitreponow. When an instance of one of these is
3114 # needed, it's constructed directly by the BzrDir. Non-native formats where
3115 # the repository is not separately opened are similar.
3116
3117 format_registry.register_lazy(
3118- 'Bazaar-NG Repository format 7',
3119- 'bzrlib.repofmt.weaverepo',
3120- 'RepositoryFormat7'
3121- )
3122-
3123-format_registry.register_lazy(
3124 'Bazaar-NG Knit Repository Format 1',
3125 'bzrlib.repofmt.knitrepo',
3126 'RepositoryFormatKnit1',
3127
3128=== modified file 'bzrlib/serializer.py'
3129--- bzrlib/serializer.py 2010-02-17 17:11:16 +0000
3130+++ bzrlib/serializer.py 2011-03-09 01:37:04 +0000
3131@@ -93,7 +93,6 @@
3132
3133
3134 format_registry = SerializerRegistry()
3135-format_registry.register_lazy('4', 'bzrlib.xml4', 'serializer_v4')
3136 format_registry.register_lazy('5', 'bzrlib.xml5', 'serializer_v5')
3137 format_registry.register_lazy('6', 'bzrlib.xml6', 'serializer_v6')
3138 format_registry.register_lazy('7', 'bzrlib.xml7', 'serializer_v7')
3139
3140=== modified file 'bzrlib/tests/__init__.py'
3141--- bzrlib/tests/__init__.py 2011-03-08 17:37:58 +0000
3142+++ bzrlib/tests/__init__.py 2011-03-09 01:37:04 +0000
3143@@ -3888,7 +3888,6 @@
3144 'bzrlib.tests.test_whitebox',
3145 'bzrlib.tests.test_win32utils',
3146 'bzrlib.tests.test_workingtree',
3147- 'bzrlib.tests.test_workingtree_2',
3148 'bzrlib.tests.test_workingtree_4',
3149 'bzrlib.tests.test_wsgi',
3150 'bzrlib.tests.test_xml',
3151
3152=== modified file 'bzrlib/tests/blackbox/test_break_lock.py'
3153--- bzrlib/tests/blackbox/test_break_lock.py 2011-01-13 05:28:55 +0000
3154+++ bzrlib/tests/blackbox/test_break_lock.py 2011-03-09 01:37:04 +0000
3155@@ -104,15 +104,6 @@
3156 self.assertRaises(errors.LockBroken, self.master_branch.unlock)
3157
3158
3159-class TestBreakLockOldBranch(tests.TestCaseWithTransport):
3160-
3161- def test_break_lock_format_5_bzrdir(self):
3162- # break lock on a format 5 bzrdir should just return
3163- self.make_branch_and_tree('foo', format=bzrdir.BzrDirFormat5())
3164- out, err = self.run_bzr('break-lock foo')
3165- self.assertEqual('', out)
3166- self.assertEqual('', err)
3167-
3168 class TestConfigBreakLock(tests.TestCaseWithTransport):
3169
3170 def setUp(self):
3171
3172=== modified file 'bzrlib/tests/blackbox/test_info.py'
3173--- bzrlib/tests/blackbox/test_info.py 2010-04-14 09:57:01 +0000
3174+++ bzrlib/tests/blackbox/test_info.py 2011-03-09 01:37:04 +0000
3175@@ -1323,89 +1323,6 @@
3176 self.knownFailure('Win32 cannot run "bzr info"'
3177 ' when the tree is locked.')
3178
3179- def test_info_locking_oslocks(self):
3180- if sys.platform == "win32":
3181- self.skip("don't use oslocks on win32 in unix manner")
3182- # This test tests old (all-in-one, OS lock using) behaviour which
3183- # simply cannot work on windows (and is indeed why we changed our
3184- # design. As such, don't try to remove the thisFailsStrictLockCheck
3185- # call here.
3186- self.thisFailsStrictLockCheck()
3187-
3188- tree = self.make_branch_and_tree('branch',
3189- format=bzrdir.BzrDirFormat6())
3190-
3191- # Test all permutations of locking the working tree, branch and repository
3192- # XXX: Well not yet, as we can't query oslocks yet. Currently, it's
3193- # implemented by raising NotImplementedError and get_physical_lock_status()
3194- # always returns false. This makes bzr info hide the lock status. (Olaf)
3195- # W B R
3196-
3197- # U U U
3198- out, err = self.run_bzr('info -v branch')
3199- self.assertEqualDiff(
3200-"""Standalone tree (format: weave)
3201-Location:
3202- branch root: %s
3203-
3204-Format:
3205- control: All-in-one format 6
3206- working tree: Working tree format 2
3207- branch: Branch format 4
3208- repository: %s
3209-
3210-In the working tree:
3211- 0 unchanged
3212- 0 modified
3213- 0 added
3214- 0 removed
3215- 0 renamed
3216- 0 unknown
3217- 0 ignored
3218- 0 versioned subdirectories
3219-
3220-Branch history:
3221- 0 revisions
3222-
3223-Repository:
3224- 0 revisions
3225-""" % ('branch', tree.branch.repository._format.get_format_description(),
3226- ), out)
3227- self.assertEqual('', err)
3228- # L L L
3229- tree.lock_write()
3230- out, err = self.run_bzr('info -v branch')
3231- self.assertEqualDiff(
3232-"""Standalone tree (format: weave)
3233-Location:
3234- branch root: %s
3235-
3236-Format:
3237- control: All-in-one format 6
3238- working tree: Working tree format 2
3239- branch: Branch format 4
3240- repository: %s
3241-
3242-In the working tree:
3243- 0 unchanged
3244- 0 modified
3245- 0 added
3246- 0 removed
3247- 0 renamed
3248- 0 unknown
3249- 0 ignored
3250- 0 versioned subdirectories
3251-
3252-Branch history:
3253- 0 revisions
3254-
3255-Repository:
3256- 0 revisions
3257-""" % ('branch', tree.branch.repository._format.get_format_description(),
3258- ), out)
3259- self.assertEqual('', err)
3260- tree.unlock()
3261-
3262 def test_info_stacked(self):
3263 # We have a mainline
3264 trunk_tree = self.make_branch_and_tree('mainline',
3265
3266=== modified file 'bzrlib/tests/per_repository/test_repository.py'
3267--- bzrlib/tests/per_repository/test_repository.py 2011-03-08 17:02:52 +0000
3268+++ bzrlib/tests/per_repository/test_repository.py 2011-03-09 01:37:04 +0000
3269@@ -38,7 +38,6 @@
3270 )
3271 from bzrlib.repofmt import (
3272 pack_repo,
3273- weaverepo,
3274 )
3275 from bzrlib.tests import (
3276 per_repository,
3277@@ -560,23 +559,6 @@
3278 self.addCleanup(rev_tree.unlock)
3279 self.assertEqual('rev_id', rev_tree.inventory.root.revision)
3280
3281- def test_upgrade_from_format4(self):
3282- from bzrlib.tests.test_upgrade import _upgrade_dir_template
3283- if isinstance(self.repository_format, remote.RemoteRepositoryFormat):
3284- return # local conversion to/from RemoteObjects is irrelevant.
3285- if self.repository_format.get_format_description() \
3286- == "Repository format 4":
3287- raise tests.TestSkipped('Cannot convert format-4 to itself')
3288- self.build_tree_contents(_upgrade_dir_template)
3289- old_repodir = bzrdir.BzrDir.open_unsupported('.')
3290- old_repo_format = old_repodir.open_repository()._format
3291- format = self.repository_format._matchingbzrdir
3292- try:
3293- format.repository_format = self.repository_format
3294- except AttributeError:
3295- pass
3296- upgrade.upgrade('.', format)
3297-
3298 def test_pointless_commit(self):
3299 tree = self.make_branch_and_tree('.')
3300 self.assertRaises(errors.PointlessCommit, tree.commit, 'pointless',
3301
3302=== modified file 'bzrlib/tests/test_bzrdir.py'
3303--- bzrlib/tests/test_bzrdir.py 2011-02-24 12:08:37 +0000
3304+++ bzrlib/tests/test_bzrdir.py 2011-03-09 01:37:04 +0000
3305@@ -1007,70 +1007,6 @@
3306 self.assertEqual(2, rpc_count)
3307
3308
3309-class TestFormat5(TestCaseWithTransport):
3310- """Tests specific to the version 5 bzrdir format."""
3311-
3312- def test_same_lockfiles_between_tree_repo_branch(self):
3313- # this checks that only a single lockfiles instance is created
3314- # for format 5 objects
3315- dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
3316- def check_dir_components_use_same_lock(dir):
3317- ctrl_1 = dir.open_repository().control_files
3318- ctrl_2 = dir.open_branch().control_files
3319- ctrl_3 = dir.open_workingtree()._control_files
3320- self.assertTrue(ctrl_1 is ctrl_2)
3321- self.assertTrue(ctrl_2 is ctrl_3)
3322- check_dir_components_use_same_lock(dir)
3323- # and if we open it normally.
3324- dir = bzrdir.BzrDir.open(self.get_url())
3325- check_dir_components_use_same_lock(dir)
3326-
3327- def test_can_convert(self):
3328- # format 5 dirs are convertable
3329- dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
3330- self.assertTrue(dir.can_convert_format())
3331-
3332- def test_needs_conversion(self):
3333- # format 5 dirs need a conversion if they are not the default,
3334- # and they aren't
3335- dir = bzrdir.BzrDirFormat5().initialize(self.get_url())
3336- # don't need to convert it to itself
3337- self.assertFalse(dir.needs_format_conversion(bzrdir.BzrDirFormat5()))
3338- # do need to convert it to the current default
3339- self.assertTrue(dir.needs_format_conversion(
3340- bzrdir.BzrDirFormat.get_default_format()))
3341-
3342-
3343-class TestFormat6(TestCaseWithTransport):
3344- """Tests specific to the version 6 bzrdir format."""
3345-
3346- def test_same_lockfiles_between_tree_repo_branch(self):
3347- # this checks that only a single lockfiles instance is created
3348- # for format 6 objects
3349- dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
3350- def check_dir_components_use_same_lock(dir):
3351- ctrl_1 = dir.open_repository().control_files
3352- ctrl_2 = dir.open_branch().control_files
3353- ctrl_3 = dir.open_workingtree()._control_files
3354- self.assertTrue(ctrl_1 is ctrl_2)
3355- self.assertTrue(ctrl_2 is ctrl_3)
3356- check_dir_components_use_same_lock(dir)
3357- # and if we open it normally.
3358- dir = bzrdir.BzrDir.open(self.get_url())
3359- check_dir_components_use_same_lock(dir)
3360-
3361- def test_can_convert(self):
3362- # format 6 dirs are convertable
3363- dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
3364- self.assertTrue(dir.can_convert_format())
3365-
3366- def test_needs_conversion(self):
3367- # format 6 dirs need an conversion if they are not the default.
3368- dir = bzrdir.BzrDirFormat6().initialize(self.get_url())
3369- self.assertTrue(dir.needs_format_conversion(
3370- bzrdir.BzrDirFormat.get_default_format()))
3371-
3372-
3373 class NotBzrDir(bzrlib.bzrdir.BzrDir):
3374 """A non .bzr based control directory."""
3375
3376
3377=== modified file 'bzrlib/tests/test_repository.py'
3378--- bzrlib/tests/test_repository.py 2011-02-24 16:13:39 +0000
3379+++ bzrlib/tests/test_repository.py 2011-03-09 01:37:04 +0000
3380@@ -23,11 +23,9 @@
3381 """
3382
3383 from stat import S_ISDIR
3384-import sys
3385
3386 import bzrlib
3387 from bzrlib.errors import (
3388- NoSuchFile,
3389 UnknownFormatError,
3390 UnsupportedFormatError,
3391 )
3392@@ -60,7 +58,6 @@
3393 groupcompress_repo,
3394 knitrepo,
3395 pack_repo,
3396- weaverepo,
3397 )
3398
3399
3400@@ -209,194 +206,6 @@
3401 self.assertIsInstance(formats[0], SampleExtraRepositoryFormat)
3402
3403
3404-class TestFormat6(TestCaseWithTransport):
3405-
3406- def test_attribute__fetch_order(self):
3407- """Weaves need topological data insertion."""
3408- control = bzrdir.BzrDirFormat6().initialize(self.get_url())
3409- repo = weaverepo.RepositoryFormat6().initialize(control)
3410- self.assertEqual('topological', repo._format._fetch_order)
3411-
3412- def test_attribute__fetch_uses_deltas(self):
3413- """Weaves do not reuse deltas."""
3414- control = bzrdir.BzrDirFormat6().initialize(self.get_url())
3415- repo = weaverepo.RepositoryFormat6().initialize(control)
3416- self.assertEqual(False, repo._format._fetch_uses_deltas)
3417-
3418- def test_attribute__fetch_reconcile(self):
3419- """Weave repositories need a reconcile after fetch."""
3420- control = bzrdir.BzrDirFormat6().initialize(self.get_url())
3421- repo = weaverepo.RepositoryFormat6().initialize(control)
3422- self.assertEqual(True, repo._format._fetch_reconcile)
3423-
3424- def test_no_ancestry_weave(self):
3425- control = bzrdir.BzrDirFormat6().initialize(self.get_url())
3426- repo = weaverepo.RepositoryFormat6().initialize(control)
3427- # We no longer need to create the ancestry.weave file
3428- # since it is *never* used.
3429- self.assertRaises(NoSuchFile,
3430- control.transport.get,
3431- 'ancestry.weave')
3432-
3433- def test_supports_external_lookups(self):
3434- control = bzrdir.BzrDirFormat6().initialize(self.get_url())
3435- repo = weaverepo.RepositoryFormat6().initialize(control)
3436- self.assertFalse(repo._format.supports_external_lookups)
3437-
3438-
3439-class TestFormat7(TestCaseWithTransport):
3440-
3441- def test_attribute__fetch_order(self):
3442- """Weaves need topological data insertion."""
3443- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3444- repo = weaverepo.RepositoryFormat7().initialize(control)
3445- self.assertEqual('topological', repo._format._fetch_order)
3446-
3447- def test_attribute__fetch_uses_deltas(self):
3448- """Weaves do not reuse deltas."""
3449- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3450- repo = weaverepo.RepositoryFormat7().initialize(control)
3451- self.assertEqual(False, repo._format._fetch_uses_deltas)
3452-
3453- def test_attribute__fetch_reconcile(self):
3454- """Weave repositories need a reconcile after fetch."""
3455- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3456- repo = weaverepo.RepositoryFormat7().initialize(control)
3457- self.assertEqual(True, repo._format._fetch_reconcile)
3458-
3459- def test_disk_layout(self):
3460- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3461- repo = weaverepo.RepositoryFormat7().initialize(control)
3462- # in case of side effects of locking.
3463- repo.lock_write()
3464- repo.unlock()
3465- # we want:
3466- # format 'Bazaar-NG Repository format 7'
3467- # lock ''
3468- # inventory.weave == empty_weave
3469- # empty revision-store directory
3470- # empty weaves directory
3471- t = control.get_repository_transport(None)
3472- self.assertEqualDiff('Bazaar-NG Repository format 7',
3473- t.get('format').read())
3474- self.assertTrue(S_ISDIR(t.stat('revision-store').st_mode))
3475- self.assertTrue(S_ISDIR(t.stat('weaves').st_mode))
3476- self.assertEqualDiff('# bzr weave file v5\n'
3477- 'w\n'
3478- 'W\n',
3479- t.get('inventory.weave').read())
3480- # Creating a file with id Foo:Bar results in a non-escaped file name on
3481- # disk.
3482- control.create_branch()
3483- tree = control.create_workingtree()
3484- tree.add(['foo'], ['Foo:Bar'], ['file'])
3485- tree.put_file_bytes_non_atomic('Foo:Bar', 'content\n')
3486- try:
3487- tree.commit('first post', rev_id='first')
3488- except errors.IllegalPath:
3489- if sys.platform != 'win32':
3490- raise
3491- self.knownFailure('Foo:Bar cannot be used as a file-id on windows'
3492- ' in repo format 7')
3493- return
3494- self.assertEqualDiff(
3495- '# bzr weave file v5\n'
3496- 'i\n'
3497- '1 7fe70820e08a1aac0ef224d9c66ab66831cc4ab1\n'
3498- 'n first\n'
3499- '\n'
3500- 'w\n'
3501- '{ 0\n'
3502- '. content\n'
3503- '}\n'
3504- 'W\n',
3505- t.get('weaves/74/Foo%3ABar.weave').read())
3506-
3507- def test_shared_disk_layout(self):
3508- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3509- repo = weaverepo.RepositoryFormat7().initialize(control, shared=True)
3510- # we want:
3511- # format 'Bazaar-NG Repository format 7'
3512- # inventory.weave == empty_weave
3513- # empty revision-store directory
3514- # empty weaves directory
3515- # a 'shared-storage' marker file.
3516- # lock is not present when unlocked
3517- t = control.get_repository_transport(None)
3518- self.assertEqualDiff('Bazaar-NG Repository format 7',
3519- t.get('format').read())
3520- self.assertEqualDiff('', t.get('shared-storage').read())
3521- self.assertTrue(S_ISDIR(t.stat('revision-store').st_mode))
3522- self.assertTrue(S_ISDIR(t.stat('weaves').st_mode))
3523- self.assertEqualDiff('# bzr weave file v5\n'
3524- 'w\n'
3525- 'W\n',
3526- t.get('inventory.weave').read())
3527- self.assertFalse(t.has('branch-lock'))
3528-
3529- def test_creates_lockdir(self):
3530- """Make sure it appears to be controlled by a LockDir existence"""
3531- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3532- repo = weaverepo.RepositoryFormat7().initialize(control, shared=True)
3533- t = control.get_repository_transport(None)
3534- # TODO: Should check there is a 'lock' toplevel directory,
3535- # regardless of contents
3536- self.assertFalse(t.has('lock/held/info'))
3537- repo.lock_write()
3538- try:
3539- self.assertTrue(t.has('lock/held/info'))
3540- finally:
3541- # unlock so we don't get a warning about failing to do so
3542- repo.unlock()
3543-
3544- def test_uses_lockdir(self):
3545- """repo format 7 actually locks on lockdir"""
3546- base_url = self.get_url()
3547- control = bzrdir.BzrDirMetaFormat1().initialize(base_url)
3548- repo = weaverepo.RepositoryFormat7().initialize(control, shared=True)
3549- t = control.get_repository_transport(None)
3550- repo.lock_write()
3551- repo.unlock()
3552- del repo
3553- # make sure the same lock is created by opening it
3554- repo = repository.Repository.open(base_url)
3555- repo.lock_write()
3556- self.assertTrue(t.has('lock/held/info'))
3557- repo.unlock()
3558- self.assertFalse(t.has('lock/held/info'))
3559-
3560- def test_shared_no_tree_disk_layout(self):
3561- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3562- repo = weaverepo.RepositoryFormat7().initialize(control, shared=True)
3563- repo.set_make_working_trees(False)
3564- # we want:
3565- # format 'Bazaar-NG Repository format 7'
3566- # lock ''
3567- # inventory.weave == empty_weave
3568- # empty revision-store directory
3569- # empty weaves directory
3570- # a 'shared-storage' marker file.
3571- t = control.get_repository_transport(None)
3572- self.assertEqualDiff('Bazaar-NG Repository format 7',
3573- t.get('format').read())
3574- ## self.assertEqualDiff('', t.get('lock').read())
3575- self.assertEqualDiff('', t.get('shared-storage').read())
3576- self.assertEqualDiff('', t.get('no-working-trees').read())
3577- repo.set_make_working_trees(True)
3578- self.assertFalse(t.has('no-working-trees'))
3579- self.assertTrue(S_ISDIR(t.stat('revision-store').st_mode))
3580- self.assertTrue(S_ISDIR(t.stat('weaves').st_mode))
3581- self.assertEqualDiff('# bzr weave file v5\n'
3582- 'w\n'
3583- 'W\n',
3584- t.get('inventory.weave').read())
3585-
3586- def test_supports_external_lookups(self):
3587- control = bzrdir.BzrDirMetaFormat1().initialize(self.get_url())
3588- repo = weaverepo.RepositoryFormat7().initialize(control)
3589- self.assertFalse(repo._format.supports_external_lookups)
3590-
3591-
3592 class TestFormatKnit1(TestCaseWithTransport):
3593
3594 def test_attribute__fetch_order(self):
3595@@ -619,35 +428,17 @@
3596 self.assertGetsDefaultInterRepository(dummy_a, dummy_b)
3597
3598
3599-class TestInterWeaveRepo(TestCaseWithTransport):
3600-
3601- def test_is_compatible_and_registered(self):
3602- # InterWeaveRepo is compatible when either side
3603- # is a format 5/6/7 branch
3604- from bzrlib.repofmt import knitrepo, weaverepo
3605- formats = [weaverepo.RepositoryFormat5(),
3606- weaverepo.RepositoryFormat6(),
3607- weaverepo.RepositoryFormat7()]
3608- incompatible_formats = [weaverepo.RepositoryFormat4(),
3609- knitrepo.RepositoryFormatKnit1(),
3610- ]
3611- repo_a = self.make_repository('a')
3612- repo_b = self.make_repository('b')
3613- is_compatible = weaverepo.InterWeaveRepo.is_compatible
3614- for source in incompatible_formats:
3615- # force incompatible left then right
3616- repo_a._format = source
3617- repo_b._format = formats[0]
3618- self.assertFalse(is_compatible(repo_a, repo_b))
3619- self.assertFalse(is_compatible(repo_b, repo_a))
3620- for source in formats:
3621- repo_a._format = source
3622- for target in formats:
3623- repo_b._format = target
3624- self.assertTrue(is_compatible(repo_a, repo_b))
3625- self.assertEqual(weaverepo.InterWeaveRepo,
3626- repository.InterRepository.get(repo_a,
3627- repo_b).__class__)
3628+
3629+class TestRepositoryFormat1(knitrepo.RepositoryFormatKnit1):
3630+
3631+ def get_format_string(self):
3632+ return "Test Format 1"
3633+
3634+
3635+class TestRepositoryFormat2(knitrepo.RepositoryFormatKnit1):
3636+
3637+ def get_format_string(self):
3638+ return "Test Format 2"
3639
3640
3641 class TestRepositoryFormat1(knitrepo.RepositoryFormatKnit1):
3642
3643=== modified file 'bzrlib/tests/test_serializer.py'
3644--- bzrlib/tests/test_serializer.py 2009-06-10 03:56:49 +0000
3645+++ bzrlib/tests/test_serializer.py 2011-03-09 01:37:04 +0000
3646@@ -21,7 +21,6 @@
3647 from bzrlib import (
3648 chk_serializer,
3649 serializer,
3650- xml4,
3651 xml5,
3652 xml6,
3653 xml7,
3654@@ -34,8 +33,6 @@
3655 """Test serializer"""
3656
3657 def test_registry(self):
3658- self.assertIs(xml4.serializer_v4,
3659- serializer.format_registry.get('4'))
3660 self.assertIs(xml5.serializer_v5,
3661 serializer.format_registry.get('5'))
3662 self.assertIs(xml6.serializer_v6,
3663
3664=== modified file 'bzrlib/tests/test_sftp_transport.py'
3665--- bzrlib/tests/test_sftp_transport.py 2011-01-12 01:01:53 +0000
3666+++ bzrlib/tests/test_sftp_transport.py 2011-03-09 01:37:04 +0000
3667@@ -189,20 +189,6 @@
3668 class SFTPBranchTest(TestCaseWithSFTPServer):
3669 """Test some stuff when accessing a bzr Branch over sftp"""
3670
3671- def test_lock_file(self):
3672- # old format branches use a special lock file on sftp.
3673- b = self.make_branch('', format=bzrdir.BzrDirFormat6())
3674- b = bzrlib.branch.Branch.open(self.get_url())
3675- self.failUnlessExists('.bzr/')
3676- self.failUnlessExists('.bzr/branch-format')
3677- self.failUnlessExists('.bzr/branch-lock')
3678-
3679- self.failIf(lexists('.bzr/branch-lock.write-lock'))
3680- b.lock_write()
3681- self.failUnlessExists('.bzr/branch-lock.write-lock')
3682- b.unlock()
3683- self.failIf(lexists('.bzr/branch-lock.write-lock'))
3684-
3685 def test_push_support(self):
3686 self.build_tree(['a/', 'a/foo'])
3687 t = bzrdir.BzrDir.create_standalone_workingtree('a')
3688
3689=== modified file 'bzrlib/tests/test_upgrade.py'
3690--- bzrlib/tests/test_upgrade.py 2011-01-10 22:20:12 +0000
3691+++ bzrlib/tests/test_upgrade.py 2011-03-09 01:37:04 +0000
3692@@ -35,130 +35,6 @@
3693
3694 class TestUpgrade(tests.TestCaseWithTransport):
3695
3696- def test_upgrade_simple(self):
3697- """Upgrade simple v0.0.4 format to latest format"""
3698- eq = self.assertEquals
3699- self.build_tree_contents(_upgrade1_template)
3700- upgrade.upgrade(u'.')
3701- control = bzrdir.BzrDir.open('.')
3702- b = control.open_branch()
3703- # tsk, peeking under the covers.
3704- self.failUnless(
3705- isinstance(
3706- control._format,
3707- bzrdir.BzrDirFormat.get_default_format().__class__))
3708- rh = b.revision_history()
3709- eq(rh,
3710- ['mbp@sourcefrog.net-20051004035611-176b16534b086b3c',
3711- 'mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd'])
3712- rt = b.repository.revision_tree(rh[0])
3713- foo_id = 'foo-20051004035605-91e788d1875603ae'
3714- rt.lock_read()
3715- try:
3716- eq(rt.get_file_text(foo_id), 'initial contents\n')
3717- finally:
3718- rt.unlock()
3719- rt = b.repository.revision_tree(rh[1])
3720- rt.lock_read()
3721- try:
3722- eq(rt.get_file_text(foo_id), 'new contents\n')
3723- finally:
3724- rt.unlock()
3725- # check a backup was made:
3726- backup_dir = 'backup.bzr.~1~'
3727- t = self.get_transport('.')
3728- t.stat(backup_dir)
3729- t.stat(backup_dir + '/README')
3730- t.stat(backup_dir + '/branch-format')
3731- t.stat(backup_dir + '/revision-history')
3732- t.stat(backup_dir + '/merged-patches')
3733- t.stat(backup_dir + '/pending-merged-patches')
3734- t.stat(backup_dir + '/pending-merges')
3735- t.stat(backup_dir + '/branch-name')
3736- t.stat(backup_dir + '/branch-lock')
3737- t.stat(backup_dir + '/inventory')
3738- t.stat(backup_dir + '/stat-cache')
3739- t.stat(backup_dir + '/text-store')
3740- t.stat(backup_dir + '/text-store/foo-20051004035611-1591048e9dc7c2d4.gz')
3741- t.stat(backup_dir + '/text-store/foo-20051004035756-4081373d897c3453.gz')
3742- t.stat(backup_dir + '/inventory-store/')
3743- t.stat(backup_dir + '/inventory-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz')
3744- t.stat(backup_dir + '/inventory-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz')
3745- t.stat(backup_dir + '/revision-store/')
3746- t.stat(backup_dir + '/revision-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz')
3747- t.stat(backup_dir + '/revision-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz')
3748-
3749- def test_upgrade_with_ghosts(self):
3750- """Upgrade v0.0.4 tree containing ghost references.
3751-
3752- That is, some of the parents of revisions mentioned in the branch
3753- aren't present in the branch's storage.
3754-
3755- This shouldn't normally happen in branches created entirely in
3756- bzr, but can happen in branches imported from baz and arch, or from
3757- other systems, where the importer knows about a revision but not
3758- its contents."""
3759- eq = self.assertEquals
3760- self.build_tree_contents(_ghost_template)
3761- upgrade.upgrade(u'.')
3762- b = branch.Branch.open(u'.')
3763- revision_id = b.revision_history()[1]
3764- rev = b.repository.get_revision(revision_id)
3765- eq(len(rev.parent_ids), 2)
3766- eq(rev.parent_ids[1], 'wibble@wobble-2')
3767-
3768- def test_upgrade_makes_dir_weaves(self):
3769- self.build_tree_contents(_upgrade_dir_template)
3770- old_repodir = bzrdir.BzrDir.open_unsupported('.')
3771- old_repo_format = old_repodir.open_repository()._format
3772- upgrade.upgrade('.')
3773- # this is the path to the literal file. As format changes
3774- # occur it needs to be updated. FIXME: ask the store for the
3775- # path.
3776- repo = repository.Repository.open('.')
3777- # it should have changed the format
3778- self.assertNotEqual(old_repo_format.__class__, repo._format.__class__)
3779- # and we should be able to read the names for the file id
3780- # 'dir-20051005095101-da1441ea3fa6917a'
3781- repo.lock_read()
3782- self.addCleanup(repo.unlock)
3783- text_keys = repo.texts.keys()
3784- dir_keys = [key for key in text_keys if key[0] ==
3785- 'dir-20051005095101-da1441ea3fa6917a']
3786- self.assertNotEqual([], dir_keys)
3787-
3788- def test_upgrade_to_meta_sets_workingtree_last_revision(self):
3789- self.build_tree_contents(_upgrade_dir_template)
3790- upgrade.upgrade('.', bzrdir.BzrDirMetaFormat1())
3791- tree = workingtree.WorkingTree.open('.')
3792- self.assertEqual([tree.branch.revision_history()[-1]],
3793- tree.get_parent_ids())
3794-
3795- def test_upgrade_v6_to_meta_no_workingtree(self):
3796- # Some format6 branches do not have checkout files. Upgrading
3797- # such a branch to metadir must not setup a working tree.
3798- self.build_tree_contents(_upgrade1_template)
3799- upgrade.upgrade('.', bzrdir.BzrDirFormat6())
3800- t = self.get_transport('.')
3801- t.delete_multi(['.bzr/pending-merges', '.bzr/inventory'])
3802- self.assertFalse(t.has('.bzr/stat-cache'))
3803- # XXX: upgrade fails if a backup.bzr is already present
3804- # -- David Allouche 2006-08-11
3805- t.delete_tree('backup.bzr.~1~')
3806- # At this point, we have a format6 branch without checkout files.
3807- upgrade.upgrade('.', bzrdir.BzrDirMetaFormat1())
3808- # The upgrade should not have set up a working tree.
3809- control = bzrdir.BzrDir.open('.')
3810- self.assertFalse(control.has_workingtree())
3811- # We have covered the scope of this test, we may as well check that
3812- # upgrade has not eaten our data, even if it's a bit redundant with
3813- # other tests.
3814- self.failUnless(isinstance(control._format, bzrdir.BzrDirMetaFormat1))
3815- b = control.open_branch()
3816- self.assertEquals(b.revision_history(),
3817- ['mbp@sourcefrog.net-20051004035611-176b16534b086b3c',
3818- 'mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd'])
3819-
3820 def test_upgrade_rich_root(self):
3821 tree = self.make_branch_and_tree('tree', format='rich-root')
3822 rev_id = tree.commit('first post')
3823@@ -254,169 +130,6 @@
3824 self.failIfExists('tree/.bzr/checkout/' + path)
3825
3826
3827-_upgrade1_template = \
3828- [
3829- ('foo', 'new contents\n'),
3830- ('.bzr/',),
3831- ('.bzr/README',
3832- 'This is a Bazaar control directory.\n'
3833- 'Do not change any files in this directory.\n'
3834- 'See http://bazaar.canonical.com/ for more information about Bazaar.\n'),
3835- ('.bzr/branch-format', 'Bazaar-NG branch, format 0.0.4\n'),
3836- ('.bzr/revision-history',
3837- 'mbp@sourcefrog.net-20051004035611-176b16534b086b3c\n'
3838- 'mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd\n'),
3839- ('.bzr/merged-patches', ''),
3840- ('.bzr/pending-merged-patches', ''),
3841- ('.bzr/branch-name', ''),
3842- ('.bzr/branch-lock', ''),
3843- ('.bzr/pending-merges', ''),
3844- ('.bzr/inventory',
3845- '<inventory>\n'
3846- '<entry file_id="foo-20051004035605-91e788d1875603ae" kind="file" name="foo" />\n'
3847- '</inventory>\n'),
3848- ('.bzr/stat-cache',
3849- '### bzr hashcache v5\n'
3850- 'foo// be9f309239729f69a6309e970ef24941d31e042c 13 1128398176 1128398176 303464 770\n'),
3851- ('.bzr/text-store/',),
3852- ('.bzr/text-store/foo-20051004035611-1591048e9dc7c2d4.gz',
3853- '\x1f\x8b\x08\x00[\xfdAC\x02\xff\xcb\xcc\xcb,\xc9L\xccQH\xce\xcf+I\xcd+)\xe6\x02\x00\xdd\xcc\xf90\x11\x00\x00\x00'),
3854- ('.bzr/text-store/foo-20051004035756-4081373d897c3453.gz',
3855- '\x1f\x8b\x08\x00\xc4\xfdAC\x02\xff\xcbK-WH\xce\xcf+I\xcd+)\xe6\x02\x00g\xc3\xdf\xc9\r\x00\x00\x00'),
3856- ('.bzr/inventory-store/',),
3857- ('.bzr/inventory-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz',
3858- '\x1f\x8b\x08\x00[\xfdAC\x02\xffm\x8f\xcd\n\xc20\x10\x84\xef>E\xc8\xbdt7?M\x02\xad\xaf"\xa1\x99`P[\xa8E\xacOo\x14\x05\x0f\xdef\xe1\xfbv\x98\xbeL7L\xeb\xbcl\xfb]_\xc3\xb2\x89\\\xce8\x944\xc8<\xcf\x8d"\xb2LdH\xdb\x8el\x13\x18\xce\xfb\xc4\xde\xd5SGHq*\xd3\x0b\xad\x8e\x14S\xbc\xe0\xadI\xb1\xe2\xbe\xfe}\xc2\xdc\xb0\rL\xc6#\xa4\xd1\x8d*\x99\x0f}=F\x1e$8G\x9d\xa0\x02\xa1rP9\x01c`FV\xda1qg\x98"\x02}\xa5\xf2\xa8\x95\xec\xa4h\xeb\x80\xf6g\xcd\x13\xb3\x01\xcc\x98\xda\x00\x00\x00'),
3859- ('.bzr/inventory-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz',
3860- '\x1f\x8b\x08\x00\xc4\xfdAC\x02\xffm\x8f\xc1\n\xc20\x10D\xef~E\xc8\xbd\xb8\x9bM\x9a,\xb4\xfe\x8a\xc4f\x83Am\xa1\x16\xb1~\xbdQ\x14<x\x9b\x81y3LW\xc6\x9b\x8c\xcb4\xaf\xbbMW\xc5\xbc\xaa\\\xce\xb2/\xa9\xd7y\x9a\x1a\x03\xe0\x10\xc0\x02\xb9\x16\\\xc3(>\x84\x84\xc1WKQ\xb4:\x95\xf1\x15\xad\x8cVc\xbc\xc8\x1b\xd3j\x91\xfb\xf2\xaf\xa4r\x8d\x85\x80\xe4)\x05\xf6\x03YG\x9f\xf4\xf5\x18\xb1\xd7\x07\xe1L\xc0\x86\xd8\x1b\xce-\xc7\xb6:a\x0f\x92\x8de\x8b\x89P\xc0\x9a\xe1\x0b\x95G\x9d\xc4\xda\xb1\xad\x07\xb6?o\x9e\xb5\xff\xf0\xf9\xda\x00\x00\x00'),
3861- ('.bzr/revision-store/',),
3862- ('.bzr/revision-store/mbp@sourcefrog.net-20051004035611-176b16534b086b3c.gz',
3863- '\x1f\x8b\x08\x00[\xfdAC\x02\xff\x9d\x8eKj\xc30\x14E\xe7^\x85\xd0 \xb3$\xefI\xd1\x8f\xd8\xa6\x1b(t\x07E?\xbb\x82H\n\xb2\x1ahW\xdfB1\x14:\xeb\xf4r\xee\xbdgl\xf1\x91\xb6T\x0b\xf15\xe7\xd4{l\x13}\xb6\xad\xa7B^j\xbd\x91\xc3\xad_\xb3\xbb?m\xf5\xbd\xf9\xb8\xb4\xba\x9eJ\xec\x87\xb5_)I\xe5\x11K\xaf\xed\xe35\x85\x89\xfe\xa5\x8e\x0c@ \xc0\x05\xb8\x90\x88GT\xd2\xa1\x14\xfc\xe2@K\xc7\xfd\xef\x85\xed\xcd\xe2D\x95\x8d\x1a\xa47<\x02c2\xb0 \xbc\xd0\x8ay\xa3\xbcp\x8a\x83\x12A3\xb7XJv\xef\x7f_\xf7\x94\xe3\xd6m\xbeO\x14\x91in4*<\x812\x88\xc60\xfc\x01>k\x89\x13\xe5\x12\x00\xe8<\x8c\xdf\x8d\xcd\xaeq\xb6!\x90\xa5\xd6\xf1\xbc\x07\xc3x\xde\x85\xe6\xe1\x0b\xc8\x8a\x98\x03T\x01\x00\x00'),
3864- ('.bzr/revision-store/mbp@sourcefrog.net-20051004035756-235f2b7dcdddd8dd.gz',
3865- '\x1f\x8b\x08\x00\xc4\xfdAC\x02\xff\x9d\x90Kj\x031\x0c\x86\xf79\xc5\xe0Ev\xe9\xc8o\x9b\xcc\x84^\xa0\xd0\x1b\x14\xbf&5d\xec`\xbb\x81\xf6\xf45\x84\xa4\x81\xaeZ\xa1\x85\x84^\xdf\xaf\xa9\x84K\xac1\xa7\xc1\xe5u\x8d\xad\x852\xa3\x17SZL\xc3k\xce\xa7a{j\xfb\xd5\x9e\x9fk\xfe(.,%\x1f\x9fRh\xdbc\xdb\xa3!\xa6KH-\x97\xcf\xb7\xe8g\xf4\xbbkG\x008\x06`@\xb9\xe4bG(_\x88\x95\xde\xf9n\xca\xfb\xc7\r\xf5\xdd\xe0\x19\xa9\x85)\x81\xf5"\xbd\x04j\xb8\x02b\xa8W\\\x0b\xc9\x14\xf4\xbc\xbb\xd7\xd6H4\xdc\xb8\xff}\xba\xc55\xd4f\xd6\xf3\x8c0&\x8ajE\xa4x\xe2@\xa5\xa6\x9a\xf3k\xc3WNaFT\x00\x00:l\xa6>Q\xcd1\x1cjp9\xf9;\xc34\xde\n\x9b\xe9lJWT{t\',a\xf9\x0b\xae\xc0x\x87\xa5\xb0Xp\xca,(a\xa9{\xd0{}\xd4\x12\x04(\xc5\xbb$\xc5$V\xceaI\x19\x01\xa2\x1dh\xed\x82d\x8c.\xccr@\xc3\xd8Q\xc6\x1f\xaa\xf1\xb6\xe8\xb0\xf9\x06QR\r\xf9\xfc\x01\x00\x00')]
3866-
3867-
3868-_ghost_template = [
3869- ( './foo',
3870- 'hello\n'
3871- ),
3872- ( './.bzr/', ),
3873- ( './.bzr/README',
3874- 'This is a Bazaar control directory.\n'
3875- 'Do not change any files in this directory.\n'
3876- 'See http://bazaar.canonical.com/ for more information about Bazaar.\n'
3877- ),
3878- ( './.bzr/branch-format',
3879- 'Bazaar-NG branch, format 0.0.4\n'
3880- ),
3881- ( './.bzr/branch-lock',
3882- ''
3883- ),
3884- ( './.bzr/branch-name',
3885- ''
3886- ),
3887- ( './.bzr/inventory',
3888- '<inventory>\n'
3889- '<entry file_id="foo-20051004104918-0379cb7c76354cde" kind="file" name="foo" />\n'
3890- '</inventory>\n'
3891- ),
3892- ( './.bzr/merged-patches',
3893- ''
3894- ),
3895- ( './.bzr/pending-merged-patches',
3896- ''
3897- ),
3898- ( './.bzr/pending-merges',
3899- ''
3900- ),
3901- ( './.bzr/revision-history',
3902- 'mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b\n'
3903- 'mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d\n'
3904- ),
3905- ( './.bzr/stat-cache',
3906- '### bzr hashcache v5\n'
3907- 'foo// f572d396fae9206628714fb2ce00f72e94f2258f 6 1128422956 1128422956 306900 770\n'
3908- ),
3909- ( './.bzr/text-store/', ),
3910- ( './.bzr/text-store/foo-20051004104921-8de8118a71be45ba.gz',
3911- '\x1f\x8b\x08\x081^BC\x00\x03foo-20051004104921-8de8118a71be45ba\x00\xcbH\xcd\xc9\xc9\xe7\x02\x00 0:6\x06\x00\x00\x00'
3912- ),
3913- ( './.bzr/inventory-store/', ),
3914- ( './.bzr/inventory-store/mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b.gz',
3915- '\x1f\x8b\x08\x081^BC\x00\x03mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b\x00m\x8f\xcb\n'
3916- '\xc20\x10E\xf7~E\xc8\xbe83\xcd\x13\xaa\xbf"yL0\xa8-\xd4"\xd6\xaf7\x8a\x82\x0bw\xb38\xe7\xde;C\x1do<.\xd3\xbc\xee7C;\xe6U\x94z\xe6C\xcd;Y\xa6\xa9#\x00\x8d\x00\n'
3917- 'Ayt\x1d\xf4\xd6\xa7h\x935\xbdV)\xb3\x14\xa7:\xbe\xd0\xe6H1\x86\x0b\xbf5)\x16\xbe/\x7fC\x08;\x97\xd9!\xba`1\xb2\xd21|\xe8\xeb1`\xe3\xb5\xa5\xdc{S\x02{\x02c\xc8YT%Rb\x80b\x89\xbd*D\xda\x95\xafT\x1f\xad\xd2H\xb1m\xfb\xb7?\xcf<\x01W}\xb5\x8b\xd9\x00\x00\x00'
3918- ),
3919- ( './.bzr/inventory-store/mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d.gz',
3920- '\x1f\x8b\x08\x08A^BC\x00\x03mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d\x00m\x8f\xcb\n'
3921- '\xc20\x10E\xf7~E\xc8\xbe83\xcd\x13\xaa\xbf"yL0\xa8-\xd4"\xd6\xaf7\x8a\x82\x0bw\xb38\xe7\xde;C\x1do<.\xd3\xbc\xee7C;\xe6U\x94z\xe6C\xcd;Y\xa6\xa9#\x00\x8d\x00\n'
3922- 'Ayt\x1d\xf4\xd6\xa7h\x935\xbdV)\xb3\x14\xa7:\xbe\xd0\xe6H1\x86\x0b\xbf5)\x16\xbe/\x7fC\x08;\x97\xd9!\xba`1\xb2\xd21|\xe8\xeb1`\xe3\xb5\xa5\xdc{S\x02{\x02c\xc8YT%Rb\x80b\x89\xbd*D\xda\x95\xafT\x1f\xad\xd2H\xb1m\xfb\xb7?\xcf<\x01W}\xb5\x8b\xd9\x00\x00\x00'
3923- ),
3924- ( './.bzr/revision-store/', ),
3925- ( './.bzr/revision-store/mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b.gz',
3926- '\x1f\x8b\x08\x081^BC\x00\x03mbp@sourcefrog.net-20051004104921-a98be2278dd30b7b\x00\x9d\x8eMj\xc30\x14\x84\xf7>\x85\xd0"\xbb$\xef\xc9\xb6,\x11\xdb\xf4\x02\x85\xde\xa0\xe8\xe7\xd9\x11\xc4R\x90\xd4@{\xfa\x06\x8a\xa1\xd0]\x97\x03\xdf\xcc|c\xa6G(!E\xe6\xd2\xb6\x85Z)O\xfc\xd5\xe4\x1a"{K\xe9\xc6\x0e\xb7z\xd9\xec\xfd\xa5\xa4\x8f\xech\xc9i=E\xaa\x87\xb5^8\x0b\xf1A\xb1\xa6\xfc\xf9\x1e\xfc\xc4\xffRG\x01\xd0#@\x87\xd0i\x81G\xa3\x95%!\x06\xe5}\x0bv\xb0\xbf\x17\xca\xd5\xe0\xc4-\xa0\xb1\x8b\xb6`\xc0I\xa4\xc5\xf4\x9el\xef\x95v [\x94\xcf\x8e\xd5\xcay\xe4l\xf7\xfe\xf7u\r'
3927- '\x1b\x95j\xb6\xfb\xc4\x11\x85\xea\x84\xd0\x12O\x03t\x83D\xad\xc4\x0f\xf0\x95"M\xbc\x95\x00\xc0\xe7f|6\x8aYi^B.u<\xef\xb1\x19\xcf\xbb\xce\xdc|\x038=\xc7\xe6R\x01\x00\x00'
3928- ),
3929- ( './.bzr/revision-store/mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d.gz',
3930- '\x1f\x8b\x08\x08A^BC\x00\x03mbp@sourcefrog.net-20051004104937-c9b7a7bfcc0bb22d\x00\x9d\x90\xc1j\xc30\x0c\x86\xef}\n'
3931- "\xe3Coie'\xb1c\x9a\x94\xbe\xc0`o0,[N\x03M\\\x1c\xafe{\xfae\x94n\x85\xc1`;Y\x88O\xd2\xff\xb9Mt\x19\xe6!N\xcc\xc5q\x1cr\xa6\xd4\xf1'\x9b\xf20\xb1\xe7\x18Ol}\xca\xbb\x11\xcf\x879\xbe&G!\xc5~3Q^\xf7y\xc7\xd90]h\xca1\xbd\xbd\x0c\xbe\xe3?\xa9B\x02\xd4\x02\xa0\x12P\x99R\x17\xce\xa0\xb6\x1a\x83s\x80(\xa5\x7f\xdc0\x1f\xad\xe88\x82\xb0\x18\x0c\x82\x05\xa7\x04\x05[{\xc2\xda7\xc6\x81*\x85B\x8dh\x1a\xe7\x05g\xf7\xdc\xff>\x9d\x87\x91\xe6l\xc7s\xc7\x85\x90M%\xa5\xd1z#\x85\xa8\x9b\x1a\xaa\xfa\x06\xbc\xc7\x89:^*\x00\xe0\xfbU\xbbL\xcc\xb6\xa7\xfdH\xa9'\x16\x03\xeb\x8fq\xce\xed\xf6\xde_\xb5g\x9b\x16\xa1y\xa9\xbe\x02&\n"
3932- '\x7fJ+EaM\x83$\xa5n\xbc/a\x91~\xd0\xbd\xfd\x135\n'
3933- '\xd0\x9a`\x0c*W\x1aR\xc1\x94du\x08(\t\xb0\x91\xdeZ\xa3\x9cU\x9cm\x7f\x8dr\x1d\x10Ot\xb8\xc6\xcf\xa7\x907|\xfb-\xb1\xbd\xd3\xfb\xd5\x07\xeeD\xee\x08*\x02\x00\x00'
3934- ),
3935-]
3936-
3937-_upgrade_dir_template = [
3938- ( './.bzr/', ),
3939- ( './.bzr/README',
3940- 'This is a Bazaar control directory.\n'
3941- 'Do not change any files in this directory.\n'
3942- 'See http://bazaar.canonical.com/ for more information about Bazaar.\n'
3943- ),
3944- ( './.bzr/branch-format',
3945- 'Bazaar-NG branch, format 0.0.4\n'
3946- ),
3947- ( './.bzr/branch-lock',
3948- ''
3949- ),
3950- ( './.bzr/branch-name',
3951- ''
3952- ),
3953- ( './.bzr/inventory',
3954- '<inventory>\n'
3955- '<entry file_id="dir-20051005095101-da1441ea3fa6917a" kind="directory" name="dir" />\n'
3956- '</inventory>\n'
3957- ),
3958- ( './.bzr/merged-patches',
3959- ''
3960- ),
3961- ( './.bzr/pending-merged-patches',
3962- ''
3963- ),
3964- ( './.bzr/pending-merges',
3965- ''
3966- ),
3967- ( './.bzr/revision-history',
3968- 'robertc@robertcollins.net-20051005095108-6065fbd8e7d8617e\n'
3969- ),
3970- ( './.bzr/stat-cache',
3971- '### bzr hashcache v5\n'
3972- ),
3973- ( './.bzr/text-store/', ),
3974- ( './.bzr/inventory-store/', ),
3975- ( './.bzr/inventory-store/robertc@robertcollins.net-20051005095108-6065fbd8e7d8617e.gz',
3976- '\x1f\x8b\x08\x00\x0c\xa2CC\x02\xff\xb3\xc9\xcc+K\xcd+\xc9/\xaa\xb4\xe3\xb2\x012\x8a*\x15\xd22sR\xe33Sl\x95R2\x8bt\x8d\x0c\x0cL\r'
3977- "\x81\xd8\xc0\x12H\x19\xea\xa6$\x1a\x9a\x98\x18\xa6&\x1a\xa7%\x9aY\x1a\x9a'*)dg\xe6A\x94\xa6&\x83LQR\xc8K\xccM\x05\x0b()\xe8\x03\xcd\xd4G\xb2\x00\x00\xc2<\x94\xb1m\x00\x00\x00"
3978- ),
3979- ( './.bzr/revision-store/', ),
3980- ( './.bzr/revision-store/robertc@robertcollins.net-20051005095108-6065fbd8e7d8617e.gz',
3981- '\x1f\x8b\x08\x00\x0c\xa2CC\x02\xff\xa5OKj\xc30\x14\xdc\xfb\x14B\x8b\xec\x92<I\xd6\xc7\xc42\x85\xde\xa0\x17(\xb6\xf4\x9c\n'
3982- 'l\xa9H"\x90\x9c\xbe\xa6\xa9\xa1\x9b\xae\xbax\x0c\xcc\xe71\xd3g\xbc\x85\x12R$.\xadk\xa8\x15\xb3\xa5oi\xc2\\\xc9kZ\x96\x10\x0b9,\xf5\x92\xbf)\xf7\xf2\x83O\xe5\x14\xb1\x1e\xae\xf5BI\x887\x8c5\xe5\xfb{\xf0\x96\xfei>r\x00\xc9\xb6\x83n\x03sT\xa0\xe4<y\x83\xda\x1b\xc54\xfe~T>Ff\xe9\xcc:\xdd\x8e\xa6E\xc7@\xa2\x82I\xaaNL\xbas\\313)\x00\xb9\xe6\xe0(\xd9\x87\xfc\xb7A\r'
3983- "+\x96:\xae\x9f\x962\xc6\x8d\x04i\x949\x01\x97R\xb7\x1d\x17O\xc3#E\xb4T(\x00\xa0C\xd3o\x892^q\x18\xbd'>\xe4\xfe\xbc\x13M\x7f\xde{\r"
3984- '\xcd\x17\x85\xea\xba\x03l\x01\x00\x00'
3985- ),
3986- ( './dir/', ),
3987-]
3988-
3989-
3990 class TestSmartUpgrade(tests.TestCaseWithTransport):
3991
3992 from_format = bzrdir.format_registry.make_bzrdir("pack-0.92")
3993
3994=== modified file 'bzrlib/tests/test_xml.py'
3995--- bzrlib/tests/test_xml.py 2011-02-21 19:58:27 +0000
3996+++ bzrlib/tests/test_xml.py 2011-03-09 01:37:04 +0000
3997@@ -26,31 +26,8 @@
3998 )
3999 from bzrlib.tests import TestCase
4000 from bzrlib.inventory import Inventory
4001-from bzrlib.xml4 import serializer_v4
4002 import bzrlib.xml5
4003
4004-_working_inventory_v4 = """<inventory file_id="TREE_ROOT">
4005-<entry file_id="bar-20050901064931-73b4b1138abc9cd2" kind="file" name="bar" parent_id="TREE_ROOT" />
4006-<entry file_id="foo-20050801201819-4139aa4a272f4250" kind="directory" name="foo" parent_id="TREE_ROOT" />
4007-<entry file_id="bar-20050824000535-6bc48cfad47ed134" kind="file" name="bar" parent_id="foo-20050801201819-4139aa4a272f4250" />
4008-</inventory>"""
4009-
4010-
4011-_revision_v4 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;"
4012- inventory_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
4013- inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
4014- revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
4015- timestamp="1125907235.212"
4016- timezone="36000">
4017-<message>- start splitting code for xml (de)serialization away from objects
4018- preparatory to supporting multiple formats by a single library
4019-</message>
4020-<parents>
4021-<revision_ref revision_id="mbp@sourcefrog.net-20050905063503-43948f59fa127d92" revision_sha1="7bdf4cc8c5bdac739f8cf9b10b78cf4b68f915ff" />
4022-</parents>
4023-</revision>
4024-"""
4025-
4026 _revision_v5 = """<revision committer="Martin Pool &lt;mbp@sourcefrog.net&gt;"
4027 inventory_sha1="e79c31c1deb64c163cf660fdedd476dd579ffd41"
4028 revision_id="mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9"
4029@@ -217,26 +194,6 @@
4030 class TestSerializer(TestCase):
4031 """Test XML serialization"""
4032
4033- def test_canned_inventory(self):
4034- """Test unpacked a canned inventory v4 file."""
4035- inp = StringIO(_working_inventory_v4)
4036- inv = serializer_v4.read_inventory(inp)
4037- self.assertEqual(len(inv), 4)
4038- self.assert_('bar-20050901064931-73b4b1138abc9cd2' in inv)
4039-
4040- def test_unpack_revision(self):
4041- """Test unpacking a canned revision v4"""
4042- inp = StringIO(_revision_v4)
4043- rev = serializer_v4.read_revision(inp)
4044- eq = self.assertEqual
4045- eq(rev.committer,
4046- "Martin Pool <mbp@sourcefrog.net>")
4047- eq(rev.inventory_id,
4048- "mbp@sourcefrog.net-20050905080035-e0439293f8b6b9f9")
4049- eq(len(rev.parent_ids), 1)
4050- eq(rev.parent_ids[0],
4051- "mbp@sourcefrog.net-20050905063503-43948f59fa127d92")
4052-
4053 def test_unpack_revision_5(self):
4054 """Test unpacking a canned revision v5"""
4055 inp = StringIO(_revision_v5)
4056
4057=== modified file 'bzrlib/workingtree.py'
4058--- bzrlib/workingtree.py 2011-03-06 18:10:47 +0000
4059+++ bzrlib/workingtree.py 2011-03-09 01:37:04 +0000
4060@@ -3067,8 +3067,3 @@
4061 "bzrlib.workingtree_4", "WorkingTreeFormat6")
4062 format_registry.register(WorkingTreeFormat3())
4063 format_registry.set_default(__default_format)
4064-# Register extra formats which have no format string are not discoverable
4065-# and not independently creatable. They are implicitly created as part of
4066-# e.g. older Bazaar formats or foreign formats.
4067-format_registry.register_extra_lazy("bzrlib.workingtree_2",
4068- "WorkingTreeFormat2")