71
def branch_name_to_ref(name, default=None):
72
"""Map a branch name to a ref.
74
:param name: Branch name
81
if not name.startswith("refs/"):
82
return "refs/heads/%s" % name
87
def ref_to_branch_name(ref):
88
"""Map a ref to a branch name
91
:return: A branch name
95
if ref.startswith("refs/heads/"):
96
return ref[len("refs/heads/"):]
97
raise ValueError("unable to map ref %s back to branch name")
100
66
class GitPullResult(branch.PullResult):
102
68
def _lookup_revno(self, revid):
138
104
ret[k] = self.branch.mapping.revision_id_foreign_to_bzr(v)
141
def _set_tag_dict(self, to_dict):
142
extra = set(self.repository._git.get_refs().keys())
143
for k, revid in to_dict.iteritems():
144
name = "refs/tags/%s" % k
147
self.set_tag(k, revid)
149
if name.startswith("refs/tags/"):
150
del self.repository._git[name]
152
107
def set_tag(self, name, revid):
153
108
self.repository._git.refs["refs/tags/%s" % name], _ = \
154
109
self.branch.mapping.revision_id_bzr_to_foreign(revid)
190
147
class GitBranch(ForeignBranch):
191
148
"""An adapter to git repositories for bzr Branch objects."""
193
def __init__(self, bzrdir, repository, ref, lockfiles, tagsdict=None):
150
def __init__(self, bzrdir, repository, name, lockfiles, tagsdict=None):
194
151
self.repository = repository
195
152
self._format = GitBranchFormat()
196
153
self.control_files = lockfiles
229
185
nick = property(_get_nick, _set_nick)
231
187
def __repr__(self):
232
return "<%s(%r, %r)>" % (self.__class__.__name__, self.repository.base,
188
return "%s(%r, %r)" % (self.__class__.__name__, self.repository.base, self.name)
235
190
def generate_revision_history(self, revid, old_revid=None):
236
191
# FIXME: Check that old_revid is in the ancestry of revid
280
235
class LocalGitBranch(GitBranch):
281
236
"""A local Git branch."""
283
def __init__(self, bzrdir, repository, name, lockfiles, tagsdict=None):
284
super(LocalGitBranch, self).__init__(bzrdir, repository, name,
286
if not name in repository._git.get_refs().keys():
287
raise errors.NotBranchError(self.base)
289
238
def create_checkout(self, to_location, revision_id=None, lightweight=False,
290
239
accelerator_tree=None, hardlink=False):
414
361
not isinstance(target, GitBranch) and
415
362
(getattr(cls._get_interrepo(source, target), "fetch_objects", None) is not None))
417
def _update_revisions(self, stop_revision=None, overwrite=False,
418
graph=None, limit=None):
419
"""Like InterBranch.update_revisions(), but with additions.
421
Compared to the `update_revisions()` below, this function takes a
422
`limit` argument that limits how many git commits will be converted
423
and returns the new git head.
364
def update_revisions(self, stop_revision=None, overwrite=False,
366
"""See InterBranch.update_revisions()."""
425
367
interrepo = self._get_interrepo(self.source, self.target)
369
self._last_revid = None
426
370
def determine_wants(heads):
427
if not self.source.ref in heads:
428
raise NoSuchRef(self.source.ref, heads.keys())
371
if not self.source.name in heads:
372
raise NoSuchRef(self.source.name, heads.keys())
429
373
if stop_revision is not None:
430
374
self._last_revid = stop_revision
431
head, mapping = self.source.repository.lookup_bzr_revision_id(
375
self._head, mapping = self.source.repository.lookup_bzr_revision_id(
434
head = heads[self.source.ref]
435
self._last_revid = self.source.mapping.revision_id_foreign_to_bzr(
378
self._head = heads[self.source.name]
380
self.source.mapping.revision_id_foreign_to_bzr(self._head)
437
381
if self.target.repository.has_revision(self._last_revid):
440
pack_hint, head = interrepo.fetch_objects(
441
determine_wants, self.source.mapping, limit=limit)
442
if pack_hint is not None and self.target.repository._format.pack_compresses:
443
self.target.repository.pack(hint=pack_hint)
445
self._last_revid = self.source.mapping.revision_id_foreign_to_bzr(head)
384
interrepo.fetch_objects(determine_wants, self.source.mapping)
447
386
prev_last_revid = None
449
388
prev_last_revid = self.target.last_revision()
450
self.target.generate_revision_history(self._last_revid,
454
def update_revisions(self, stop_revision=None, overwrite=False,
456
"""See InterBranch.update_revisions()."""
457
self._update_revisions(stop_revision, overwrite, graph)
389
self.target.generate_revision_history(self._last_revid, prev_last_revid)
459
391
def pull(self, overwrite=False, stop_revision=None,
460
392
possible_transports=None, _hook_master=None, run_hooks=True,
461
_override_hook_target=None, local=False, limit=None):
393
_override_hook_target=None, local=False):
462
394
"""See Branch.pull.
464
396
:param _hook_master: Private parameter - set the branch to
485
415
# We assume that during 'pull' the target repository is closer than
486
416
# the source one.
487
417
graph = self.target.repository.get_graph(self.source.repository)
488
(result.old_revno, result.old_revid) = \
418
result.old_revno, result.old_revid = \
489
419
self.target.last_revision_info()
490
result.new_git_head = self._update_revisions(
491
stop_revision, overwrite=overwrite, graph=graph, limit=limit)
420
self.update_revisions(stop_revision, overwrite=overwrite,
422
result.new_git_head = self._head
492
423
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
494
(result.new_revno, result.new_revid) = \
495
self.target.last_revision_info()
425
result.new_revno, result.new_revid = self.target.last_revision_info()
497
427
result.master_branch = _hook_master
498
428
result.local_branch = result.target_branch
512
442
result.target_branch = self.target
513
443
graph = self.target.repository.get_graph(self.source.repository)
514
444
result.old_revno, result.old_revid = self.target.last_revision_info()
515
result.new_git_head = self._update_revisions(
516
stop_revision, overwrite=overwrite, graph=graph)
445
self.update_revisions(stop_revision, overwrite=overwrite, graph=graph)
446
result.new_git_head = self._head
517
447
result.tag_conflicts = self.source.tags.merge_to(self.target.tags,
519
449
result.new_revno, result.new_revid = self.target.last_revision_info()
541
471
stop_revision = self.source.last_revision()
542
472
# FIXME: Check for diverged branches
543
473
def get_changed_refs(old_refs):
544
result.old_revid = self.target.mapping.revision_id_foreign_to_bzr(old_refs.get(self.target.ref, "0" * 40))
545
refs = { self.target.ref: self.source.repository.lookup_bzr_revision_id(stop_revision)[0] }
474
result.old_revid = self.target.mapping.revision_id_foreign_to_bzr(old_refs.get("refs/heads/master", "0" * 40))
475
refs = { "refs/heads/master": self.source.repository.lookup_bzr_revision_id(stop_revision)[0] }
546
476
result.new_revid = stop_revision
547
477
for name, sha in self.source.repository._git.refs.as_dict("refs/tags").iteritems():
548
478
refs["refs/tags/%s" % name] = sha
550
480
self.target.repository.send_pack(get_changed_refs,
551
self.source.repository._git.object_store.generate_pack_contents)
481
self.source.repository._git.object_store.generate_pack_contents)
588
518
return refs, stop_revision
590
520
def pull(self, stop_revision=None, overwrite=False,
591
possible_transports=None, run_hooks=True,local=False):
521
possible_transports=None, local=False):
592
522
# This type of branch can't be bound.
594
524
raise errors.LocalRequiresBoundBranch()
626
556
result = GitBranchPushResult()
627
557
result.source_branch = self.source
628
558
result.target_branch = self.target
560
result.old_revid = self.target.last_revision()
562
result.old_revid = revision.NULL_REVISION
629
563
if stop_revision is None:
630
564
stop_revision = self.source.last_revision()
631
565
# FIXME: Check for diverged branches
632
refs = { self.target.ref: stop_revision }
566
refs = { "refs/heads/master": stop_revision }
633
567
for name, revid in self.source.tags.get_tag_dict().iteritems():
634
568
if self.source.repository.has_revision(revid):
635
569
refs["refs/tags/%s" % name] = revid
636
revidmap, old_refs, new_refs = self.target.repository.dfetch_refs(
570
revidmap, new_refs = self.target.repository.dfetch_refs(
637
571
self.source.repository, refs)
638
result.old_revid = self.target.mapping.revision_id_foreign_to_bzr(
639
old_refs.get(self.target.ref, "0" * 40))
640
result.new_revid = self.target.mapping.revision_id_foreign_to_bzr(
641
new_refs[self.target.ref])
573
self.target.generate_revision_history(revidmap[stop_revision])
574
result.new_revid = revidmap[stop_revision]
576
result.new_revid = result.old_revid
642
577
result.revidmap = revidmap