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

Simply refer to bzr's docs in HACKING.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
from bzrlib import (
26
26
    branch,
 
27
    bzrdir,
27
28
    config,
28
29
    errors,
29
 
    foreign,
30
30
    repository,
31
31
    revision,
32
32
    tag,
40
40
    mutter,
41
41
    )
42
42
 
 
43
from bzrlib.plugins.git import (
 
44
    get_rich_root_format,
 
45
    )
43
46
from bzrlib.plugins.git.config import (
44
47
    GitBranchConfig,
45
48
    )
48
51
    NoSuchRef,
49
52
    )
50
53
 
51
 
try:
52
 
    from bzrlib.foreign import ForeignBranch
53
 
except ImportError:
54
 
    class ForeignBranch(branch.Branch):
55
 
        def __init__(self, mapping):
56
 
            self.mapping = mapping
57
 
            super(ForeignBranch, self).__init__()
 
54
from bzrlib.foreign import ForeignBranch
58
55
 
59
56
 
60
57
def extract_tags(refs, mapping):
92
89
    def get_tag_dict(self):
93
90
        ret = {}
94
91
        for k,v in self.repository._git.refs.as_dict("refs/tags").iteritems():
95
 
            obj = self.repository._git.get_object(v)
 
92
            try:
 
93
                obj = self.repository._git.get_object(v)
 
94
            except KeyError:
 
95
                mutter("Tag %s points at unknown object %s, ignoring", v, obj)
 
96
                continue
96
97
            while isinstance(obj, Tag):
97
98
                v = obj.object[1]
98
99
                obj = self.repository._git.get_object(v)
108
109
            self.branch.mapping.revision_id_bzr_to_foreign(revid)
109
110
 
110
111
 
 
112
class DictTagDict(LocalGitTagDict):
 
113
 
 
114
 
 
115
    def __init__(self, branch, tags):
 
116
        super(DictTagDict, self).__init__(branch)
 
117
        self._tags = tags
 
118
 
 
119
    def get_tag_dict(self):
 
120
        return self._tags
 
121
 
 
122
 
 
123
 
111
124
class GitBranchFormat(branch.BranchFormat):
112
125
 
113
126
    def get_format_description(self):
127
140
class GitBranch(ForeignBranch):
128
141
    """An adapter to git repositories for bzr Branch objects."""
129
142
 
130
 
    def __init__(self, bzrdir, repository, name, lockfiles):
 
143
    def __init__(self, bzrdir, repository, name, lockfiles, tagsdict=None):
131
144
        self.repository = repository
132
145
        self._format = GitBranchFormat()
133
146
        self.control_files = lockfiles
134
147
        self.bzrdir = bzrdir
135
148
        super(GitBranch, self).__init__(repository.get_mapping())
 
149
        if tagsdict is not None:
 
150
            self.tags = DictTagDict(self, tagsdict)
136
151
        self.name = name
137
152
        self._head = None
138
153
        self.base = bzrdir.transport.base
139
154
 
 
155
    def _get_checkout_format(self):
 
156
        """Return the most suitable metadir for a checkout of this branch.
 
157
        Weaves are used if this branch's repository uses weaves.
 
158
        """
 
159
        return get_rich_root_format()
 
160
 
 
161
    def get_child_submit_format(self):
 
162
        """Return the preferred format of submissions to this branch."""
 
163
        ret = self.get_config().get_user_option("child_submit_format")
 
164
        if ret is not None:
 
165
            return ret
 
166
        return "git"
 
167
 
140
168
    def _get_nick(self, local=False, possible_master_transports=None):
141
169
        """Find the nick name for this branch.
142
170
 
152
180
    def __repr__(self):
153
181
        return "%s(%r, %r)" % (self.__class__.__name__, self.repository.base, self.name)
154
182
 
155
 
    def dpull(self, source, stop_revision=None):
156
 
        return branch.InterBranch.get(source, self).lossy_push()
157
 
 
158
183
    def generate_revision_history(self, revid, old_revid=None):
159
184
        # FIXME: Check that old_revid is in the ancestry of revid
160
185
        newhead, self.mapping = self.mapping.revision_id_bzr_to_foreign(revid)
195
220
            return revision.NULL_REVISION
196
221
        return self.mapping.revision_id_foreign_to_bzr(self.head)
197
222
 
 
223
    def _basic_push(self, target, overwrite=False, stop_revision=None):
 
224
        return branch.InterBranch.get(self, target)._basic_push(
 
225
            overwrite, stop_revision)
 
226
 
198
227
 
199
228
class LocalGitBranch(GitBranch):
200
229
    """A local Git branch."""
201
230
 
202
 
    def _get_checkout_format(self):
203
 
        """Return the most suitable metadir for a checkout of this branch.
204
 
        Weaves are used if this branch's repository uses weaves.
205
 
        """
206
 
        format = self.repository.bzrdir.checkout_metadir()
207
 
        format.set_branch_format(self._format)
208
 
        return format
209
 
 
210
231
    def create_checkout(self, to_location, revision_id=None, lightweight=False,
211
232
        accelerator_tree=None, hardlink=False):
212
233
        if lightweight:
232
253
        :param hardlink: Whether to hardlink
233
254
        :return: WorkingTree object of checkout.
234
255
        """
235
 
        checkout_branch = BzrDir.create_branch_convenience(
 
256
        checkout_branch = bzrdir.BzrDir.create_branch_convenience(
236
257
            to_location, force_new_tree=False, format=get_rich_root_format())
237
258
        checkout = checkout_branch.bzrdir
238
259
        checkout_branch.bind(self)
255
276
        except KeyError:
256
277
            return None
257
278
 
 
279
    def set_last_revision_info(self, revno, revid):
 
280
        self.set_last_revision(revid)
 
281
 
 
282
    def set_last_revision(self, revid):
 
283
        (newhead, self.mapping) = self.mapping.revision_id_bzr_to_foreign(
 
284
                revid)
 
285
        self.head = newhead
 
286
 
258
287
    def _set_head(self, value):
259
288
        self._head = value
260
289
        self.repository._git.refs[self.name] = self._head
291
320
        self._show_tag_conficts(to_file)
292
321
 
293
322
 
294
 
class InterFromGitBranch(branch.InterBranch):
 
323
class GitBranchPushResult(branch.BranchPushResult):
 
324
 
 
325
    def _lookup_revno(self, revid):
 
326
        assert isinstance(revid, str), "was %r" % revid
 
327
        # Try in source branch first, it'll be faster
 
328
        try:
 
329
            return self.source_branch.revision_id_to_revno(revid)
 
330
        except errors.NoSuchRevision:
 
331
            # FIXME: Check using graph.find_distance_to_null() ?
 
332
            return self.target_branch.revision_id_to_revno(revid)
 
333
 
 
334
    @property
 
335
    def old_revno(self):
 
336
        return self._lookup_revno(self.old_revid)
 
337
 
 
338
    @property
 
339
    def new_revno(self):
 
340
        return self._lookup_revno(self.new_revid)
 
341
 
 
342
 
 
343
class InterFromGitBranch(branch.GenericInterBranch):
295
344
    """InterBranch implementation that pulls from Git into bzr."""
296
345
 
297
346
    @classmethod
375
424
            self.source.unlock()
376
425
        return result
377
426
 
378
 
 
379
 
class InterGitRemoteLocalBranch(branch.InterBranch):
 
427
    def _basic_push(self, overwrite=False, stop_revision=None):
 
428
        result = branch.BranchPushResult()
 
429
        result.source_branch = self.source
 
430
        result.target_branch = self.target
 
431
        graph = self.target.repository.get_graph(self.source.repository)
 
432
        result.old_revno, result.old_revid = self.target.last_revision_info()
 
433
        self.update_revisions(stop_revision, overwrite=overwrite, 
 
434
            graph=graph)
 
435
        result.new_git_head = self._head
 
436
        result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
 
437
            overwrite)
 
438
        result.new_revno, result.new_revid = self.target.last_revision_info()
 
439
        return result
 
440
 
 
441
 
 
442
class InterGitBranch(branch.GenericInterBranch):
380
443
    """InterBranch implementation that pulls between Git branches."""
381
444
 
 
445
 
 
446
class InterGitLocalRemoteBranch(InterGitBranch):
 
447
    """InterBranch that copies from a local to a remote git branch."""
 
448
 
 
449
    @classmethod
 
450
    def is_compatible(self, source, target):
 
451
        from bzrlib.plugins.git.remote import RemoteGitBranch
 
452
        return (isinstance(source, LocalGitBranch) and 
 
453
                isinstance(target, RemoteGitBranch))
 
454
 
 
455
    def _basic_push(self, overwrite=False, stop_revision=None):
 
456
        result = GitBranchPushResult()
 
457
        result.source_branch = self.source
 
458
        result.target_branch = self.target
 
459
        if stop_revision is None:
 
460
            stop_revision = self.source.last_revision()
 
461
        # FIXME: Check for diverged branches
 
462
        def get_changed_refs(old_refs):
 
463
            result.old_revid = self.target.mapping.revision_id_foreign_to_bzr(old_refs.get("refs/heads/master", "0" * 40))
 
464
            refs = { "refs/heads/master": self.source.repository.lookup_git_revid(stop_revision)[0] }
 
465
            result.new_revid = stop_revision
 
466
            for name, sha in self.source.repository._git.refs.as_dict("refs/tags").iteritems():
 
467
                refs["refs/tags/%s" % name] = sha
 
468
            return refs
 
469
        self.target.repository.send_pack(get_changed_refs, 
 
470
                self.source.repository._git.object_store.generate_pack_contents)
 
471
        return result
 
472
 
 
473
 
 
474
class InterGitRemoteLocalBranch(InterGitBranch):
 
475
    """InterBranch that copies from a remote to a local git branch."""
 
476
 
382
477
    @classmethod
383
478
    def is_compatible(self, source, target):
384
479
        from bzrlib.plugins.git.remote import RemoteGitBranch
385
480
        return (isinstance(source, RemoteGitBranch) and 
386
481
                isinstance(target, LocalGitBranch))
387
482
 
 
483
    def _basic_push(self, overwrite=False, stop_revision=None):
 
484
        result = branch.BranchPushResult()
 
485
        result.source_branch = self.source
 
486
        result.target_branch = self.target
 
487
        result.old_revid = self.target.last_revision()
 
488
        refs, stop_revision = self.update_refs(stop_revision)
 
489
        self.target.generate_revision_history(stop_revision, result.old_revid)
 
490
        self.update_tags(refs)
 
491
        result.new_revid = self.target.last_revision()
 
492
        return result
 
493
 
 
494
    def update_tags(self, refs):
 
495
        for name, revid in extract_tags(refs, self.target.mapping).iteritems():
 
496
            self.target.tags.set_tag(name, revid)
 
497
 
 
498
    def update_refs(self, stop_revision=None):
 
499
        interrepo = repository.InterRepository.get(self.source.repository, 
 
500
            self.target.repository)
 
501
        if stop_revision is None:
 
502
            refs = interrepo.fetch_refs(branches=["HEAD"])
 
503
            stop_revision = self.target.mapping.revision_id_foreign_to_bzr(refs["HEAD"])
 
504
        else:
 
505
            refs = interrepo.fetch_refs(revision_id=stop_revision)
 
506
        return refs, stop_revision
 
507
 
388
508
    def pull(self, stop_revision=None, overwrite=False, 
389
509
        possible_transports=None, local=False):
390
510
        # This type of branch can't be bound.
393
513
        result = GitPullResult()
394
514
        result.source_branch = self.source
395
515
        result.target_branch = self.target
396
 
        interrepo = repository.InterRepository.get(self.source.repository, 
397
 
            self.target.repository)
398
516
        result.old_revid = self.target.last_revision()
399
 
        if stop_revision is None:
400
 
            refs = interrepo.fetch_refs(branches=["HEAD"])
401
 
            stop_revision = self.target.mapping.revision_id_foreign_to_bzr(refs["HEAD"])
402
 
        else:
403
 
            refs = interrepo.fetch_refs(revision_id=stop_revision)
 
517
        refs, stop_revision = self.update_refs(stop_revision)
404
518
        self.target.generate_revision_history(stop_revision, result.old_revid)
405
 
        for name, revid in extract_tags(refs, self.target.mapping).iteritems():
406
 
            self.target.tags.set_tag(name, revid)
 
519
        self.update_tags(refs)
407
520
        result.new_revid = self.target.last_revision()
408
521
        return result
409
522
 
416
529
        return (not isinstance(source, GitBranch) and 
417
530
                isinstance(target, GitBranch))
418
531
 
 
532
    def update_revisions(self, *args, **kwargs):
 
533
        raise NoPushSupport()
 
534
 
419
535
    def push(self, overwrite=True, stop_revision=None, 
420
536
             _override_hook_source_branch=None):
421
537
        raise NoPushSupport()
422
538
 
423
539
    def lossy_push(self, stop_revision=None):
 
540
        result = GitBranchPushResult()
 
541
        result.source_branch = self.source
 
542
        result.target_branch = self.target
 
543
        try:
 
544
            result.old_revid = self.target.last_revision()
 
545
        except NoSuchRef:
 
546
            result.old_revid = revision.NULL_REVISION
424
547
        if stop_revision is None:
425
548
            stop_revision = self.source.last_revision()
426
549
        # FIXME: Check for diverged branches
432
555
            self.source.repository, refs)
433
556
        if revidmap != {}:
434
557
            self.target.generate_revision_history(revidmap[stop_revision])
435
 
        return revidmap
 
558
            result.new_revid = revidmap[stop_revision]
 
559
        else:
 
560
            result.new_revid = result.old_revid
 
561
        result.revidmap = revidmap
 
562
        return result
436
563
 
437
564
 
438
565
branch.InterBranch.register_optimiser(InterGitRemoteLocalBranch)
439
566
branch.InterBranch.register_optimiser(InterFromGitBranch)
440
567
branch.InterBranch.register_optimiser(InterToGitBranch)
 
568
branch.InterBranch.register_optimiser(InterGitLocalRemoteBranch)