76
81
return self._lookup_revno(self.new_revid)
79
class LocalGitTagDict(tag.BasicTags):
80
"""Dictionary with tags in a local repository."""
84
class GitTags(tag.BasicTags):
85
"""Ref-based tag dictionary."""
82
87
def __init__(self, branch):
83
88
self.branch = branch
84
89
self.repository = branch.repository
92
raise NotImplementedError(self.get_refs)
94
def _iter_tag_refs(self, refs):
95
raise NotImplementedError(self._iter_tag_refs)
97
def _merge_to_git(self, to_tags, refs, overwrite=False):
98
target_repo = to_tags.repository
100
for k, v in refs.iteritems():
103
if overwrite or not k in self.target.repository.refs:
104
target_repo.refs[k] = v
105
elif target_repo.repository.refs[k] == v:
108
conflicts.append((ref_to_tag_name(k), v, target_repo.refs[k]))
111
def _merge_to_non_git(self, to_tags, refs, overwrite=False):
112
unpeeled_map = defaultdict(set)
114
result = dict(to_tags.get_tag_dict())
115
for n, peeled, unpeeled, bzr_revid in self._iter_tag_refs(refs):
116
if unpeeled is not None:
117
unpeeled_map[peeled].add(unpeeled)
118
if n not in result or overwrite:
119
result[n] = bzr_revid
120
elif result[n] == bzr_revid:
123
conflicts.append((n, result[n], bzr_revid))
124
to_tags._set_tag_dict(result)
125
if len(unpeeled_map) > 0:
126
map_file = UnpeelMap.from_repository(to_tags.branch.repository)
127
map_file.update(unpeeled_map)
128
map_file.save_in_repository(to_tags.branch.repository)
131
def merge_to(self, to_tags, overwrite=False, ignore_master=False,
133
if source_refs is None:
134
source_refs = self.get_refs()
137
if isinstance(to_tags, GitTags):
138
return self._merge_to_git(to_tags, source_refs,
144
master = to_tags.branch.get_master_branch()
145
conflicts = self._merge_to_non_git(to_tags, source_refs,
147
if master is not None:
148
conflicts += self.merge_to(to_tags, overwrite=overwrite,
149
source_refs=source_refs,
150
ignore_master=ignore_master)
86
153
def get_tag_dict(self):
88
for k,v in extract_tags(self.repository._git.get_refs()).iteritems():
155
refs = self.get_refs()
156
for (name, peeled, unpeeled, bzr_revid) in self._iter_tag_refs(refs):
157
ret[name] = bzr_revid
161
class LocalGitTagDict(GitTags):
162
"""Dictionary with tags in a local repository."""
164
def __init__(self, branch):
165
super(LocalGitTagDict, self).__init__(branch)
166
self.refs = self.repository._git.refs
169
return self.repository._git.get_refs()
171
def _iter_tag_refs(self, refs):
172
"""Iterate over the tag refs.
174
:param refs: Refs dictionary (name -> git sha1)
175
:return: iterator over (name, peeled_sha1, unpeeled_sha1, bzr_revid)
177
for k, (peeled, unpeeled) in extract_tags(refs).iteritems():
90
obj = self.repository._git[v]
179
obj = self.repository._git[peeled]
92
mutter("Tag %s points at unknown object %s, ignoring", v, obj)
181
mutter("Tag %s points at unknown object %s, ignoring", peeled,
184
# FIXME: this shouldn't really be necessary, the repository
185
# already should have these unpeeled.
94
186
while isinstance(obj, Tag):
96
obj = self.repository._git[v]
187
peeled = obj.object[1]
188
obj = self.repository._git[peeled]
97
189
if not isinstance(obj, Commit):
98
190
mutter("Tag %s points at object %r that is not a commit, "
99
191
"ignoring", k, obj)
101
ret[k] = self.branch.lookup_foreign_revision_id(v)
193
yield (k, peeled, unpeeled,
194
self.branch.lookup_foreign_revision_id(peeled))
104
196
def _set_tag_dict(self, to_dict):
105
extra = set(self.repository._git.get_refs().keys())
197
extra = set(self.get_refs().keys())
106
198
for k, revid in to_dict.iteritems():
107
199
name = tag_name_to_ref(k)
108
200
if name in extra:
109
201
extra.remove(name)
110
202
self.set_tag(k, revid)
111
203
for name in extra:
112
if name.startswith("refs/tags/"):
113
205
del self.repository._git[name]
115
207
def set_tag(self, name, revid):
116
self.repository._git.refs[tag_name_to_ref(name)], _ = \
208
self.refs[tag_name_to_ref(name)], _ = \
117
209
self.branch.lookup_bzr_revision_id(revid)
662
758
def _get_new_refs(self, stop_revision=None):
663
759
if stop_revision is None:
664
stop_revision = self.source.last_revision()
760
(stop_revno, stop_revision) = self.source.last_revision_info()
665
761
assert type(stop_revision) is str
666
762
main_ref = self.target.ref or "refs/heads/master"
667
763
refs = { main_ref: (None, stop_revision) }
668
764
for name, revid in self.source.tags.get_tag_dict().iteritems():
669
765
if self.source.repository.has_revision(revid):
670
766
refs[tag_name_to_ref(name)] = (None, revid)
671
return refs, main_ref
767
return refs, main_ref, (stop_revno, stop_revision)
673
769
def pull(self, overwrite=False, stop_revision=None, local=False,
674
770
possible_transports=None):