def _unpack_revision(self, elt): """XML Element -> Revision object""" format = elt.get('format') format_num = self.format_num if self.revision_format_num is not None: format_num = self.revision_format_num if format is not None: if format != format_num: raise BzrError("invalid format version %r on revision" % format) get_cached = _get_utf8_or_ascii rev = Revision(committer = elt.get('committer'), timestamp = float(elt.get('timestamp')), revision_id = get_cached(elt.get('revision_id')), inventory_sha1 = elt.get('inventory_sha1') ) parents = elt.find('parents') or [] for p in parents: rev.parent_ids.append(get_cached(p.get('revision_id'))) self._unpack_revision_properties(elt, rev) v = elt.get('timezone') if v is None: rev.timezone = 0 else: rev.timezone = int(v) rev.message = elt.findtext('message') # text of <message> return rev
def as_revision(self): rev = Revision(revision_id=self.revision_id, committer=self.committer, timestamp=float(self.timestamp), timezone=int(self.timezone), inventory_sha1=self.inventory_sha1, message='\n'.join(self.message)) if self.parent_ids: rev.parent_ids.extend(self.parent_ids) if self.properties: for property in self.properties: key_end = property.find(': ') if key_end == -1: if not property.endswith(':'): raise ValueError(property) key = str(property[:-1]) value = '' else: key = str(property[:key_end]) value = property[key_end + 2:] rev.properties[key] = value return rev
def test_fetch_missing_text_other_location_fails(self): source_tree = self.make_branch_and_tree('source') source = source_tree.branch.repository target = self.make_to_repository('target') # start by adding a file so the data knit for the file exists in # repositories that have specific files for each fileid. self.build_tree(['source/id']) source_tree.add(['id'], ['id']) source_tree.commit('a', rev_id='a') # now we manually insert a revision with an inventory referencing # 'id' at revision 'b', but we do not insert revision b. # this should ensure that the new versions of files are being checked # for during pull operations inv = source.get_inventory('a') source.lock_write() self.addCleanup(source.unlock) source.start_write_group() inv['id'].revision = 'b' inv.revision_id = 'b' sha1 = source.add_inventory('b', inv, ['a']) rev = Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id='b') rev.parent_ids = ['a'] source.add_revision('b', rev) source.commit_write_group() self.assertRaises(errors.RevisionNotPresent, target.fetch, source) self.assertFalse(target.has_revision('b'))
def test_fetch_missing_text_other_location_fails(self): source_tree = self.make_branch_and_tree('source') source = source_tree.branch.repository target = self.make_to_repository('target') # start by adding a file so the data knit for the file exists in # repositories that have specific files for each fileid. self.build_tree(['source/id']) source_tree.add(['id'], ['id']) source_tree.commit('a', rev_id='a') # now we manually insert a revision with an inventory referencing # file 'id' at revision 'b', but we do not insert revision b. # this should ensure that the new versions of files are being checked # for during pull operations inv = source.get_inventory('a') source.lock_write() self.addCleanup(source.unlock) source.start_write_group() inv['id'].revision = 'b' inv.revision_id = 'b' sha1 = source.add_inventory('b', inv, ['a']) rev = Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id='b') rev.parent_ids = ['a'] source.add_revision('b', rev) self.disable_commit_write_group_paranoia(source) source.commit_write_group() self.assertRaises(errors.RevisionNotPresent, target.fetch, source) self.assertFalse(target.has_revision('b'))
def _unpack_revision(self, elt): """XML Element -> Revision object""" format = elt.get('format') format_num = self.format_num if self.revision_format_num is not None: format_num = self.revision_format_num if format is not None: if format != format_num: raise BzrError("invalid format version %r on revision" % format) get_cached = _get_utf8_or_ascii rev = Revision(committer=elt.get('committer'), timestamp=float(elt.get('timestamp')), revision_id=get_cached(elt.get('revision_id')), inventory_sha1=elt.get('inventory_sha1')) parents = elt.find('parents') or [] for p in parents: rev.parent_ids.append(get_cached(p.get('revision_id'))) self._unpack_revision_properties(elt, rev) v = elt.get('timezone') if v is None: rev.timezone = 0 else: rev.timezone = int(v) rev.message = elt.findtext('message') # text of <message> return rev
def as_revision(self): rev = Revision(revision_id=self.revision_id, committer=self.committer, timestamp=float(self.timestamp), timezone=int(self.timezone), inventory_sha1=self.inventory_sha1, message='\n'.join(self.message)) if self.parent_ids: rev.parent_ids.extend(self.parent_ids) if self.properties: for property in self.properties: key_end = property.find(': ') if key_end == -1: if not property.endswith(':'): raise ValueError(property) key = str(property[:-1]) value = '' else: key = str(property[:key_end]) value = property[key_end+2:] rev.properties[key] = value return rev
def test_cscvs(self): x = Revision("myrevid") x.properties = { "cscvs-svn-repository-uuid": "someuuid", "cscvs-svn-revision-number": "4", "cscvs-svn-branch-path": "/trunk"} self.assertEquals(set([("svn", "someuuid:4:trunk")]), extract_foreign_revids(x))
def test_roundtrips_non_ascii(self): rev = Revision("revid1") rev.message = u"\n\xe5me" rev.committer = u'Erik B\xe5gfors' rev.timestamp = 1242385452 rev.inventory_sha1 = "4a2c7fb50e077699242cf6eb16a61779c7b680a7" rev.timezone = 3600 self.assertRoundTrips(chk_bencode_serializer, rev)
def test_roundtrips_xml_invalid_chars(self): rev = Revision("revid1") rev.message = "\t\ue000" rev.committer = u'Erik B\xe5gfors' rev.timestamp = 1242385452 rev.timezone = 3600 rev.inventory_sha1 = "4a2c7fb50e077699242cf6eb16a61779c7b680a7" self.assertRoundTrips(chk_bencode_serializer, rev)
def test_fetch_inconsistent_last_changed_entries(self): """If an inventory has odd data we should still get what it references. This test tests that we do fetch a file text created in a revision not being fetched, but referenced from the revision we are fetching when the adjacent revisions to the one being fetched do not reference that text. """ tree = self.make_branch_and_tree('source') revid = tree.commit('old') to_repo = self.make_to_repository('to_repo') to_repo.fetch(tree.branch.repository, revid) # Make a broken revision and fetch it. source = tree.branch.repository source.lock_write() self.addCleanup(source.unlock) source.start_write_group() try: # We need two revisions: OLD and NEW. NEW will claim to need a file # 'FOO' changed in 'OLD'. OLD will not have that file at all. source.texts.insert_record_stream([ versionedfile.FulltextContentFactory(('foo', revid), (), None, 'contents') ]) basis = source.revision_tree(revid) parent_id = basis.path2id('') entry = inventory.make_entry('file', 'foo-path', parent_id, 'foo') entry.revision = revid entry.text_size = len('contents') entry.text_sha1 = osutils.sha_string('contents') inv_sha1, _ = source.add_inventory_by_delta( revid, [(None, 'foo-path', 'foo', entry)], 'new', [revid]) rev = Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=inv_sha1, revision_id='new', parent_ids=[revid]) source.add_revision(rev.revision_id, rev) except: source.abort_write_group() raise else: source.commit_write_group() to_repo.fetch(source, 'new') to_repo.lock_read() self.addCleanup(to_repo.unlock) self.assertEqual( 'contents', to_repo.texts.get_record_stream( [('foo', revid)], 'unordered', True).next().get_bytes_as('fulltext'))
def test_short_author(self): rev = Revision('a-id') rev.committer = 'John Doe <*****@*****.**>' lf = LogFormatter(None) self.assertEqual('John Doe', lf.short_author(rev)) rev.properties['author'] = 'John Smith <*****@*****.**>' self.assertEqual('John Smith', lf.short_author(rev)) rev.properties['author'] = 'John Smith' self.assertEqual('John Smith', lf.short_author(rev)) rev.properties['author'] = '*****@*****.**' self.assertEqual('*****@*****.**', lf.short_author(rev)) rev.properties['author'] = '<*****@*****.**>' self.assertEqual('*****@*****.**', lf.short_author(rev)) rev.properties['author'] = 'John Smith [email protected]' self.assertEqual('John Smith', lf.short_author(rev))
def _unpack_revision(self, elt): """XML Element -> Revision object""" # <changeset> is deprecated... if elt.tag not in ('revision', 'changeset'): raise BzrError("unexpected tag in revision file: %r" % elt) rev = Revision(committer = elt.get('committer'), timestamp = float(elt.get('timestamp')), revision_id = elt.get('revision_id'), inventory_id = elt.get('inventory_id'), inventory_sha1 = elt.get('inventory_sha1') ) precursor = elt.get('precursor') precursor_sha1 = elt.get('precursor_sha1') pelts = elt.find('parents') if pelts: for p in pelts: rev.parent_ids.append(p.get('revision_id')) rev.parent_sha1s.append(p.get('revision_sha1')) if precursor: # must be consistent prec_parent = rev.parent_ids[0] elif precursor: # revisions written prior to 0.0.5 have a single precursor # give as an attribute rev.parent_ids.append(precursor) rev.parent_sha1s.append(precursor_sha1) v = elt.get('timezone') rev.timezone = v and int(v) rev.message = elt.findtext('message') # text of <message> return rev
def annotate_file_tree(tree, file_id, to_file, verbose=False, full=False, show_ids=False, branch=None): """Annotate file_id in a tree. The tree should already be read_locked() when annotate_file_tree is called. :param tree: The tree to look for revision numbers and history from. :param file_id: The file_id to annotate. :param to_file: The file to output the annotation to. :param verbose: Show all details rather than truncating to ensure reasonable text width. :param full: XXXX Not sure what this does. :param show_ids: Show revision ids in the annotation output. :param branch: Branch to use for revision revno lookups """ if branch is None: branch = tree.branch if to_file is None: to_file = sys.stdout # Handle the show_ids case annotations = list(tree.annotate_iter(file_id)) if show_ids: return _show_id_annotations(annotations, to_file, full) if not getattr(tree, "get_revision_id", False): # Create a virtual revision to represent the current tree state. # Should get some more pending commit attributes, like pending tags, # bugfixes etc. current_rev = Revision(CURRENT_REVISION) current_rev.parent_ids = tree.get_parent_ids() try: current_rev.committer = branch.get_config_stack().get('email') except errors.NoWhoami: current_rev.committer = 'local user' current_rev.message = "?" current_rev.timestamp = round(time.time(), 3) current_rev.timezone = osutils.local_time_offset() else: current_rev = None annotation = list(_expand_annotations(annotations, branch, current_rev)) _print_annotations(annotation, verbose, to_file, full)
def _unpack_revision(self, elt): """XML Element -> Revision object""" # <changeset> is deprecated... if elt.tag not in ('revision', 'changeset'): raise BzrError("unexpected tag in revision file: %r" % elt) rev = Revision(committer=elt.get('committer'), timestamp=float(elt.get('timestamp')), revision_id=elt.get('revision_id'), inventory_id=elt.get('inventory_id'), inventory_sha1=elt.get('inventory_sha1')) precursor = elt.get('precursor') precursor_sha1 = elt.get('precursor_sha1') pelts = elt.find('parents') if pelts: for p in pelts: rev.parent_ids.append(p.get('revision_id')) rev.parent_sha1s.append(p.get('revision_sha1')) if precursor: # must be consistent prec_parent = rev.parent_ids[0] elif precursor: # revisions written prior to 0.0.5 have a single precursor # give as an attribute rev.parent_ids.append(precursor) rev.parent_sha1s.append(precursor_sha1) v = elt.get('timezone') rev.timezone = v and int(v) rev.message = elt.findtext('message') # text of <message> return rev
def add_revision(self, repo, revision_id, inv, parent_ids): """Add a revision with a given inventory and parents to a repository. :param repo: a repository. :param revision_id: the revision ID for the new revision. :param inv: an inventory (such as created by `make_one_file_inventory`). :param parent_ids: the parents for the new revision. """ inv.revision_id = revision_id inv.root.revision = revision_id if repo.supports_rich_root(): root_id = inv.root.file_id repo.texts.add_lines((root_id, revision_id), [], []) repo.add_inventory(revision_id, inv, parent_ids) revision = Revision(revision_id, committer='*****@*****.**', timestamp=0, inventory_sha1='', timezone=0, message='foo', parent_ids=parent_ids) repo.add_revision(revision_id, revision, inv)
def test_add_signature_text(self): repo = self.make_repository('repo') repo.lock_write() self.addCleanup(repo.unlock) self.addCleanup(repo.commit_write_group) repo.start_write_group() inv = Inventory(revision_id='A') inv.root.revision = 'A' repo.add_inventory('A', inv, []) repo.add_revision( 'A', Revision('A', committer='A', timestamp=0, inventory_sha1='', timezone=0, message='A')) repo.add_signature_text('A', 'This might be a signature') self.assertEqual('This might be a signature', repo.get_signature_text('A'))
def fake_up_revision(self, tree, revid, shape): tree.lock_write() try: tree.branch.repository.start_write_group() try: if shape.root.revision is None: shape.root.revision = revid sha1 = tree.branch.repository.add_inventory(revid, shape, []) rev = Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id=revid) tree.branch.repository.add_revision(revid, rev) except: tree.branch.repository.abort_write_group() raise else: tree.branch.repository.commit_write_group() finally: tree.unlock()
def test_add_revision_inventory_sha1(self): repo = self.make_repository('repo') inv = Inventory(revision_id='A') inv.root.revision = 'A' inv.root.file_id = 'fixed-root' repo.lock_write() repo.start_write_group() repo.add_revision('A', Revision('A', committer='B', timestamp=0, timezone=0, message='C'), inv=inv) repo.commit_write_group() repo.unlock() repo.lock_read() self.assertEquals( osutils.sha_string( repo._serializer.write_inventory_to_string(inv)), repo.get_revision('A').inventory_sha1) repo.unlock()
def setUp(self): self.reduceLockdirTimeout() super(TestReconcileWithIncorrectRevisionCache, self).setUp() t = get_transport(self.get_url()) # we need a revision with two parents in the wrong order # which should trigger reinsertion. # and another with the first one correct but the other two not # which should not trigger reinsertion. # these need to be in different repositories so that we don't # trigger a reconcile based on the other case. # there is no api to construct a broken knit repository at # this point. if we ever encounter a bad graph in a knit repo # we should add a lower level api to allow constructing such cases. # first off the common logic: tree = self.make_branch_and_tree('wrong-first-parent') second_tree = self.make_branch_and_tree('reversed-secondary-parents') for t in [tree, second_tree]: t.commit('1', rev_id='1') uncommit(t.branch, tree=t) t.commit('2', rev_id='2') uncommit(t.branch, tree=t) t.commit('3', rev_id='3') uncommit(t.branch, tree=t) #second_tree = self.make_branch_and_tree('reversed-secondary-parents') #second_tree.pull(tree) # XXX won't copy the repo? repo_secondary = second_tree.branch.repository # now setup the wrong-first parent case repo = tree.branch.repository repo.lock_write() repo.start_write_group() inv = Inventory(revision_id='wrong-first-parent') inv.root.revision = 'wrong-first-parent' sha1 = repo.add_inventory('wrong-first-parent', inv, ['2', '1']) rev = Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id='wrong-first-parent') rev.parent_ids = ['1', '2'] repo.add_revision('wrong-first-parent', rev) repo.commit_write_group() repo.unlock() # now setup the wrong-secondary parent case repo = repo_secondary repo.lock_write() repo.start_write_group() inv = Inventory(revision_id='wrong-secondary-parent') inv.root.revision = 'wrong-secondary-parent' if repo.supports_rich_root(): root_id = inv.root.file_id repo.texts.add_lines((root_id, 'wrong-secondary-parent'), [], []) sha1 = repo.add_inventory('wrong-secondary-parent', inv, ['1', '3', '2']) rev = Revision(timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>", message="Message", inventory_sha1=sha1, revision_id='wrong-secondary-parent') rev.parent_ids = ['1', '2', '3'] repo.add_revision('wrong-secondary-parent', rev) repo.commit_write_group() repo.unlock()
def extractBugInfo(self, bug_property): revision = Revision(self.factory.getUniqueString(), properties=dict(bugs=bug_property)) bug_linker = BugBranchLinker(None) return bug_linker.extractBugInfo(revision)