Mercurial > hg
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 |