def initialize(self, a_controldir, name=None, repository=None, append_revisions_only=None): """Create a branch of this format in a_controldir.""" super(LoomFormatMixin, self).initialize(a_controldir, name=name, repository=repository, append_revisions_only=append_revisions_only) branch_transport = a_controldir.get_branch_transport(self) files = [] state = loom_state.LoomState() writer = loom_io.LoomStateWriter(state) state_stream = BytesIO() writer.write(state_stream) state_stream.seek(0) files.append(('last-loom', state_stream)) control_files = breezy.lockable_files.LockableFiles( branch_transport, 'lock', breezy.lockdir.LockDir) control_files.lock_write() try: for filename, stream in files: branch_transport.put_file(filename, stream) finally: control_files.unlock() return self.open(a_controldir, _found=True, name=name)
def test_default_constructor(self): state = loom_state.LoomState() # the default object must have no parents and no threads. self.assertEqual([], state.get_parents()) self.assertEqual([], state.get_threads()) self.assertEqual(NULL_REVISION, state.get_basis_revision_id()) self.assertEqual({}, state.get_threads_dict())
def get_loom_state(self): """Get the current loom state object.""" # TODO: cache the loom state during the transaction lifetime. current_content = self._transport.get('last-loom') reader = loom_io.LoomStateReader(current_content) state = loom_state.LoomState(reader) return state
def test_reader_constructor(self): # make a state state = loom_state.LoomState() state.set_threads([('name', b'rev', [None, None]), ('dangerous name', b'rev2', [None, None])]) state.set_parents([b'bar', b'am']) stream = BytesIO() writer = loom_io.LoomStateWriter(state) writer.write(stream) # creating state from a serialised loom stream.seek(0) reader = loom_io.LoomStateReader(stream) state = loom_state.LoomState(reader) self.assertEqual([b'bar', b'am'], state.get_parents()) self.assertEqual([('name', b'rev', [None, None]), ('dangerous name', b'rev2', [None, None])], state.get_threads()) self.assertEqual(b'bar', state.get_basis_revision_id())
def test_write_state_with_threads(self): state = loom_state.LoomState() state.set_threads([ ('base ', b'baserev', []), (u'\xedtop', b'\xc3\xa9toprev', []), ]) self.assertWritesStateCorrectly( loom_io._CURRENT_LOOM_FORMAT_STRING + b'\n' b'\n' b' : baserev base \n' b' : \xc3\xa9toprev \xc3\xadtop\n', state)
def test_write_state_with_threads_and_parents(self): state = loom_state.LoomState() state.set_threads([ ('base ', b'baserev', [None, None]), (u'\xedtop', b'\xc3\xa9toprev', [None, None]), ]) state.set_parents([b'1', u'2\xeb'.encode('utf-8')]) self.assertWritesStateCorrectly( loom_io._CURRENT_LOOM_FORMAT_STRING + b'\n' b'1 2\xc3\xab\n' b' : baserev base \n' b' : \xc3\xa9toprev \xc3\xadtop\n', state)
def test_set_get_threads(self): state = loom_state.LoomState() sample_threads = [('foo', b'bar', []), (u'g\xbe', b'bar', [])] state.set_threads(sample_threads) self.assertEqual([], state.get_parents()) self.assertEqual(NULL_REVISION, state.get_basis_revision_id()) self.assertEqual(sample_threads, state.get_threads()) # alter the sample threads we just set, to see that the stored copy is # separate sample_threads.append('foo') self.assertNotEqual(sample_threads, state.get_threads()) # and check the returned copy is also independent. sample_threads = state.get_threads() sample_threads.append('foo') self.assertNotEqual(sample_threads, state.get_threads())
def take_over(self, branch): """Take an existing breezy branch over into Loom format. This currently cannot convert branches to Loom format unless they are in Branch 5 format. The conversion takes effect when the branch is next opened. """ assert branch._format.__class__ is self._parent_classs branch._transport.put_bytes('format', self.get_format_string()) state = loom_state.LoomState() writer = loom_io.LoomStateWriter(state) state_stream = BytesIO() writer.write(state_stream) state_stream.seek(0) branch._transport.put_file('last-loom', state_stream)
def test_set_get_parents(self): state = loom_state.LoomState() sample_threads = [('foo', b'bar', [])] state.set_threads(sample_threads) # can set parents to nothing with no side effects state.set_parents([]) self.assertEqual([], state.get_parents()) self.assertEqual(NULL_REVISION, state.get_basis_revision_id()) self.assertEqual(sample_threads, state.get_threads()) # can set a single parent with no threads state.set_parents([b'foo']) self.assertEqual([b'foo'], state.get_parents()) self.assertEqual(b'foo', state.get_basis_revision_id()) self.assertEqual(sample_threads, state.get_threads()) # can set a single parent with threads state.set_parents([b'bar']) self.assertEqual([b'bar'], state.get_parents()) self.assertEqual(b'bar', state.get_basis_revision_id()) self.assertEqual(sample_threads, state.get_threads()) # can set multiple parents state.set_parents([b'bar', b' am']) self.assertEqual([b'bar', b' am'], state.get_parents()) self.assertEqual(b'bar', state.get_basis_revision_id()) self.assertEqual(sample_threads, state.get_threads())
def copy_content_into(self, revision_id=None, tag_selector=None): with self.lock_write(): if not self.__class__.branch_is_loom(self.source): # target is loom, but the generic code path works Just Fine for # regular to loom copy_content_into. return super(InterLoomBranch, self).copy_content_into(revision_id=revision_id, tag_selector=tag_selector) # XXX: hint for breezy - break this into two routines, one for # copying the last-rev pointer, one for copying parent etc. state = self.get_loom_state(self.source) parents = state.get_parents() if parents: loom_tip = parents[0] else: loom_tip = None threads = self.get_threads(self.source, state.get_basis_revision_id()) if revision_id not in (None, NULL_REVISION): if threads: # revision_id should be in the loom, or its an error found_threads = [ thread for thread, rev in threads if rev == revision_id ] if not found_threads: # the thread we have been asked to set in the remote # side has not been recorded yet, so its data is not # present at this point. raise UnrecordedRevision(self.source, revision_id) # pull in the warp, which was skipped during the initial pull # because the front end does not know what to pull. # nb: this is mega huge hacky. THINK. RBC 2006062 nested = ui.ui_factory.nested_progress_bar() try: if parents: self.target.repository.fetch(self.source.repository, revision_id=parents[0]) if threads: for thread, rev_id in reversed(threads): # fetch the loom content for this revision self.target.repository.fetch( self.source.repository, revision_id=rev_id) finally: nested.finished() state = loom_state.LoomState() try: require_loom_branch(self.target) if threads: last_rev = threads[-1][1] if last_rev == EMPTY_REVISION: last_rev = breezy.revision.NULL_REVISION self.target.generate_revision_history(last_rev) state.set_parents([loom_tip]) state.set_threads( (thread + ([thread[1]], ) for thread in threads)) else: # no threads yet, be a normal branch. self.source._synchronize_history(self.target, revision_id) target_loom = self.unwrap_branch(self.target) target_loom._set_last_loom(state) except NotALoom: self.source._synchronize_history(self.target, revision_id) try: parent = self.source.get_parent() except errors.InaccessibleParent as e: trace.mutter('parent was not accessible to copy: %s', e) else: if parent: self.target.set_parent(parent) if threads: self.target._set_nick(threads[-1][0]) if self.source._push_should_merge_tags(): self.source.tags.merge_to(self.target.tags, seletor=tag_selector)
def test_write_state_with_parents(self): state = loom_state.LoomState() state.set_parents([b'1', u'2\xeb'.encode('utf-8')]) self.assertWritesStateCorrectly( loom_io._CURRENT_LOOM_FORMAT_STRING + b'\n' b'1 2\xc3\xab\n', state)
def test_write_state_with_parent(self): state = loom_state.LoomState() state.set_parents([b'1']) self.assertWritesStateCorrectly( loom_io._CURRENT_LOOM_FORMAT_STRING + b'\n' b'1\n', state)
def test_write_empty_state(self): state = loom_state.LoomState() self.assertWritesStateCorrectly( loom_io._CURRENT_LOOM_FORMAT_STRING + b'\n\n', state)
def test_writer_constructors(self): writer = loom_io.LoomWriter() state = loom_state.LoomState() writer = loom_io.LoomStateWriter(state)
def get_sample_state(self): state = loom_state.LoomState() sample_threads = [('foo', b'bar', []), (u'g\xbe', b'bar', [])] state.set_threads(sample_threads) return state
def test_new_thread_after_deleting_one_thread(self): state = loom_state.LoomState() state.set_threads([('foo', b'bar', [])]) self.assertIs(None, state.get_new_thread_after_deleting('foo'))