/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/plugins/git/mapping.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2018-07-03 03:20:44 UTC
  • mfrom: (7018.3.10 git-fixes)
  • Revision ID: breezy.the.bot@gmail.com-20180703032044-t5a5w5y0tmzrbezc
Port a few more bits of the git plugin to python 3.

Merged from https://code.launchpad.net/~jelmer/brz/git-fixes2/+merge/348803

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
    errors,
29
29
    foreign,
30
30
    trace,
 
31
    urlutils,
31
32
    )
32
33
from ...bzr.inventory import (
33
34
    ROOT_ID,
40
41
from ...revision import (
41
42
    NULL_REVISION,
42
43
    )
43
 
from ...sixish import text_type
 
44
from ...sixish import (
 
45
    PY3,
 
46
    text_type,
 
47
    viewitems,
 
48
    )
44
49
from .errors import (
45
50
    NoPushSupport,
46
51
    UnknownCommitExtra,
58
63
    serialize_fileid_map,
59
64
    )
60
65
 
61
 
try:
62
 
    from urllib.parse import quote
63
 
except ImportError:
64
 
    from urllib import quote
65
66
 
66
67
DEFAULT_FILE_MODE = stat.S_IFREG | 0o644
67
 
HG_RENAME_SOURCE = "HG:rename-source"
68
 
HG_EXTRA = "HG:extra"
 
68
HG_RENAME_SOURCE = b"HG:rename-source"
 
69
HG_EXTRA = b"HG:extra"
69
70
 
70
71
# This HG extra is used to indicate the commit that this commit was based on.
71
 
HG_EXTRA_AMEND_SOURCE = "amend_source"
 
72
HG_EXTRA_AMEND_SOURCE = b"amend_source"
72
73
 
73
74
FILE_ID_PREFIX = b'git:'
74
75
 
75
76
 
76
77
def escape_file_id(file_id):
77
 
    return file_id.replace('_', '__').replace(' ', '_s').replace('\x0c', '_c')
 
78
    return file_id.replace(b'_', b'__').replace(b' ', b'_s').replace(b'\x0c', b'_c')
78
79
 
79
80
 
80
81
def unescape_file_id(file_id):
81
 
    ret = []
 
82
    ret = bytearray()
82
83
    i = 0
83
84
    while i < len(file_id):
84
 
        if file_id[i] != '_':
 
85
        if file_id[i:i+1] != b'_':
85
86
            ret.append(file_id[i])
86
87
        else:
87
 
            if file_id[i+1] == '_':
88
 
                ret.append("_")
89
 
            elif file_id[i+1] == 's':
90
 
                ret.append(" ")
91
 
            elif file_id[i+1] == 'c':
92
 
                ret.append("\x0c")
 
88
            if file_id[i+1:i+2] == b'_':
 
89
                ret.append(b"_"[0])
 
90
            elif file_id[i+1:i+2] == b's':
 
91
                ret.append(b" "[0])
 
92
            elif file_id[i+1:i+2] == b'c':
 
93
                ret.append(b"\x0c"[0])
93
94
            else:
94
95
                raise ValueError("unknown escape character %s" %
95
 
                    file_id[i+1])
 
96
                        file_id[i+1:i+2])
96
97
            i += 1
97
98
        i += 1
98
 
    return "".join(ret)
 
99
    return bytes(ret)
99
100
 
100
101
 
101
102
def fix_person_identifier(text):
146
147
        from dulwich.protocol import ZERO_SHA
147
148
        if git_rev_id == ZERO_SHA:
148
149
            return NULL_REVISION
149
 
        return "%s:%s" % (cls.revid_prefix, git_rev_id)
 
150
        return b"%s:%s" % (cls.revid_prefix, git_rev_id)
150
151
 
151
152
    @classmethod
152
153
    def revision_id_bzr_to_foreign(cls, bzr_rev_id):
153
154
        """Convert a Bazaar revision id to a git revision id handle."""
154
 
        if not bzr_rev_id.startswith("%s:" % cls.revid_prefix):
 
155
        if not bzr_rev_id.startswith(b"%s:" % cls.revid_prefix):
155
156
            raise errors.InvalidRevisionId(bzr_rev_id, cls)
156
157
        return bzr_rev_id[len(cls.revid_prefix)+1:], cls()
157
158
 
172
173
        return unescape_file_id(file_id[len(FILE_ID_PREFIX):])
173
174
 
174
175
    def revid_as_refname(self, revid):
175
 
        return "refs/bzr/%s" % quote(revid)
 
176
        if not isinstance(revid, bytes):
 
177
            raise TypeError(revid)
 
178
        if PY3:
 
179
            revid = revid.decode('utf-8')
 
180
        quoted_revid = urlutils.quote(revid)
 
181
        return b"refs/bzr/" + quoted_revid.encode('utf-8')
176
182
 
177
183
    def import_unusual_file_modes(self, rev, unusual_file_modes):
178
184
        if unusual_file_modes:
229
235
        (message, renames, branch, extra) = extract_hg_metadata(message)
230
236
        if branch is not None:
231
237
            rev.properties[u'hg:extra:branch'] = branch
232
 
        for name, value in extra.iteritems():
 
238
        for name, value in viewitems(extra):
233
239
            rev.properties[u'hg:extra:' + name] = base64.b64encode(value)
234
240
        if renames:
235
241
            rev.properties[u'hg:renames'] = base64.b64encode(bencode.bencode(
236
 
                [(new, old) for (old, new) in renames.iteritems()]))
 
242
                [(new, old) for (old, new) in viewitems(renames)]))
237
243
        return message
238
244
 
239
245
    def _extract_bzr_metadata(self, rev, message):
301
307
            encoding))
302
308
        commit.author = fix_person_identifier(
303
309
            rev.get_apparent_authors()[0].encode(encoding))
 
310
        # TODO(jelmer): Don't use this hack.
 
311
        long = getattr(__builtins__, 'long', int)
304
312
        commit.commit_time = long(rev.timestamp)
305
313
        if u'author-timestamp' in rev.properties:
306
314
            commit.author_time = long(rev.properties[u'author-timestamp'])
329
337
                 u'commit-timezone-neg-utc', u'git-implicit-encoding',
330
338
                 u'git-gpg-signature', u'git-explicit-encoding',
331
339
                 u'author-timestamp', u'file-modes'])
332
 
            for k, v in rev.properties.iteritems():
 
340
            for k, v in viewitems(rev.properties):
333
341
                if not k in mapping_properties:
334
342
                    metadata.properties[k] = v
335
343
        if not lossy and metadata:
343
351
        i = 0
344
352
        propname = u'git-mergetag-0'
345
353
        while propname in rev.properties:
346
 
            commit.mergetag.append(Tag.from_string(rev.properties[propname].encode(encoding)))
 
354
            commit.mergetag.append(Tag.from_string(rev.properties[propname]))
347
355
            i += 1
348
356
            propname = u'git-mergetag-%d' % i
349
357
        if u'git-extra' in rev.properties:
350
 
            commit.extra.extend([l.split(' ', 1) for l in rev.properties[u'git-extra'].splitlines()])
 
358
            commit.extra.extend([l.split(b' ', 1) for l in rev.properties[u'git-extra'].splitlines()])
351
359
        return commit
352
360
 
353
361
    def import_fileid_map(self, blob):
370
378
                self.revision_id_foreign_to_bzr(commit.id))
371
379
        rev.git_metadata = None
372
380
        def decode_using_encoding(rev, commit, encoding):
373
 
            rev.committer = str(commit.committer).decode(encoding)
 
381
            rev.committer = commit.committer.decode(encoding)
374
382
            if commit.committer != commit.author:
375
 
                rev.properties[u'author'] = str(commit.author).decode(encoding)
 
383
                rev.properties[u'author'] = commit.author.decode(encoding)
376
384
            rev.message, rev.git_metadata = self._decode_commit_message(
377
385
                rev, commit.message, encoding)
378
386
        if commit.encoding is not None:
379
 
            rev.properties[u'git-explicit-encoding'] = commit.encoding
380
 
            decode_using_encoding(rev, commit, commit.encoding)
 
387
            rev.properties[u'git-explicit-encoding'] = commit.encoding.decode('ascii')
 
388
            decode_using_encoding(rev, commit, commit.encoding.decode('ascii'))
381
389
        else:
382
390
            for encoding in ('utf-8', 'latin1'):
383
391
                try:
426
434
        extra_lines = []
427
435
        for k, v in commit.extra:
428
436
            if k == HG_RENAME_SOURCE:
429
 
                extra_lines.append(k + ' ' + v + '\n')
 
437
                extra_lines.append(k + b' ' + v + b'\n')
430
438
            elif k == HG_EXTRA:
431
 
                hgk, hgv = v.split(':', 1)
 
439
                hgk, hgv = v.split(b':', 1)
432
440
                if hgk not in (HG_EXTRA_AMEND_SOURCE, ):
433
441
                    raise UnknownMercurialCommitExtra(commit, hgk)
434
 
                extra_lines.append(k + ' ' + v + '\n')
 
442
                extra_lines.append(k + b' ' + v + b'\n')
435
443
            else:
436
444
                unknown_extra_fields.append(k)
437
445
        if unknown_extra_fields:
438
 
            raise UnknownCommitExtra(commit, unknown_extra_fields)
 
446
            raise UnknownCommitExtra(
 
447
                commit, [f.decode('ascii', 'replace') for f in unknown_extra_fields])
439
448
        if extra_lines:
440
 
            rev.properties[u'git-extra'] = ''.join(extra_lines)
 
449
            rev.properties[u'git-extra'] = b''.join(extra_lines)
441
450
        return rev, roundtrip_revid, verifiers
442
451
 
443
452
    def get_fileid_map(self, lookup_object, tree_sha):
457
466
 
458
467
 
459
468
class BzrGitMappingv1(BzrGitMapping):
460
 
    revid_prefix = 'git-v1'
 
469
    revid_prefix = b'git-v1'
461
470
    experimental = False
462
471
 
463
472
    def __str__(self):
465
474
 
466
475
 
467
476
class BzrGitMappingExperimental(BzrGitMappingv1):
468
 
    revid_prefix = 'git-experimental'
 
477
    revid_prefix = b'git-experimental'
469
478
    experimental = True
470
479
    roundtripping = True
471
480
 
508
517
 
509
518
 
510
519
mapping_registry = GitMappingRegistry()
511
 
mapping_registry.register_lazy('git-v1', "breezy.plugins.git.mapping",
 
520
mapping_registry.register_lazy(b'git-v1', "breezy.plugins.git.mapping",
512
521
    "BzrGitMappingv1")
513
 
mapping_registry.register_lazy('git-experimental',
 
522
mapping_registry.register_lazy(b'git-experimental',
514
523
    "breezy.plugins.git.mapping", "BzrGitMappingExperimental")
515
524
# Uncomment the next line to enable the experimental bzr-git mappings.
516
525
# This will make sure all bzr metadata is pushed into git, allowing for
518
527
# NOTE: THIS IS EXPERIMENTAL. IT MAY EAT YOUR DATA OR CORRUPT
519
528
# YOUR BZR OR GIT REPOSITORIES. USE WITH CARE.
520
529
#mapping_registry.set_default('git-experimental')
521
 
mapping_registry.set_default('git-v1')
 
530
mapping_registry.set_default(b'git-v1')
522
531
 
523
532
 
524
533
class ForeignGit(ForeignVcs):
544
553
 
545
554
    @classmethod
546
555
    def show_foreign_revid(cls, foreign_revid):
547
 
        return { "git commit": foreign_revid }
 
556
        return { "git commit": foreign_revid.decode('utf-8') }
548
557
 
549
558
 
550
559
foreign_vcs_git = ForeignGit()
640
649
        return self.file_ids.values()
641
650
 
642
651
    def set_file_id(self, path, file_id):
 
652
        if type(path) is not str:
 
653
            raise TypeError(path)
643
654
        if not isinstance(file_id, bytes):
644
655
            raise TypeError(file_id)
645
656
        self.file_ids[path] = file_id
646
657
 
647
658
    def lookup_file_id(self, path):
 
659
        if not isinstance(path, text_type):
 
660
            raise TypeError(path)
648
661
        try:
649
662
            file_id = self.file_ids[path]
650
663
        except KeyError:
656
669
    def lookup_path(self, file_id):
657
670
        if self.paths is None:
658
671
            self.paths = {}
659
 
            for k, v in self.file_ids.iteritems():
 
672
            for k, v in viewitems(self.file_ids):
660
673
                self.paths[v] = k
661
674
        try:
662
675
            path = self.paths[file_id]
663
676
        except KeyError:
664
677
            return self.mapping.parse_file_id(file_id)
665
678
        else:
666
 
            if not isinstance(path, bytes):
 
679
            if not isinstance(path, text_type):
667
680
                raise TypeError(path)
668
681
            return path
669
682