[PATCH] client: handle commit messages with \0 characters
Mathias De Mare
mathias.de_mare at nokia.com
Wed Mar 8 15:24:15 UTC 2023
# HG changeset patch
# User Mathias De Mare <mathias.de_mare at nokia.com>
# Date 1678288941 -3600
# Wed Mar 08 16:22:21 2023 +0100
# Node ID b5616919f129d028699764153cab594038f884fa
# Parent e3e9e403927565cb9440576065274688e26ab78f
client: handle commit messages with \0 characters
Mercurial allows commit messages containing \0 characters,
but hglib does not properly handle them.
By using the json template, these characters are correctly escaped.
Note: initial change only modifies this for the 'log' command,
I'll follow-up for other commands if this is ok.
diff --git a/hglib/client.py b/hglib/client.py
--- a/hglib/client.py
+++ b/hglib/client.py
@@ -1,4 +1,4 @@
-import struct, re, datetime
+import struct, re, datetime, json
import hglib
from hglib import error, util, templates, merge, context
@@ -172,6 +172,19 @@ class hgclient(object):
rev[4], rev[5], dt))
return revs
+ @staticmethod
+ def _parsejsonrevs(jsonrevs):
+ revs = []
+ for rev in jsonrevs:
+ # truncate the timezone and convert to a local datetime
+ posixtime = float(rev["date"][0])
+ dt = datetime.datetime.fromtimestamp(posixtime)
+ revs.append(revision(str(rev["rev"]).encode(), rev["node"].encode(),
+ ' '.join(rev["tags"]).encode(),
+ rev["branch"].encode(), rev["user"].encode(),
+ rev["desc"].encode(), dt))
+ return revs
+
def runcommand(self, args, inchannels, outchannels):
def writeblock(data):
if self._protocoltracefn is not None:
@@ -1094,7 +1107,7 @@ class hgclient(object):
"""
if hidden is None:
hidden = self.hidden
- args = cmdbuilder(b('log'), template=templates.changeset,
+ args = cmdbuilder(b('log'), template="json",
r=revrange, f=follow, follow_first=followfirst,
d=date, C=copies, k=keyword, removed=removed,
m=onlymerges, u=user, b=branch, P=prune,
@@ -1102,9 +1115,9 @@ class hgclient(object):
hidden=hidden, *files)
out = self.rawcommand(args)
- out = out.split(b('\0'))[:-1]
+ json_out = json.loads(out)
- return self._parserevs(out)
+ return self._parsejsonrevs(json_out)
def manifest(self, rev=None, all=False):
"""Yields (nodeid, permission, executable, symlink, file path) tuples
More information about the Mercurial-devel
mailing list