diff --git a/hgext/churn.py b/hgext/churn.py --- a/hgext/churn.py +++ b/hgext/churn.py @@ -44,9 +44,7 @@ def maketemplater(ui, repo, tmpl): def changedlines(ui, repo, ctx1, ctx2): lines = 0 - ui.pushbuffer() - patch.diff(repo, ctx1.node(), ctx2.node()) - diff = ui.popbuffer() + diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node())) for l in diff.split('\n'): if (l.startswith("+") and not l.startswith("+++ ") or l.startswith("-") and not l.startswith("--- ")): diff --git a/hgext/hgk.py b/hgext/hgk.py --- a/hgext/hgk.py +++ b/hgext/hgk.py @@ -92,8 +92,10 @@ def difftree(ui, repo, node1=None, node2 if opts['pretty']: catcommit(ui, repo, node2, "") m = cmdutil.match(repo, files) - patch.diff(repo, node1, node2, match=m, - opts=patch.diffopts(ui, {'git': True})) + chunks = patch.diff(repo, node1, node2, match=m, + opts=patch.diffopts(ui, {'git': True})) + for chunk in chunks: + repo.ui.write(chunk) else: __difftree(repo, node1, node2, files=files) if not opts['stdin']: diff --git a/hgext/keyword.py b/hgext/keyword.py --- a/hgext/keyword.py +++ b/hgext/keyword.py @@ -501,15 +501,15 @@ def reposetup(ui, repo): # shrink keywords read from working dir self.lines = kwt.shrinklines(self.fname, self.lines) - def kw_diff(orig, repo, node1=None, node2=None, match=None, - fp=None, changes=None, opts=None): + def kw_diff(orig, repo, node1=None, node2=None, match=None, changes=None, + opts=None): '''Monkeypatch patch.diff to avoid expansion except when comparing against working dir.''' if node2 is not None: kwt.matcher = util.never elif node1 is not None and node1 != repo['.'].node(): kwt.restrict = True - orig(repo, node1, node2, match, fp, changes, opts) + return orig(repo, node1, node2, match, changes, opts) def kwweb_skip(orig, web, req, tmpl): '''Wraps webcommands.x turning off keyword expansion.''' diff --git a/hgext/mq.py b/hgext/mq.py --- a/hgext/mq.py +++ b/hgext/mq.py @@ -321,7 +321,10 @@ class queue: def printdiff(self, repo, node1, node2=None, files=None, fp=None, changes=None, opts={}): m = cmdutil.match(repo, files, opts) - patch.diff(repo, node1, node2, m, fp, changes, self.diffopts()) + chunks = patch.diff(repo, node1, node2, m, changes, self.diffopts()) + write = fp is None and repo.ui.write or fp.write + for chunk in chunks: + write(chunk) def mergeone(self, repo, mergeq, head, patch, rev): # first try just applying the patch @@ -697,8 +700,10 @@ class queue: diffopts = self.diffopts() if opts.get('git'): diffopts.git = True parent = self.qparents(repo, n) - patch.diff(repo, node1=parent, node2=n, fp=p, - match=match, opts=diffopts) + chunks = patch.diff(repo, node1=parent, node2=n, + match=match, opts=diffopts) + for chunk in chunks: + p.write(chunk) p.close() wlock = None r = self.qrepo() @@ -1139,8 +1144,10 @@ class queue: a = util.unique(aa) c = [filter(matchfn, l) for l in (m, a, r)] match = cmdutil.matchfiles(repo, util.unique(c[0] + c[1] + c[2])) - patch.diff(repo, patchparent, match=match, - fp=patchf, changes=c, opts=self.diffopts()) + chunks = patch.diff(repo, patchparent, match=match, + changes=c, opts=self.diffopts()) + for chunk in chunks: + patchf.write(chunk) patchf.close() repo.dirstate.setparents(*cparents) diff --git a/hgext/notify.py b/hgext/notify.py --- a/hgext/notify.py +++ b/hgext/notify.py @@ -238,9 +238,8 @@ class notifier(object): maxdiff = int(self.ui.config('notify', 'maxdiff', 300)) prev = self.repo.changelog.parents(node)[0] - self.ui.pushbuffer() - patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui)) - difflines = self.ui.popbuffer().splitlines() + chunks = patch.diff(self.repo, prev, ref, opts=patch.diffopts(self.ui)) + difflines = ''.join(chunks).splitlines() if self.ui.configbool('notify', 'diffstat', True): s = patch.diffstat(difflines) diff --git a/hgext/record.py b/hgext/record.py --- a/hgext/record.py +++ b/hgext/record.py @@ -413,9 +413,10 @@ def dorecord(ui, repo, committer, *pats, modified, added, removed = changes match = cmdutil.matchfiles(repo, modified + added + removed) diffopts = mdiff.diffopts(git=True, nodates=True) + chunks = patch.diff(repo, repo.dirstate.parents()[0], match=match, + changes=changes, opts=diffopts) fp = cStringIO.StringIO() - patch.diff(repo, repo.dirstate.parents()[0], match=match, - changes=changes, opts=diffopts, fp=fp) + fp.write(''.join(chunks)) fp.seek(0) # 1. filter patch, so we have intending-to apply subset of it diff --git a/hgext/transplant.py b/hgext/transplant.py --- a/hgext/transplant.py +++ b/hgext/transplant.py @@ -138,7 +138,9 @@ class transplanter: else: fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-') fp = os.fdopen(fd, 'w') - patch.diff(source, parents[0], node, fp=fp, opts=diffopts) + gen = patch.diff(source, parents[0], node, opts=diffopts) + for chunk in gen: + fp.write(chunk) fp.close() del revmap[rev] @@ -405,7 +407,8 @@ def browserevs(ui, repo, nodes, opts): action = None elif action == 'p': parent = repo.changelog.parents(node)[0] - patch.diff(repo, parent, node) + for chunk in patch.diff(repo, parent, node): + repo.ui.write(chunk) action = None elif action not in ('y', 'n', 'm', 'c', 'q'): ui.write('no such option\n') diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -673,8 +673,10 @@ class changeset_printer(object): def showpatch(self, node): if self.patch: prev = self.repo.changelog.parents(node)[0] - patch.diff(self.repo, prev, node, match=self.patch, fp=self.ui, - opts=patch.diffopts(self.ui)) + chunks = patch.diff(self.repo, prev, node, match=self.patch, + opts=patch.diffopts(self.ui)) + for chunk in chunks: + self.ui.write(chunk) self.ui.write("\n") def _meaningful_parentrevs(self, log, rev): diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -1010,7 +1010,9 @@ def diff(ui, repo, *pats, **opts): node1, node2 = cmdutil.revpair(repo, opts.get('rev')) m = cmdutil.match(repo, pats, opts) - patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts)) + it = patch.diff(repo, node1, node2, match=m, opts=patch.diffopts(ui, opts)) + for chunk in it: + repo.ui.write(chunk) def export(ui, repo, *changesets, **opts): """dump the header and diffs for one or more changesets diff --git a/mercurial/patch.py b/mercurial/patch.py --- a/mercurial/patch.py +++ b/mercurial/patch.py @@ -1169,9 +1169,8 @@ def _addmodehdr(header, omode, nmode): header.append('old mode %s\n' % omode) header.append('new mode %s\n' % nmode) -def diff(repo, node1=None, node2=None, match=None, - fp=None, changes=None, opts=None): - '''print diff of changes to files between two nodes, or node and +def diff(repo, node1=None, node2=None, match=None, changes=None, opts=None): + '''yields diff of changes to files between two nodes, or node and working directory. if node1 is None, use first dirstate parent instead. @@ -1182,8 +1181,6 @@ def diff(repo, node1=None, node2=None, m if opts is None: opts = mdiff.defaultopts - if fp is None: - fp = repo.ui if not node1: node1 = repo.dirstate.parents()[0] @@ -1274,9 +1271,10 @@ def diff(repo, node1=None, node2=None, m # ctx2 date may be dynamic tn, util.datestr(ctx2.date()), a, b, r, opts=opts) - if text or len(header) > 1: - fp.write(''.join(header)) - fp.write(text) + if header and (text or len(header) > 1): + yield ''.join(header) + if text: + yield text def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False, opts=None): @@ -1312,7 +1310,8 @@ def export(repo, revs, template='hg-%h.p fp.write(ctx.description().rstrip()) fp.write("\n\n") - diff(repo, prev, node, fp=fp, opts=opts) + for chunk in diff(repo, prev, node, opts=opts): + fp.write(chunk) if fp not in (sys.stdout, repo.ui): fp.close()