Mercurial > python-hglib
changeset 224:2ab42323f149
client: handle commit messages with \0 characters for all commands
Each of the impacted commands will now use the 'json' template,
which they all support as of Mercurial 3.7.3 (the first version
tested in the regression tests).
Note: I tried to add a test with null bytes,
but both hglib and using hg directly through subprocess
rejected adding a commit message with a null byte.
author | Mathias De Mare <mathias.de_mare@nokia.com> |
---|---|
date | Mon, 13 Mar 2023 15:32:20 +0100 |
parents | 3f9dd44be8c2 |
children | fba806958dba |
files | hglib/client.py |
diffstat | 1 files changed, 23 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/hglib/client.py Thu Mar 09 16:18:54 2023 +0100 +++ b/hglib/client.py Mon Mar 13 15:32:20 2023 +0100 @@ -159,20 +159,6 @@ return channel, self.server.stdout.read(length) @staticmethod - def _parserevs(splitted): - '''splitted is a list of fields according to our rev.style, where - each 6 fields compose one revision. - ''' - revs = [] - for rev in util.grouper(7, splitted): - # truncate the timezone and convert to a local datetime - posixtime = float(rev[6].split(b('.'), 1)[0]) - dt = datetime.datetime.fromtimestamp(posixtime) - revs.append(revision(rev[0], rev[1], rev[2], rev[3], - rev[4], rev[5], dt)) - return revs - - @staticmethod def _parsejsonrevs(jsonrevs): revs = [] for rev in jsonrevs: @@ -929,7 +915,7 @@ rev = [rev] args = cmdbuilder(b('heads'), r=startrev, t=topological, c=closed, - template=templates.changeset, hidden=self.hidden, + template="json", hidden=self.hidden, *rev) def eh(ret, out, err): @@ -937,8 +923,12 @@ raise error.CommandError(args, ret, out, err) return b('') - out = self.rawcommand(args, eh=eh).split(b('\0'))[:-1] - return self._parserevs(out) + out = self.rawcommand(args, eh=eh) + if not out: + return [] + json_out = json.loads(out) + + return self._parsejsonrevs(json_out) def identify(self, rev=None, source=None, num=False, id=False, branch=False, tags=False, bookmarks=False): @@ -1036,7 +1026,7 @@ """ args = cmdbuilder(b('incoming'), path, - template=templates.changeset, r=revrange, + template="json", r=revrange, f=force, n=newest, bundle=bundle, B=bookmarks, b=branch, l=limit, M=nomerges, S=subrepos) @@ -1050,14 +1040,15 @@ return [] out = util.eatlines(out, 2) + if bookmarks: bms = [] for line in out.splitlines(): bms.append(tuple(line.split())) return bms else: - out = out.split(b('\0'))[:-1] - return self._parserevs(out) + json_out = json.loads(out) + return self._parsejsonrevs(json_out) def log(self, revrange=None, files=[], follow=False, followfirst=False, date=None, copies=False, keyword=None, @@ -1235,7 +1226,7 @@ """ args = cmdbuilder(b('outgoing'), path, - template=templates.changeset, r=revrange, + template="json", r=revrange, f=force, n=newest, B=bookmarks, b=branch, S=subrepos) @@ -1254,8 +1245,8 @@ bms.append(tuple(line.split())) return bms else: - out = out.split(b('\0'))[:-1] - return self._parserevs(out) + json_out = json.loads(out) + return self._parsejsonrevs(json_out) def parents(self, rev=None, file=None): """Return the working directory's parent revisions. If rev is given, @@ -1265,16 +1256,19 @@ is returned. """ - args = cmdbuilder(b('parents'), file, template=templates.changeset, + args = cmdbuilder(b('parents'), file, template="json", r=rev, hidden=self.hidden) out = self.rawcommand(args) if not out: return - out = out.split(b('\0'))[:-1] + json_out = json.loads(out) - return self._parserevs(out) + if not json_out: + return + + return self._parsejsonrevs(json_out) def paths(self, name=None): """ @@ -1682,12 +1676,12 @@ changeset most recently added to the repository (and therefore the most recently changed head). """ - args = cmdbuilder(b('tip'), template=templates.changeset, + args = cmdbuilder(b('tip'), template="json", hidden=self.hidden) out = self.rawcommand(args) - out = out.split(b('\0')) + json_out = json.loads(out) - return self._parserevs(out)[0] + return self._parsejsonrevs(json_out)[0] def update(self, rev=None, clean=False, check=False, date=None): """