diff: patch.diff() writes in repo.ui as in a binary stream while stdout is actually a text-stream under win32. diff -r 633b57952896 mercurial/patch.py --- a/mercurial/patch.py Sun Feb 18 17:51:02 2007 +0100 +++ b/mercurial/patch.py Sun Feb 18 21:11:35 2007 +0100 @@ -433,8 +433,6 @@ def diff(repo, node1=None, node2=None, f if opts is None: opts = mdiff.defaultopts - if fp is None: - fp = repo.ui if not node1: node1 = repo.dirstate.parents()[0] @@ -527,68 +525,77 @@ def diff(repo, node1=None, node2=None, f all = modified + added + removed all.sort() gone = {} - - for f in all: - to = None - tn = None - dodiff = True - header = [] - if f in man1: - to = getfilectx(f, ctx1).data() - if f not in removed: - tn = getfilectx(f, ctx2).data() - if opts.git: - def gitmode(x): - return x and '100755' or '100644' - def addmodehdr(header, omode, nmode): - if omode != nmode: - header.append('old mode %s\n' % omode) - header.append('new mode %s\n' % nmode) - - a, b = f, f - if f in added: - mode = gitmode(man2.execf(f)) - if f in copied: - a = copied[f] - omode = gitmode(man1.execf(a)) - addmodehdr(header, omode, mode) - if a in removed and a not in gone: - op = 'rename' - gone[a] = 1 + + if fp is None: + fp = repo.ui.binaryfile() + fp_close = fp.close + else: + fp_close = lambda: None + + try: + for f in all: + to = None + tn = None + dodiff = True + header = [] + if f in man1: + to = getfilectx(f, ctx1).data() + if f not in removed: + tn = getfilectx(f, ctx2).data() + if opts.git: + def gitmode(x): + return x and '100755' or '100644' + def addmodehdr(header, omode, nmode): + if omode != nmode: + header.append('old mode %s\n' % omode) + header.append('new mode %s\n' % nmode) + + a, b = f, f + if f in added: + mode = gitmode(man2.execf(f)) + if f in copied: + a = copied[f] + omode = gitmode(man1.execf(a)) + addmodehdr(header, omode, mode) + if a in removed and a not in gone: + op = 'rename' + gone[a] = 1 + else: + op = 'copy' + header.append('%s from %s\n' % (op, a)) + header.append('%s to %s\n' % (op, f)) + to = getfilectx(a, ctx1).data() else: - op = 'copy' - header.append('%s from %s\n' % (op, a)) - header.append('%s to %s\n' % (op, f)) - to = getfilectx(a, ctx1).data() + header.append('new file mode %s\n' % mode) + if util.binary(tn): + dodiff = 'binary' + elif f in removed: + if f in srcs: + dodiff = False + else: + mode = gitmode(man1.execf(f)) + header.append('deleted file mode %s\n' % mode) else: - header.append('new file mode %s\n' % mode) - if util.binary(tn): - dodiff = 'binary' - elif f in removed: - if f in srcs: - dodiff = False - else: - mode = gitmode(man1.execf(f)) - header.append('deleted file mode %s\n' % mode) - else: - omode = gitmode(man1.execf(f)) - nmode = gitmode(man2.execf(f)) - addmodehdr(header, omode, nmode) - if util.binary(to) or util.binary(tn): - dodiff = 'binary' - r = None - header.insert(0, 'diff --git a/%s b/%s\n' % (a, b)) - if dodiff == 'binary': - fp.write(''.join(header)) - b85diff(fp, to, tn) - elif dodiff: - text = mdiff.unidiff(to, date1, - # ctx2 date may be dynamic - tn, util.datestr(ctx2.date()), - f, r, opts=opts) - if text or len(header) > 1: + omode = gitmode(man1.execf(f)) + nmode = gitmode(man2.execf(f)) + addmodehdr(header, omode, nmode) + if util.binary(to) or util.binary(tn): + dodiff = 'binary' + r = None + header.insert(0, 'diff --git a/%s b/%s\n' % (a, b)) + if dodiff == 'binary': fp.write(''.join(header)) - fp.write(text) + b85diff(fp, to, tn) + elif dodiff: + text = mdiff.unidiff(to, date1, + # ctx2 date may be dynamic + tn, util.datestr(ctx2.date()), + f, r, opts=opts) + if text or len(header) > 1: + fp.write(''.join(header)) + fp.write(text) + finally: + fp_close() def export(repo, revs, template='hg-%h.patch', fp=None, switch_parent=False, opts=None): diff -r 633b57952896 mercurial/ui.py --- a/mercurial/ui.py Sun Feb 18 17:51:02 2007 +0100 +++ b/mercurial/ui.py Sun Feb 18 21:11:35 2007 +0100 @@ -368,6 +368,28 @@ class ui(object): if not path and default is not None: path = self.config("paths", default) return path or loc + + def binaryfile(self): + """Return ui as a binary file. Using binaryfile() and ui file + like functions at the same time has undefined behaviour. Close the + binary file to return to ui normal operation mode. + """ + class binaryui(object): + def __init__(self, ui): + self._ui = ui + self._ui.flush() + util.set_binary(sys.stdout) + + def __getattr__(self, name): + return getattr(sys.stdout, name) + + def close(self): + if self._ui is not None: + sys.stdout.flush() + util.set_binary(sys.stdout, False) + self._ui = None + + return binaryui(self) def pushbuffer(self): self.buffers.append([]) diff -r 633b57952896 mercurial/util.py --- a/mercurial/util.py Sun Feb 18 17:51:02 2007 +0100 +++ b/mercurial/util.py Sun Feb 18 21:11:35 2007 +0100 @@ -846,8 +846,12 @@ if os.name == 'nt': def set_link(f, mode): pass - def set_binary(fd): - msvcrt.setmode(fd.fileno(), os.O_BINARY) + def set_binary(fd, binary=True): + if binary: + mode = os.O_BINARY + else: + mode = os.O_TEXT + msvcrt.setmode(fd.fileno(), mode) def pconvert(path): return path.replace("\\", "/") @@ -971,7 +975,7 @@ else: os.unlink(f) file(f, "w").write(data) - def set_binary(fd): + def set_binary(fd, binary=True): pass def pconvert(path):