def make_commit_message_template_encoded(working_tree, specific_files, diff=None, output_encoding='utf-8'): """Prepare a template file for a commit into a branch. Returns an encoded string. """ # TODO: make provision for this to be overridden or modified by a hook # # TODO: Rather than running the status command, should prepare a draft of # the revision to be committed, then pause and ask the user to # confirm/write a message. from StringIO import StringIO # must be unicode-safe from bzrlib.diff import show_diff_trees template = make_commit_message_template(working_tree, specific_files) template = template.encode(output_encoding, "replace") if diff: stream = StringIO() show_diff_trees(working_tree.basis_tree(), working_tree, stream, specific_files, path_encoding=output_encoding) template = template + '\n' + stream.getvalue() return template
def get_diff(self): """Add the diff from the commit to the output. If the diff has more than difflimit lines, it will be skipped. """ difflimit = self.difflimit() if not difflimit: # No need to compute a diff if we aren't going to display it return from bzrlib.diff import show_diff_trees # optionally show the diff if its smaller than the post_commit_difflimit option revid_new = self.revision.revision_id if self.revision.parent_ids: revid_old = self.revision.parent_ids[0] tree_new, tree_old = self.repository.revision_trees( (revid_new, revid_old)) else: # revision_trees() doesn't allow None or 'null:' to be passed as a # revision. So we need to call revision_tree() twice. revid_old = _mod_revision.NULL_REVISION tree_new = self.repository.revision_tree(revid_new) tree_old = self.repository.revision_tree(revid_old) # We can use a cStringIO because show_diff_trees should only write # 8-bit strings. It is an error to write a Unicode string here. from cStringIO import StringIO diff_content = StringIO() show_diff_trees(tree_old, tree_new, diff_content) numlines = diff_content.getvalue().count('\n') + 1 if numlines <= difflimit: return diff_content.getvalue() else: return ("\nDiff too large for email" " (%d lines, the limit is %d).\n" % (numlines, difflimit))
def get_diff(self): """Add the diff from the commit to the output. If the diff has more than difflimit lines, it will be skipped. """ difflimit = self.difflimit() if not difflimit: # No need to compute a diff if we aren't going to display it return from bzrlib.diff import show_diff_trees # optionally show the diff if its smaller than the post_commit_difflimit option revid_new = self.revision.revision_id if self.revision.parent_ids: revid_old = self.revision.parent_ids[0] tree_new, tree_old = self.repository.revision_trees((revid_new, revid_old)) else: # revision_trees() doesn't allow None or 'null:' to be passed as a # revision. So we need to call revision_tree() twice. revid_old = _mod_revision.NULL_REVISION tree_new = self.repository.revision_tree(revid_new) tree_old = self.repository.revision_tree(revid_old) # We can use a cStringIO because show_diff_trees should only write # 8-bit strings. It is an error to write a Unicode string here. from cStringIO import StringIO diff_content = StringIO() show_diff_trees(tree_old, tree_new, diff_content) numlines = diff_content.getvalue().count('\n')+1 if numlines <= difflimit: return diff_content.getvalue() else: return ("\nDiff too large for email" " (%d lines, the limit is %d).\n" % (numlines, difflimit))
def diff(self): """Difference between working copy and repository.""" iostream = StringIO() diff.show_diff_trees(self.workingtree.basis_tree(), self.workingtree, iostream) # textstream return iostream.getvalue()
def stats(self): if not self._stats: s = DiffStat() prev_revtree = self._get_revtree(self.prev_id) show_diff_trees(prev_revtree, self.revtree, s) self._stats = s return self._stats
def fromTrees(klass, from_tree, to_tree, filename=None): """Create a Diff from two Bazaar trees. :from_tree: The old tree in the diff. :to_tree: The new tree in the diff. """ diff_content = StringIO() show_diff_trees(from_tree, to_tree, diff_content, old_label='', new_label='') return klass.fromFileAtEnd(diff_content, filename)
def readlines(self): from bzrlib.diff import show_diff_trees from StringIO import StringIO f = StringIO() show_diff_trees(self.old_tree, self.tree, f, self.file_list, old_label='', new_label='') f.seek(0) return f.readlines()
def write_diff(self, merger): """Write this operation's diff to self.write_diff_to.""" tree_merger = merger.make_merger() tt = tree_merger.make_preview_transform() new_tree = tt.get_preview_tree() if self.write_diff_to is None: self.write_diff_to = ui.ui_factory.make_output_stream(encoding_type='exact') path_encoding = osutils.get_diff_header_encoding() diff.show_diff_trees(merger.this_tree, new_tree, self.write_diff_to, path_encoding=path_encoding) tt.finalize()
def write_diff(self, merger): """Write this operation's diff to self.write_diff_to.""" tree_merger = merger.make_merger() tt = tree_merger.make_preview_transform() new_tree = tt.get_preview_tree() if self.write_diff_to is None: self.write_diff_to = ui.ui_factory.make_output_stream( encoding_type='exact') path_encoding = osutils.get_diff_header_encoding() diff.show_diff_trees(merger.this_tree, new_tree, self.write_diff_to, path_encoding=path_encoding) tt.finalize()
def bzr_get_changeset(branch, revid): # the changes delta = branch.repository.get_revision_delta(revid) out = StringIO() revspec = "before:revid:" + str(revid) before = revisionspec.RevisionSpec.from_string(revspec) before_revid = before.as_revision_id(branch) tree1 = branch.repository.revision_tree(before_revid) tree2 = branch.repository.revision_tree(revid) diff.show_diff_trees(tree1, tree2, out) changes = out.getvalue() if not "+++" in changes: # otherwise patch will complain about no useful text in the # generated diff changes = None # the log message revision = branch.repository.get_revision(revid) log = revision.message.encode("utf8", "replace") # hg enforces utf-8 author = revision.get_apparent_author() date = "%d %d" % (revision.timestamp, -revision.timezone) # bizarre hg format # collect the file attributes changes inventory = dict(tree2.inventory.entries()) attr_changed = [path for (path, fileid, kind, cont, attr) in delta.modified if attr] attr_changed.extend(path for (path, path2, fileid, kind, cont, attr) in delta.renamed if attr) attr_changed.extend(path for path, fileid, kind in delta.added if inventory[path].executable) executables = [(path, inventory[path].executable) for path in attr_changed] added = [] newdirs = [] for name, fileid, type in delta.added: encoded = name.encode(encode_locale) added.append(encoded) if type == "directory": newdirs.append(encoded) removed = [name.encode(encode_locale) for name, fileid, type in delta.removed] renamed = [(old.encode(encode_locale), new.encode(encode_locale)) for old, new, fileid, type, _, __ in delta.renamed] return (date, author, log, changes, added, removed, renamed, executables, newdirs)
def bzr_get_changeset(branch, revid): # the changes delta = branch.repository.get_revision_delta(revid) out = StringIO() revspec = "before:revid:" + str(revid) before = revisionspec.RevisionSpec.from_string(revspec) before_revid = before.as_revision_id(branch) tree1 = branch.repository.revision_tree(before_revid) tree2 = branch.repository.revision_tree(revid) diff.show_diff_trees(tree1, tree2, out) changes = out.getvalue() if not "+++" in changes: # otherwise patch will complain about no useful text in the # generated diff changes = None # the log message revision = branch.repository.get_revision(revid) log = revision.message.encode("utf8", "replace") # hg enforces utf-8 author = revision.get_apparent_author() date = "%d %d" % (revision.timestamp, -revision.timezone ) # bizarre hg format # collect the file attributes changes inventory = dict(tree2.inventory.entries()) attr_changed = [ path for (path, fileid, kind, cont, attr) in delta.modified if attr ] attr_changed.extend(path for (path, path2, fileid, kind, cont, attr) in delta.renamed if attr) attr_changed.extend(path for path, fileid, kind in delta.added if inventory[path].executable) executables = [(path, inventory[path].executable) for path in attr_changed] added = [] newdirs = [] for name, fileid, type in delta.added: encoded = name.encode(encode_locale) added.append(encoded) if type == "directory": newdirs.append(encoded) removed = [ name.encode(encode_locale) for name, fileid, type in delta.removed ] renamed = [(old.encode(encode_locale), new.encode(encode_locale)) for old, new, fileid, type, _, __ in delta.renamed] return (date, author, log, changes, added, removed, renamed, executables, newdirs)
def run(self): revision = _parse_revision_str('submit:') diff_data = get_trees_and_branches_to_diff_locked( None, revision, None, None, self.add_cleanup, apply_view=True) (old_tree, new_tree, old_branch, new_branch, specific_files, extra_trees) = diff_data stream = StringIO() show_diff_trees( old_tree, new_tree, stream, old_label='', new_label='', extra_trees=extra_trees) stream.seek(0) patches = parse_patches(stream) comments = get_comments_from_diff(patches) tags = ('XXX', 'TODO') number = -1 for number, todo in enumerate(todos_from_comments(comments, tags)): print todo print "Things to do: %s" % (number + 1)
def getDiffForRevisions(self, from_revision_id, to_revision_id): """Generate the diff between from_revision_id and to_revision_id.""" # Try to reuse a tree from the last time through. repository = self.bzr_branch.repository from_tree = self._tree_cache.get(from_revision_id) if from_tree is None: from_tree = repository.revision_tree(from_revision_id) to_tree = self._tree_cache.get(to_revision_id) if to_tree is None: to_tree = repository.revision_tree(to_revision_id) # Replace the tree cache with these two trees. self._tree_cache = { from_revision_id: from_tree, to_revision_id: to_tree} # Now generate the diff. diff_content = StringIO() show_diff_trees( from_tree, to_tree, diff_content, old_label='', new_label='') return diff_content.getvalue()
def show_diff(self, specific_files): """Show the diff for the specified files""" s = StringIO() show_diff_trees(self.parent_tree, self.rev_tree, s, specific_files, old_label='', new_label='', # path_encoding=sys.getdefaultencoding() # The default is utf-8, but we interpret the file # contents as getdefaultencoding(), so we should # probably try to make the paths in the same encoding. ) # str.decode(encoding, 'replace') doesn't do anything. Because if a # character is not valid in 'encoding' there is nothing to replace, the # 'replace' is for 'str.encode()' try: decoded = s.getvalue().decode(sys.getdefaultencoding()) except UnicodeDecodeError: try: decoded = s.getvalue().decode('UTF-8') except UnicodeDecodeError: decoded = s.getvalue().decode('iso-8859-1') # This always works, because every byte has a valid # mapping from iso-8859-1 to Unicode # TextBuffer must contain pure UTF-8 data self.buffer.set_text(decoded.encode('UTF-8'))
def bzr_get_changeset(branch, revid): # the changes delta = branch.repository.get_revision_delta(revid) out = StringIO() revspec = "before:revid:" + str(revid) before = revisionspec.RevisionSpec.from_string(revspec) before_revid = before.as_revision_id(branch) tree1 = branch.repository.revision_tree(before_revid) tree2 = branch.repository.revision_tree(revid) diff.show_diff_trees(tree1, tree2, out) changes = out.getvalue() if not "+++" in changes: # otherwise patch will complain about no useful text in the # generated diff changes = None # the log message log = branch.repository.get_revision(revid).message added = [name.encode(encode_locale) for name, fileid, type in delta.added] removed = [name.encode(encode_locale) for name, fileid, type in delta.removed] renamed = [(old.encode(encode_locale), new.encode(encode_locale)) for old, new, fileid, type, _, __ in delta.renamed] return log, changes, added, removed, renamed
def get_stats_for(self, files=[]): s = DiffStat() prev_revtree = self._get_revtree(self.prev_id) show_diff_trees(prev_revtree, self.revtree, s, files) return s
def _generate_diff(repository, revision_id, ancestor_id): tree_1 = repository.revision_tree(ancestor_id) tree_2 = repository.revision_tree(revision_id) s = StringIO() diff.show_diff_trees(tree_1, tree_2, s, old_label='', new_label='') return s.getvalue()
def diff(self, team, file, rev, code=None): """ This function returns the patch applied by a particular revision to a file. """ if file[:9] == 'New File ': return dict(path=file, history=[]) project, file = self.get_project_path(file) b = open_branch(int(team), project) if code == None: #the patch from a commit rev_id = b.revision_history()[int(rev) - 1] rev = b.repository.get_revision(rev_id) from cStringIO import StringIO from bzrlib import diff if len(rev.parent_ids) == 0: ancestor_id = bzrlib.revision.NULL_REVISION else: ancestor_id = rev.parent_ids[0] tree_1 = b.repository.revision_tree(ancestor_id) tree_2 = b.repository.revision_tree(rev_id) s = StringIO() diff.show_diff_trees(tree_1, tree_2, s, old_label='', new_label='') filediff = s.getvalue() else: #the current difference path, file_name = os.path.split(file) ancestor_id = b.last_revision() # Check out the code wt = WorkingTree(int(team), project) # Directory we're working in td = wt.tmpdir print td + os.path.sep + file tmpfile = open(td + os.path.sep + file, 'w') tmpfile.write(str(code)) tmpfile.close() print 'temp_dir: ' + td + "\nfile: " + file # Run pychecker p = subprocess.Popen(['bzr', 'diff'], cwd=td, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = p.communicate() rval = p.wait() wt.destroy() if rval == 0: return dict() else: filediff = output[0] return dict(diff=filediff, oldrev=b.revision_id_to_revno(ancestor_id))