/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/tag.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:
35
35
from .inter import InterObject
36
36
from .registry import Registry
37
37
from .sixish import text_type
38
 
from .lazy_import import lazy_import
39
 
lazy_import(globals(), """
40
 
 
41
 
from breezy import (
 
38
from . import (
42
39
    cleanup,
43
 
    )
44
 
""")
45
 
 
46
 
from . import (
47
40
    errors,
48
41
    )
49
42
 
50
43
 
51
 
def _reconcile_tags(source_dict, dest_dict, overwrite):
 
44
def _reconcile_tags(source_dict, dest_dict, overwrite, selector):
52
45
    """Do a two-way merge of two tag dictionaries.
53
46
 
54
47
    * only in source => source value
64
57
    updates = {}
65
58
    result = dict(dest_dict)  # copy
66
59
    for name, target in source_dict.items():
 
60
        if selector and not selector(name):
 
61
            continue
67
62
        if result.get(name) == target:
68
63
            pass
69
64
        elif name not in result or overwrite:
93
88
            rev[d[key]].add(key)
94
89
        return rev
95
90
 
96
 
    def merge_to(self, to_tags, overwrite=False, ignore_master=False):
 
91
    def merge_to(self, to_tags, overwrite=False, ignore_master=False, selector=None):
97
92
        """Copy tags between repositories if necessary and possible.
98
93
 
99
94
        This method has common command-line behaviour about handling
115
110
            done.
116
111
        """
117
112
        intertags = InterTags.get(self, to_tags)
118
 
        return intertags.merge(overwrite=overwrite, ignore_master=ignore_master)
 
113
        return intertags.merge(
 
114
            overwrite=overwrite, ignore_master=ignore_master,
 
115
            selector=selector)
119
116
 
120
117
    def set_tag(self, tag_name, revision):
121
118
        """Set a tag.
174
171
    lookup_tag = _not_supported
175
172
    delete_tag = _not_supported
176
173
 
177
 
    def merge_to(self, to_tags, overwrite=False, ignore_master=False):
 
174
    def merge_to(self, to_tags, overwrite=False, ignore_master=False, selector=None):
178
175
        # we never have anything to copy
179
176
        return {}, []
180
177
 
199
196
        # This is the default implementation
200
197
        return True
201
198
 
202
 
    def merge(self, overwrite=False, ignore_master=False):
 
199
    def merge(self, overwrite=False, ignore_master=False, selector=None):
203
200
        """Copy tags between repositories if necessary and possible.
204
201
 
205
202
        This method has common command-line behaviour about handling
212
209
        :param overwrite: Overwrite conflicting tags in the target branch
213
210
        :param ignore_master: Do not modify the tags in the target's master
214
211
            branch (if any).  Default is false (so the master will be updated).
 
212
        :param selector: Callback that determines whether a tag should be
 
213
            copied. It should take a tag name and as argument and return a
 
214
            boolean.
215
215
 
216
216
        :returns: Tuple with tag_updates and tag_conflicts.
217
217
            tag_updates is a dictionary with new tags, None is used for
250
250
                master = self.target.branch.get_master_branch()
251
251
            if master is not None:
252
252
                stack.enter_context(master.lock_write())
253
 
            updates, conflicts = self._merge_to(self.target, source_dict, overwrite)
 
253
            updates, conflicts = self._merge_to(
 
254
                self.target, source_dict, overwrite, selector=selector)
254
255
            if master is not None:
255
 
                extra_updates, extra_conflicts = self._merge_to(master.tags,
256
 
                                                                source_dict, overwrite)
 
256
                extra_updates, extra_conflicts = self._merge_to(
 
257
                    master.tags, source_dict, overwrite, selector=selector)
257
258
                updates.update(extra_updates)
258
259
                conflicts += extra_conflicts
259
260
            # We use set() to remove any duplicate conflicts from the master
261
262
            return updates, set(conflicts)
262
263
 
263
264
    @classmethod
264
 
    def _merge_to(cls, to_tags, source_dict, overwrite):
 
265
    def _merge_to(cls, to_tags, source_dict, overwrite, selector):
265
266
        dest_dict = to_tags.get_tag_dict()
266
267
        result, updates, conflicts = _reconcile_tags(
267
 
            source_dict, dest_dict, overwrite)
 
268
            source_dict, dest_dict, overwrite, selector)
268
269
        if result != dest_dict:
269
270
            to_tags._set_tag_dict(result)
270
271
        return updates, conflicts
303
304
    def _set_tag_dict(self, result):
304
305
        self._tag_dict = dict(result.items())
305
306
 
306
 
    def merge_to(self, to_tags, overwrite=False, ignore_master=False):
 
307
    def merge_to(self, to_tags, overwrite=False, ignore_master=False, selector=None):
307
308
        source_dict = self.get_tag_dict()
308
309
        dest_dict = to_tags.get_tag_dict()
309
310
        result, updates, conflicts = _reconcile_tags(
310
 
            source_dict, dest_dict, overwrite)
 
311
            source_dict, dest_dict, overwrite, selector)
311
312
        if result != dest_dict:
312
313
            to_tags._set_tag_dict(result)
313
314
        return updates, conflicts