/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

  • Committer: Jelmer Vernooij
  • Date: 2010-05-05 09:58:55 UTC
  • mto: (0.200.912 trunk)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20100505095855-i0165hooflvk9chy
Ignore control files in inventories.

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,
26
25
    errors,
27
26
    foreign,
28
27
    trace,
29
28
    )
 
29
try:
 
30
    from bzrlib import bencode
 
31
except ImportError:
 
32
    from bzrlib.util import bencode
30
33
from bzrlib.inventory import (
31
34
    ROOT_ID,
32
35
    )
92
95
                 "property. ", mode, path, commit)
93
96
 
94
97
 
 
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
 
95
120
class BzrGitMapping(foreign.VcsMapping):
96
121
    """Class that maps between Git and Bazaar semantics."""
97
122
    experimental = False
98
123
 
99
 
    BZR_FILE_IDS_FILE = None
 
124
    BZR_FILE_IDS_FILE = '.bzrfileids'
100
125
 
101
 
    BZR_DUMMY_FILE = None
 
126
    BZR_DUMMY_FILE = '.bzrdummy'
102
127
 
103
128
    def __init__(self):
104
129
        super(BzrGitMapping, self).__init__(foreign_git)
105
130
 
106
131
    def __eq__(self, other):
107
 
        return (type(self) == type(other) and
 
132
        return (type(self) == type(other) and 
108
133
                self.revid_prefix == other.revid_prefix)
109
134
 
110
135
    @classmethod
127
152
        # We must just hope they are valid UTF-8..
128
153
        if path == "":
129
154
            return ROOT_ID
130
 
        if type(path) is unicode:
131
 
            path = path.encode("utf-8")
132
155
        return escape_file_id(path)
133
156
 
134
157
    def is_control_file(self, path):
185
208
 
186
209
    def _extract_git_svn_metadata(self, rev, message):
187
210
        lines = message.split("\n")
188
 
        if not (lines[-1] == "" and len(lines) >= 2 and lines[-2].startswith("git-svn-id:")):
 
211
        if not (lines[-1] == "" and lines[-2].startswith("git-svn-id:")):
189
212
            return message
190
213
        git_svn_id = lines[-2].split(": ", 1)[1]
191
214
        rev.properties['git-svn-id'] = git_svn_id
211
234
        return message, metadata
212
235
 
213
236
    def _decode_commit_message(self, rev, message, encoding):
214
 
        return message.decode(encoding), BzrGitRevisionMetadata()
 
237
        message, metadata = self._extract_bzr_metadata(rev, message)
 
238
        return message.decode(encoding), metadata
215
239
 
216
240
    def _encode_commit_message(self, rev, message, encoding):
217
241
        return message.encode(encoding)
227
251
        b.set_raw_chunks(serialize_fileid_map(fileid_map))
228
252
        return b
229
253
 
230
 
    def export_commit(self, rev, tree_sha, parent_lookup, roundtrip,
231
 
                      verifiers):
 
254
    def export_commit(self, rev, tree_sha, parent_lookup, roundtrip):
232
255
        """Turn a Bazaar revision in to a Git commit
233
256
 
234
257
        :param tree_sha: Tree sha for the commit
235
258
        :param parent_lookup: Function for looking up the GIT sha equiv of a
236
259
            bzr revision
237
 
        :param roundtrip: Whether to store roundtripping information.
238
 
        :param verifiers: Verifiers info
239
260
        :return dulwich.objects.Commit represent the revision:
240
261
        """
241
262
        from dulwich.objects import Commit
243
264
        commit.tree = tree_sha
244
265
        if roundtrip:
245
266
            metadata = BzrGitRevisionMetadata()
246
 
            metadata.verifiers = verifiers
247
267
        else:
248
268
            metadata = None
249
 
        parents = []
250
269
        for p in rev.parent_ids:
251
270
            try:
252
271
                git_p = parent_lookup(p)
256
275
                    metadata.explicit_parent_ids = rev.parent_ids
257
276
            if git_p is not None:
258
277
                assert len(git_p) == 40, "unexpected length for %r" % git_p
259
 
                parents.append(git_p)
260
 
        commit.parents = parents
 
278
                commit.parents.append(git_p)
261
279
        try:
262
280
            encoding = rev.properties['git-explicit-encoding']
263
281
        except KeyError:
281
299
            commit.author_timezone = commit.commit_timezone
282
300
        commit.message = self._encode_commit_message(rev, rev.message, 
283
301
            encoding)
284
 
        assert type(commit.message) == str
285
302
        if metadata is not None:
286
303
            try:
287
304
                mapping_registry.parse_revision_id(rev.revision_id)
294
311
            for k, v in rev.properties.iteritems():
295
312
                if not k in mapping_properties:
296
313
                    metadata.properties[k] = v
297
 
        if self.roundtripping:
298
 
            commit.message = inject_bzr_metadata(commit.message, metadata, 
299
 
                                                 encoding)
300
 
        assert type(commit.message) == str
 
314
        commit.message = inject_bzr_metadata(commit.message, metadata)
301
315
        return commit
302
316
 
303
317
    def import_fileid_map(self, blob):
308
322
        """
309
323
        return deserialize_fileid_map(blob.data)
310
324
 
311
 
    def import_commit(self, commit, lookup_parent_revid):
 
325
    def import_commit(self, commit):
312
326
        """Convert a git commit to a bzr revision.
313
327
 
314
 
        :return: a `bzrlib.revision.Revision` object, foreign revid and a
315
 
            testament sha1
 
328
        :return: a `bzrlib.revision.Revision` object and a 
 
329
            dictionary of path -> file ids
316
330
        """
317
331
        if commit is None:
318
332
            raise AssertionError("Commit object can't be None")
319
333
        rev = ForeignRevision(commit.id, self,
320
334
                self.revision_id_foreign_to_bzr(commit.id))
321
 
        rev.parent_ids = tuple([lookup_parent_revid(p) for p in commit.parents])
 
335
        rev.parent_ids = tuple([self.revision_id_foreign_to_bzr(p) for p in commit.parents])
322
336
        rev.git_metadata = None
323
337
        def decode_using_encoding(rev, commit, encoding):
324
338
            rev.committer = str(commit.committer).decode(encoding)
351
365
        rev.timezone = commit.commit_timezone
352
366
        if rev.git_metadata is not None:
353
367
            md = rev.git_metadata
354
 
            roundtrip_revid = md.revision_id
 
368
            if md.revision_id:
 
369
                rev.revision_id = md.revision_id
355
370
            if md.explicit_parent_ids:
356
371
                rev.parent_ids = md.explicit_parent_ids
357
372
            rev.properties.update(md.properties)
358
 
            verifiers = md.verifiers
359
 
        else:
360
 
            roundtrip_revid = None
361
 
            verifiers = {}
362
 
        return rev, roundtrip_revid, verifiers
363
 
 
364
 
    def get_fileid_map(self, lookup_object, tree_sha):
365
 
        """Obtain a fileid map for a particular tree.
366
 
 
367
 
        :param lookup_object: Function for looking up an object
368
 
        :param tree_sha: SHA of the root tree
369
 
        :return: GitFileIdMap instance
370
 
        """
371
 
        try:
372
 
            file_id_map_sha = lookup_object(tree_sha)[self.BZR_FILE_IDS_FILE][1]
373
 
        except KeyError:
374
 
            file_ids = {}
375
 
        else:
376
 
            file_ids = self.import_fileid_map(lookup_object(file_id_map_sha))
377
 
        return GitFileIdMap(file_ids, self)
 
373
        return rev
378
374
 
379
375
 
380
376
class BzrGitMappingv1(BzrGitMapping):
388
384
class BzrGitMappingExperimental(BzrGitMappingv1):
389
385
    revid_prefix = 'git-experimental'
390
386
    experimental = True
391
 
    roundtripping = True
392
 
 
393
 
    BZR_FILE_IDS_FILE = '.bzrfileids'
394
 
 
395
 
    BZR_DUMMY_FILE = '.bzrdummy'
396
387
 
397
388
    def _decode_commit_message(self, rev, message, encoding):
398
389
        message = self._extract_hg_metadata(rev, message)
406
397
        ret += self._generate_git_svn_metadata(rev, encoding)
407
398
        return ret
408
399
 
409
 
    def import_commit(self, commit, lookup_parent_revid):
410
 
        rev, roundtrip_revid, verifiers = super(BzrGitMappingExperimental, self).import_commit(commit, lookup_parent_revid)
 
400
    def import_commit(self, commit):
 
401
        rev, file_ids = super(BzrGitMappingExperimental, self).import_commit(commit)
411
402
        rev.properties['converted_revision'] = "git %s\n" % commit.id
412
 
        return rev, roundtrip_revid, verifiers
 
403
        return rev, file_ids
413
404
 
414
405
 
415
406
class GitMappingRegistry(VcsMappingRegistry):
581
572
        self.mapping = mapping
582
573
 
583
574
    def lookup_file_id(self, path):
584
 
        assert type(path) is str
585
575
        try:
586
 
            file_id = self.file_ids[path]
 
576
            return self.file_ids[path]
587
577
        except KeyError:
588
 
            file_id = self.mapping.generate_file_id(path)
589
 
        assert type(file_id) is str
590
 
        return file_id
 
578
            return self.mapping.generate_file_id(path)
591
579
 
592
580
    def lookup_path(self, file_id):
593
581
        if self.paths is None:
595
583
            for k, v in self.file_ids.iteritems():
596
584
                self.paths[v] = k
597
585
        try:
598
 
            path = self.paths[file_id]
 
586
            return self.paths[file_id]
599
587
        except KeyError:
600
588
            return self.mapping.parse_file_id(file_id)
601
 
        else:
602
 
            assert type(path) is str
603
 
            return path