1
# Copyright (C) 2010 Jelmer Vernooij <jelmer@samba.org>
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Conversion between refs and Bazaar revision pointers."""
19
from dulwich.repo import (
28
is_tag = lambda x: x.startswith("refs/tags/")
31
def gather_peeled(refs):
33
for k, v in refs.iteritems():
34
if not k.endswith("^{}"):
36
peeled = refs[k+"^{}"]
41
ret[k] = (peeled, unpeeled)
45
def extract_tags(refs):
46
"""Extract the tags from a refs dictionary.
48
:param refs: Refs to extract the tags from.
49
:return: Dictionary mapping tag names to SHA1s of the actual object
50
and unpeeled object SHA1s.
53
for k, v in gather_peeled(refs).iteritems():
55
tagname = ref_to_tag_name(k)
56
except (ValueError, UnicodeDecodeError):
63
def branch_name_to_ref(name, default=None):
64
"""Map a branch name to a ref.
66
:param name: Branch name
72
return osutils.safe_utf8(name)
73
if not name.startswith("refs/"):
74
return "refs/heads/%s" % osutils.safe_utf8(name)
76
return osutils.safe_utf8(name)
79
def tag_name_to_ref(name):
80
"""Map a tag name to a ref.
85
return "refs/tags/%s" % osutils.safe_utf8(name)
88
def ref_to_branch_name(ref):
89
"""Map a ref to a branch name
92
:return: A branch name
94
if ref in (None, "HEAD"):
96
if ref.startswith("refs/heads/"):
97
return osutils.safe_unicode(ref[len("refs/heads/"):])
98
raise ValueError("unable to map ref %s back to branch name" % ref)
101
def ref_to_tag_name(ref):
102
if ref.startswith("refs/tags/"):
103
return ref[len('refs/tags/'):].decode("utf-8")
104
raise ValueError("unable to map ref %s back to tag name" % ref)
107
class BazaarRefsContainer(RefsContainer):
109
def __init__(self, dir, object_store):
111
self.object_store = object_store
113
def set_symbolic_ref(self, name, other):
115
pass # FIXME: Switch default branch
117
raise NotImplementedError(
118
"Symbolic references not supported for anything other than "
121
def _get_revid_by_tag_name(self, tag_name):
122
for branch in self.dir.list_branches():
124
# FIXME: This is ambiguous!
125
return branch.tags.lookup_tag(tag_name)
126
except errors.NoSuchTag:
130
def _get_revid_by_branch_name(self, branch_name):
132
branch = self.dir.open_branch(branch_name)
133
except errors.NoColocatedBranchSupport:
134
if branch_name in ("HEAD", "master"):
135
branch = self.dir.open_branch()
138
return branch.last_revision()
140
def read_loose_ref(self, ref):
142
branch_name = ref_to_branch_name(ref)
144
tag_name = ref_to_tag_name(ref)
145
revid = self._get_revid_by_tag_name(tag_name)
147
revid = self._get_revid_by_branch_name(branch_name)
148
return self.object_store._lookup_revision_sha1(revid)
152
for branch in self.dir.list_branches():
153
repo = branch.repository
154
if repo.has_revision(branch.last_revision()):
155
ref = branch_name_to_ref(getattr(branch, "name", None),
158
if getattr(branch, "name", None) is None:
161
for tag_name, revid in branch.tags.get_tag_dict().iteritems():
162
if repo.has_revision(revid):
163
keys.add(tag_name_to_ref(tag_name))
164
except errors.TagsNotSupported:
168
def __delitem__(self, ref):
170
branch_name = ref_to_branch_name(ref)
172
return # FIXME: Cope with tags!
173
self.dir.destroy_branch(branch_name)
175
def __setitem__(self, ref, sha):
177
branch_name = ref_to_branch_name(ref)
179
# FIXME: Cope with tags!
182
target_branch = self.repo_dir.open_branch(branch_name)
183
except errors.NotBranchError:
184
target_branch = self.repo.create_branch(branch_name)
186
rev_id = self.mapping.revision_id_foreign_to_bzr(sha)
187
target_branch.lock_write()
189
target_branch.generate_revision_history(rev_id)
191
target_branch.unlock()
194
def get_refs_container(controldir, object_store):
195
repo = controldir.find_repository()
196
git_repo = getattr(repo, "_git", None)
197
if git_repo is not None:
199
return BazaarRefsContainer(controldir, object_store)
202
def get_refs(controldir, object_store=None):
203
cb = getattr(controldir, "get_refs", None)
206
return BazaarRefsContainer(controldir, object_store).as_dict()