Mercurial > hg
comparison mercurial/obsolete.py @ 38707:6b5ca1d0aa1e
obsolete: store user name and note in UTF-8 (issue5754) (BC)
Before, user names were stored in local encoding and transferred across
repositories, which made it impossible to restore non-ASCII user names on
different platforms. This patch fixes new markers to be encoded in UTF-8
and decoded back to local encoding when displaying. Existing markers are
unfixable so they may result in mojibake.
I don't like the API that requires metadata dict to be UTF-8 encoded, which
is a source of bugs, but there's no abstraction layer to process the encoding
thingy efficiently. So we apply the same rule as extras dict to obsstore
metadata.
author | Yuya Nishihara <yuya@tcha.org> |
---|---|
date | Sun, 15 Jul 2018 18:24:57 +0900 |
parents | 02f992ac26e9 |
children | ff1182d166a2 |
comparison
equal
deleted
inserted
replaced
38706:83d965803325 | 38707:6b5ca1d0aa1e |
---|---|
72 import errno | 72 import errno |
73 import struct | 73 import struct |
74 | 74 |
75 from .i18n import _ | 75 from .i18n import _ |
76 from . import ( | 76 from . import ( |
77 encoding, | |
77 error, | 78 error, |
78 node, | 79 node, |
79 obsutil, | 80 obsutil, |
80 phases, | 81 phases, |
81 policy, | 82 policy, |
524 | 525 |
525 fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents') | 526 fields = ('prec', 'succs', 'flag', 'meta', 'date', 'parents') |
526 # prec: nodeid, predecessors changesets | 527 # prec: nodeid, predecessors changesets |
527 # succs: tuple of nodeid, successor changesets (0-N length) | 528 # succs: tuple of nodeid, successor changesets (0-N length) |
528 # flag: integer, flag field carrying modifier for the markers (see doc) | 529 # flag: integer, flag field carrying modifier for the markers (see doc) |
529 # meta: binary blob, encoded metadata dictionary | 530 # meta: binary blob in UTF-8, encoded metadata dictionary |
530 # date: (float, int) tuple, date of marker creation | 531 # date: (float, int) tuple, date of marker creation |
531 # parents: (tuple of nodeid) or None, parents of predecessors | 532 # parents: (tuple of nodeid) or None, parents of predecessors |
532 # None is used when no data has been recorded | 533 # None is used when no data has been recorded |
533 | 534 |
534 def __init__(self, svfs, defaultformat=_fm1version, readonly=False): | 535 def __init__(self, svfs, defaultformat=_fm1version, readonly=False): |
948 """Add obsolete markers between changesets in a repo | 949 """Add obsolete markers between changesets in a repo |
949 | 950 |
950 <relations> must be an iterable of (<old>, (<new>, ...)[,{metadata}]) | 951 <relations> must be an iterable of (<old>, (<new>, ...)[,{metadata}]) |
951 tuple. `old` and `news` are changectx. metadata is an optional dictionary | 952 tuple. `old` and `news` are changectx. metadata is an optional dictionary |
952 containing metadata for this marker only. It is merged with the global | 953 containing metadata for this marker only. It is merged with the global |
953 metadata specified through the `metadata` argument of this function, | 954 metadata specified through the `metadata` argument of this function. |
955 Any string values in metadata must be UTF-8 bytes. | |
954 | 956 |
955 Trying to obsolete a public changeset will raise an exception. | 957 Trying to obsolete a public changeset will raise an exception. |
956 | 958 |
957 Current user and date are used except if specified otherwise in the | 959 Current user and date are used except if specified otherwise in the |
958 metadata attribute. | 960 metadata attribute. |
962 """ | 964 """ |
963 # prepare metadata | 965 # prepare metadata |
964 if metadata is None: | 966 if metadata is None: |
965 metadata = {} | 967 metadata = {} |
966 if 'user' not in metadata: | 968 if 'user' not in metadata: |
967 develuser = repo.ui.config('devel', 'user.obsmarker') | 969 luser = repo.ui.config('devel', 'user.obsmarker') or repo.ui.username() |
968 if develuser: | 970 metadata['user'] = encoding.fromlocal(luser) |
969 metadata['user'] = develuser | |
970 else: | |
971 metadata['user'] = repo.ui.username() | |
972 | 971 |
973 # Operation metadata handling | 972 # Operation metadata handling |
974 useoperation = repo.ui.configbool('experimental', | 973 useoperation = repo.ui.configbool('experimental', |
975 'evolution.track-operation') | 974 'evolution.track-operation') |
976 if useoperation and operation: | 975 if useoperation and operation: |