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

Avoid invoking git directly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import stat
23
23
 
24
24
from bzrlib import (
 
25
    bencode,
25
26
    errors,
26
27
    foreign,
27
28
    trace,
28
29
    )
29
 
try:
30
 
    from bzrlib import bencode
31
 
except ImportError:
32
 
    from bzrlib.util import bencode
33
30
from bzrlib.inventory import (
34
31
    ROOT_ID,
35
32
    )
95
92
                 "property. ", mode, path, commit)
96
93
 
97
94
 
98
 
def squash_revision(target_repo, rev):
99
 
    """Remove characters that can't be stored from a revision, if necessary.
100
 
 
101
 
    :param target_repo: Repository in which the revision will be stored
102
 
    :param rev: Revision object, will be modified in-place
103
 
    """
104
 
    if not getattr(target_repo._serializer, "squashes_xml_invalid_characters", True):
105
 
        return
106
 
    from bzrlib.xml_serializer import escape_invalid_chars
107
 
    rev.message, num_escaped = escape_invalid_chars(rev.message)
108
 
    if num_escaped:
109
 
        warn_escaped(rev.foreign_revid, num_escaped)
110
 
    if 'author' in rev.properties:
111
 
        rev.properties['author'], num_escaped = escape_invalid_chars(
112
 
            rev.properties['author'])
113
 
        if num_escaped:
114
 
            warn_escaped(rev.foreign_revid, num_escaped)
115
 
    rev.committer, num_escaped = escape_invalid_chars(rev.committer)
116
 
    if num_escaped:
117
 
        warn_escaped(rev.foreign_revid, num_escaped)
118
 
 
119
 
 
120
95
class BzrGitMapping(foreign.VcsMapping):
121
96
    """Class that maps between Git and Bazaar semantics."""
122
97
    experimental = False
123
98
 
124
 
    BZR_FILE_IDS_FILE = '.bzrfileids'
 
99
    BZR_FILE_IDS_FILE = None
125
100
 
126
 
    BZR_DUMMY_FILE = '.bzrdummy'
 
101
    BZR_DUMMY_FILE = None
127
102
 
128
103
    def __init__(self):
129
104
        super(BzrGitMapping, self).__init__(foreign_git)
152
127
        # We must just hope they are valid UTF-8..
153
128
        if path == "":
154
129
            return ROOT_ID
 
130
        if type(path) is unicode:
 
131
            path = path.encode("utf-8")
155
132
        return escape_file_id(path)
156
133
 
157
134
    def is_control_file(self, path):
234
211
        return message, metadata
235
212
 
236
213
    def _decode_commit_message(self, rev, message, encoding):
237
 
        message, metadata = self._extract_bzr_metadata(rev, message)
238
 
        return message.decode(encoding), metadata
 
214
        return message.decode(encoding), BzrGitRevisionMetadata()
239
215
 
240
216
    def _encode_commit_message(self, rev, message, encoding):
241
217
        return message.encode(encoding)
266
242
            metadata = BzrGitRevisionMetadata()
267
243
        else:
268
244
            metadata = None
 
245
        parents = []
269
246
        for p in rev.parent_ids:
270
247
            try:
271
248
                git_p = parent_lookup(p)
275
252
                    metadata.explicit_parent_ids = rev.parent_ids
276
253
            if git_p is not None:
277
254
                assert len(git_p) == 40, "unexpected length for %r" % git_p
278
 
                commit.parents.append(git_p)
 
255
                parents.append(git_p)
 
256
        commit.parents = parents
279
257
        try:
280
258
            encoding = rev.properties['git-explicit-encoding']
281
259
        except KeyError:
299
277
            commit.author_timezone = commit.commit_timezone
300
278
        commit.message = self._encode_commit_message(rev, rev.message, 
301
279
            encoding)
 
280
        assert type(commit.message) == str
302
281
        if metadata is not None:
303
282
            try:
304
283
                mapping_registry.parse_revision_id(rev.revision_id)
311
290
            for k, v in rev.properties.iteritems():
312
291
                if not k in mapping_properties:
313
292
                    metadata.properties[k] = v
314
 
        commit.message = inject_bzr_metadata(commit.message, metadata)
 
293
        if self.roundtripping:
 
294
            commit.message = inject_bzr_metadata(commit.message, metadata, 
 
295
                                                 encoding)
 
296
        assert type(commit.message) == str
315
297
        return commit
316
298
 
317
299
    def import_fileid_map(self, blob):
322
304
        """
323
305
        return deserialize_fileid_map(blob.data)
324
306
 
325
 
    def import_commit(self, commit):
 
307
    def import_commit(self, commit, lookup_parent_revid):
326
308
        """Convert a git commit to a bzr revision.
327
309
 
328
310
        :return: a `bzrlib.revision.Revision` object and a 
332
314
            raise AssertionError("Commit object can't be None")
333
315
        rev = ForeignRevision(commit.id, self,
334
316
                self.revision_id_foreign_to_bzr(commit.id))
335
 
        rev.parent_ids = tuple([self.revision_id_foreign_to_bzr(p) for p in commit.parents])
 
317
        rev.parent_ids = tuple([lookup_parent_revid(p) for p in commit.parents])
336
318
        rev.git_metadata = None
337
319
        def decode_using_encoding(rev, commit, encoding):
338
320
            rev.committer = str(commit.committer).decode(encoding)
372
354
            rev.properties.update(md.properties)
373
355
        return rev
374
356
 
 
357
    def get_fileid_map(self, lookup_object, tree_sha):
 
358
        """Obtain a fileid map for a particular tree.
 
359
 
 
360
        :param lookup_object: Function for looking up an object
 
361
        :param tree_sha: SHA of the root tree
 
362
        :return: GitFileIdMap instance
 
363
        """
 
364
        try:
 
365
            file_id_map_sha = lookup_object(tree_sha)[self.BZR_FILE_IDS_FILE][1]
 
366
        except KeyError:
 
367
            file_ids = {}
 
368
        else:
 
369
            file_ids = self.import_fileid_map(lookup_object(file_id_map_sha))
 
370
        return GitFileIdMap(file_ids, self)
 
371
 
375
372
 
376
373
class BzrGitMappingv1(BzrGitMapping):
377
374
    revid_prefix = 'git-v1'
384
381
class BzrGitMappingExperimental(BzrGitMappingv1):
385
382
    revid_prefix = 'git-experimental'
386
383
    experimental = True
 
384
    roundtripping = True
 
385
 
 
386
    BZR_FILE_IDS_FILE = '.bzrfileids'
 
387
 
 
388
    BZR_DUMMY_FILE = '.bzrdummy'
387
389
 
388
390
    def _decode_commit_message(self, rev, message, encoding):
389
391
        message = self._extract_hg_metadata(rev, message)
397
399
        ret += self._generate_git_svn_metadata(rev, encoding)
398
400
        return ret
399
401
 
400
 
    def import_commit(self, commit):
401
 
        rev, file_ids = super(BzrGitMappingExperimental, self).import_commit(commit)
 
402
    def import_commit(self, commit, lookup_parent_revid):
 
403
        rev, file_ids = super(BzrGitMappingExperimental, self).import_commit(commit, lookup_parent_revid)
402
404
        rev.properties['converted_revision'] = "git %s\n" % commit.id
403
405
        return rev, file_ids
404
406
 
572
574
        self.mapping = mapping
573
575
 
574
576
    def lookup_file_id(self, path):
 
577
        assert type(path) is str
575
578
        try:
576
 
            return self.file_ids[path]
 
579
            file_id = self.file_ids[path]
577
580
        except KeyError:
578
 
            return self.mapping.generate_file_id(path)
 
581
            file_id = self.mapping.generate_file_id(path)
 
582
        assert type(file_id) is str
 
583
        return file_id
579
584
 
580
585
    def lookup_path(self, file_id):
581
586
        if self.paths is None:
583
588
            for k, v in self.file_ids.iteritems():
584
589
                self.paths[v] = k
585
590
        try:
586
 
            return self.paths[file_id]
 
591
            path = self.paths[file_id]
587
592
        except KeyError:
588
593
            return self.mapping.parse_file_id(file_id)
 
594
        else:
 
595
            assert type(path) is str
 
596
            return path