def test_get_commit_builder(self): branch = self.make_branch(".") branch.lock_write() builder = branch.get_commit_builder([]) self.assertIsInstance(builder, repository.CommitBuilder) branch.repository.commit_write_group() branch.unlock()
def _get_version_from_bzr_lib(path): import bzrlib.tag, bzrlib.branch fullpath = os.path.abspath(path) if sys.platform == 'win32': fullpath = fullpath.replace('\\', '/') fullpath = '/' + fullpath branch = bzrlib.branch.Branch.open('file://' + fullpath) tags = bzrlib.tag.BasicTags(branch) #print "Getting version information from bzr branch..." branch.lock_read() try: history = branch.iter_merge_sorted_revisions(direction="reverse") version = None extra_version = [] for revid, depth, revno, end_of_merge in history: for tag_name, tag_revid in tags.get_tag_dict().iteritems(): #print tag_revid, "<==>", revid if tag_revid == revid: #print "%s matches tag %s" % (revid, tag_name) version = [int(s) for s in tag_name.split('.')] ## if the current revision does not match the last ## tag, we append current revno to the version if tag_revid != branch.last_revision(): extra_version = [branch.revno()] break if version: break finally: branch.unlock() assert version is not None _version = version + extra_version return _version
def create_components_from_branches(branches=None): if branches is None: branches = os.listdir('/srv/lava/branches') components = {} for branch_name in branches: component = Component(branch_name) branch = bzrlib.branch.Branch.open( os.path.join('/srv/lava/branches', branch_name)) branch.lock_read() try: branch_tags = branch.tags.get_tag_dict() revno2release = {} release2revno = {} for tag, revid in branch_tags.iteritems(): if tag.startswith('release-'): try: revno = branch.revision_id_to_dotted_revno(revid) except bzrlib.errors.NoSuchRevision: pass else: if len(revno) > 1: continue revno2release[revno[0]] = tag[len('release-'):] release2revno[tag[len('release-'):]] = revno[0] if revno2release: component.released_revno = max(revno2release) component.last_release = revno2release[max(revno2release)] else: component.released_revno = None component.release2revno = release2revno component.revno2release = revno2release revno, revid = branch.last_revision_info() component.tip_revno = revno component.tip_revid = revid mainline_revs = [] unreleased_revs = [] while True: rev = branch.repository.get_revision(revid) if rev.message.strip() != 'post release bump': if component.released_revno and revno > component.released_revno: unreleased_revs.append((rev, revno)) mainline_revs.append((rev, revno)) if not rev.parent_ids: break revid = rev.parent_ids[0] revno -= 1 component.unreleased_revisions = unreleased_revs component.mainline_revs = mainline_revs finally: branch.unlock() components[branch_name] = component return components
def copy_tree(revid): files = files_cache[revid] = {} branch.lock_read() tree = branch.repository.revision_tree(revid) try: for path, entry in tree.iter_entries_by_dir(): files[path] = [entry.file_id, None] finally: branch.unlock() return files
def apply(self, bzrdir): branch = bzrdir.open_branch() branch.lock_write() try: branch.set_stacked_on_url(None) if not trace.is_quiet(): ui.ui_factory.note(gettext( "%s is now not stacked\n") % (branch.base,)) finally: branch.unlock()
def test_revision_history_when_locked(self): """Repeated calls to revision history will only call _gen_revision_history once while the branch is locked. """ branch, calls = self.get_instrumented_branch() # Lock the branch, then repeatedly call revision_history. branch.lock_read() try: branch.revision_history() branch.revision_history() self.assertEqual(['_gen_revision_history'], calls) finally: branch.unlock()
def test_set_revision_history_when_locked(self): """When the branch is locked, calling set_revision_history should cache the revision history so that a later call to revision_history will not need to call _gen_revision_history. """ branch, calls = self.get_instrumented_branch() # Lock the branch, set the revision history, then repeatedly call # revision_history. branch.lock_write() branch.set_revision_history([]) try: branch.revision_history() self.assertEqual([], calls) finally: branch.unlock()
def apply(self, bzrdir, stacked_on_url): branch = bzrdir.open_branch() # it may be a path relative to the cwd or a url; the branch wants # a path relative to itself... on_url = urlutils.relative_url(branch.base, urlutils.normalize_url(stacked_on_url)) branch.lock_write() try: branch.set_stacked_on_url(on_url) if not trace.is_quiet(): ui.ui_factory.note(gettext( "{0} is now stacked on {1}\n").format( branch.base, branch.get_stacked_on_url())) finally: branch.unlock()
def test_cached_revision_history_not_accidentally_mutable(self): """When there's a cached version of the history, revision_history returns a copy of the cached data so that callers cannot accidentally corrupt the cache. """ branch = self.get_branch() # Lock the branch, then repeatedly call revision_history, mutating the # results. branch.lock_read() try: # The first time the data returned will not be in the cache. history = branch.revision_history() history.append('one') # The second time the data comes from the cache. history = branch.revision_history() history.append('two') # The revision_history() should still be unchanged, even though # we've mutated the return values from earlier calls. self.assertEqual([], branch.revision_history()) finally: branch.unlock()
def do_list(parser): master_branch = None for name in branches: if not master_branch: master_branch = name print "? refs/heads/%s" % name branch = get_remote_branch(master_branch) branch.lock_read() for tag, revid in branch.tags.get_tag_dict().items(): try: branch.revision_id_to_dotted_revno(revid) except bzrlib.errors.NoSuchRevision: continue if not ref_is_valid(tag): continue print "? refs/tags/%s" % tag tags[tag] = revid branch.unlock() print "@refs/heads/%s HEAD" % master_branch print
def test_store_signature(self): wt = self.make_branch_and_tree('.') branch = wt.branch branch.lock_write() try: branch.repository.start_write_group() try: branch.repository.store_revision_signature( gpg.LoopbackGPGStrategy(None), 'FOO', 'A') except: branch.repository.abort_write_group() raise else: branch.repository.commit_write_group() finally: branch.unlock() # A signature without a revision should not be accessible. self.assertRaises(errors.NoSuchRevision, branch.repository.has_signature_for_revision_id, 'A') wt.commit("base", allow_pointless=True, rev_id='A') self.assertEqual( '-----BEGIN PSEUDO-SIGNED CONTENT-----\n' 'FOO-----END PSEUDO-SIGNED CONTENT-----\n', branch.repository.get_signature_text('A'))
def test_store_signature(self): wt = self.make_branch_and_tree('.') branch = wt.branch branch.lock_write() try: branch.repository.start_write_group() try: branch.repository.store_revision_signature( gpg.LoopbackGPGStrategy(None), 'FOO', 'A') except: branch.repository.abort_write_group() raise else: branch.repository.commit_write_group() finally: branch.unlock() # A signature without a revision should not be accessible. self.assertRaises(errors.NoSuchRevision, branch.repository.has_signature_for_revision_id, 'A') wt.commit("base", allow_pointless=True, rev_id='A') self.assertEqual('-----BEGIN PSEUDO-SIGNED CONTENT-----\n' 'FOO-----END PSEUDO-SIGNED CONTENT-----\n', branch.repository.get_signature_text('A'))
def parse_commit(parser): parents = [] ref = parser[1] parser.next() if ref.startswith('refs/heads/'): name = ref[len('refs/heads/'):] branch = get_remote_branch(name) else: die('unknown ref') commit_mark = parser.get_mark() parser.next() author = parser.get_author() parser.next() committer = parser.get_author() parser.next() data = parser.get_data() parser.next() if parser.check('from'): parents.append(parser.get_mark()) parser.next() while parser.check('merge'): parents.append(parser.get_mark()) parser.next() # fast-export adds an extra newline if data[-1] == '\n': data = data[:-1] files = {} for line in parser: if parser.check('M'): t, m, mark_ref, path = line.split(' ', 3) mark = int(mark_ref[1:]) f = {'mode': m, 'mark': mark} elif parser.check('D'): t, path = line.split(' ', 1) f = {'deleted': True} else: die('Unknown file command: %s' % line) path = c_style_unescape(path).decode('utf-8') files[path] = f committer, date, tz = committer author, _, _ = author parents = [mark_to_rev(p) for p in parents] revid = bzrlib.generate_ids.gen_revision_id(committer, date) props = {} props['branch-nick'] = branch.nick props['authors'] = author mtree = CustomTree(branch, revid, parents, files) changes = mtree.iter_changes() branch.lock_write() try: builder = branch.get_commit_builder(parents, None, date, tz, committer, props, revid) try: list( builder.record_iter_changes(mtree, mtree.last_revision(), changes)) builder.finish_inventory() builder.commit(data.decode('utf-8', 'replace')) except Exception, e: builder.abort() raise finally: branch.unlock() parsed_refs[ref] = revid marks.new_mark(revid, commit_mark)
def make_html(components, instances): table = tags.table(class_='main') heading_row = tags.tr() for heading in 'component', 'tip revno', 'unreleased revisions', 'latest release': heading_row(tags.th(heading)) for instance_name in sorted(instances): heading_row(tags.th(instance_name, class_="instance-name")) table(tags.thead(heading_row)) tbody = tags.tbody() for name, component in sorted(components.items()): row = tags.tr(class_="component") revs_between_ids = {} extra_rows = [] def td(*args, **kwargs): row(tags.td(*args, **kwargs)) td(name) td(str(component.tip_revno), class_='version') unreleased_count = len(component.unreleased_revisions) if unreleased_count: id_ = get_id() td(tags.a(str(unreleased_count), href='#', class_='highlight'), class_='version clickable', id=id_) sub_name = 'revs between %s (r%s) and tip (r%s)' % ( component.last_release, component.released_revno, component.tip_revno) extra_rows.append( tags.tr(tags.td(format_revlist(component.unreleased_revisions, name=sub_name), colspan=str(4 + len(instances))), class_='hidden', id="show-" + id_)) elif not component.last_release: td(u'\N{EM DASH}', class_='version') else: td(str(unreleased_count), class_='version') if component.last_release: td(component.last_release, class_='version') else: td(u'???', class_='version') for instance_name, instance in sorted(instances.items()): ver, location = instance.get(name, (None, None)) if ver is None: td(u'\N{EM DASH}', class_='version') elif ver == component.last_release: td(ver, class_='version') elif ver in component.release2revno: revno_low = component.release2revno[ver] sub_name = 'revs between %s (r%s) and %s (r%s)' % ( ver, revno_low, component.last_release, component.released_revno) revlist = [] for rev, revno in component.mainline_revs: if revno_low < revno < component.released_revno: revlist.append((rev, revno)) if revlist: id_ = get_id() revs_between_ids[revno_low] = id_ extra_rows.append( tags.tr(tags.td(format_revlist(revlist, name=sub_name), colspan=str(4 + len(instances))), class_='hidden branch-diff', id="show-" + id_)) td(tags.a(ver, href='#', class_='highlight'), class_='version clickable', id=id_) else: td(tags.span(ver, class_='highlight'), class_='version') elif location: try: branch = bzrlib.branch.Branch.open(location) except bzrlib.errors.NoSuchBranch: td(tags.span(ver, class_='highlight'), class_='version') else: branch.lock_read() try: # This utterly half-assed version of bzr missing # doesn't take merges into account! revno, revid = branch.last_revision_info() ver = ver.split('dev')[0] + 'dev' + str(revno) mainline_revids = dict( (rev.revision_id, revno) for rev, revno in component.mainline_revs) in_branch_revs = [] while revid not in mainline_revids: rev = branch.repository.get_revision(revid) if rev.message != 'post release bump': in_branch_revs.append((rev, revno)) revno -= 1 if not rev.parent_ids: break revid = rev.parent_ids[0] tables = [] if in_branch_revs: tables.append( format_revlist( in_branch_revs, 'in branch (with nick %s) but not tip' % branch.nick)) in_trunk_revs = [] lca_revno = revno for rev, revno in component.mainline_revs: if revno > lca_revno: in_trunk_revs.append((rev, revno)) if in_trunk_revs: tables.append( format_revlist(in_trunk_revs, 'in tip but not branch')) if tables: id_ = get_id() td(tags.a(ver, href='#', class_='highlight'), class_='version clickable', id=id_) extra_rows.append( tags.tr(tags.td(tables, colspan=str(4 + len(instances))), class_='hidden branch-diff', id="show-" + id_)) else: if branch.last_revision() == component.tip_revno: td(ver, class_='highlight version') else: td(ver, class_='version') finally: branch.unlock() else: td(tags.span(ver, class_='highlight'), class_='version') tbody(row, *extra_rows) table(tbody) html = tags.html( tags.head( tags.title("Deployment report"), tags.script( src= 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', type='text/javascript'), tags.script( src= 'https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js', type='text/javascript'), tags.script(CDATA(js), type='text/javascript'), tags.style(CDATA(css), type="text/css"), ), tags.body( tags.h1("Deployment report"), table, ), ) html(xmlns="http://www.w3.org/1999/xhtml") return DOCTYPE + flatten(html)
def export_branch(repo, name): ref = '%s/heads/%s' % (prefix, name) tip = marks.get_tip(name) branch = get_remote_branch(name) repo = branch.repository branch.lock_read() revs = branch.iter_merge_sorted_revisions(None, tip, 'exclude', 'forward') try: tip_revno = branch.revision_id_to_revno(tip) last_revno, _ = branch.last_revision_info() total = last_revno - tip_revno except bzrlib.errors.NoSuchRevision: tip_revno = 0 total = 0 for revid, _, seq, _ in revs: if marks.is_marked(revid): continue rev = repo.get_revision(revid) revno = seq[0] parents = rev.parent_ids time = rev.timestamp tz = rev.timezone committer = rev.committer.encode('utf-8') committer = "%s %u %s" % (fixup_user(committer), time, gittz(tz)) authors = rev.get_apparent_authors() if authors: author = authors[0].encode('utf-8') author = "%s %u %s" % (fixup_user(author), time, gittz(tz)) else: author = committer msg = rev.message.encode('utf-8') msg += '\n' if len(parents) == 0: parent = bzrlib.revision.NULL_REVISION else: parent = parents[0] cur_tree = repo.revision_tree(revid) prev = repo.revision_tree(parent) modified, removed = get_filechanges(cur_tree, prev) modified_final = export_files(cur_tree, modified) if len(parents) == 0: print 'reset %s' % ref print "commit %s" % ref print "mark :%d" % (marks.get_mark(revid)) print "author %s" % (author) print "committer %s" % (committer) print "data %d" % (len(msg)) print msg for i, p in enumerate(parents): try: m = rev_to_mark(p) except KeyError: # ghost? continue if i == 0: print "from :%s" % m else: print "merge :%s" % m for f in removed: print "D %s" % (f, ) for f in modified_final: print "M %s :%u %s" % f print if len(seq) > 1: # let's skip branch revisions from the progress report continue progress = (revno - tip_revno) if (progress % 100 == 0): if total: print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total) else: print "progress revision %d '%s' (%d)" % (revno, name, progress) branch.unlock() revid = branch.last_revision() # make sure the ref is updated print "reset %s" % ref print "from :%u" % rev_to_mark(revid) print marks.set_tip(name, revid)
def parse_commit(parser): parents = [] ref = parser[1] parser.next() if ref.startswith('refs/heads/'): name = ref[len('refs/heads/'):] branch = get_remote_branch(name) else: die('unknown ref') commit_mark = parser.get_mark() parser.next() author = parser.get_author() parser.next() committer = parser.get_author() parser.next() data = parser.get_data() parser.next() if parser.check('from'): parents.append(parser.get_mark()) parser.next() while parser.check('merge'): parents.append(parser.get_mark()) parser.next() # fast-export adds an extra newline if data[-1] == '\n': data = data[:-1] files = {} for line in parser: if parser.check('M'): t, m, mark_ref, path = line.split(' ', 3) mark = int(mark_ref[1:]) f = { 'mode' : m, 'mark' : mark } elif parser.check('D'): t, path = line.split(' ', 1) f = { 'deleted' : True } else: die('Unknown file command: %s' % line) path = c_style_unescape(path).decode('utf-8') files[path] = f committer, date, tz = committer author, _, _ = author parents = [mark_to_rev(p) for p in parents] revid = bzrlib.generate_ids.gen_revision_id(committer, date) props = {} props['branch-nick'] = branch.nick props['authors'] = author mtree = CustomTree(branch, revid, parents, files) changes = mtree.iter_changes() branch.lock_write() try: builder = branch.get_commit_builder(parents, None, date, tz, committer, props, revid) try: list(builder.record_iter_changes(mtree, mtree.last_revision(), changes)) builder.finish_inventory() builder.commit(data.decode('utf-8', 'replace')) except Exception, e: builder.abort() raise finally: branch.unlock() parsed_refs[ref] = revid marks.new_mark(revid, commit_mark)
for f in modified_final: print "M %s :%u %s" % f print if len(seq) > 1: # let's skip branch revisions from the progress report continue progress = (revno - tip_revno) if (progress % 100 == 0): if total: print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total) else: print "progress revision %d '%s' (%d)" % (revno, name, progress) branch.unlock() revid = branch.last_revision() # make sure the ref is updated print "reset %s" % ref print "from :%u" % rev_to_mark(revid) print marks.set_tip(name, revid) def export_tag(repo, name): ref = '%s/tags/%s' % (prefix, name) print "reset %s" % ref print "from :%u" % rev_to_mark(tags[name]) print
def export_branch(repo, name): ref = '%s/heads/%s' % (prefix, name) tip = marks.get_tip(name) branch = get_remote_branch(name) repo = branch.repository branch.lock_read() revs = branch.iter_merge_sorted_revisions(None, tip, 'exclude', 'forward') try: tip_revno = branch.revision_id_to_revno(tip) last_revno, _ = branch.last_revision_info() total = last_revno - tip_revno except bzrlib.errors.NoSuchRevision: tip_revno = 0 total = 0 for revid, _, seq, _ in revs: if marks.is_marked(revid): continue rev = repo.get_revision(revid) revno = seq[0] parents = rev.parent_ids time = rev.timestamp tz = rev.timezone committer = rev.committer.encode('utf-8') committer = "%s %u %s" % (fixup_user(committer), time, gittz(tz)) authors = rev.get_apparent_authors() if authors: author = authors[0].encode('utf-8') author = "%s %u %s" % (fixup_user(author), time, gittz(tz)) else: author = committer msg = rev.message.encode('utf-8') msg += '\n' if len(parents) == 0: parent = bzrlib.revision.NULL_REVISION else: parent = parents[0] cur_tree = repo.revision_tree(revid) prev = repo.revision_tree(parent) modified, removed = get_filechanges(cur_tree, prev) modified_final = export_files(cur_tree, modified) if len(parents) == 0: print 'reset %s' % ref print "commit %s" % ref print "mark :%d" % (marks.get_mark(revid)) print "author %s" % (author) print "committer %s" % (committer) print "data %d" % (len(msg)) print msg for i, p in enumerate(parents): try: m = rev_to_mark(p) except KeyError: # ghost? continue if i == 0: print "from :%s" % m else: print "merge :%s" % m for f in removed: print "D %s" % (f,) for f in modified_final: print "M %s :%u %s" % f print if len(seq) > 1: # let's skip branch revisions from the progress report continue progress = (revno - tip_revno) if (progress % 100 == 0): if total: print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total) else: print "progress revision %d '%s' (%d)" % (revno, name, progress) branch.unlock() revid = branch.last_revision() # make sure the ref is updated print "reset %s" % ref print "from :%u" % rev_to_mark(revid) print marks.set_tip(name, revid)
print if len(seq) > 1: # let's skip branch revisions from the progress report continue progress = (revno - tip_revno) if (progress % 100 == 0): if total: print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total) else: print "progress revision %d '%s' (%d)" % (revno, name, progress) branch.unlock() revid = branch.last_revision() # make sure the ref is updated print "reset %s" % ref print "from :%u" % rev_to_mark(revid) print marks.set_tip(name, revid) def export_tag(repo, name): ref = '%s/tags/%s' % (prefix, name) print "reset %s" % ref print "from :%u" % rev_to_mark(tags[name])
def make_html(components, instances): table = tags.table(class_='main') heading_row = tags.tr() for heading in 'component', 'tip revno', 'unreleased revisions', 'latest release': heading_row(tags.th(heading)) for instance_name in sorted(instances): heading_row(tags.th(instance_name, class_="instance-name")) table(tags.thead(heading_row)) tbody = tags.tbody() for name, component in sorted(components.items()): row = tags.tr(class_="component") revs_between_ids = {} extra_rows = [] def td(*args, **kwargs): row(tags.td(*args, **kwargs)) td(name) td(str(component.tip_revno), class_='version') unreleased_count = len(component.unreleased_revisions) if unreleased_count: id_ = get_id() td( tags.a(str(unreleased_count), href='#', class_='highlight'), class_='version clickable', id=id_) sub_name = 'revs between %s (r%s) and tip (r%s)' % ( component.last_release, component.released_revno, component.tip_revno) extra_rows.append( tags.tr( tags.td( format_revlist(component.unreleased_revisions, name=sub_name), colspan=str(4 + len(instances))), class_='hidden', id="show-" + id_)) elif not component.last_release: td(u'\N{EM DASH}', class_='version') else: td(str(unreleased_count), class_='version') if component.last_release: td(component.last_release, class_='version') else: td(u'???', class_='version') for instance_name, instance in sorted(instances.items()): ver, location = instance.get(name, (None, None)) if ver is None: td(u'\N{EM DASH}', class_='version') elif ver == component.last_release: td(ver, class_='version') elif ver in component.release2revno: revno_low = component.release2revno[ver] sub_name = 'revs between %s (r%s) and %s (r%s)' % ( ver, revno_low, component.last_release, component.released_revno) revlist = [] for rev, revno in component.mainline_revs: if revno_low < revno < component.released_revno: revlist.append((rev, revno)) if revlist: id_ = get_id() revs_between_ids[revno_low] = id_ extra_rows.append( tags.tr( tags.td( format_revlist(revlist, name=sub_name), colspan=str(4 + len(instances))), class_='hidden branch-diff', id="show-" + id_)) td( tags.a(ver, href='#', class_='highlight'), class_='version clickable', id=id_) else: td(tags.span(ver, class_='highlight'), class_='version') elif location: try: branch = bzrlib.branch.Branch.open(location) except bzrlib.errors.NoSuchBranch: td(tags.span(ver, class_='highlight'), class_='version') else: branch.lock_read() try: # This utterly half-assed version of bzr missing # doesn't take merges into account! revno, revid = branch.last_revision_info() ver = ver.split('dev')[0] + 'dev' + str(revno) mainline_revids = dict( (rev.revision_id, revno) for rev, revno in component.mainline_revs) in_branch_revs = [] while revid not in mainline_revids: rev = branch.repository.get_revision(revid) if rev.message != 'post release bump': in_branch_revs.append((rev, revno)) revno -= 1 if not rev.parent_ids: break revid = rev.parent_ids[0] tables = [] if in_branch_revs: tables.append( format_revlist( in_branch_revs, 'in branch (with nick %s) but not tip' % branch.nick)) in_trunk_revs = [] lca_revno = revno for rev, revno in component.mainline_revs: if revno > lca_revno: in_trunk_revs.append((rev, revno)) if in_trunk_revs: tables.append( format_revlist( in_trunk_revs, 'in tip but not branch')) if tables: id_ = get_id() td( tags.a(ver, href='#', class_='highlight'), class_='version clickable', id=id_) extra_rows.append( tags.tr( tags.td( tables, colspan=str(4 + len(instances))), class_='hidden branch-diff', id="show-" + id_)) else: if branch.last_revision() == component.tip_revno: td(ver, class_='highlight version') else: td(ver, class_='version') finally: branch.unlock() else: td(tags.span(ver, class_='highlight'), class_='version') tbody(row, *extra_rows) table(tbody) html = tags.html( tags.head( tags.title("Deployment report"), tags.script( src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', type='text/javascript'), tags.script( src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js', type='text/javascript'), tags.script(CDATA(js), type='text/javascript'), tags.style(CDATA(css), type="text/css"), ), tags.body( tags.h1("Deployment report"), table, ), ) html(xmlns="http://www.w3.org/1999/xhtml") return DOCTYPE + flatten(html)