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

Add a tag_selector argument to push/pull/sprout functions.

Merged from https://code.launchpad.net/~jelmer/brz/tag-selector/+merge/379435

Show diffs side-by-side

added added

removed removed

Lines of Context:
131
131
            return False
132
132
        return True
133
133
 
134
 
    def merge(self, overwrite=False, ignore_master=False):
 
134
    def merge(self, overwrite=False, ignore_master=False, selector=None):
135
135
        if self.source.branch.repository.has_same_location(self.target.branch.repository):
136
136
            return {}, []
137
137
        updates = {}
142
142
            ret = dict(old_refs)
143
143
            for ref_name, tag_name, peeled, unpeeled in (
144
144
                    source_tag_refs.iteritems()):
 
145
                if selector and not selector(tag_name):
 
146
                    continue
145
147
                if old_refs.get(ref_name) == unpeeled:
146
148
                    pass
147
149
                elif overwrite or ref_name not in old_refs:
158
160
            return ret
159
161
        self.target.branch.repository.controldir.send_pack(
160
162
            get_changed_refs, lambda have, want: [])
161
 
        return updates, conflicts
 
163
        return updates, set(conflicts)
162
164
 
163
165
 
164
166
class InterTagsFromGitToLocalGit(InterTags):
173
175
            return False
174
176
        return True
175
177
 
176
 
    def merge(self, overwrite=False, ignore_master=False):
 
178
    def merge(self, overwrite=False, ignore_master=False, selector=None):
177
179
        if self.source.branch.repository.has_same_location(self.target.branch.repository):
178
180
            return {}, []
179
181
 
184
186
        target_repo = self.target.branch.repository
185
187
 
186
188
        for ref_name, tag_name, peeled, unpeeled in source_tag_refs:
 
189
            if selector and not selector(tag_name):
 
190
                continue
187
191
            if target_repo._git.refs.get(ref_name) == unpeeled:
188
192
                pass
189
193
            elif overwrite or ref_name not in target_repo._git.refs:
215
219
                                  tag_name)
216
220
                    continue
217
221
                conflicts.append((tag_name, source_revid, target_revid))
218
 
        return updates, conflicts
 
222
        return updates, set(conflicts)
219
223
 
220
224
 
221
225
class InterTagsFromGitToNonGit(InterTags):
228
232
            return False
229
233
        return True
230
234
 
231
 
    def merge(self, overwrite=False, ignore_master=False):
 
235
    def merge(self, overwrite=False, ignore_master=False, selector=None):
232
236
        """See Tags.merge_to."""
233
237
        source_tag_refs = self.source.branch.get_tag_refs()
234
238
        if ignore_master:
239
243
            if master is not None:
240
244
                es.enter_context(master.lock_write())
241
245
            updates, conflicts = self._merge_to(
242
 
                self.target, source_tag_refs, overwrite=overwrite)
 
246
                self.target, source_tag_refs, overwrite=overwrite,
 
247
                selector=selector)
243
248
            if master is not None:
244
249
                extra_updates, extra_conflicts = self._merge_to(
245
250
                    master.tags, overwrite=overwrite,
246
251
                    source_tag_refs=source_tag_refs,
247
 
                    ignore_master=ignore_master)
 
252
                    ignore_master=ignore_master, selector=selector)
248
253
                updates.update(extra_updates)
249
 
                conflicts += extra_conflicts
 
254
                conflicts.update(extra_conflicts)
250
255
            return updates, conflicts
251
256
 
252
 
    def _merge_to(self, to_tags, source_tag_refs, overwrite=False):
 
257
    def _merge_to(self, to_tags, source_tag_refs, overwrite=False,
 
258
                  selector=None):
253
259
        unpeeled_map = defaultdict(set)
254
260
        conflicts = []
255
261
        updates = {}
256
262
        result = dict(to_tags.get_tag_dict())
257
263
        for ref_name, tag_name, peeled, unpeeled in source_tag_refs:
 
264
            if selector and not selector(tag_name):
 
265
                continue
258
266
            if unpeeled is not None:
259
267
                unpeeled_map[peeled].add(unpeeled)
260
268
            try:
273
281
            map_file = UnpeelMap.from_repository(to_tags.branch.repository)
274
282
            map_file.update(unpeeled_map)
275
283
            map_file.save_in_repository(to_tags.branch.repository)
276
 
        return updates, conflicts
 
284
        return updates, set(conflicts)
277
285
 
278
286
 
279
287
InterTags.register_optimiser(InterTagsFromGitToRemoteGit)
659
667
                return revision.NULL_REVISION
660
668
            return self.lookup_foreign_revision_id(self.head)
661
669
 
662
 
    def _basic_push(self, target, overwrite=False, stop_revision=None):
 
670
    def _basic_push(self, target, overwrite=False, stop_revision=None,
 
671
                    tag_selector=None):
663
672
        return branch.InterBranch.get(self, target)._basic_push(
664
 
            overwrite, stop_revision)
 
673
            overwrite, stop_revision, tag_selector=tag_selector)
665
674
 
666
675
    def lookup_foreign_revision_id(self, foreign_revid):
667
676
        try:
981
990
            stop_revision, fetch_tags=fetch_tags, limit=limit, lossy=lossy)
982
991
        return _mod_repository.FetchResult()
983
992
 
984
 
    def fetch_objects(self, stop_revision, fetch_tags, limit=None, lossy=False):
 
993
    def fetch_objects(self, stop_revision, fetch_tags, limit=None, lossy=False, tag_selector=None):
985
994
        interrepo = self._get_interrepo(self.source, self.target)
986
995
        if fetch_tags is None:
987
996
            c = self.source.get_config_stack()
999
1008
            else:
1000
1009
                self._last_revid = stop_revision
1001
1010
            real = interrepo.get_determine_wants_revids(
1002
 
                [self._last_revid], include_tags=fetch_tags)
 
1011
                [self._last_revid], include_tags=fetch_tags, tag_selector=tag_selector)
1003
1012
            return real(heads)
1004
1013
        pack_hint, head, refs = interrepo.fetch_objects(
1005
1014
            determine_wants, self.source.mapping, limit=limit,
1009
1018
            self.target.repository.pack(hint=pack_hint)
1010
1019
        return head, refs
1011
1020
 
1012
 
    def _update_revisions(self, stop_revision=None, overwrite=False):
1013
 
        head, refs = self.fetch_objects(stop_revision, fetch_tags=None)
 
1021
    def _update_revisions(self, stop_revision=None, overwrite=False, tag_selector=None):
 
1022
        head, refs = self.fetch_objects(stop_revision, fetch_tags=None, tag_selector=tag_selector)
1014
1023
        if overwrite:
1015
1024
            prev_last_revid = None
1016
1025
        else:
1035
1044
            pass
1036
1045
 
1037
1046
    def _basic_pull(self, stop_revision, overwrite, run_hooks,
1038
 
                    _override_hook_target, _hook_master):
 
1047
                    _override_hook_target, _hook_master, tag_selector=None):
1039
1048
        if overwrite is True:
1040
1049
            overwrite = set(["history", "tags"])
1041
1050
        elif not overwrite:
1052
1061
            (result.old_revno, result.old_revid) = \
1053
1062
                self.target.last_revision_info()
1054
1063
            result.new_git_head, remote_refs = self._update_revisions(
1055
 
                stop_revision, overwrite=("history" in overwrite))
 
1064
                stop_revision, overwrite=("history" in overwrite),
 
1065
                tag_selector=tag_selector)
1056
1066
            tags_ret = self.source.tags.merge_to(
1057
1067
                self.target.tags, ("tags" in overwrite), ignore_master=True)
1058
1068
            if isinstance(tags_ret, tuple):
1075
1085
 
1076
1086
    def pull(self, overwrite=False, stop_revision=None,
1077
1087
             possible_transports=None, _hook_master=None, run_hooks=True,
1078
 
             _override_hook_target=None, local=False):
 
1088
             _override_hook_target=None, local=False, tag_selector=None):
1079
1089
        """See Branch.pull.
1080
1090
 
1081
1091
        :param _hook_master: Private parameter - set the branch to
1113
1123
                master_branch = None
1114
1124
            return self._basic_pull(stop_revision, overwrite, run_hooks,
1115
1125
                                    _override_hook_target,
1116
 
                                    _hook_master=master_branch)
 
1126
                                    _hook_master=master_branch,
 
1127
                                    tag_selector=tag_selector)
1117
1128
 
1118
 
    def _basic_push(self, overwrite, stop_revision):
 
1129
    def _basic_push(self, overwrite, stop_revision, tag_selector=None):
1119
1130
        if overwrite is True:
1120
1131
            overwrite = set(["history", "tags"])
1121
1132
        elif not overwrite:
1125
1136
        result.target_branch = self.target
1126
1137
        result.old_revno, result.old_revid = self.target.last_revision_info()
1127
1138
        result.new_git_head, remote_refs = self._update_revisions(
1128
 
            stop_revision, overwrite=("history" in overwrite))
 
1139
            stop_revision, overwrite=("history" in overwrite),
 
1140
            tag_selector=tag_selector)
1129
1141
        tags_ret = self.source.tags.merge_to(
1130
 
            self.target.tags, "tags" in overwrite, ignore_master=True)
 
1142
            self.target.tags, "tags" in overwrite, ignore_master=True,
 
1143
            selector=tag_selector)
1131
1144
        (result.tag_updates, result.tag_conflicts) = tags_ret
1132
1145
        result.new_revno, result.new_revid = self.target.last_revision_info()
1133
1146
        self.update_references(revid=result.new_revid)
1156
1169
        return (isinstance(source, LocalGitBranch) and
1157
1170
                isinstance(target, RemoteGitBranch))
1158
1171
 
1159
 
    def _basic_push(self, overwrite, stop_revision):
 
1172
    def _basic_push(self, overwrite, stop_revision, tag_selector=None):
1160
1173
        result = GitBranchPushResult()
1161
1174
        result.source_branch = self.source
1162
1175
        result.target_branch = self.target
1181
1194
            result.new_revid = stop_revision
1182
1195
            for name, sha in viewitems(
1183
1196
                    self.source.repository._git.refs.as_dict(b"refs/tags")):
 
1197
                if tag_selector and not tag_selector(name):
 
1198
                    continue
1184
1199
                if sha not in self.source.repository._git:
1185
1200
                    trace.mutter('Ignoring missing SHA: %s', sha)
1186
1201
                    continue
1220
1235
        interrepo.fetch_objects(determine_wants, limit=limit, lossy=lossy)
1221
1236
        return _mod_repository.FetchResult()
1222
1237
 
1223
 
    def _basic_push(self, overwrite=False, stop_revision=None):
 
1238
    def _basic_push(self, overwrite=False, stop_revision=None, tag_selector=None):
1224
1239
        if overwrite is True:
1225
1240
            overwrite = set(["history", "tags"])
1226
1241
        elif not overwrite:
1236
1251
            other_branch=self.source)
1237
1252
        tags_ret = self.source.tags.merge_to(
1238
1253
            self.target.tags,
1239
 
            overwrite=("tags" in overwrite))
 
1254
            overwrite=("tags" in overwrite),
 
1255
            selector=tag_selector)
1240
1256
        if isinstance(tags_ret, tuple):
1241
1257
            (result.tag_updates, result.tag_conflicts) = tags_ret
1242
1258
        else:
1264
1280
        return result.refs, stop_revision
1265
1281
 
1266
1282
    def pull(self, stop_revision=None, overwrite=False,
1267
 
             possible_transports=None, run_hooks=True, local=False):
 
1283
             possible_transports=None, run_hooks=True, local=False,
 
1284
             tag_selector=None):
1268
1285
        # This type of branch can't be bound.
1269
1286
        if local:
1270
1287
            raise errors.LocalRequiresBoundBranch()
1284
1301
                (result.old_revid if ("history" not in overwrite) else None),
1285
1302
                other_branch=self.source)
1286
1303
            tags_ret = self.source.tags.merge_to(
1287
 
                self.target.tags, overwrite=("tags" in overwrite))
 
1304
                self.target.tags, overwrite=("tags" in overwrite),
 
1305
                selector=tag_selector)
1288
1306
            if isinstance(tags_ret, tuple):
1289
1307
                (result.tag_updates, result.tag_conflicts) = tags_ret
1290
1308
            else:
1352
1370
                    refs[ref] = (None, revid)
1353
1371
        return refs, main_ref, (stop_revno, stop_revision)
1354
1372
 
1355
 
    def _update_refs(self, result, old_refs, new_refs, overwrite):
 
1373
    def _update_refs(self, result, old_refs, new_refs, overwrite, tag_selector):
1356
1374
        mutter("updating refs. old refs: %r, new refs: %r",
1357
1375
               old_refs, new_refs)
1358
1376
        result.tag_updates = {}
1391
1409
                except ValueError:
1392
1410
                    pass
1393
1411
                else:
 
1412
                    if tag_selector and not tag_selector(tag_name):
 
1413
                        continue
1394
1414
                    result.tag_updates[tag_name] = revid
1395
1415
                ret[ref] = (git_sha, revid)
1396
1416
            else:
1426
1446
            for (old_revid, (new_sha, new_revid)) in revidmap.items()})
1427
1447
 
1428
1448
    def pull(self, overwrite=False, stop_revision=None, local=False,
1429
 
             possible_transports=None, run_hooks=True, _stop_revno=None):
 
1449
             possible_transports=None, run_hooks=True, _stop_revno=None,
 
1450
             tag_selector=None):
1430
1451
        result = GitBranchPullResult()
1431
1452
        result.source_branch = self.source
1432
1453
        result.target_branch = self.target
1435
1456
                stop_revision, stop_revno=_stop_revno)
1436
1457
 
1437
1458
            def update_refs(old_refs):
1438
 
                return self._update_refs(result, old_refs, new_refs, overwrite)
 
1459
                return self._update_refs(result, old_refs, new_refs, overwrite, tag_selector)
1439
1460
            try:
1440
1461
                result.revidmap, old_refs, new_refs = (
1441
1462
                    self.interrepo.fetch_refs(update_refs, lossy=False))
1455
1476
        return result
1456
1477
 
1457
1478
    def push(self, overwrite=False, stop_revision=None, lossy=False,
1458
 
             _override_hook_source_branch=None, _stop_revno=None):
 
1479
             _override_hook_source_branch=None, _stop_revno=None,
 
1480
             tag_selector=None):
1459
1481
        result = GitBranchPushResult()
1460
1482
        result.source_branch = self.source
1461
1483
        result.target_branch = self.target
1466
1488
                stop_revision, stop_revno=_stop_revno)
1467
1489
 
1468
1490
            def update_refs(old_refs):
1469
 
                return self._update_refs(result, old_refs, new_refs, overwrite)
 
1491
                return self._update_refs(result, old_refs, new_refs, overwrite, tag_selector)
1470
1492
            try:
1471
1493
                result.revidmap, old_refs, new_refs = (
1472
1494
                    self.interrepo.fetch_refs(