/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/git/mapping.py

  • Committer: Jelmer Vernooij
  • Date: 2019-06-02 02:35:46 UTC
  • mfrom: (7309 work)
  • mto: This revision was merged to the branch mainline in revision 7319.
  • Revision ID: jelmer@jelmer.uk-20190602023546-lqco868tnv26d8ow
merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
    trace,
31
31
    urlutils,
32
32
    )
33
 
from ..bzr.inventory import (
34
 
    ROOT_ID,
35
 
    )
36
33
from ..foreign import (
37
34
    ForeignVcs,
38
35
    VcsMappingRegistry,
40
37
    )
41
38
from ..revision import (
42
39
    NULL_REVISION,
 
40
    Revision,
43
41
    )
44
42
from ..sixish import (
45
43
    PY3,
73
71
 
74
72
FILE_ID_PREFIX = b'git:'
75
73
 
 
74
# Always the same.
 
75
ROOT_ID = b"TREE_ROOT"
 
76
 
76
77
 
77
78
def escape_file_id(file_id):
78
 
    return file_id.replace(b'_', b'__').replace(b' ', b'_s').replace(b'\x0c', b'_c')
 
79
    file_id = file_id.replace(b'_', b'__')
 
80
    file_id = file_id.replace(b' ', b'_s')
 
81
    file_id = file_id.replace(b'\x0c', b'_c')
 
82
    return file_id
79
83
 
80
84
 
81
85
def unescape_file_id(file_id):
82
86
    ret = bytearray()
83
87
    i = 0
84
88
    while i < len(file_id):
85
 
        if file_id[i:i+1] != b'_':
 
89
        if file_id[i:i + 1] != b'_':
86
90
            ret.append(file_id[i])
87
91
        else:
88
 
            if file_id[i+1:i+2] == b'_':
 
92
            if file_id[i + 1:i + 2] == b'_':
89
93
                ret.append(b"_"[0])
90
 
            elif file_id[i+1:i+2] == b's':
 
94
            elif file_id[i + 1:i + 2] == b's':
91
95
                ret.append(b" "[0])
92
 
            elif file_id[i+1:i+2] == b'c':
 
96
            elif file_id[i + 1:i + 2] == b'c':
93
97
                ret.append(b"\x0c"[0])
94
98
            else:
95
99
                raise ValueError("unknown escape character %s" %
96
 
                        file_id[i+1:i+2])
 
100
                                 file_id[i + 1:i + 2])
97
101
            i += 1
98
102
        i += 1
99
103
    return bytes(ret)
100
104
 
101
105
 
102
106
def fix_person_identifier(text):
103
 
    if not b"<" in text and not b">" in text:
 
107
    if b"<" not in text and b">" not in text:
104
108
        username = text
105
109
        email = text
106
110
    else:
138
142
        super(BzrGitMapping, self).__init__(foreign_vcs_git)
139
143
 
140
144
    def __eq__(self, other):
141
 
        return (type(self) == type(other) and
142
 
                self.revid_prefix == other.revid_prefix)
 
145
        return (type(self) == type(other)
 
146
                and self.revid_prefix == other.revid_prefix)
143
147
 
144
148
    @classmethod
145
149
    def revision_id_foreign_to_bzr(cls, git_rev_id):
154
158
        """Convert a Bazaar revision id to a git revision id handle."""
155
159
        if not bzr_rev_id.startswith(b"%s:" % cls.revid_prefix):
156
160
            raise errors.InvalidRevisionId(bzr_rev_id, cls)
157
 
        return bzr_rev_id[len(cls.revid_prefix)+1:], cls()
 
161
        return bzr_rev_id[len(cls.revid_prefix) + 1:], cls()
158
162
 
159
163
    def generate_file_id(self, path):
160
164
        # Git paths are just bytestrings
223
227
 
224
228
    def _extract_git_svn_metadata(self, rev, message):
225
229
        lines = message.split("\n")
226
 
        if not (lines[-1] == "" and len(lines) >= 2 and lines[-2].startswith("git-svn-id:")):
 
230
        if not (lines[-1] == "" and len(lines) >= 2 and
 
231
                lines[-2].startswith("git-svn-id:")):
227
232
            return message
228
233
        git_svn_id = lines[-2].split(": ", 1)[1]
229
234
        rev.properties[u'git-svn-id'] = git_svn_id
300
305
        except KeyError:
301
306
            encoding = rev.properties.get(u'git-implicit-encoding', 'utf-8')
302
307
        try:
303
 
            commit.encoding = rev.properties[u'git-explicit-encoding'].encode('ascii')
 
308
            commit.encoding = rev.properties[u'git-explicit-encoding'].encode(
 
309
                'ascii')
304
310
        except KeyError:
305
311
            pass
306
312
        commit.committer = fix_person_identifier(rev.committer.encode(
314
320
            commit.author_time = long(rev.properties[u'author-timestamp'])
315
321
        else:
316
322
            commit.author_time = commit.commit_time
317
 
        commit._commit_timezone_neg_utc = u"commit-timezone-neg-utc" in rev.properties
 
323
        commit._commit_timezone_neg_utc = (
 
324
            u"commit-timezone-neg-utc" in rev.properties)
318
325
        commit.commit_timezone = rev.timezone
319
 
        commit._author_timezone_neg_utc = u"author-timezone-neg-utc" in rev.properties
 
326
        commit._author_timezone_neg_utc = (
 
327
            u"author-timezone-neg-utc" in rev.properties)
320
328
        if u'author-timezone' in rev.properties:
321
329
            commit.author_timezone = int(rev.properties[u'author-timezone'])
322
330
        else:
323
331
            commit.author_timezone = commit.commit_timezone
324
332
        if u'git-gpg-signature' in rev.properties:
325
 
            commit.gpgsig = rev.properties[u'git-gpg-signature'].encode('ascii')
 
333
            commit.gpgsig = rev.properties[u'git-gpg-signature'].encode(
 
334
                'ascii')
326
335
        commit.message = self._encode_commit_message(rev, rev.message,
327
 
            encoding)
 
336
                                                     encoding)
328
337
        if not isinstance(commit.message, bytes):
329
338
            raise TypeError(commit.message)
330
339
        if metadata is not None:
338
347
                 u'git-gpg-signature', u'git-explicit-encoding',
339
348
                 u'author-timestamp', u'file-modes'])
340
349
            for k, v in viewitems(rev.properties):
341
 
                if not k in mapping_properties:
 
350
                if k not in mapping_properties:
342
351
                    metadata.properties[k] = v
343
352
        if not lossy and metadata:
344
353
            if self.roundtripping:
345
354
                commit.message = inject_bzr_metadata(commit.message, metadata,
346
355
                                                     encoding)
347
356
            else:
348
 
                raise NoPushSupport(None, None, self, revision_id=rev.revision_id)
 
357
                raise NoPushSupport(
 
358
                    None, None, self, revision_id=rev.revision_id)
349
359
        if not isinstance(commit.message, bytes):
350
360
            raise TypeError(commit.message)
351
361
        i = 0
355
365
            i += 1
356
366
            propname = u'git-mergetag-%d' % i
357
367
        if u'git-extra' in rev.properties:
358
 
            commit.extra.extend([l.split(b' ', 1) for l in rev.properties[u'git-extra'].splitlines()])
 
368
            commit.extra.extend(
 
369
                [l.split(b' ', 1)
 
370
                 for l in rev.properties[u'git-extra'].splitlines()])
359
371
        return commit
360
372
 
361
373
    def import_fileid_map(self, blob):
366
378
        """
367
379
        return deserialize_fileid_map(blob.data)
368
380
 
 
381
    def get_revision_id(self, commit):
 
382
        if commit.encoding:
 
383
            encoding = commit.encoding.decode('ascii')
 
384
        else:
 
385
            encoding = 'utf-8'
 
386
        message, metadata = self._decode_commit_message(
 
387
            None, commit.message, encoding)
 
388
        if metadata.revision_id:
 
389
            return metadata.revision_id
 
390
        return self.revision_id_foreign_to_bzr(commit.id)
 
391
 
369
392
    def import_commit(self, commit, lookup_parent_revid):
370
393
        """Convert a git commit to a bzr revision.
371
394
 
375
398
        if commit is None:
376
399
            raise AssertionError("Commit object can't be None")
377
400
        rev = ForeignRevision(commit.id, self,
378
 
                self.revision_id_foreign_to_bzr(commit.id))
 
401
                              self.revision_id_foreign_to_bzr(commit.id))
379
402
        rev.git_metadata = None
 
403
 
380
404
        def decode_using_encoding(rev, commit, encoding):
381
405
            rev.committer = commit.committer.decode(encoding)
382
406
            if commit.committer != commit.author:
384
408
            rev.message, rev.git_metadata = self._decode_commit_message(
385
409
                rev, commit.message, encoding)
386
410
        if commit.encoding is not None:
387
 
            rev.properties[u'git-explicit-encoding'] = commit.encoding.decode('ascii')
 
411
            rev.properties[u'git-explicit-encoding'] = commit.encoding.decode(
 
412
                'ascii')
388
413
            decode_using_encoding(rev, commit, commit.encoding.decode('ascii'))
389
414
        else:
390
415
            for encoding in ('utf-8', 'latin1'):
405
430
        if commit._commit_timezone_neg_utc:
406
431
            rev.properties[u'commit-timezone-neg-utc'] = ""
407
432
        if commit.gpgsig:
408
 
            rev.properties[u'git-gpg-signature'] = commit.gpgsig.decode('ascii')
 
433
            rev.properties[u'git-gpg-signature'] = commit.gpgsig.decode(
 
434
                'ascii')
409
435
        if commit.mergetag:
410
436
            for i, tag in enumerate(commit.mergetag):
411
437
                rev.properties[u'git-mergetag-%d' % i] = tag.as_raw_string()
438
464
            elif k == HG_EXTRA:
439
465
                hgk, hgv = v.split(b':', 1)
440
466
                if hgk not in (HG_EXTRA_AMEND_SOURCE, ):
441
 
                    raise UnknownMercurialCommitExtra(commit, hgk)
 
467
                    raise UnknownMercurialCommitExtra(commit, [hgk])
442
468
                extra_lines.append(k + b' ' + v + b'\n')
443
469
            else:
444
470
                unknown_extra_fields.append(k)
445
471
        if unknown_extra_fields:
446
472
            raise UnknownCommitExtra(
447
 
                commit, [f.decode('ascii', 'replace') for f in unknown_extra_fields])
 
473
                commit,
 
474
                [f.decode('ascii', 'replace') for f in unknown_extra_fields])
448
475
        if extra_lines:
449
476
            rev.properties[u'git-extra'] = b''.join(extra_lines)
450
477
        return rev, roundtrip_revid, verifiers
457
484
        :return: GitFileIdMap instance
458
485
        """
459
486
        try:
460
 
            file_id_map_sha = lookup_object(tree_sha)[self.BZR_FILE_IDS_FILE][1]
 
487
            file_id_map_sha = lookup_object(
 
488
                tree_sha)[self.BZR_FILE_IDS_FILE][1]
461
489
        except KeyError:
462
490
            file_ids = {}
463
491
        else:
483
511
    BZR_DUMMY_FILE = '.bzrdummy'
484
512
 
485
513
    def _decode_commit_message(self, rev, message, encoding):
 
514
        if rev is None:
 
515
            rev = Revision()
486
516
        message = self._extract_hg_metadata(rev, message)
487
517
        message = self._extract_git_svn_metadata(rev, message)
488
518
        message, metadata = self._extract_bzr_metadata(rev, message)
495
525
        return ret
496
526
 
497
527
    def import_commit(self, commit, lookup_parent_revid):
498
 
        rev, roundtrip_revid, verifiers = super(BzrGitMappingExperimental, self).import_commit(commit, lookup_parent_revid)
 
528
        rev, roundtrip_revid, verifiers = super(
 
529
            BzrGitMappingExperimental, self).import_commit(
 
530
                commit, lookup_parent_revid)
499
531
        rev.properties[u'converted_revision'] = "git %s\n" % commit.id
500
532
        return rev, roundtrip_revid, verifiers
501
533
 
518
550
 
519
551
mapping_registry = GitMappingRegistry()
520
552
mapping_registry.register_lazy(b'git-v1', __name__,
521
 
    "BzrGitMappingv1")
 
553
                               "BzrGitMappingv1")
522
554
mapping_registry.register_lazy(b'git-experimental',
523
 
    __name__, "BzrGitMappingExperimental")
 
555
                               __name__, "BzrGitMappingExperimental")
524
556
# Uncomment the next line to enable the experimental bzr-git mappings.
525
557
# This will make sure all bzr metadata is pushed into git, allowing for
526
558
# full roundtripping later.
527
559
# NOTE: THIS IS EXPERIMENTAL. IT MAY EAT YOUR DATA OR CORRUPT
528
560
# YOUR BZR OR GIT REPOSITORIES. USE WITH CARE.
529
 
#mapping_registry.set_default('git-experimental')
 
561
# mapping_registry.set_default('git-experimental')
530
562
mapping_registry.set_default(b'git-v1')
531
563
 
532
564
 
553
585
 
554
586
    @classmethod
555
587
    def show_foreign_revid(cls, foreign_revid):
556
 
        return { "git commit": foreign_revid.decode('utf-8') }
 
588
        return {"git commit": foreign_revid.decode('utf-8')}
557
589
 
558
590
 
559
591
foreign_vcs_git = ForeignGit()
645
677
        self.paths = None
646
678
        self.mapping = mapping
647
679
 
648
 
    def all_file_ids(self):
649
 
        return self.file_ids.values()
650
 
 
651
680
    def set_file_id(self, path, file_id):
652
681
        if type(path) is not str:
653
682
            raise TypeError(path)