diff --git a/eden/scm/edenscm/mercurial/cmdutil.py b/eden/scm/edenscm/mercurial/cmdutil.py index 0ebd49a79d..ca16e20670 100644 --- a/eden/scm/edenscm/mercurial/cmdutil.py +++ b/eden/scm/edenscm/mercurial/cmdutil.py @@ -223,17 +223,17 @@ def parsealiases(cmd): def setupwrapcolorwrite(ui): # wrap ui.write so diff output can be labeled/colorized - def wrapwrite(orig, *args, **kw): + def wrapwritebytes(orig, *args, **kw): label = kw.pop(r"label", "") for chunk, l in patch.difflabel(lambda: args): orig(chunk, label=label + l) - oldwrite = ui.write + oldwrite = ui.writebytes def wrap(*args, **kwargs): - return wrapwrite(oldwrite, *args, **kwargs) + return wrapwritebytes(oldwrite, *args, **kwargs) - setattr(ui, "write", wrap) + setattr(ui, "writebytes", wrap) return oldwrite @@ -265,7 +265,7 @@ def recordfilter(ui, originalhunks, operation=None): ui, originalhunks, usecurses, testfile, operation ) finally: - ui.write = oldwrite + ui.writebytes = oldwrite return newchunks, newopts diff --git a/eden/scm/edenscm/mercurial/color.py b/eden/scm/edenscm/mercurial/color.py index 63438a4f0a..4c9d1fbbe0 100644 --- a/eden/scm/edenscm/mercurial/color.py +++ b/eden/scm/edenscm/mercurial/color.py @@ -449,12 +449,12 @@ def colorlabel(ui, msg, label, usebytes=False): if label and msg: if msg[-1] == "\n": if usebytes: - msg = b"[%s|%s]\n" % (label, msg[:-1]) + msg = b"[%s|%s]\n" % (encodeutf8(label), msg[:-1]) else: msg = "[%s|%s]\n" % (label, msg[:-1]) else: if usebytes: - msg = b"[%s|%s]" % (label, msg) + msg = b"[%s|%s]" % (encodeutf8(label), msg) else: msg = "[%s|%s]" % (label, msg) elif ui._colormode is not None: diff --git a/eden/scm/edenscm/mercurial/mdiff.py b/eden/scm/edenscm/mercurial/mdiff.py index 024890c430..84030f6a8d 100644 --- a/eden/scm/edenscm/mercurial/mdiff.py +++ b/eden/scm/edenscm/mercurial/mdiff.py @@ -321,7 +321,7 @@ def unidiff(a, ad, b, bd, fn1, fn2, opts=defaultopts, check_binary=True): message = b"Binary file %s has changed\n" % encodeutf8(fn1) hunks = iter([(None, [message])]) elif not a: - without_newline = b[-1:] != "\n" + without_newline = b[-1:] != b"\n" bl = splitnewlines(b) if a is None: l1 = b"--- /dev/null%s" % datetag(epoch) diff --git a/eden/scm/edenscm/mercurial/patch.py b/eden/scm/edenscm/mercurial/patch.py index 4adcc8e282..8c31236ed2 100644 --- a/eden/scm/edenscm/mercurial/patch.py +++ b/eden/scm/edenscm/mercurial/patch.py @@ -59,17 +59,17 @@ def split(stream): """return an iterator of individual patches from a stream""" def isheader(line, inheader): - if inheader and line[0] in (" ", "\t"): + if inheader and line[:1] in (b" ", b"\t"): # continuation return True - if line[0] in (" ", "-", "+"): + if line[:1] in (b" ", b"-", b"+"): # diff line - don't check for header pattern in there return False - l = line.split(": ", 1) - return len(l) == 2 and " " not in l[0] + l = line.split(b": ", 1) + return len(l) == 2 and b" " not in l[0] def chunk(lines): - return stringio("".join(lines)) + return stringio(b"".join(lines)) def hgsplit(stream, cur): inheader = True @@ -89,7 +89,7 @@ def split(stream): def mboxsplit(stream, cur): for line in stream: - if line.startswith("From "): + if line.startswith(b"From "): for c in split(chunk(cur[1:])): yield c cur = [] @@ -168,16 +168,16 @@ def split(stream): for line in stream: cur.append(line) - if line.startswith("# HG changeset patch"): + if line.startswith(b"# HG changeset patch"): return hgsplit(stream, cur) - elif line.startswith("From "): + elif line.startswith(b"From "): return mboxsplit(stream, cur) elif isheader(line, inheader): inheader = True - if line.split(":", 1)[0].lower() in mimeheaders: + if line.split(b":", 1)[0].lower() in mimeheaders: # let email parser handle this return mimesplit(stream, cur) - elif line.startswith("--- ") and inheader: + elif line.startswith(b"--- ") and inheader: # No evil headers seen by diff start, split by hand return headersplit(stream, cur) # Not enough info, keep reading @@ -712,14 +712,14 @@ class patchfile(object): if self.eolmode == "auto": eol = self.eol elif self.eolmode == "crlf": - eol = "\r\n" + eol = b"\r\n" else: - eol = "\n" + eol = b"\n" - if self.eolmode != "strict" and eol and eol != "\n": + if self.eolmode != "strict" and eol and eol != b"\n": rawlines = [] for l in lines: - if l and l[-1] == "\n": + if l and l[-1] == b"\n": l = l[:-1] + eol rawlines.append(l) lines = rawlines @@ -872,13 +872,13 @@ class header(object): """patch header """ - diffgit_re = re.compile("diff --git a/(.*) b/(.*)$") - diff_re = re.compile("diff -r .* (.*)$") - allhunks_re = re.compile("(?:index|deleted file) ") - pretty_re = re.compile("(?:new file|deleted file) ") - special_re = re.compile("(?:index|deleted|copy|rename) ") - newfile_re = re.compile("(?:new file)") - copyre = re.compile("(?:copy|rename) from (.*)$") + diffgit_re = re.compile(b"diff --git a/(.*) b/(.*)$") + diff_re = re.compile(b"diff -r .* (.*)$") + allhunks_re = re.compile(b"(?:index|deleted file) ") + pretty_re = re.compile(b"(?:new file|deleted file) ") + special_re = re.compile(b"(?:index|deleted|copy|rename) ") + newfile_re = re.compile(b"(?:new file)") + copyre = re.compile(b"(?:copy|rename) from (.*)$") def __init__(self, header): self.header = header @@ -887,29 +887,29 @@ class header(object): def binary(self): return any(h.startswith("index ") for h in self.header) - def pretty(self, fp): + def pretty(self,fd): for h in self.header: - if h.startswith("index "): - fp.write(_("this modifies a binary file (all or nothing)\n")) + if h.startswith(b"index "): + fd.write(b"this modifies a binary file (all or nothing)\n") break if self.pretty_re.match(h): - fp.write(h) + fd.write(h) if self.binary(): - fp.write(_("this is a binary file\n")) + fd.write(b"this is a binary file\n") break - if h.startswith("---"): - fp.write( - _("%d hunks, %d lines changed\n") + if h.startswith(b"---"): + fd.write( + b"%d hunks, %d lines changed\n" % ( len(self.hunks), sum([max(h.added, h.removed) for h in self.hunks]), ) ) break - fp.write(h) + fd.write(h) def write(self, fp): - fp.write("".join(self.header)) + fp.write(b"".join(self.header)) def allhunks(self): return any(self.allhunks_re.match(h) for h in self.header) @@ -1001,8 +1001,8 @@ class recordhunk(object): def countchanges(self, hunk): """hunk -> (n+,n-)""" - add = len([h for h in hunk if h.startswith("+")]) - rem = len([h for h in hunk if h.startswith("-")]) + add = len([h for h in hunk if h.startswith(b"+")]) + rem = len([h for h in hunk if h.startswith(b"-")]) return add, rem def reversehunk(self): @@ -1024,23 +1024,23 @@ class recordhunk(object): self.after, ) - def write(self, fp): + def write(self, fd): delta = len(self.before) + len(self.after) - if self.after and self.after[-1] == "\\ No newline at end of file\n": + if self.after and self.after[-1] == b"\\ No newline at end of file\n": delta -= 1 fromlen = delta + self.removed tolen = delta + self.added - fp.write( - "@@ -%d,%d +%d,%d @@%s\n" + fd.write( + b"@@ -%d,%d +%d,%d @@%s\n" % ( self.fromline, fromlen, self.toline, tolen, - self.proc and (" " + self.proc), + self.proc and (b" " + self.proc), ) ) - fp.write("".join(self.before + self.hunk + self.after)) + fd.write(b"".join(self.before + self.hunk + self.after)) pretty = write @@ -1168,7 +1168,7 @@ the hunk is left unchanged. ncpatchfp = None try: # Write the initial patch - f = util.fdopen(patchfd, pycompat.sysstr("w")) + f = util.fdopen(patchfd, pycompat.sysstr("wb")) chunk.header.write(f) chunk.write(f) f.write("\n".join(["# " + i for i in phelp.splitlines()])) @@ -1214,18 +1214,24 @@ the hunk is left unchanged. applied = {} # 'filename' -> [] of chunks skipfile, skipall = None, None pos, total = 1, sum(len(h.hunks) for h in headers) + + class fd: + @staticmethod + def write(*args, **opts): + ui.writebytes(*args, **opts) + for h in headers: pos += len(h.hunks) skipfile = None fixoffset = 0 - hdr = "".join(h.header) + hdr = b"".join(h.header) if hdr in seen: continue seen.add(hdr) if skipall is None: - h.pretty(ui) + h.pretty(fd) msg = _("examine changes to %s?") % _(" and ").join( - "'%s'" % f for f in h.files() + "'%s'" % decodeutf8(f) for f in h.files() ) r, skipfile, skipall, np = prompt(skipfile, skipall, msg, None) if not r: @@ -1236,12 +1242,16 @@ the hunk is left unchanged. continue for i, chunk in enumerate(h.hunks): if skipfile is None and skipall is None: - chunk.pretty(ui) + chunk.pretty(fd) if total == 1: - msg = messages["single"][operation] % chunk.filename() + msg = messages["single"][operation] % decodeutf8(chunk.filename()) else: idx = pos - len(h.hunks) + i - msg = messages["multiple"][operation] % (idx, total, chunk.filename()) + msg = messages["multiple"][operation] % ( + idx, + total, + decodeutf8(chunk.filename()), + ) r, skipfile, skipall, newpatches = prompt(skipfile, skipall, msg, chunk) if r: if fixoffset: @@ -1740,7 +1750,7 @@ def parsepatch(originalchunks, maxcontext=None): p = parser() fp = stringio() - fp.write("".join(originalchunks)) + fp.write(b"".join(originalchunks)) fp.seek(0) state = "context" @@ -1869,7 +1879,7 @@ def scanpatch(fp): def scanwhile(first, p): """scan lr while predicate holds""" lines = [first] - for line in iter(lr.readline, ""): + for line in iter(lr.readline, b""): if p(line): lines.append(line) else: @@ -1877,25 +1887,25 @@ def scanpatch(fp): break return lines - for line in iter(lr.readline, ""): - if line.startswith("diff --git a/") or line.startswith("diff -r "): + for line in iter(lr.readline, b""): + if line.startswith(b"diff --git a/") or line.startswith(b"diff -r "): def notheader(line): s = line.split(None, 1) - return not s or s[0] not in ("---", "diff") + return not s or s[0] not in (b"---", b"diff") header = scanwhile(line, notheader) fromfile = lr.readline() - if fromfile.startswith("---"): + if fromfile.startswith(b"---"): tofile = lr.readline() header += [fromfile, tofile] else: lr.push(fromfile) yield "file", header - elif line[0:1] == " ": - yield "context", scanwhile(line, lambda l: l[0] in " \\") - elif line[0] in "-+": - yield "hunk", scanwhile(line, lambda l: l[0] in "-+\\") + elif line[:1] == b" ": + yield "context", scanwhile(line, lambda l: l[:1] in b" \\") + elif line[:1] in b"-+": + yield "hunk", scanwhile(line, lambda l: l[:1] in b"-+\\") else: m = lines_re.match(line) if m: @@ -2677,7 +2687,7 @@ def diffsinglehunk(hunklines): else: raise error.ProgrammingError("unexpected hunk line: %s" % line) for token in tabsplitter.findall(stripline): - if "\t" == token[0]: + if b"\t" == token[0:1]: yield (token, "diff.tab") else: yield (token, label) @@ -2742,7 +2752,7 @@ def diffsinglehunkinline(hunklines): endspaces = chomp[len(token) :] # scan tabs for maybetab in tabsplitter.findall(token): - if b"\t" == maybetab[0]: + if b"\t" == maybetab[0:1]: currentlabel = "diff.tab" else: if changed: diff --git a/eden/scm/edenscm/mercurial/revlog.py b/eden/scm/edenscm/mercurial/revlog.py index 1047e9ad5d..3b6bc59593 100644 --- a/eden/scm/edenscm/mercurial/revlog.py +++ b/eden/scm/edenscm/mercurial/revlog.py @@ -1893,7 +1893,10 @@ class revlog(object): if node == wdirid: raise RevlogError(_("%s: attempt to add wdir revision") % (self.indexfile)) - btext = [rawtext] + if isinstance(rawtext, memoryview): + btext = [bytes(rawtext)] + else: + btext = [rawtext] def buildtext(): if btext[0] is not None: diff --git a/eden/scm/tests/test-diff-change.t b/eden/scm/tests/test-diff-change.t index d3c2ddee91..aa78945c3b 100644 --- a/eden/scm/tests/test-diff-change.t +++ b/eden/scm/tests/test-diff-change.t @@ -1,4 +1,3 @@ -#require py2 #chg-compatible $ disable treemanifest diff --git a/eden/scm/tests/test-diff-unified.t b/eden/scm/tests/test-diff-unified.t index 5c6374b03e..1ad07b5099 100644 --- a/eden/scm/tests/test-diff-unified.t +++ b/eden/scm/tests/test-diff-unified.t @@ -1,4 +1,3 @@ -#require py2 #chg-compatible $ hg init repo diff --git a/eden/scm/tests/test-diff-upgrade.t b/eden/scm/tests/test-diff-upgrade.t index 512c6d7108..4480e183c3 100644 --- a/eden/scm/tests/test-diff-upgrade.t +++ b/eden/scm/tests/test-diff-upgrade.t @@ -1,4 +1,3 @@ -#require py2 #chg-compatible #require execbit diff --git a/eden/scm/tests/test-diffstat.t b/eden/scm/tests/test-diffstat.t index 545155d6fe..95159bf0f8 100644 --- a/eden/scm/tests/test-diffstat.t +++ b/eden/scm/tests/test-diffstat.t @@ -1,4 +1,3 @@ -#require py2 #chg-compatible $ hg init repo @@ -57,7 +56,7 @@ Binary git diffstat: $ hg ci -m createb - >>> _ = open("file with spaces", "wb").write("\0") + >>> _ = open("file with spaces", "wb").write(b"\0") $ hg add "file with spaces" Filename with spaces diffstat: