242
253
return LocalGitTagDict(branch)
255
def initialize(self, a_bzrdir, name=None, repository=None):
256
from bzrlib.plugins.git.dir import LocalGitDir
257
if not isinstance(a_bzrdir, LocalGitDir):
258
raise errors.IncompatibleFormat(self, a_bzrdir._format)
259
if repository is None:
260
repository = a_bzrdir.open_repository()
261
ref = branch_name_to_ref(name, "HEAD")
262
repository._git[ref] = ZERO_SHA
263
return LocalGitBranch(a_bzrdir, repository, ref, a_bzrdir._lockfiles)
245
266
class GitReadLock(object):
251
272
class GitWriteLock(object):
253
274
def __init__(self, unlock):
275
self.branch_token = None
254
276
self.unlock = unlock
257
279
class GitBranch(ForeignBranch):
258
280
"""An adapter to git repositories for bzr Branch objects."""
283
def control_transport(self):
284
return self.bzrdir.control_transport
260
286
def __init__(self, bzrdir, repository, ref, lockfiles, tagsdict=None):
261
287
self.repository = repository
262
288
self._format = GitBranchFormat()
357
386
class LocalGitBranch(GitBranch):
358
387
"""A local Git branch."""
360
def __init__(self, bzrdir, repository, name, lockfiles, tagsdict=None):
361
super(LocalGitBranch, self).__init__(bzrdir, repository, name,
389
def __init__(self, bzrdir, repository, ref, lockfiles, tagsdict=None):
390
super(LocalGitBranch, self).__init__(bzrdir, repository, ref,
362
391
lockfiles, tagsdict)
363
392
refs = repository._git.get_refs()
364
if not (name in refs.keys() or "HEAD" in refs.keys()):
393
if not (ref in refs.keys() or "HEAD" in refs.keys()):
365
394
raise errors.NotBranchError(self.base)
367
396
def create_checkout(self, to_location, revision_id=None, lightweight=False,
526
555
def _get_branch_formats_to_test():
557
default_format = branch.format_registry.get_default()
558
except AttributeError:
559
default_format = branch.BranchFormat._default_format
561
(GitBranchFormat(), GitBranchFormat()),
562
(GitBranchFormat(), default_format)]
530
565
def _get_interrepo(self, source, target):
531
return repository.InterRepository.get(source.repository,
566
return _mod_repository.InterRepository.get(source.repository, target.repository)
535
569
def is_compatible(cls, source, target):
537
571
not isinstance(target, GitBranch) and
538
572
(getattr(cls._get_interrepo(source, target), "fetch_objects", None) is not None))
540
def _update_revisions(self, stop_revision=None, overwrite=False,
541
graph=None, limit=None):
542
"""Like InterBranch.update_revisions(), but with additions.
574
def fetch(self, stop_revision=None, fetch_tags=True):
575
self.fetch_objects(stop_revision, fetch_tags=fetch_tags)
544
Compared to the `update_revisions()` below, this function takes a
545
`limit` argument that limits how many git commits will be converted
546
and returns the new git head and remote refs.
577
def fetch_objects(self, stop_revision, fetch_tags):
548
578
interrepo = self._get_interrepo(self.source, self.target)
549
579
def determine_wants(heads):
550
580
if self.source.ref is not None and not self.source.ref in heads:
551
581
raise NoSuchRef(self.source.ref, heads.keys())
552
if stop_revision is not None:
553
self._last_revid = stop_revision
554
head, mapping = self.source.repository.lookup_bzr_revision_id(
583
if stop_revision is None:
557
584
if self.source.ref is not None:
558
585
head = heads[self.source.ref]
560
587
head = heads["HEAD"]
561
588
self._last_revid = self.source.lookup_foreign_revision_id(head)
562
if self.target.repository.has_revision(self._last_revid):
590
self._last_revid = stop_revision
591
real = interrepo.get_determine_wants_revids(
592
[self._last_revid], include_tags=fetch_tags)
565
594
pack_hint, head, refs = interrepo.fetch_objects(
566
determine_wants, self.source.mapping, limit=limit)
595
determine_wants, self.source.mapping)
567
596
if (pack_hint is not None and
568
597
self.target.repository._format.pack_compresses):
569
598
self.target.repository.pack(hint=pack_hint)
571
self._last_revid = self.source.lookup_foreign_revision_id(head)
601
def update_revisions(self, stop_revision=None, overwrite=False,
603
"""See InterBranch.update_revisions()."""
604
head, refs = self.fetch_objects(stop_revision, fetch_tags=True)
573
606
prev_last_revid = None
575
608
prev_last_revid = self.target.last_revision()
576
609
self.target.generate_revision_history(self._last_revid,
610
prev_last_revid, self.source)
578
611
return head, refs
580
def update_revisions(self, stop_revision=None, overwrite=False,
582
"""See InterBranch.update_revisions()."""
583
self._update_revisions(stop_revision, overwrite, graph)
585
613
def pull(self, overwrite=False, stop_revision=None,
586
614
possible_transports=None, _hook_master=None, run_hooks=True,
587
_override_hook_target=None, local=False, limit=None):
615
_override_hook_target=None, local=False):
588
616
"""See Branch.pull.
590
618
:param _hook_master: Private parameter - set the branch to
613
639
graph = self.target.repository.get_graph(self.source.repository)
614
640
(result.old_revno, result.old_revid) = \
615
641
self.target.last_revision_info()
616
result.new_git_head, remote_refs = self._update_revisions(
617
stop_revision, overwrite=overwrite, graph=graph, limit=limit)
642
result.new_git_head, remote_refs = self.update_revisions(
643
stop_revision, overwrite=overwrite, graph=graph)
618
644
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
620
646
(result.new_revno, result.new_revid) = \
638
664
result.target_branch = self.target
639
665
graph = self.target.repository.get_graph(self.source.repository)
640
666
result.old_revno, result.old_revid = self.target.last_revision_info()
641
result.new_git_head, remote_refs = self._update_revisions(
667
result.new_git_head, remote_refs = self.update_revisions(
642
668
stop_revision, overwrite=overwrite, graph=graph)
643
669
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
686
class InterGitRemoteLocalBranch(InterGitBranch):
712
class InterGitLocalGitBranch(InterGitBranch):
687
713
"""InterBranch that copies from a remote to a local git branch."""
690
716
def _get_branch_formats_to_test():
694
721
def is_compatible(self, source, target):
695
from bzrlib.plugins.git.remote import RemoteGitBranch
696
return (isinstance(source, RemoteGitBranch) and
722
return (isinstance(source, GitBranch) and
697
723
isinstance(target, LocalGitBranch))
699
725
def _basic_push(self, overwrite=False, stop_revision=None):
741
767
def __init__(self, source, target):
742
768
super(InterToGitBranch, self).__init__(source, target)
743
self.interrepo = repository.InterRepository.get(source.repository,
769
self.interrepo = _mod_repository.InterRepository.get(source.repository,
744
770
target.repository)
747
773
def _get_branch_formats_to_test():
775
default_format = branch.format_registry.get_default()
776
except AttributeError:
777
default_format = branch.BranchFormat._default_format
778
return [(default_format, GitBranchFormat())]
751
781
def is_compatible(self, source, target):
767
799
return refs, main_ref, (stop_revno, stop_revision)
769
801
def pull(self, overwrite=False, stop_revision=None, local=False,
770
possible_transports=None):
771
from dulwich.protocol import ZERO_SHA
802
possible_transports=None, run_hooks=True):
772
803
result = GitBranchPullResult()
773
804
result.source_branch = self.source
774
805
result.target_branch = self.target
778
809
# FIXME: Check for diverged branches
779
810
refs.update(new_refs)
781
old_refs, new_refs = self.interrepo.fetch_refs(update_refs)
813
old_refs, new_refs = self.interrepo.fetch_refs(update_refs)
814
except NoPushSupport:
815
raise errors.NoRoundtrippingSupport(self.source, self.target)
782
816
(result.old_revid, old_sha1) = old_refs.get(main_ref, (ZERO_SHA, NULL_REVISION))
783
817
if result.old_revid is None:
784
818
result.old_revid = self.target.lookup_foreign_revision_id(old_sha1)
797
830
# FIXME: Check for diverged branches
798
831
refs.update(new_refs)
800
old_refs, new_refs = self.interrepo.fetch_refs(update_refs)
834
old_refs, new_refs = self.interrepo.fetch_refs(update_refs)
835
except NoPushSupport:
836
raise errors.NoRoundtrippingSupport(self.source, self.target)
801
837
(result.old_revid, old_sha1) = old_refs.get(main_ref, (ZERO_SHA, NULL_REVISION))
802
838
if result.old_revid is None:
803
839
result.old_revid = self.target.lookup_foreign_revision_id(old_sha1)