comparison hgext/convert/cvsps.py @ 33388:0823f0983eaa

convert: transcode CVS log messages by specified encoding (issue5597) Converting from CVS to Mercurial assumes that CVS log messages in "cvs rlog" output are encoded in UTF-8 (or basic Latin-1). But cvs itself is usually unaware of encoding of log messages, in practice. Therefore, if there are commits, of which log message is encoded in other than UTF-8, log message of corresponded revisions in the converted repository will be broken. To avoid such broken log messages, this patch transcodes CVS log messages by encoding specified via "convert.cvsps.logencoding" configuration. This patch accepts multiple encoding for convenience, because "multiple encoding mixed in a repository" easily occurs. For example, UTF-8 (recent POSIX), cp932 (Windows), and EUC-JP (legacy POSIX) are well known encoding for Japanese.
author FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
date Tue, 11 Jul 2017 02:10:04 +0900
parents 6e3c79bc9a35
children 0fa781320203
comparison
equal deleted inserted replaced
33387:68e9762a357b 33388:0823f0983eaa
10 import re 10 import re
11 11
12 from mercurial.i18n import _ 12 from mercurial.i18n import _
13 from mercurial import ( 13 from mercurial import (
14 encoding, 14 encoding,
15 error,
15 hook, 16 hook,
16 pycompat, 17 pycompat,
17 util, 18 util,
18 ) 19 )
19 20
488 pickle.dump(log, open(cachefile, 'w')) 489 pickle.dump(log, open(cachefile, 'w'))
489 else: 490 else:
490 log = oldlog 491 log = oldlog
491 492
492 ui.status(_('%d log entries\n') % len(log)) 493 ui.status(_('%d log entries\n') % len(log))
494
495 encodings = ui.configlist('convert', 'cvsps.logencoding')
496 if encodings:
497 def revstr(r):
498 # this is needed, because logentry.revision is a tuple of "int"
499 # (e.g. (1, 2) for "1.2")
500 return '.'.join(pycompat.maplist(pycompat.bytestr, r))
501
502 for entry in log:
503 comment = entry.comment
504 for e in encodings:
505 try:
506 entry.comment = comment.decode(e).encode('utf-8')
507 if ui.debugflag:
508 ui.debug("transcoding by %s: %s of %s\n" %
509 (e, revstr(entry.revision), entry.file))
510 break
511 except UnicodeDecodeError:
512 pass # try next encoding
513 except LookupError as inst: # unknown encoding, maybe
514 raise error.Abort(inst,
515 hint=_('check convert.cvsps.logencoding'
516 ' configuration'))
517 else:
518 raise error.Abort(_("no encoding can transcode"
519 " CVS log message for %s of %s")
520 % (revstr(entry.revision), entry.file),
521 hint=_('check convert.cvsps.logencoding'
522 ' configuration'))
493 523
494 hook.hook(ui, None, "cvslog", True, log=log) 524 hook.hook(ui, None, "cvslog", True, log=log)
495 525
496 return log 526 return log
497 527