/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5752.3.8 by John Arbash Meinel
Merge bzr.dev 5764 to resolve release-notes (aka NEWS) conflicts
1
# Copyright (C) 2005-2011 Canonical Ltd
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
2
#
1110 by Martin Pool
- merge aaron's merge improvements:
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.
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
7
#
1110 by Martin Pool
- merge aaron's merge improvements:
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.
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
12
#
1110 by Martin Pool
- merge aaron's merge improvements:
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1110 by Martin Pool
- merge aaron's merge improvements:
16
7479.2.1 by Jelmer Vernooij
Drop python2 support.
17
import contextlib
18
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
19
from .lazy_import import lazy_import
5246.2.15 by Andrew Bennetts
Lazy import most things in merge.py, to minimise the impact of plugins that need to import bzrlib.merge to install a hook.
20
lazy_import(globals(), """
7290.14.1 by Jelmer Vernooij
Use external patiencediff.
21
import patiencediff
22
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
23
from breezy import (
4721.3.1 by Vincent Ladeuil
Cleanup imports.
24
    branch as _mod_branch,
25
    conflicts as _mod_conflicts,
1551.19.17 by Aaron Bentley
Add debugging flag for merges
26
    debug,
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
27
    graph as _mod_graph,
4721.3.1 by Vincent Ladeuil
Cleanup imports.
28
    merge3,
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
29
    osutils,
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
30
    revision as _mod_revision,
4721.3.1 by Vincent Ladeuil
Cleanup imports.
31
    textfile,
32
    trace,
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
33
    tree as _mod_tree,
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
34
    tsort,
4721.3.1 by Vincent Ladeuil
Cleanup imports.
35
    ui,
6670.4.3 by Jelmer Vernooij
Fix more imports.
36
    workingtree,
37
    )
38
from breezy.bzr import (
7265.5.4 by Jelmer Vernooij
Fix import.
39
    generate_ids,
5246.2.15 by Andrew Bennetts
Lazy import most things in merge.py, to minimise the impact of plugins that need to import bzrlib.merge to install a hook.
40
    versionedfile,
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
41
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
42
from breezy.i18n import gettext
5246.2.15 by Andrew Bennetts
Lazy import most things in merge.py, to minimise the impact of plugins that need to import bzrlib.merge to install a hook.
43
""")
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
44
from . import (
5246.2.15 by Andrew Bennetts
Lazy import most things in merge.py, to minimise the impact of plugins that need to import bzrlib.merge to install a hook.
45
    decorators,
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
46
    errors,
5246.2.15 by Andrew Bennetts
Lazy import most things in merge.py, to minimise the impact of plugins that need to import bzrlib.merge to install a hook.
47
    hooks,
6259.3.1 by Martin Packman
Relocate merge type registry to bzrlib.merge from bzrlib.option
48
    registry,
7490.77.8 by Jelmer Vernooij
Change argument order for Transform.version_file.
49
    transform,
5246.2.15 by Andrew Bennetts
Lazy import most things in merge.py, to minimise the impact of plugins that need to import bzrlib.merge to install a hook.
50
    )
1545.2.6 by Aaron Bentley
Removed _merge, renamed MergeConflictHandler to _MergeConflictHandler
51
# TODO: Report back as changes are merged in
52
2325.3.1 by John Arbash Meinel
New helper function for merge, which allows us to re-use the existing workingtree, rather than opening it again.
53
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
54
def transform_tree(from_tree, to_tree, interesting_files=None):
7058.4.25 by Jelmer Vernooij
Use contexts.
55
    with from_tree.lock_tree_write():
56
        merge_inner(from_tree.branch, to_tree, from_tree,
7143.15.2 by Jelmer Vernooij
Run autopep8.
57
                    ignore_zero=True, this_tree=from_tree,
58
                    interesting_files=interesting_files)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
59
1457.1.12 by Robert Collins
Update comment to reflect author.
60
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
61
class MergeHooks(hooks.Hooks):
62
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
63
    def __init__(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
64
        hooks.Hooks.__init__(self, "breezy.merge", "Merger.hooks")
5622.3.2 by Jelmer Vernooij
Add more lazily usable hook points.
65
        self.add_hook('merge_file_content',
7143.15.2 by Jelmer Vernooij
Run autopep8.
66
                      "Called with a breezy.merge.Merger object to create a per file "
67
                      "merge object when starting a merge. "
68
                      "Should return either None or a subclass of "
69
                      "``breezy.merge.AbstractPerFileMerger``. "
70
                      "Such objects will then be called per file "
71
                      "that needs to be merged (including when one "
72
                      "side has deleted the file and the other has changed it). "
73
                      "See the AbstractPerFileMerger API docs for details on how it is "
74
                      "used by merge.",
75
                      (2, 1))
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
76
        self.add_hook('pre_merge',
7143.15.2 by Jelmer Vernooij
Run autopep8.
77
                      'Called before a merge. '
78
                      'Receives a Merger object as the single argument.',
79
                      (2, 5))
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
80
        self.add_hook('post_merge',
7143.15.2 by Jelmer Vernooij
Run autopep8.
81
                      'Called after a merge. '
82
                      'Receives a Merger object as the single argument. '
83
                      'The return value is ignored.',
84
                      (2, 5))
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
85
86
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
87
class AbstractPerFileMerger(object):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
88
    """PerFileMerger objects are used by plugins extending merge for breezy.
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
89
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
90
    See ``breezy.plugins.news_merge.news_merge`` for an example concrete class.
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
91
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
92
    :ivar merger: The Merge3Merger performing the merge.
93
    """
94
95
    def __init__(self, merger):
96
        """Create a PerFileMerger for use with merger."""
97
        self.merger = merger
98
99
    def merge_contents(self, merge_params):
100
        """Attempt to merge the contents of a single file.
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
101
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
102
        :param merge_params: A breezy.merge.MergeFileHookParams
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
103
        :return: A tuple of (status, chunks), where status is one of
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
104
            'not_applicable', 'success', 'conflicted', or 'delete'.  If status
105
            is 'success' or 'conflicted', then chunks should be an iterable of
106
            strings for the new file contents.
107
        """
108
        return ('not applicable', None)
109
110
5168.2.2 by Andrew Bennetts
Create a PerFileMerger helper class that is midway between AbstractPerFileMerger and ConfigurableFileMerger. It allows the example merge plugin in the docs (the always conflict *.xml files) to be much, much simpler.
111
class PerFileMerger(AbstractPerFileMerger):
112
    """Merge individual files when self.file_matches returns True.
113
114
    This class is intended to be subclassed.  The file_matches and
115
    merge_matching methods should be overridden with concrete implementations.
116
    """
117
118
    def file_matches(self, params):
119
        """Return True if merge_matching should be called on this file.
120
121
        Only called with merges of plain files with no clear winner.
122
123
        Subclasses must override this.
124
        """
125
        raise NotImplementedError(self.file_matches)
126
127
    def merge_contents(self, params):
128
        """Merge the contents of a single file."""
129
        # Check whether this custom merge logic should be used.
130
        if (
131
            # OTHER is a straight winner, rely on default merge.
132
            params.winner == 'other' or
133
            # THIS and OTHER aren't both files.
134
            not params.is_file_merge() or
6282.3.1 by Vincent Ladeuil
First cut at a working plugin to avoid conflicts in .po files by shelling out to msgmerge.
135
            # The filename doesn't match
7143.15.2 by Jelmer Vernooij
Run autopep8.
136
                not self.file_matches(params)):
5168.2.2 by Andrew Bennetts
Create a PerFileMerger helper class that is midway between AbstractPerFileMerger and ConfigurableFileMerger. It allows the example merge plugin in the docs (the always conflict *.xml files) to be much, much simpler.
137
            return 'not_applicable', None
5168.2.3 by Andrew Bennetts
Change implementation of get_filename as suggested by John.
138
        return self.merge_matching(params)
5168.2.2 by Andrew Bennetts
Create a PerFileMerger helper class that is midway between AbstractPerFileMerger and ConfigurableFileMerger. It allows the example merge plugin in the docs (the always conflict *.xml files) to be much, much simpler.
139
140
    def merge_matching(self, params):
141
        """Merge the contents of a single file that has matched the criteria
142
        in PerFileMerger.merge_contents (is a conflict, is a file,
143
        self.file_matches is True).
144
145
        Subclasses must override this.
146
        """
147
        raise NotImplementedError(self.merge_matching)
148
149
150
class ConfigurableFileMerger(PerFileMerger):
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
151
    """Merge individual files when configured via a .conf file.
152
153
    This is a base class for concrete custom file merging logic. Concrete
154
    classes should implement ``merge_text``.
155
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
156
    See ``breezy.plugins.news_merge.news_merge`` for an example concrete class.
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
157
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
158
    :ivar affected_files: The configured file paths to merge.
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
159
4797.5.3 by Robert Collins
Tweak ConfigurableFileMerger to use class variables rather than requiring __init__ wrapping as future proofing for helper functions.
160
    :cvar name_prefix: The prefix to use when looking up configuration
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
161
        details. <name_prefix>_merge_files describes the files targeted by the
162
        hook for example.
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
163
4797.5.3 by Robert Collins
Tweak ConfigurableFileMerger to use class variables rather than requiring __init__ wrapping as future proofing for helper functions.
164
    :cvar default_files: The default file paths to merge when no configuration
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
165
        is present.
166
    """
167
4797.5.3 by Robert Collins
Tweak ConfigurableFileMerger to use class variables rather than requiring __init__ wrapping as future proofing for helper functions.
168
    name_prefix = None
169
    default_files = None
170
171
    def __init__(self, merger):
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
172
        super(ConfigurableFileMerger, self).__init__(merger)
173
        self.affected_files = None
4797.5.3 by Robert Collins
Tweak ConfigurableFileMerger to use class variables rather than requiring __init__ wrapping as future proofing for helper functions.
174
        self.default_files = self.__class__.default_files or []
175
        self.name_prefix = self.__class__.name_prefix
176
        if self.name_prefix is None:
177
            raise ValueError("name_prefix must be set.")
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
178
5168.2.2 by Andrew Bennetts
Create a PerFileMerger helper class that is midway between AbstractPerFileMerger and ConfigurableFileMerger. It allows the example merge plugin in the docs (the always conflict *.xml files) to be much, much simpler.
179
    def file_matches(self, params):
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
180
        """Check whether the file should call the merge hook.
181
182
        <name_prefix>_merge_files configuration variable is a list of files
183
        that should use the hook.
184
        """
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
185
        affected_files = self.affected_files
186
        if affected_files is None:
4797.21.1 by Aaron Bentley
Fix merge when this_tree is not a WorkingTree.
187
            config = self.merger.this_branch.get_config()
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
188
            # Until bzr provides a better policy for caching the config, we
189
            # just add the part we're interested in to the params to avoid
6740.1.1 by Jelmer Vernooij
Rename bazaar.conf to breezy.conf.
190
            # reading the config files repeatedly (breezy.conf, location.conf,
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
191
            # branch.conf).
192
            config_key = self.name_prefix + '_merge_files'
193
            affected_files = config.get_user_option_as_list(config_key)
194
            if affected_files is None:
195
                # If nothing was specified in the config, use the default.
196
                affected_files = self.default_files
197
            self.affected_files = affected_files
198
        if affected_files:
6883.10.1 by Jelmer Vernooij
Fix more tets.
199
            filepath = params.this_path
5168.2.2 by Andrew Bennetts
Create a PerFileMerger helper class that is midway between AbstractPerFileMerger and ConfigurableFileMerger. It allows the example merge plugin in the docs (the always conflict *.xml files) to be much, much simpler.
200
            if filepath in affected_files:
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
201
                return True
202
        return False
203
5168.2.2 by Andrew Bennetts
Create a PerFileMerger helper class that is midway between AbstractPerFileMerger and ConfigurableFileMerger. It allows the example merge plugin in the docs (the always conflict *.xml files) to be much, much simpler.
204
    def merge_matching(self, params):
4797.9.1 by Vincent Ladeuil
No test was exercising the faulty code path.
205
        return self.merge_text(params)
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
206
207
    def merge_text(self, params):
208
        """Merge the byte contents of a single file.
209
210
        This is called after checking that the merge should be performed in
211
        merge_contents, and it should behave as per
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
212
        ``breezy.merge.AbstractPerFileMerger.merge_contents``.
4797.5.2 by Robert Collins
Refactor NewsMerger into a reusable base class merge.ConfigurableFileMerger.
213
        """
214
        raise NotImplementedError(self.merge_text)
215
216
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
217
class MergeFileHookParams(object):
4869.3.11 by Andrew Bennetts
More docs.
218
    """Object holding parameters passed to merge_file_content hooks.
219
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
220
    There are some fields hooks can access:
4869.3.11 by Andrew Bennetts
More docs.
221
6883.10.1 by Jelmer Vernooij
Fix more tets.
222
    :ivar base_path: Path in base tree
223
    :ivar other_path: Path in other tree
224
    :ivar this_path: Path in this tree
4869.3.24 by Andrew Bennetts
Mention 'winner' attribute in MergeHookParams' docstring.
225
    :ivar trans_id: the transform ID for the merge of this file
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
226
    :ivar this_kind: kind of file in 'this' tree
227
    :ivar other_kind: kind of file in 'other' tree
4869.3.24 by Andrew Bennetts
Mention 'winner' attribute in MergeHookParams' docstring.
228
    :ivar winner: one of 'this', 'other', 'conflict'
4869.3.11 by Andrew Bennetts
More docs.
229
    """
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
230
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
231
    def __init__(self, merger, paths, trans_id, this_kind, other_kind,
7143.15.2 by Jelmer Vernooij
Run autopep8.
232
                 winner):
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
233
        self._merger = merger
6883.10.1 by Jelmer Vernooij
Fix more tets.
234
        self.paths = paths
235
        self.base_path, self.other_path, self.this_path = paths
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
236
        self.trans_id = trans_id
4869.3.21 by Andrew Bennetts
Pass kinds (not pairs) to MergeHookParams.
237
        self.this_kind = this_kind
238
        self.other_kind = other_kind
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
239
        self.winner = winner
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
240
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
241
    def is_file_merge(self):
4869.3.21 by Andrew Bennetts
Pass kinds (not pairs) to MergeHookParams.
242
        """True if this_kind and other_kind are both 'file'."""
243
        return self.this_kind == 'file' and self.other_kind == 'file'
4869.3.34 by Vincent Ladeuil
Finish the patch based on reviews.
244
4869.3.13 by Andrew Bennetts
Add simple cachedproperty decorator, and add {this,other,base}_lines cachedproperties to MergeHookParams.
245
    @decorators.cachedproperty
246
    def base_lines(self):
247
        """The lines of the 'base' version of the file."""
7192.5.1 by Jelmer Vernooij
Remove more file ids.
248
        return self._merger.get_lines(self._merger.base_tree, self.base_path)
4869.3.13 by Andrew Bennetts
Add simple cachedproperty decorator, and add {this,other,base}_lines cachedproperties to MergeHookParams.
249
250
    @decorators.cachedproperty
251
    def this_lines(self):
252
        """The lines of the 'this' version of the file."""
7192.5.1 by Jelmer Vernooij
Remove more file ids.
253
        return self._merger.get_lines(self._merger.this_tree, self.this_path)
4869.3.13 by Andrew Bennetts
Add simple cachedproperty decorator, and add {this,other,base}_lines cachedproperties to MergeHookParams.
254
255
    @decorators.cachedproperty
256
    def other_lines(self):
257
        """The lines of the 'other' version of the file."""
7192.5.1 by Jelmer Vernooij
Remove more file ids.
258
        return self._merger.get_lines(self._merger.other_tree, self.other_path)
4869.3.13 by Andrew Bennetts
Add simple cachedproperty decorator, and add {this,other,base}_lines cachedproperties to MergeHookParams.
259
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
260
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
261
class Merger(object):
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
262
5622.3.10 by Jelmer Vernooij
Don't require arguments to hooks.
263
    hooks = MergeHooks()
4869.3.1 by Andrew Bennetts
Basic per-file merge hook.
264
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
265
    def __init__(self, this_branch, other_tree=None, base_tree=None,
6719.1.1 by Jelmer Vernooij
Remove some more deprecated stuff.
266
                 this_tree=None, change_reporter=None,
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
267
                 recurse='down', revision_graph=None):
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
268
        object.__init__(self)
269
        self.this_branch = this_branch
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
270
        self.this_basis = _mod_revision.ensure_null(
271
            this_branch.last_revision())
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
272
        self.this_rev_id = None
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
273
        self.this_tree = this_tree
1185.12.83 by Aaron Bentley
Preliminary weave merge support
274
        self.this_revision_tree = None
1185.35.5 by Aaron Bentley
Made weave merge succeed if interesting files match history
275
        self.this_basis_tree = None
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
276
        self.other_tree = other_tree
2100.3.29 by Aaron Bentley
Get merge working initially
277
        self.other_branch = None
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
278
        self.base_tree = base_tree
279
        self.ignore_zero = False
280
        self.backup_files = False
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
281
        self.interesting_files = None
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
282
        self.show_base = False
1185.24.3 by Aaron Bentley
Integrated reprocessing into the rest of the merge stuff
283
        self.reprocess = False
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
284
        self.pp = None
2100.3.29 by Aaron Bentley
Get merge working initially
285
        self.recurse = recurse
1551.11.9 by Aaron Bentley
Apply change reporting to merge
286
        self.change_reporter = change_reporter
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
287
        self._cached_trees = {}
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
288
        self._revision_graph = revision_graph
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
289
        self._base_is_ancestor = None
290
        self._base_is_other_ancestor = None
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
291
        self._is_criss_cross = None
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
292
        self._lca_trees = None
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
293
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
294
    def cache_trees_with_revision_ids(self, trees):
295
        """Cache any tree in trees if it has a revision_id."""
296
        for maybe_tree in trees:
297
            if maybe_tree is None:
298
                continue
299
            try:
300
                rev_id = maybe_tree.get_revision_id()
301
            except AttributeError:
302
                continue
303
            self._cached_trees[rev_id] = maybe_tree
304
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
305
    @property
306
    def revision_graph(self):
307
        if self._revision_graph is None:
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
308
            self._revision_graph = self.this_branch.repository.get_graph()
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
309
        return self._revision_graph
310
311
    def _set_base_is_ancestor(self, value):
312
        self._base_is_ancestor = value
313
314
    def _get_base_is_ancestor(self):
315
        if self._base_is_ancestor is None:
316
            self._base_is_ancestor = self.revision_graph.is_ancestor(
317
                self.base_rev_id, self.this_basis)
318
        return self._base_is_ancestor
319
320
    base_is_ancestor = property(_get_base_is_ancestor, _set_base_is_ancestor)
321
322
    def _set_base_is_other_ancestor(self, value):
323
        self._base_is_other_ancestor = value
324
325
    def _get_base_is_other_ancestor(self):
326
        if self._base_is_other_ancestor is None:
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
327
            if self.other_basis is None:
328
                return True
329
            self._base_is_other_ancestor = self.revision_graph.is_ancestor(
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
330
                self.base_rev_id, self.other_basis)
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
331
        return self._base_is_other_ancestor
332
333
    base_is_other_ancestor = property(_get_base_is_other_ancestor,
334
                                      _set_base_is_other_ancestor)
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
335
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
336
    @staticmethod
6719.1.2 by Jelmer Vernooij
Fix some tests.
337
    def from_uncommitted(tree, other_tree, base_tree=None):
1551.15.74 by Aaron Bentley
Textual updates from review
338
        """Return a Merger for uncommitted changes in other_tree.
339
340
        :param tree: The tree to merge into
341
        :param other_tree: The tree to get uncommitted changes from
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
342
        :param base_tree: The basis to use for the merge.  If unspecified,
343
            other_tree.basis_tree() will be used.
1551.15.74 by Aaron Bentley
Textual updates from review
344
        """
3363.17.17 by Aaron Bentley
Start testing merging PreviewTree as OTHER
345
        if base_tree is None:
346
            base_tree = other_tree.basis_tree()
6719.1.2 by Jelmer Vernooij
Fix some tests.
347
        merger = Merger(tree.branch, other_tree, base_tree, tree)
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
348
        merger.base_rev_id = merger.base_tree.get_revision_id()
349
        merger.other_rev_id = None
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
350
        merger.other_basis = merger.base_rev_id
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
351
        return merger
352
353
    @classmethod
6719.1.2 by Jelmer Vernooij
Fix some tests.
354
    def from_mergeable(klass, tree, mergeable):
1551.15.74 by Aaron Bentley
Textual updates from review
355
        """Return a Merger for a bundle or merge directive.
356
357
        :param tree: The tree to merge changes into
358
        :param mergeable: A merge directive or bundle
359
        """
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
360
        mergeable.install_revisions(tree.branch.repository)
361
        base_revision_id, other_revision_id, verified =\
362
            mergeable.get_merge_request(tree.branch.repository)
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
363
        revision_graph = tree.branch.repository.get_graph()
1551.19.44 by Aaron Bentley
Fix handling of old merge directives with stricter get_parent_map
364
        if base_revision_id is not None:
365
            if (base_revision_id != _mod_revision.NULL_REVISION and
366
                revision_graph.is_ancestor(
7143.15.2 by Jelmer Vernooij
Run autopep8.
367
                    base_revision_id, tree.branch.last_revision())):
1551.19.44 by Aaron Bentley
Fix handling of old merge directives with stricter get_parent_map
368
                base_revision_id = None
369
            else:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
370
                trace.warning('Performing cherrypick')
6719.1.2 by Jelmer Vernooij
Fix some tests.
371
        merger = klass.from_revision_ids(tree, other_revision_id,
7143.15.2 by Jelmer Vernooij
Run autopep8.
372
                                         base_revision_id, revision_graph=revision_graph)
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
373
        return merger, verified
374
375
    @staticmethod
6719.1.2 by Jelmer Vernooij
Fix some tests.
376
    def from_revision_ids(tree, other, base=None, other_branch=None,
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
377
                          base_branch=None, revision_graph=None,
378
                          tree_branch=None):
1551.15.74 by Aaron Bentley
Textual updates from review
379
        """Return a Merger for revision-ids.
380
381
        :param tree: The tree to merge changes into
382
        :param other: The revision-id to use as OTHER
383
        :param base: The revision-id to use as BASE.  If not specified, will
384
            be auto-selected.
385
        :param other_branch: A branch containing the other revision-id.  If
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
386
            not supplied, tree.branch is used.
1551.15.74 by Aaron Bentley
Textual updates from review
387
        :param base_branch: A branch containing the base revision-id.  If
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
388
            not supplied, other_branch or tree.branch will be used.
389
        :param revision_graph: If you have a revision_graph precomputed, pass
390
            it in, otherwise it will be created for you.
3363.17.15 by Aaron Bentley
Update docs
391
        :param tree_branch: The branch associated with tree.  If not supplied,
392
            tree.branch will be used.
1551.15.74 by Aaron Bentley
Textual updates from review
393
        """
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
394
        if tree_branch is None:
395
            tree_branch = tree.branch
6719.1.2 by Jelmer Vernooij
Fix some tests.
396
        merger = Merger(tree_branch, this_tree=tree,
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
397
                        revision_graph=revision_graph)
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
398
        if other_branch is None:
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
399
            other_branch = tree.branch
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
400
        merger.set_other_revision(other, other_branch)
401
        if base is None:
402
            merger.find_base()
403
        else:
404
            if base_branch is None:
405
                base_branch = other_branch
406
            merger.set_base_revision(base, base_branch)
407
        return merger
408
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
409
    def revision_tree(self, revision_id, branch=None):
410
        if revision_id not in self._cached_trees:
411
            if branch is None:
412
                branch = self.this_branch
413
            try:
414
                tree = self.this_tree.revision_tree(revision_id)
415
            except errors.NoSuchRevisionInTree:
416
                tree = branch.repository.revision_tree(revision_id)
417
            self._cached_trees[revision_id] = tree
418
        return self._cached_trees[revision_id]
419
2485.8.58 by Vincent Ladeuil
merge bzr.dev@1617
420
    def _get_tree(self, treespec, possible_transports=None):
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
421
        location, revno = treespec
422
        if revno is None:
423
            tree = workingtree.WorkingTree.open_containing(location)[0]
424
            return tree.branch, tree
4721.3.1 by Vincent Ladeuil
Cleanup imports.
425
        branch = _mod_branch.Branch.open_containing(
426
            location, possible_transports)[0]
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
427
        if revno == -1:
428
            revision_id = branch.last_revision()
429
        else:
430
            revision_id = branch.get_rev_id(revno)
4721.3.1 by Vincent Ladeuil
Cleanup imports.
431
        revision_id = _mod_revision.ensure_null(revision_id)
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
432
        return branch, self.revision_tree(revision_id, branch)
1185.12.83 by Aaron Bentley
Preliminary weave merge support
433
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
434
    def set_interesting_files(self, file_list):
2590.2.7 by Aaron Bentley
Misc cleanup
435
        self.interesting_files = file_list
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
436
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
437
    def set_pending(self):
4721.3.2 by Vincent Ladeuil
Simplify mutable_tree.has_changes() and update call sites.
438
        if (not self.base_is_ancestor or not self.base_is_other_ancestor
7143.15.2 by Jelmer Vernooij
Run autopep8.
439
                or self.other_rev_id is None):
1185.12.77 by Aaron Bentley
Prevented all ancestors from being marked as pending merges
440
            return
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
441
        self._add_parent()
442
443
    def _add_parent(self):
444
        new_parents = self.this_tree.get_parent_ids() + [self.other_rev_id]
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
445
        new_parent_trees = []
7479.2.1 by Jelmer Vernooij
Drop python2 support.
446
        with contextlib.ExitStack() as stack:
7356.1.1 by Jelmer Vernooij
Use ExitStack context rather than brz-specific OperationWithCleanup.
447
            for revision_id in new_parents:
448
                try:
449
                    tree = self.revision_tree(revision_id)
450
                except errors.NoSuchRevision:
451
                    tree = None
452
                else:
453
                    stack.enter_context(tree.lock_read())
454
                new_parent_trees.append((revision_id, tree))
455
            self.this_tree.set_parent_trees(new_parent_trees, allow_leftmost_as_ghost=True)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
456
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
457
    def set_other(self, other_revision, possible_transports=None):
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
458
        """Set the revision and tree to merge from.
459
460
        This sets the other_tree, other_rev_id, other_basis attributes.
461
462
        :param other_revision: The [path, revision] list to merge from.
463
        """
2485.8.58 by Vincent Ladeuil
merge bzr.dev@1617
464
        self.other_branch, self.other_tree = self._get_tree(other_revision,
465
                                                            possible_transports)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
466
        if other_revision[1] == -1:
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
467
            self.other_rev_id = _mod_revision.ensure_null(
468
                self.other_branch.last_revision())
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
469
            if _mod_revision.is_null(self.other_rev_id):
4721.3.1 by Vincent Ladeuil
Cleanup imports.
470
                raise errors.NoCommits(self.other_branch)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
471
            self.other_basis = self.other_rev_id
472
        elif other_revision[1] is not None:
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
473
            self.other_rev_id = self.other_branch.get_rev_id(other_revision[1])
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
474
            self.other_basis = self.other_rev_id
475
        else:
476
            self.other_rev_id = None
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
477
            self.other_basis = self.other_branch.last_revision()
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
478
            if self.other_basis is None:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
479
                raise errors.NoCommits(self.other_branch)
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
480
        if self.other_rev_id is not None:
481
            self._cached_trees[self.other_rev_id] = self.other_tree
7143.15.2 by Jelmer Vernooij
Run autopep8.
482
        self._maybe_fetch(self.other_branch,
483
                          self.this_branch, self.other_basis)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
484
2100.3.29 by Aaron Bentley
Get merge working initially
485
    def set_other_revision(self, revision_id, other_branch):
486
        """Set 'other' based on a branch and revision id
487
488
        :param revision_id: The revision to use for a tree
489
        :param other_branch: The branch containing this tree
490
        """
491
        self.other_rev_id = revision_id
492
        self.other_branch = other_branch
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
493
        self._maybe_fetch(other_branch, self.this_branch, self.other_rev_id)
2100.3.29 by Aaron Bentley
Get merge working initially
494
        self.other_tree = self.revision_tree(revision_id)
495
        self.other_basis = revision_id
496
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
497
    def set_base_revision(self, revision_id, branch):
498
        """Set 'base' based on a branch and revision id
499
500
        :param revision_id: The revision to use for a tree
501
        :param branch: The branch containing this tree
502
        """
503
        self.base_rev_id = revision_id
504
        self.base_branch = branch
2520.4.132 by Aaron Bentley
Merge from bzr.dev
505
        self._maybe_fetch(branch, self.this_branch, revision_id)
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
506
        self.base_tree = self.revision_tree(revision_id)
2520.4.132 by Aaron Bentley
Merge from bzr.dev
507
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
508
    def _maybe_fetch(self, source, target, revision_id):
2665.5.2 by Aaron Bentley
Switch commit and merge to Repository.has_same_location
509
        if not source.repository.has_same_location(target.repository):
5741.1.9 by Jelmer Vernooij
Remove fetch_tags argument.
510
            target.fetch(source, revision_id)
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
511
1185.82.25 by Aaron Bentley
Added changeset-merging functionality
512
    def find_base(self):
4721.3.1 by Vincent Ladeuil
Cleanup imports.
513
        revisions = [_mod_revision.ensure_null(self.this_basis),
514
                     _mod_revision.ensure_null(self.other_basis)]
515
        if _mod_revision.NULL_REVISION in revisions:
516
            self.base_rev_id = _mod_revision.NULL_REVISION
3514.4.36 by John Arbash Meinel
Optimizing how we extracted multiple trees left a path that didn't create a base_tree.
517
            self.base_tree = self.revision_tree(self.base_rev_id)
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
518
            self._is_criss_cross = False
2590.2.22 by Aaron Bentley
Remove cruft
519
        else:
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
520
            lcas = self.revision_graph.find_lca(revisions[0], revisions[1])
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
521
            self._is_criss_cross = False
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
522
            if len(lcas) == 0:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
523
                self.base_rev_id = _mod_revision.NULL_REVISION
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
524
            elif len(lcas) == 1:
525
                self.base_rev_id = list(lcas)[0]
7143.15.2 by Jelmer Vernooij
Run autopep8.
526
            else:  # len(lcas) > 1
5540.1.3 by Gary van der Merwe
Make merge correctly locate a lca where there is a criss-cross merge of a new root.
527
                self._is_criss_cross = True
3514.4.23 by John Arbash Meinel
Handle when there are more than 2 LCAs while searching for the unique lca.
528
                if len(lcas) > 2:
529
                    # find_unique_lca can only handle 2 nodes, so we have to
530
                    # start back at the beginning. It is a shame to traverse
531
                    # the graph again, but better than re-implementing
532
                    # find_unique_lca.
533
                    self.base_rev_id = self.revision_graph.find_unique_lca(
7143.15.2 by Jelmer Vernooij
Run autopep8.
534
                        revisions[0], revisions[1])
3514.4.23 by John Arbash Meinel
Handle when there are more than 2 LCAs while searching for the unique lca.
535
                else:
536
                    self.base_rev_id = self.revision_graph.find_unique_lca(
7143.15.2 by Jelmer Vernooij
Run autopep8.
537
                        *lcas)
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
538
                sorted_lca_keys = self.revision_graph.find_merge_order(
5540.1.3 by Gary van der Merwe
Make merge correctly locate a lca where there is a criss-cross merge of a new root.
539
                    revisions[0], lcas)
540
                if self.base_rev_id == _mod_revision.NULL_REVISION:
541
                    self.base_rev_id = sorted_lca_keys[0]
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
542
4721.3.1 by Vincent Ladeuil
Cleanup imports.
543
            if self.base_rev_id == _mod_revision.NULL_REVISION:
544
                raise errors.UnrelatedBranches()
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
545
            if self._is_criss_cross:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
546
                trace.warning('Warning: criss-cross merge encountered.  See bzr'
547
                              ' help criss-cross.')
548
                trace.mutter('Criss-cross lcas: %r' % lcas)
5540.1.7 by Gary van der Merwe
Add mutter for when we cant find a unique lca, and what revision we used as a base_rev_id.
549
                if self.base_rev_id in lcas:
550
                    trace.mutter('Unable to find unique lca. '
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
551
                                 'Fallback %r as best option.'
552
                                 % self.base_rev_id)
5540.1.6 by Gary van der Merwe
We just need a set for this.
553
                interesting_revision_ids = set(lcas)
554
                interesting_revision_ids.add(self.base_rev_id)
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
555
                interesting_trees = dict((t.get_revision_id(), t)
7143.15.2 by Jelmer Vernooij
Run autopep8.
556
                                         for t in self.this_branch.repository.revision_trees(
557
                    interesting_revision_ids))
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
558
                self._cached_trees.update(interesting_trees)
5540.1.3 by Gary van der Merwe
Make merge correctly locate a lca where there is a criss-cross merge of a new root.
559
                if self.base_rev_id in lcas:
560
                    self.base_tree = interesting_trees[self.base_rev_id]
561
                else:
562
                    self.base_tree = interesting_trees.pop(self.base_rev_id)
3514.4.13 by John Arbash Meinel
Switch the lca_trees to be in 'find_merge_order'.
563
                self._lca_trees = [interesting_trees[key]
564
                                   for key in sorted_lca_keys]
3514.4.2 by John Arbash Meinel
Extract the lca trees and the base tree when we find a criss-cross
565
            else:
566
                self.base_tree = self.revision_tree(self.base_rev_id)
2590.2.13 by Aaron Bentley
Make find_base implement the base_finding code
567
        self.base_is_ancestor = True
2590.2.18 by Aaron Bentley
Merge is_ancestor fix
568
        self.base_is_other_ancestor = True
4721.3.1 by Vincent Ladeuil
Cleanup imports.
569
        trace.mutter('Base revid: %r' % self.base_rev_id)
1185.82.25 by Aaron Bentley
Added changeset-merging functionality
570
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
571
    def set_base(self, base_revision):
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
572
        """Set the base revision to use for the merge.
573
574
        :param base_revision: A 2-list containing a path and revision number.
575
        """
4721.3.1 by Vincent Ladeuil
Cleanup imports.
576
        trace.mutter("doing merge() with no base_revision specified")
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
577
        if base_revision == [None, None]:
2590.2.13 by Aaron Bentley
Make find_base implement the base_finding code
578
            self.find_base()
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
579
        else:
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
580
            base_branch, self.base_tree = self._get_tree(base_revision)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
581
            if base_revision[1] == -1:
582
                self.base_rev_id = base_branch.last_revision()
583
            elif base_revision[1] is None:
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
584
                self.base_rev_id = _mod_revision.NULL_REVISION
493 by Martin Pool
- Merge aaron's merge command
585
            else:
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
586
                self.base_rev_id = _mod_revision.ensure_null(
587
                    base_branch.get_rev_id(base_revision[1]))
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
588
            self._maybe_fetch(base_branch, self.this_branch, self.base_rev_id)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
589
3008.1.8 by Michael Hudson
extract merger creation into a method
590
    def make_merger(self):
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
591
        kwargs = {'working_tree': self.this_tree, 'this_tree': self.this_tree,
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
592
                  'other_tree': self.other_tree,
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
593
                  'interesting_files': self.interesting_files,
4961.2.20 by Martin Pool
Resolve conflicts with trunk
594
                  'this_branch': self.this_branch,
6410.1.1 by Jelmer Vernooij
Add other_branch argument to Merge3Merger.
595
                  'other_branch': self.other_branch,
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
596
                  'do_merge': False}
1534.7.84 by Aaron Bentley
Added reprocess support, support for varying merge types
597
        if self.merge_type.requires_base:
598
            kwargs['base_tree'] = self.base_tree
1534.7.137 by Aaron Bentley
Avoided generating a new tree for every weave merge
599
        if self.merge_type.supports_reprocess:
600
            kwargs['reprocess'] = self.reprocess
601
        elif self.reprocess:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
602
            raise errors.BzrError(
603
                "Conflict reduction is not supported for merge"
604
                " type %s." % self.merge_type)
1534.7.137 by Aaron Bentley
Avoided generating a new tree for every weave merge
605
        if self.merge_type.supports_show_base:
606
            kwargs['show_base'] = self.show_base
607
        elif self.show_base:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
608
            raise errors.BzrError("Showing base is not supported for this"
609
                                  " merge type. %s" % self.merge_type)
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
610
        if (not getattr(self.merge_type, 'supports_reverse_cherrypick', True)
7143.15.2 by Jelmer Vernooij
Run autopep8.
611
                and not self.base_is_other_ancestor):
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
612
            raise errors.CannotReverseCherrypick()
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
613
        if self.merge_type.supports_cherrypick:
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
614
            kwargs['cherrypick'] = (not self.base_is_ancestor or
615
                                    not self.base_is_other_ancestor)
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
616
        if self._is_criss_cross and getattr(self.merge_type,
617
                                            'supports_lca_trees', False):
618
            kwargs['lca_trees'] = self._lca_trees
6719.1.2 by Jelmer Vernooij
Fix some tests.
619
        return self.merge_type(change_reporter=self.change_reporter,
3008.1.8 by Michael Hudson
extract merger creation into a method
620
                               **kwargs)
621
4797.16.1 by Andrew Bennetts
Replace many try/finally blocks in merge.py with more robust OperationWithCleanups.
622
    def _do_merge_to(self):
623
        merge = self.make_merger()
4273.1.9 by Aaron Bentley
Cleanup
624
        if self.other_branch is not None:
625
            self.other_branch.update_references(self.this_branch)
6388.1.4 by Jelmer Vernooij
Fix tests.
626
        for hook in Merger.hooks['pre_merge']:
627
            hook(merge)
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
628
        merge.do_merge()
6388.1.3 by Jelmer Vernooij
Add pre and post merge hooks.
629
        for hook in Merger.hooks['post_merge']:
630
            hook(merge)
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
631
        if self.recurse == 'down':
7350.2.1 by Jelmer Vernooij
Drop file_id return value from Tree.iter_references.
632
            for relpath in self.this_tree.iter_references():
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
633
                sub_tree = self.this_tree.get_nested_tree(relpath)
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
634
                other_revision = self.other_tree.get_reference_revision(
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
635
                    relpath)
7143.15.2 by Jelmer Vernooij
Run autopep8.
636
                if other_revision == sub_tree.last_revision():
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
637
                    continue
638
                sub_merge = Merger(sub_tree.branch, this_tree=sub_tree)
639
                sub_merge.merge_type = self.merge_type
7447.3.1 by Jelmer Vernooij
Move tree reference info functions to workingtree.
640
                other_branch = self.other_tree.reference_parent(relpath)
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
641
                sub_merge.set_other_revision(other_revision, other_branch)
7391.3.2 by Jelmer Vernooij
Revert changes that will be brought in with other branch.
642
                base_tree_path = _mod_tree.find_previous_path(
643
                    self.this_tree, self.base_tree, relpath)
6809.4.1 by Jelmer Vernooij
Swap file_id and path arguments for get_reference_revision and get_nested_tree.
644
                base_revision = self.base_tree.get_reference_revision(
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
645
                    base_tree_path)
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
646
                sub_merge.base_tree = \
647
                    sub_tree.branch.repository.revision_tree(base_revision)
648
                sub_merge.base_rev_id = base_revision
649
                sub_merge.do_merge()
4797.16.1 by Andrew Bennetts
Replace many try/finally blocks in merge.py with more robust OperationWithCleanups.
650
        return merge
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
651
3008.1.8 by Michael Hudson
extract merger creation into a method
652
    def do_merge(self):
7479.2.1 by Jelmer Vernooij
Drop python2 support.
653
        with contextlib.ExitStack() as stack:
7356.1.1 by Jelmer Vernooij
Use ExitStack context rather than brz-specific OperationWithCleanup.
654
            stack.enter_context(self.this_tree.lock_tree_write())
655
            if self.base_tree is not None:
656
                stack.enter_context(self.base_tree.lock_read())
657
            if self.other_tree is not None:
658
                stack.enter_context(self.other_tree.lock_read())
659
            merge = self._do_merge_to()
1534.7.151 by Aaron Bentley
Fixed all changes applied successfully
660
        if len(merge.cooked_conflicts) == 0:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
661
            if not self.ignore_zero and not trace.is_quiet():
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
662
                trace.note(gettext("All changes applied successfully."))
1534.7.141 by Aaron Bentley
Added conflict reporting
663
        else:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
664
            trace.note(gettext("%d conflicts encountered.")
4721.3.1 by Vincent Ladeuil
Cleanup imports.
665
                       % len(merge.cooked_conflicts))
1534.7.141 by Aaron Bentley
Added conflict reporting
666
1534.7.134 by Aaron Bentley
Hid raw conflicts
667
        return len(merge.cooked_conflicts)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
668
1545.2.4 by Aaron Bentley
PEP8 fixes
669
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
670
class _InventoryNoneEntry(object):
671
    """This represents an inventory entry which *isn't there*.
672
673
    It simplifies the merging logic if we always have an InventoryEntry, even
674
    if it isn't actually present
675
    """
676
    executable = None
677
    kind = None
678
    name = None
679
    parent_id = None
680
    revision = None
681
    symlink_target = None
682
    text_sha1 = None
683
7397.2.1 by Jelmer Vernooij
Add TreeEntry.is_unmodified.
684
    def is_unmodified(self, other):
7397.2.4 by Jelmer Vernooij
Simplify.
685
        return other is self
7397.2.1 by Jelmer Vernooij
Add TreeEntry.is_unmodified.
686
7143.15.2 by Jelmer Vernooij
Run autopep8.
687
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
688
_none_entry = _InventoryNoneEntry()
689
690
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
691
class Merge3Merger(object):
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
692
    """Three-way merger that uses the merge3 text merger"""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
693
    requires_base = True
694
    supports_reprocess = True
695
    supports_show_base = True
696
    history_based = False
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
697
    supports_cherrypick = True
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
698
    supports_reverse_cherrypick = True
2590.2.7 by Aaron Bentley
Misc cleanup
699
    winner_idx = {"this": 2, "other": 1, "conflict": 1}
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
700
    supports_lca_trees = True
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
701
    requires_file_merge_plan = False
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
702
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
703
    def __init__(self, working_tree, this_tree, base_tree, other_tree,
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
704
                 reprocess=False, show_base=False,
6719.1.1 by Jelmer Vernooij
Remove some more deprecated stuff.
705
                 change_reporter=None, interesting_files=None, do_merge=True,
6410.1.1 by Jelmer Vernooij
Add other_branch argument to Merge3Merger.
706
                 cherrypick=False, lca_trees=None, this_branch=None,
707
                 other_branch=None):
2590.2.10 by Aaron Bentley
Updates from review
708
        """Initialize the merger object and perform the merge.
709
710
        :param working_tree: The working tree to apply the merge to
711
        :param this_tree: The local tree in the merge operation
712
        :param base_tree: The common tree in the merge operation
4031.3.1 by Frank Aspell
Fixing various typos
713
        :param other_tree: The other tree to merge changes from
5162.3.1 by Aaron Bentley
Fix switch/merge when a ConfigurableFileMerger is used.
714
        :param this_branch: The branch associated with this_tree.  Defaults to
715
            this_tree.branch if not supplied.
6410.1.1 by Jelmer Vernooij
Add other_branch argument to Merge3Merger.
716
        :param other_branch: The branch associated with other_tree, if any.
2590.2.10 by Aaron Bentley
Updates from review
717
        :param: reprocess If True, perform conflict-reduction processing.
718
        :param show_base: If True, show the base revision in text conflicts.
719
            (incompatible with reprocess)
720
        :param change_reporter: An object that should report changes made
721
        :param interesting_files: The tree-relative paths of files that should
722
            participate in the merge.  If these paths refer to directories,
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
723
            the contents of those directories will also be included.  If not
724
            specified, all files may participate in the
2590.2.10 by Aaron Bentley
Updates from review
725
            merge.
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
726
        :param lca_trees: Can be set to a dictionary of {revision_id:rev_tree}
727
            if the ancestry was found to include a criss-cross merge.
728
            Otherwise should be None.
2590.2.10 by Aaron Bentley
Updates from review
729
        """
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
730
        object.__init__(self)
5162.3.1 by Aaron Bentley
Fix switch/merge when a ConfigurableFileMerger is used.
731
        if this_branch is None:
732
            this_branch = this_tree.branch
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
733
        self.interesting_files = interesting_files
6410.1.2 by Jelmer Vernooij
Distinguish working tree and this tree.
734
        self.working_tree = working_tree
735
        self.this_tree = this_tree
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
736
        self.base_tree = base_tree
737
        self.other_tree = other_tree
4869.3.27 by Andrew Bennetts
Move news_merge plugin from contrib to bzrlib/plugins, change it to be enabled via a 'news_merge_files' config option, move more code out of the __init__ to minimise overhead, and add lots of docstrings, add NEWS entry.
738
        self.this_branch = this_branch
6410.1.1 by Jelmer Vernooij
Add other_branch argument to Merge3Merger.
739
        self.other_branch = other_branch
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
740
        self._raw_conflicts = []
741
        self.cooked_conflicts = []
742
        self.reprocess = reprocess
743
        self.show_base = show_base
3514.4.4 by John Arbash Meinel
Test that the lca_trees are passed down to the Merger object when appropriate.
744
        self._lca_trees = lca_trees
3514.4.37 by John Arbash Meinel
Tests pass when using _entries_lca as the default algorithm.
745
        # Uncommenting this will change the default algorithm to always use
746
        # _entries_lca. This can be useful for running the test suite and
747
        # making sure we haven't missed any corner cases.
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
748
        # if lca_trees is None:
749
        #     self._lca_trees = [self.base_tree]
1551.11.9 by Aaron Bentley
Apply change reporting to merge
750
        self.change_reporter = change_reporter
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
751
        self.cherrypick = cherrypick
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
752
        if do_merge:
753
            self.do_merge()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
754
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
755
    def do_merge(self):
7479.2.1 by Jelmer Vernooij
Drop python2 support.
756
        with contextlib.ExitStack() as stack:
7356.1.1 by Jelmer Vernooij
Use ExitStack context rather than brz-specific OperationWithCleanup.
757
            stack.enter_context(self.working_tree.lock_tree_write())
758
            stack.enter_context(self.this_tree.lock_read())
759
            stack.enter_context(self.base_tree.lock_read())
760
            stack.enter_context(self.other_tree.lock_read())
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
761
            self.tt = self.working_tree.transform()
7356.1.1 by Jelmer Vernooij
Use ExitStack context rather than brz-specific OperationWithCleanup.
762
            stack.enter_context(self.tt)
763
            self._compute_transform()
764
            results = self.tt.apply(no_conflicts=True)
765
            self.write_modified(results)
766
            try:
767
                self.working_tree.add_conflicts(self.cooked_conflicts)
768
            except errors.UnsupportedOperation:
769
                pass
1534.7.192 by Aaron Bentley
Record hashes produced by merges
770
3008.1.9 by Michael Hudson
wanton hacking that lets me write an efficient version of get_diff_as_merged
771
    def make_preview_transform(self):
7058.4.25 by Jelmer Vernooij
Use contexts.
772
        with self.base_tree.lock_read(), self.other_tree.lock_read():
7490.77.2 by Jelmer Vernooij
Split out git and bzr-specific transforms.
773
            self.tt = self.working_tree.preview_transform()
7058.4.25 by Jelmer Vernooij
Use contexts.
774
            self._compute_transform()
775
            return self.tt
3008.1.9 by Michael Hudson
wanton hacking that lets me write an efficient version of get_diff_as_merged
776
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
777
    def _compute_transform(self):
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
778
        if self._lca_trees is None:
7490.77.11 by Jelmer Vernooij
Merge lp:brz/3.1.
779
            entries = list(self._entries3())
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
780
            resolver = self._three_way
781
        else:
7490.77.11 by Jelmer Vernooij
Merge lp:brz/3.1.
782
            entries = list(self._entries_lca())
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
783
            resolver = self._lca_multi_way
6282.3.1 by Vincent Ladeuil
First cut at a working plugin to avoid conflicts in .po files by shelling out to msgmerge.
784
        # Prepare merge hooks
785
        factories = Merger.hooks['merge_file_content']
786
        # One hook for each registered one plus our default merger
787
        hooks = [factory(self) for factory in factories] + [self]
788
        self.active_hooks = [hook for hook in hooks if hook is not None]
6861.4.1 by Jelmer Vernooij
Make progress bars context managers.
789
        with ui.ui_factory.nested_progress_bar() as child_pb:
6883.10.1 by Jelmer Vernooij
Fix more tets.
790
            for num, (file_id, changed, paths3, parents3, names3,
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
791
                      executable3) in enumerate(entries):
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
792
                trans_id = self.tt.trans_id_file_id(file_id)
6282.3.1 by Vincent Ladeuil
First cut at a working plugin to avoid conflicts in .po files by shelling out to msgmerge.
793
                # Try merging each entry
794
                child_pb.update(gettext('Preparing file merge'),
795
                                num, len(entries))
7350.6.9 by Jelmer Vernooij
Fix conflict tests.
796
                self._merge_names(trans_id, file_id, paths3, parents3,
7143.15.2 by Jelmer Vernooij
Run autopep8.
797
                                  names3, resolver=resolver)
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
798
                if changed:
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
799
                    file_status = self._do_merge_contents(paths3, trans_id, file_id)
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
800
                else:
801
                    file_status = 'unmodified'
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
802
                self._merge_executable(paths3, trans_id, executable3,
7143.15.2 by Jelmer Vernooij
Run autopep8.
803
                                       file_status, resolver=resolver)
5993.2.4 by Jelmer Vernooij
Remove feature flag.
804
        self.tt.fixup_new_roots()
5246.2.33 by Andrew Bennetts
Rename _finish_transform to _finish_computing_transform.
805
        self._finish_computing_transform()
5246.2.4 by Andrew Bennetts
Remove a little bit of duplication.
806
5246.2.33 by Andrew Bennetts
Rename _finish_transform to _finish_computing_transform.
807
    def _finish_computing_transform(self):
5246.2.4 by Andrew Bennetts
Remove a little bit of duplication.
808
        """Finalize the transform and report the changes.
809
810
        This is the second half of _compute_transform.
811
        """
6861.4.1 by Jelmer Vernooij
Make progress bars context managers.
812
        with ui.ui_factory.nested_progress_bar() as child_pb:
7350.3.4 by Jelmer Vernooij
Use context managers.
813
            fs_conflicts = transform.resolve_conflicts(
814
                self.tt, child_pb,
815
                lambda t, c: transform.conflict_pass(t, c, self.other_tree))
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
816
        if self.change_reporter is not None:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
817
            from breezy import delta
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
818
            delta.report_changes(
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
819
                self.tt.iter_changes(), self.change_reporter)
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
820
        self.cook_conflicts(fs_conflicts)
821
        for conflict in self.cooked_conflicts:
6973.6.4 by Jelmer Vernooij
Avoid text_type()
822
            trace.warning('%s', conflict.describe())
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
823
2590.2.4 by Aaron Bentley
Move entry generation to a helper
824
    def _entries3(self):
2590.2.7 by Aaron Bentley
Misc cleanup
825
        """Gather data about files modified between three trees.
826
827
        Return a list of tuples of file_id, changed, parents3, names3,
828
        executable3.  changed is a boolean indicating whether the file contents
829
        or kind were changed.  parents3 is a tuple of parent ids for base,
830
        other and this.  names3 is a tuple of names for base, other and this.
831
        executable3 is a tuple of execute-bit values for base, other and this.
832
        """
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
833
        iterator = self.other_tree.iter_changes(self.base_tree,
7143.15.2 by Jelmer Vernooij
Run autopep8.
834
                                                specific_files=self.interesting_files,
835
                                                extra_trees=[self.this_tree])
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
836
        this_interesting_files = self.this_tree.find_related_paths_across_trees(
7143.15.2 by Jelmer Vernooij
Run autopep8.
837
            self.interesting_files, trees=[self.other_tree])
6883.10.1 by Jelmer Vernooij
Fix more tets.
838
        this_entries = dict(self.this_tree.iter_entries_by_dir(
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
839
                            specific_files=this_interesting_files))
7322.1.6 by Jelmer Vernooij
Use the new attributes on TreeChange.
840
        for change in iterator:
841
            if change.path[0] is not None:
7391.3.2 by Jelmer Vernooij
Revert changes that will be brought in with other branch.
842
                this_path = _mod_tree.find_previous_path(
843
                    self.base_tree, self.this_tree, change.path[0])
6883.10.1 by Jelmer Vernooij
Fix more tets.
844
            else:
7391.3.2 by Jelmer Vernooij
Revert changes that will be brought in with other branch.
845
                this_path = _mod_tree.find_previous_path(
846
                    self.other_tree, self.this_tree, change.path[1])
6883.10.2 by Jelmer Vernooij
Resolve TODO
847
            this_entry = this_entries.get(this_path)
6883.10.1 by Jelmer Vernooij
Fix more tets.
848
            if this_entry is not None:
849
                this_name = this_entry.name
850
                this_parent = this_entry.parent_id
851
                this_executable = this_entry.executable
2590.2.4 by Aaron Bentley
Move entry generation to a helper
852
            else:
853
                this_name = None
854
                this_parent = None
855
                this_executable = None
7322.1.6 by Jelmer Vernooij
Use the new attributes on TreeChange.
856
            parents3 = change.parent_id + (this_parent,)
857
            names3 = change.name + (this_name,)
858
            paths3 = change.path + (this_path, )
859
            executable3 = change.executable + (this_executable,)
7490.77.11 by Jelmer Vernooij
Merge lp:brz/3.1.
860
            yield (
7322.1.6 by Jelmer Vernooij
Use the new attributes on TreeChange.
861
                (change.file_id, change.changed_content, paths3,
862
                 parents3, names3, executable3))
2590.2.4 by Aaron Bentley
Move entry generation to a helper
863
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
864
    def _entries_lca(self):
865
        """Gather data about files modified between multiple trees.
866
867
        This compares OTHER versus all LCA trees, and for interesting entries,
868
        it then compares with THIS and BASE.
869
870
        For the multi-valued entries, the format will be (BASE, [lca1, lca2])
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
871
6883.10.1 by Jelmer Vernooij
Fix more tets.
872
        :return: [(file_id, changed, paths, parents, names, executable)], where:
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
873
874
            * file_id: Simple file_id of the entry
875
            * changed: Boolean, True if the kind or contents changed else False
6883.10.1 by Jelmer Vernooij
Fix more tets.
876
            * paths: ((base, [path, in, lcas]), path_other, path_this)
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
877
            * parents: ((base, [parent_id, in, lcas]), parent_id_other,
878
                        parent_id_this)
879
            * names:   ((base, [name, in, lcas]), name_in_other, name_in_this)
880
            * executable: ((base, [exec, in, lcas]), exec_in_other,
881
                        exec_in_this)
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
882
        """
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
883
        if self.interesting_files is not None:
884
            lookup_trees = [self.this_tree, self.base_tree]
885
            lookup_trees.extend(self._lca_trees)
886
            # I think we should include the lca trees as well
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
887
            interesting_files = self.other_tree.find_related_paths_across_trees(
7143.15.2 by Jelmer Vernooij
Run autopep8.
888
                self.interesting_files, lookup_trees)
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
889
        else:
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
890
            interesting_files = None
7296.7.1 by Jelmer Vernooij
Split out MultiWalker.
891
        from .multiwalker import MultiWalker
892
        walker = MultiWalker(self.other_tree, self._lca_trees)
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
893
7296.7.2 by Jelmer Vernooij
Avoid call to id2path.
894
        for other_path, file_id, other_ie, lca_values in walker.iter_all():
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
895
            # Is this modified at all from any of the other trees?
3514.4.15 by John Arbash Meinel
Handle when OTHER doesn't have the entry.
896
            if other_ie is None:
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
897
                other_ie = _none_entry
6883.10.1 by Jelmer Vernooij
Fix more tets.
898
                other_path = None
6883.10.3 by Jelmer Vernooij
Merge trunk.
899
            if interesting_files is not None and other_path not in interesting_files:
3514.4.24 by John Arbash Meinel
Implement support for 'interesting_files' and 'interesting_ids' for _entries_lca
900
                continue
3514.4.15 by John Arbash Meinel
Handle when OTHER doesn't have the entry.
901
3514.4.30 by John Arbash Meinel
Several updates.
902
            # If other_revision is found in any of the lcas, that means this
903
            # node is uninteresting. This is because when merging, if there are
904
            # multiple heads(), we have to create a new node. So if we didn't,
905
            # we know that the ancestry is linear, and that OTHER did not
906
            # modify anything
907
            # See doc/developers/lca_merge_resolution.txt for details
7397.2.1 by Jelmer Vernooij
Add TreeEntry.is_unmodified.
908
            # We can't use this shortcut when other_revision is None,
909
            # because it may be None because things are WorkingTrees, and
910
            # not because it is *actually* None.
911
            is_unmodified = False
912
            for lca_path, ie in lca_values:
913
                if ie is not None and other_ie.is_unmodified(ie):
914
                    is_unmodified = True
915
                    break
916
            if is_unmodified:
917
                continue
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
918
919
            lca_entries = []
6883.10.1 by Jelmer Vernooij
Fix more tets.
920
            lca_paths = []
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
921
            for lca_path, lca_ie in lca_values:
922
                if lca_ie is None:
923
                    lca_entries.append(_none_entry)
6883.10.1 by Jelmer Vernooij
Fix more tets.
924
                    lca_paths.append(None)
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
925
                else:
926
                    lca_entries.append(lca_ie)
6928.1.2 by Jelmer Vernooij
Fix path specification.
927
                    lca_paths.append(lca_path)
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
928
6883.7.12 by Jelmer Vernooij
avoid has_id.
929
            try:
7296.7.6 by Jelmer Vernooij
Avoid using inventories in merge.
930
                base_path = self.base_tree.id2path(file_id)
6883.7.12 by Jelmer Vernooij
avoid has_id.
931
            except errors.NoSuchId:
7296.7.6 by Jelmer Vernooij
Avoid using inventories in merge.
932
                base_path = None
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
933
                base_ie = _none_entry
6883.10.1 by Jelmer Vernooij
Fix more tets.
934
            else:
7296.7.6 by Jelmer Vernooij
Avoid using inventories in merge.
935
                base_ie = next(self.base_tree.iter_entries_by_dir(specific_files=[base_path]))[1]
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
936
6883.7.12 by Jelmer Vernooij
avoid has_id.
937
            try:
7296.7.6 by Jelmer Vernooij
Avoid using inventories in merge.
938
                this_path = self.this_tree.id2path(file_id)
6883.7.12 by Jelmer Vernooij
avoid has_id.
939
            except errors.NoSuchId:
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
940
                this_ie = _none_entry
6883.10.1 by Jelmer Vernooij
Fix more tets.
941
                this_path = None
942
            else:
7296.7.6 by Jelmer Vernooij
Avoid using inventories in merge.
943
                this_ie = next(self.this_tree.iter_entries_by_dir(specific_files=[this_path]))[1]
3514.4.11 by John Arbash Meinel
Handle when an entry is missing in THIS
944
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
945
            lca_kinds = []
946
            lca_parent_ids = []
947
            lca_names = []
948
            lca_executable = []
949
            for lca_ie in lca_entries:
950
                lca_kinds.append(lca_ie.kind)
951
                lca_parent_ids.append(lca_ie.parent_id)
952
                lca_names.append(lca_ie.name)
953
                lca_executable.append(lca_ie.executable)
954
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
955
            kind_winner = self._lca_multi_way(
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
956
                (base_ie.kind, lca_kinds),
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
957
                other_ie.kind, this_ie.kind)
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
958
            parent_id_winner = self._lca_multi_way(
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
959
                (base_ie.parent_id, lca_parent_ids),
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
960
                other_ie.parent_id, this_ie.parent_id)
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
961
            name_winner = self._lca_multi_way(
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
962
                (base_ie.name, lca_names),
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
963
                other_ie.name, this_ie.name)
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
964
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
965
            content_changed = True
966
            if kind_winner == 'this':
967
                # No kind change in OTHER, see if there are *any* changes
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
968
                if other_ie.kind == 'directory':
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
969
                    if parent_id_winner == 'this' and name_winner == 'this':
970
                        # No change for this directory in OTHER, skip
971
                        continue
972
                    content_changed = False
3948.1.1 by John Arbash Meinel
Fix an edge case with deleted files and criss-cross merges.
973
                elif other_ie.kind is None or other_ie.kind == 'file':
6883.10.1 by Jelmer Vernooij
Fix more tets.
974
                    def get_sha1(tree, path):
975
                        if path is None:
976
                            return None
977
                        try:
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
978
                            return tree.get_file_sha1(path)
6883.10.1 by Jelmer Vernooij
Fix more tets.
979
                        except errors.NoSuchFile:
980
                            return None
981
                    base_sha1 = get_sha1(self.base_tree, base_path)
6928.1.2 by Jelmer Vernooij
Fix path specification.
982
                    lca_sha1s = [get_sha1(tree, lca_path)
983
                                 for tree, lca_path
6883.10.1 by Jelmer Vernooij
Fix more tets.
984
                                 in zip(self._lca_trees, lca_paths)]
985
                    this_sha1 = get_sha1(self.this_tree, this_path)
986
                    other_sha1 = get_sha1(self.other_tree, other_path)
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
987
                    sha1_winner = self._lca_multi_way(
3514.4.30 by John Arbash Meinel
Several updates.
988
                        (base_sha1, lca_sha1s), other_sha1, this_sha1,
989
                        allow_overriding_lca=False)
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
990
                    exec_winner = self._lca_multi_way(
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
991
                        (base_ie.executable, lca_executable),
992
                        other_ie.executable, this_ie.executable)
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
993
                    if (parent_id_winner == 'this' and name_winner == 'this'
7143.15.2 by Jelmer Vernooij
Run autopep8.
994
                            and sha1_winner == 'this' and exec_winner == 'this'):
3514.4.22 by John Arbash Meinel
Handle executable bit changes as well.
995
                        # No kind, parent, name, exec, or content change for
996
                        # OTHER, so this node is not considered interesting
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
997
                        continue
998
                    if sha1_winner == 'this':
999
                        content_changed = False
3514.4.27 by John Arbash Meinel
A couple of symlink tests, we need to do more.
1000
                elif other_ie.kind == 'symlink':
6883.10.1 by Jelmer Vernooij
Fix more tets.
1001
                    def get_target(ie, tree, path):
3514.4.35 by John Arbash Meinel
Add a test that we only call get_symlink_target if the object should be a symlink.
1002
                        if ie.kind != 'symlink':
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
1003
                            return None
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1004
                        return tree.get_symlink_target(path)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1005
                    base_target = get_target(base_ie, self.base_tree, base_path)
1006
                    lca_targets = [get_target(ie, tree, lca_path) for ie, tree, lca_path
1007
                                   in zip(lca_entries, self._lca_trees, lca_paths)]
7143.15.2 by Jelmer Vernooij
Run autopep8.
1008
                    this_target = get_target(
1009
                        this_ie, self.this_tree, this_path)
1010
                    other_target = get_target(
1011
                        other_ie, self.other_tree, other_path)
3514.4.39 by John Arbash Meinel
Use self._lca_multi_way rather than Merge3Merger._lca_multi_way by Aaron's request.
1012
                    target_winner = self._lca_multi_way(
3514.4.34 by John Arbash Meinel
Handle symlinks properly when objects are not RevisionTrees
1013
                        (base_target, lca_targets),
1014
                        other_target, this_target)
3514.4.28 by John Arbash Meinel
More symlink tests.
1015
                    if (parent_id_winner == 'this' and name_winner == 'this'
7143.15.2 by Jelmer Vernooij
Run autopep8.
1016
                            and target_winner == 'this'):
3514.4.28 by John Arbash Meinel
More symlink tests.
1017
                        # No kind, parent, name, or symlink target change
1018
                        # not interesting
1019
                        continue
1020
                    if target_winner == 'this':
1021
                        content_changed = False
3514.4.33 by John Arbash Meinel
Implement support for 'tree-reference'.
1022
                elif other_ie.kind == 'tree-reference':
1023
                    # The 'changed' information seems to be handled at a higher
1024
                    # level. At least, _entries3 returns False for content
1025
                    # changed, even when at a new revision_id.
1026
                    content_changed = False
1027
                    if (parent_id_winner == 'this' and name_winner == 'this'):
1028
                        # Nothing interesting
1029
                        continue
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1030
                else:
1031
                    raise AssertionError('unhandled kind: %s' % other_ie.kind)
3514.4.13 by John Arbash Meinel
Switch the lca_trees to be in 'find_merge_order'.
1032
1033
            # If we have gotten this far, that means something has changed
7490.77.11 by Jelmer Vernooij
Merge lp:brz/3.1.
1034
            yield (file_id, content_changed,
6883.10.1 by Jelmer Vernooij
Fix more tets.
1035
                           ((base_path, lca_paths),
1036
                            other_path, this_path),
3514.4.20 by John Arbash Meinel
Use the _lca_multi_way to work out if there is actually a kind/parent/name/content change.
1037
                           ((base_ie.parent_id, lca_parent_ids),
1038
                            other_ie.parent_id, this_ie.parent_id),
1039
                           ((base_ie.name, lca_names),
1040
                            other_ie.name, this_ie.name),
1041
                           ((base_ie.executable, lca_executable),
1042
                            other_ie.executable, this_ie.executable)
7490.77.11 by Jelmer Vernooij
Merge lp:brz/3.1.
1043
                           )
3514.4.5 by John Arbash Meinel
Initial work on _entries_lca.
1044
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1045
    def write_modified(self, results):
6885.2.1 by Jelmer Vernooij
Add WorkingTree.supports_merge_modified.
1046
        if not self.working_tree.supports_merge_modified():
1047
            return
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1048
        modified_hashes = {}
1049
        for path in results.modified_paths:
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1050
            wt_relpath = self.working_tree.relpath(path)
7350.4.1 by Jelmer Vernooij
Use paths as keys in merge modified dictionaries.
1051
            if not self.working_tree.is_versioned(wt_relpath):
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1052
                continue
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1053
            hash = self.working_tree.get_file_sha1(wt_relpath)
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1054
            if hash is None:
1055
                continue
7350.4.1 by Jelmer Vernooij
Use paths as keys in merge modified dictionaries.
1056
            modified_hashes[wt_relpath] = hash
6885.2.1 by Jelmer Vernooij
Add WorkingTree.supports_merge_modified.
1057
        self.working_tree.set_merge_modified(modified_hashes)
1534.7.192 by Aaron Bentley
Record hashes produced by merges
1058
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1059
    @staticmethod
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1060
    def parent(entry):
1534.7.157 by Aaron Bentley
Added more docs
1061
        """Determine the parent for a file_id (used as a key method)"""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1062
        if entry is None:
1063
            return None
1064
        return entry.parent_id
1065
1066
    @staticmethod
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1067
    def name(entry):
1534.7.157 by Aaron Bentley
Added more docs
1068
        """Determine the name for a file_id (used as a key method)"""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1069
        if entry is None:
1070
            return None
1071
        return entry.name
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1072
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1073
    @staticmethod
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1074
    def contents_sha1(tree, path):
1534.7.157 by Aaron Bentley
Added more docs
1075
        """Determine the sha1 of the file contents (used as a key method)."""
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1076
        try:
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1077
            return tree.get_file_sha1(path)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1078
        except errors.NoSuchFile:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1079
            return None
1080
1081
    @staticmethod
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1082
    def executable(tree, path):
1534.7.157 by Aaron Bentley
Added more docs
1083
        """Determine the executability of a file-id (used as a key method)."""
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1084
        try:
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1085
            if tree.kind(path) != "file":
6883.10.1 by Jelmer Vernooij
Fix more tets.
1086
                return False
1087
        except errors.NoSuchFile:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1088
            return None
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1089
        return tree.is_executable(path)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1090
1091
    @staticmethod
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1092
    def kind(tree, path):
1534.7.157 by Aaron Bentley
Added more docs
1093
        """Determine the kind of a file-id (used as a key method)."""
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1094
        try:
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1095
            return tree.kind(path)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1096
        except errors.NoSuchFile:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1097
            return None
1098
1099
    @staticmethod
2590.2.8 by Aaron Bentley
Restore conflict handling changes
1100
    def _three_way(base, other, this):
1101
        if base == other:
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
1102
            # if 'base == other', either they all agree, or only 'this' has
1103
            # changed.
2590.2.8 by Aaron Bentley
Restore conflict handling changes
1104
            return 'this'
2590.2.10 by Aaron Bentley
Updates from review
1105
        elif this not in (base, other):
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
1106
            # 'this' is neither 'base' nor 'other', so both sides changed
2590.2.8 by Aaron Bentley
Restore conflict handling changes
1107
            return 'conflict'
1108
        elif this == other:
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
1109
            # "Ambiguous clean merge" -- both sides have made the same change.
2590.2.8 by Aaron Bentley
Restore conflict handling changes
1110
            return "this"
1111
        else:
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
1112
            # this == base: only other has changed.
2590.2.8 by Aaron Bentley
Restore conflict handling changes
1113
            return "other"
1114
1115
    @staticmethod
3514.4.30 by John Arbash Meinel
Several updates.
1116
    def _lca_multi_way(bases, other, this, allow_overriding_lca=True):
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1117
        """Consider LCAs when determining whether a change has occurred.
1118
1119
        If LCAS are all identical, this is the same as a _three_way comparison.
1120
1121
        :param bases: value in (BASE, [LCAS])
1122
        :param other: value in OTHER
1123
        :param this: value in THIS
3514.4.30 by John Arbash Meinel
Several updates.
1124
        :param allow_overriding_lca: If there is more than one unique lca
1125
            value, allow OTHER to override THIS if it has a new value, and
1126
            THIS only has an lca value, or vice versa. This is appropriate for
1127
            truly scalar values, not as much for non-scalars.
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1128
        :return: 'this', 'other', or 'conflict' depending on whether an entry
1129
            changed or not.
1130
        """
3948.1.7 by Vincent Ladeuil
Slight refactoring and test fixing.
1131
        # See doc/developers/lca_tree_merging.txt for details about this
3514.4.30 by John Arbash Meinel
Several updates.
1132
        # algorithm.
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1133
        if other == this:
1134
            # Either Ambiguously clean, or nothing was actually changed. We
1135
            # don't really care
1136
            return 'this'
1137
        base_val, lca_vals = bases
1138
        # Remove 'base_val' from the lca_vals, because it is not interesting
1139
        filtered_lca_vals = [lca_val for lca_val in lca_vals
7143.15.2 by Jelmer Vernooij
Run autopep8.
1140
                             if lca_val != base_val]
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1141
        if len(filtered_lca_vals) == 0:
1142
            return Merge3Merger._three_way(base_val, other, this)
3514.4.30 by John Arbash Meinel
Several updates.
1143
1144
        unique_lca_vals = set(filtered_lca_vals)
1145
        if len(unique_lca_vals) == 1:
1146
            return Merge3Merger._three_way(unique_lca_vals.pop(), other, this)
1147
1148
        if allow_overriding_lca:
1149
            if other in unique_lca_vals:
1150
                if this in unique_lca_vals:
1151
                    # Each side picked a different lca, conflict
1152
                    return 'conflict'
1153
                else:
1154
                    # This has a value which supersedes both lca values, and
1155
                    # other only has an lca value
1156
                    return 'this'
1157
            elif this in unique_lca_vals:
1158
                # OTHER has a value which supersedes both lca values, and this
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1159
                # only has an lca value
3514.4.30 by John Arbash Meinel
Several updates.
1160
                return 'other'
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1161
5128.1.1 by Vincent Ladeuil
Uncontroversial cleanups, mostly comments
1162
        # At this point, the lcas disagree, and the tip disagree
3514.4.19 by John Arbash Meinel
Add the _lca_multi_way function, and explicit tests.
1163
        return 'conflict'
1164
7350.6.9 by Jelmer Vernooij
Fix conflict tests.
1165
    def _merge_names(self, trans_id, file_id, paths, parents, names, resolver):
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
1166
        """Perform a merge on file names and parents"""
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
1167
        base_name, other_name, this_name = names
1168
        base_parent, other_parent, this_parent = parents
6883.10.1 by Jelmer Vernooij
Fix more tets.
1169
        unused_base_path, other_path, this_path = paths
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
1170
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1171
        name_winner = resolver(*names)
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
1172
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1173
        parent_id_winner = resolver(*parents)
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
1174
        if this_name is None:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1175
            if name_winner == "this":
1176
                name_winner = "other"
1177
            if parent_id_winner == "this":
1178
                parent_id_winner = "other"
1179
        if name_winner == "this" and parent_id_winner == "this":
1180
            return
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1181
        if name_winner == 'conflict' or parent_id_winner == 'conflict':
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
1182
            # Creating helpers (.OTHER or .THIS) here cause problems down the
1183
            # road if a ContentConflict needs to be created so we should not do
1184
            # that
7350.6.9 by Jelmer Vernooij
Fix conflict tests.
1185
            self._raw_conflicts.append(('path conflict', trans_id, file_id,
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1186
                                        this_parent, this_name,
1187
                                        other_parent, other_name))
6883.10.1 by Jelmer Vernooij
Fix more tets.
1188
        if other_path is None:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1189
            # it doesn't matter whether the result was 'other' or
5954.4.6 by Aaron Bentley
Updates from review.
1190
            # 'conflict'-- if it has no file id, we leave it alone.
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1191
            return
2590.2.7 by Aaron Bentley
Misc cleanup
1192
        parent_id = parents[self.winner_idx[parent_id_winner]]
5954.4.2 by Aaron Bentley
Support merging into null tree.
1193
        name = names[self.winner_idx[name_winner]]
1194
        if parent_id is not None or name is not None:
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1195
            # if we get here, name_winner and parent_winner are set to safe
1196
            # values.
5954.4.2 by Aaron Bentley
Support merging into null tree.
1197
            if parent_id is None and name is not None:
1198
                # if parent_id is None and name is non-None, current file is
1199
                # the tree root.
1200
                if names[self.winner_idx[parent_id_winner]] != '':
1201
                    raise AssertionError(
1202
                        'File looks like a root, but named %s' %
1203
                        names[self.winner_idx[parent_id_winner]])
1204
                parent_trans_id = transform.ROOT_PARENT
1205
            else:
1206
                parent_trans_id = self.tt.trans_id_file_id(parent_id)
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
1207
            self.tt.adjust_path(name, parent_trans_id, trans_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1208
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
1209
    def _do_merge_contents(self, paths, trans_id, file_id):
3874.2.10 by Vincent Ladeuil
Fix typo.
1210
        """Performs a merge on file_id contents."""
6883.10.1 by Jelmer Vernooij
Fix more tets.
1211
        def contents_pair(tree, path):
1212
            if path is None:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1213
                return (None, None)
6809.4.17 by Jelmer Vernooij
One more :)
1214
            try:
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1215
                kind = tree.kind(path)
6809.4.17 by Jelmer Vernooij
One more :)
1216
            except errors.NoSuchFile:
1217
                return (None, None)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1218
            if kind == "file":
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1219
                contents = tree.get_file_sha1(path)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1220
            elif kind == "symlink":
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1221
                contents = tree.get_symlink_target(path)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1222
            else:
1223
                contents = None
1224
            return kind, contents
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
1225
6883.10.1 by Jelmer Vernooij
Fix more tets.
1226
        base_path, other_path, this_path = paths
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1227
        # See SPOT run.  run, SPOT, run.
1228
        # So we're not QUITE repeating ourselves; we do tricky things with
1229
        # file kind...
6883.10.1 by Jelmer Vernooij
Fix more tets.
1230
        other_pair = contents_pair(self.other_tree, other_path)
1231
        this_pair = contents_pair(self.this_tree, this_path)
3955.2.1 by John Arbash Meinel
Change the workings of merge_content to be lca aware.
1232
        if self._lca_trees:
6883.10.1 by Jelmer Vernooij
Fix more tets.
1233
            (base_path, lca_paths) = base_path
1234
            base_pair = contents_pair(self.base_tree, base_path)
1235
            lca_pairs = [contents_pair(tree, path)
1236
                         for tree, path in zip(self._lca_trees, lca_paths)]
3955.2.1 by John Arbash Meinel
Change the workings of merge_content to be lca aware.
1237
            winner = self._lca_multi_way((base_pair, lca_pairs), other_pair,
1238
                                         this_pair, allow_overriding_lca=False)
1239
        else:
6883.10.1 by Jelmer Vernooij
Fix more tets.
1240
            base_pair = contents_pair(self.base_tree, base_path)
3948.1.7 by Vincent Ladeuil
Slight refactoring and test fixing.
1241
            if base_pair == other_pair:
1242
                winner = 'this'
1243
            else:
1244
                # We delayed evaluating this_pair as long as we can to avoid
1245
                # unnecessary sha1 calculation
6883.10.1 by Jelmer Vernooij
Fix more tets.
1246
                this_pair = contents_pair(self.this_tree, this_path)
3948.1.7 by Vincent Ladeuil
Slight refactoring and test fixing.
1247
                winner = self._three_way(base_pair, other_pair, this_pair)
3955.2.1 by John Arbash Meinel
Change the workings of merge_content to be lca aware.
1248
        if winner == 'this':
1249
            # No interesting changes introduced by OTHER
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1250
            return "unmodified"
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1251
        # We have a hypothetical conflict, but if we have files, then we
1252
        # can try to merge the content
6883.10.1 by Jelmer Vernooij
Fix more tets.
1253
        params = MergeFileHookParams(
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1254
            self, (base_path, other_path, this_path), trans_id, this_pair[0],
4869.3.21 by Andrew Bennetts
Pass kinds (not pairs) to MergeHookParams.
1255
            other_pair[0], winner)
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
1256
        hooks = self.active_hooks
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1257
        hook_status = 'not_applicable'
1258
        for hook in hooks:
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
1259
            hook_status, lines = hook.merge_contents(params)
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1260
            if hook_status != 'not_applicable':
1261
                # Don't try any more hooks, this one applies.
4869.3.5 by Andrew Bennetts
Hook is invoked for delete vs. change conflicts, and may choose to result in deleting the file.
1262
                break
6015.47.8 by Vincent Ladeuil
Address some points from gz's review.
1263
        # If the merge ends up replacing the content of the file, we get rid of
1264
        # it at the end of this method (this variable is used to track the
1265
        # exceptions to this rule).
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1266
        keep_this = False
4869.3.18 by Andrew Bennetts
Simplify slightly more.
1267
        result = "modified"
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1268
        if hook_status == 'not_applicable':
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1269
            # No merge hook was able to resolve the situation. Two cases exist:
1270
            # a content conflict or a duplicate one.
4869.3.18 by Andrew Bennetts
Simplify slightly more.
1271
            result = None
4869.3.17 by Andrew Bennetts
Remove contents_conflict nested function, replace last callsite with simpler form.
1272
            name = self.tt.final_name(trans_id)
1273
            parent_id = self.tt.final_parent(trans_id)
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1274
            inhibit_content_conflict = False
7143.15.2 by Jelmer Vernooij
Run autopep8.
1275
            if params.this_kind is None:  # file_id is not in THIS
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1276
                # Is the name used for a different file_id ?
6883.10.1 by Jelmer Vernooij
Fix more tets.
1277
                if self.this_tree.is_versioned(other_path):
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1278
                    # Two entries for the same path
1279
                    keep_this = True
1280
                    # versioning the merged file will trigger a duplicate
1281
                    # conflict
7490.77.8 by Jelmer Vernooij
Change argument order for Transform.version_file.
1282
                    self.tt.version_file(trans_id, file_id=file_id)
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1283
                    transform.create_from_tree(
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1284
                        self.tt, trans_id, self.other_tree,
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1285
                        other_path,
1286
                        filter_tree_path=self._get_filter_tree_path(other_path))
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1287
                    inhibit_content_conflict = True
7143.15.2 by Jelmer Vernooij
Run autopep8.
1288
            elif params.other_kind is None:  # file_id is not in OTHER
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1289
                # Is the name used for a different file_id ?
6883.10.1 by Jelmer Vernooij
Fix more tets.
1290
                if self.other_tree.is_versioned(this_path):
6015.47.5 by Vincent Ladeuil
Fix the other half by also producing a conflict but rely on merge to create the appropriate content. This covers the case where a file is modified in THIS but replaced in OTHER
1291
                    # Two entries for the same path again, but here, the other
1292
                    # entry will also be merged.  We simply inhibit the
1293
                    # 'content' conflict creation because we know OTHER will
1294
                    # create (or has already created depending on ordering) an
1295
                    # entry at the same path. This will trigger a 'duplicate'
1296
                    # conflict later.
1297
                    keep_this = True
1298
                    inhibit_content_conflict = True
1299
            if not inhibit_content_conflict:
1300
                if params.this_kind is not None:
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1301
                    self.tt.unversion_file(trans_id)
1302
                # This is a contents conflict, because none of the available
1303
                # functions could merge it.
6923.1.1 by Jelmer Vernooij
Fix regression.
1304
                file_group = self._dump_conflicts(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1305
                    name, (base_path, other_path, this_path), parent_id,
1306
                    file_id, set_version=True)
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1307
                self._raw_conflicts.append(('contents conflict', file_group))
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1308
        elif hook_status == 'success':
1309
            self.tt.create_file(lines, trans_id)
1310
        elif hook_status == 'conflicted':
1311
            # XXX: perhaps the hook should be able to provide
1312
            # the BASE/THIS/OTHER files?
1313
            self.tt.create_file(lines, trans_id)
1314
            self._raw_conflicts.append(('text conflict', trans_id))
1315
            name = self.tt.final_name(trans_id)
1316
            parent_id = self.tt.final_parent(trans_id)
6923.1.1 by Jelmer Vernooij
Fix regression.
1317
            self._dump_conflicts(
1318
                name, (base_path, other_path, this_path), parent_id, file_id)
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1319
        elif hook_status == 'delete':
1320
            self.tt.unversion_file(trans_id)
4869.3.18 by Andrew Bennetts
Simplify slightly more.
1321
            result = "deleted"
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1322
        elif hook_status == 'done':
1323
            # The hook function did whatever it needs to do directly, no
1324
            # further action needed here.
1325
            pass
1326
        else:
4869.3.18 by Andrew Bennetts
Simplify slightly more.
1327
            raise AssertionError('unknown hook_status: %r' % (hook_status,))
6883.10.1 by Jelmer Vernooij
Fix more tets.
1328
        if not this_path and result == "modified":
7490.77.8 by Jelmer Vernooij
Change argument order for Transform.version_file.
1329
            self.tt.version_file(trans_id, file_id=file_id)
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1330
        if not keep_this:
6015.47.8 by Vincent Ladeuil
Address some points from gz's review.
1331
            # The merge has been performed and produced a new content, so the
1332
            # old contents should not be retained.
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1333
            self.tt.delete_contents(trans_id)
4869.3.18 by Andrew Bennetts
Simplify slightly more.
1334
        return result
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1335
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1336
    def _default_other_winner_merge(self, merge_hook_params):
1337
        """Replace this contents with other."""
1338
        trans_id = merge_hook_params.trans_id
6883.10.1 by Jelmer Vernooij
Fix more tets.
1339
        if merge_hook_params.other_path is not None:
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1340
            # OTHER changed the file
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1341
            transform.create_from_tree(
6809.4.7 by Jelmer Vernooij
Swap arguments for get_symlink_target and kind/stored_kind.
1342
                self.tt, trans_id, self.other_tree,
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1343
                merge_hook_params.other_path,
1344
                filter_tree_path=self._get_filter_tree_path(merge_hook_params.other_path))
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1345
            return 'done', None
6883.10.1 by Jelmer Vernooij
Fix more tets.
1346
        elif merge_hook_params.this_path is not None:
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1347
            # OTHER deleted the file
1348
            return 'delete', None
1349
        else:
1350
            raise AssertionError(
7350.6.5 by Jelmer Vernooij
Fix exception.
1351
                'winner is OTHER, but file %r not in THIS or OTHER tree'
1352
                % (merge_hook_params.base_path,))
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1353
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
1354
    def merge_contents(self, merge_hook_params):
1355
        """Fallback merge logic after user installed hooks."""
1356
        # This function is used in merge hooks as the fallback instance.
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
1357
        # Perhaps making this function and the functions it calls be a
4797.5.1 by Robert Collins
Support state on per-file merging to permit more efficient use of configuration data.
1358
        # a separate class would be better.
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1359
        if merge_hook_params.winner == 'other':
1360
            # OTHER is a straight winner, so replace this contents with other
1361
            return self._default_other_winner_merge(merge_hook_params)
1362
        elif merge_hook_params.is_file_merge():
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1363
            # THIS and OTHER are both files, so text merge.  Either
1364
            # BASE is a file, or both converted to files, so at least we
1365
            # have agreement that output should be a file.
1366
            try:
6883.10.1 by Jelmer Vernooij
Fix more tets.
1367
                self.text_merge(merge_hook_params.trans_id,
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1368
                                merge_hook_params.paths)
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1369
            except errors.BinaryFile:
1370
                return 'not_applicable', None
4869.3.16 by Andrew Bennetts
Move handling of winner==OTHER case into generic hook path too.
1371
            return 'done', None
4869.3.15 by Andrew Bennetts
Refactor so that the default text merge is the final hook tried. Other hooks can now invoke it directly via merger.default_text_merge if they wish.
1372
        else:
1373
            return 'not_applicable', None
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1374
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1375
    def get_lines(self, tree, path):
1534.7.157 by Aaron Bentley
Added more docs
1376
        """Return the lines in a file, or an empty list."""
6883.10.1 by Jelmer Vernooij
Fix more tets.
1377
        if path is None:
1378
            return []
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1379
        try:
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1380
            kind = tree.kind(path)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1381
        except errors.NoSuchFile:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1382
            return []
6809.4.5 by Jelmer Vernooij
Swap arguments for get_file_*.
1383
        else:
6883.10.1 by Jelmer Vernooij
Fix more tets.
1384
            if kind != 'file':
1385
                return []
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1386
            return tree.get_file_lines(path)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1387
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1388
    def text_merge(self, trans_id, paths):
1389
        """Perform a three-way text merge on a file"""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1390
        # it's possible that we got here with base as a different type.
1391
        # if so, we just want two-way text conflicts.
6883.10.1 by Jelmer Vernooij
Fix more tets.
1392
        base_path, other_path, this_path = paths
7192.5.2 by Jelmer Vernooij
Fixes.
1393
        base_lines = self.get_lines(self.base_tree, base_path)
1394
        other_lines = self.get_lines(self.other_tree, other_path)
1395
        this_lines = self.get_lines(self.this_tree, this_path)
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1396
        m3 = merge3.Merge3(base_lines, this_lines, other_lines,
1397
                           is_cherrypick=self.cherrypick)
6973.9.1 by Jelmer Vernooij
More test fixes.
1398
        start_marker = b"!START OF MERGE CONFLICT!" + b"I HOPE THIS IS UNIQUE"
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1399
        if self.show_base is True:
7045.1.1 by Jelmer Vernooij
Fix another 300 tests.
1400
            base_marker = b'|' * 7
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1401
        else:
1402
            base_marker = None
1403
1404
        def iter_merge3(retval):
1405
            retval["text_conflicts"] = False
7143.15.2 by Jelmer Vernooij
Run autopep8.
1406
            for line in m3.merge_lines(name_a=b"TREE",
1407
                                       name_b=b"MERGE-SOURCE",
1408
                                       name_base=b"BASE-REVISION",
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1409
                                       start_marker=start_marker,
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1410
                                       base_marker=base_marker,
1411
                                       reprocess=self.reprocess):
1412
                if line.startswith(start_marker):
1413
                    retval["text_conflicts"] = True
6973.9.1 by Jelmer Vernooij
More test fixes.
1414
                    yield line.replace(start_marker, b'<' * 7)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1415
                else:
1416
                    yield line
1417
        retval = {}
1418
        merge3_iterator = iter_merge3(retval)
1419
        self.tt.create_file(merge3_iterator, trans_id)
1420
        if retval["text_conflicts"] is True:
1421
            self._raw_conflicts.append(('text conflict', trans_id))
1422
            name = self.tt.final_name(trans_id)
1423
            parent_id = self.tt.final_parent(trans_id)
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1424
            file_id = self.tt.final_file_id(trans_id)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1425
            file_group = self._dump_conflicts(name, paths, parent_id, file_id,
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1426
                                              this_lines, base_lines,
1427
                                              other_lines)
1428
            file_group.append(trans_id)
1429
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1430
    def _get_filter_tree_path(self, path):
6015.47.8 by Vincent Ladeuil
Address some points from gz's review.
1431
        if self.this_tree.supports_content_filtering():
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1432
            # We get the path from the working tree if it exists.
1433
            # That fails though when OTHER is adding a file, so
1434
            # we fall back to the other tree to find the path if
1435
            # it doesn't exist locally.
7391.3.2 by Jelmer Vernooij
Revert changes that will be brought in with other branch.
1436
            filter_path = _mod_tree.find_previous_path(
1437
                self.other_tree, self.working_tree, path)
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1438
            if filter_path is None:
1439
                filter_path = path
1440
            return filter_path
1441
        # Skip the lookup for older formats
6015.47.8 by Vincent Ladeuil
Address some points from gz's review.
1442
        return None
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1443
6883.10.1 by Jelmer Vernooij
Fix more tets.
1444
    def _dump_conflicts(self, name, paths, parent_id, file_id, this_lines=None,
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1445
                        base_lines=None, other_lines=None, set_version=False,
1446
                        no_base=False):
1534.7.157 by Aaron Bentley
Added more docs
1447
        """Emit conflict files.
1448
        If this_lines, base_lines, or other_lines are omitted, they will be
1449
        determined automatically.  If set_version is true, the .OTHER, .THIS
1450
        or .BASE (in that order) will be created as versioned files.
1451
        """
6883.10.1 by Jelmer Vernooij
Fix more tets.
1452
        base_path, other_path, this_path = paths
1453
        data = [('OTHER', self.other_tree, other_path, other_lines),
1454
                ('THIS', self.this_tree, this_path, this_lines)]
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1455
        if not no_base:
6883.10.1 by Jelmer Vernooij
Fix more tets.
1456
            data.append(('BASE', self.base_tree, base_path, base_lines))
4443.2.1 by Ian Clatworthy
apply content filters when merging new files
1457
1458
        # We need to use the actual path in the working tree of the file here,
7490.83.6 by Jelmer Vernooij
Add final_is_versioned.
1459
        if self.this_tree.supports_content_filtering():
1460
            filter_tree_path = this_path
4443.2.1 by Ian Clatworthy
apply content filters when merging new files
1461
        else:
1462
            # Skip the id2path lookup for older formats
1463
            filter_tree_path = None
1464
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1465
        versioned = False
1466
        file_group = []
6883.10.1 by Jelmer Vernooij
Fix more tets.
1467
        for suffix, tree, path, lines in data:
1468
            if path is not None:
6809.4.21 by Jelmer Vernooij
Fix long lines.
1469
                trans_id = self._conflict_file(
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1470
                    name, parent_id, path, tree, suffix, lines,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1471
                    filter_tree_path)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1472
                file_group.append(trans_id)
1473
                if set_version and not versioned:
7490.77.8 by Jelmer Vernooij
Change argument order for Transform.version_file.
1474
                    self.tt.version_file(trans_id, file_id=file_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1475
                    versioned = True
1476
        return file_group
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1477
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1478
    def _conflict_file(self, name, parent_id, path, tree, suffix,
4443.2.1 by Ian Clatworthy
apply content filters when merging new files
1479
                       lines=None, filter_tree_path=None):
1534.7.157 by Aaron Bentley
Added more docs
1480
        """Emit a single conflict file."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1481
        name = name + '.' + suffix
1482
        trans_id = self.tt.create_path(name, parent_id)
6809.4.21 by Jelmer Vernooij
Fix long lines.
1483
        transform.create_from_tree(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1484
            self.tt, trans_id, tree, path,
7350.5.1 by Jelmer Vernooij
Remove file_id from transform's create_from_tree, get filter tree paths by path.
1485
            chunks=lines,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1486
            filter_tree_path=filter_tree_path)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1487
        return trans_id
1488
7350.6.3 by Jelmer Vernooij
Remove number of file_id => trans_id lookups.
1489
    def _merge_executable(self, paths, trans_id, executable, file_status,
3514.4.40 by John Arbash Meinel
Make 'resolver' a required parameter.
1490
                          resolver):
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
1491
        """Perform a merge on the execute bit."""
1492
        base_executable, other_executable, this_executable = executable
6883.10.1 by Jelmer Vernooij
Fix more tets.
1493
        base_path, other_path, this_path = paths
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1494
        if file_status == "deleted":
1495
            return
3514.4.21 by John Arbash Meinel
Hook up the lca-way logic into the path handlers.
1496
        winner = resolver(*executable)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1497
        if winner == "conflict":
7143.15.2 by Jelmer Vernooij
Run autopep8.
1498
            # There must be a None in here, if we have a conflict, but we
1499
            # need executability since file status was not deleted.
6928.1.2 by Jelmer Vernooij
Fix path specification.
1500
            if other_path is None:
1534.7.142 by Aaron Bentley
Fixed executability conflicts
1501
                winner = "this"
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1502
            else:
1534.7.142 by Aaron Bentley
Fixed executability conflicts
1503
                winner = "other"
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
1504
        if winner == 'this' and file_status != "modified":
1505
            return
4597.9.7 by Vincent Ladeuil
transform.final_kind() now returns None instead of raising NoSuchFile.
1506
        if self.tt.final_kind(trans_id) != "file":
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
1507
            return
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1508
        if winner == "this":
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
1509
            executability = this_executable
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1510
        else:
6883.10.1 by Jelmer Vernooij
Fix more tets.
1511
            if other_path is not None:
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
1512
                executability = other_executable
6883.10.1 by Jelmer Vernooij
Fix more tets.
1513
            elif this_path is not None:
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
1514
                executability = this_executable
6883.10.1 by Jelmer Vernooij
Fix more tets.
1515
            elif base_path is not None:
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
1516
                executability = base_executable
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
1517
        if executability is not None:
1518
            self.tt.set_executability(executability, trans_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1519
1534.7.172 by Aaron Bentley
Integrated fs conflicts with merge conflicts.
1520
    def cook_conflicts(self, fs_conflicts):
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1521
        """Convert all conflicts into a form that doesn't depend on trans_id"""
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
1522
        content_conflict_file_ids = set()
1523
        cooked_conflicts = transform.cook_conflicts(fs_conflicts, self.tt)
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1524
        fp = transform.FinalPaths(self.tt)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1525
        for conflict in self._raw_conflicts:
1526
            conflict_type = conflict[0]
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1527
            if conflict_type == 'path conflict':
7350.6.9 by Jelmer Vernooij
Fix conflict tests.
1528
                (trans_id, file_id,
1529
                 this_parent, this_name,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1530
                 other_parent, other_name) = conflict[1:]
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1531
                if this_parent is None or this_name is None:
1532
                    this_path = '<deleted>'
1533
                else:
7143.15.2 by Jelmer Vernooij
Run autopep8.
1534
                    parent_path = fp.get_path(
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1535
                        self.tt.trans_id_file_id(this_parent))
1536
                    this_path = osutils.pathjoin(parent_path, this_name)
1537
                if other_parent is None or other_name is None:
1538
                    other_path = '<deleted>'
1539
                else:
7358.14.1 by Jelmer Vernooij
Remove Tree.get_root_id() in favour of Tree.path2id('').
1540
                    if other_parent == self.other_tree.path2id(''):
5050.73.9 by Vincent Ladeuil
Fix typo.
1541
                        # The tree transform doesn't know about the other root,
5050.73.8 by Vincent Ladeuil
Handle path conflicts involving different root-ids
1542
                        # so we special case here to avoid a NoFinalPath
1543
                        # exception
1544
                        parent_path = ''
1545
                    else:
7143.15.2 by Jelmer Vernooij
Run autopep8.
1546
                        parent_path = fp.get_path(
5050.73.8 by Vincent Ladeuil
Handle path conflicts involving different root-ids
1547
                            self.tt.trans_id_file_id(other_parent))
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1548
                    other_path = osutils.pathjoin(parent_path, other_name)
1549
                c = _mod_conflicts.Conflict.factory(
1550
                    'path conflict', path=this_path,
1551
                    conflict_path=other_path,
1552
                    file_id=file_id)
1553
            elif conflict_type == 'contents conflict':
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1554
                for trans_id in conflict[1]:
1555
                    file_id = self.tt.final_file_id(trans_id)
1556
                    if file_id is not None:
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1557
                        # Ok we found the relevant file-id
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1558
                        break
1559
                path = fp.get_path(trans_id)
1560
                for suffix in ('.BASE', '.THIS', '.OTHER'):
1561
                    if path.endswith(suffix):
6015.47.4 by Vincent Ladeuil
Fix first half of the bug by producing a 'duplicate' conflict instead of a 'content' one when the file has been replaced in THIS and modified in OTHER.
1562
                        # Here is the raw path
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1563
                        path = path[:-len(suffix)]
1564
                        break
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1565
                c = _mod_conflicts.Conflict.factory(conflict_type,
1566
                                                    path=path, file_id=file_id)
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
1567
                content_conflict_file_ids.add(file_id)
4597.7.11 by Vincent Ladeuil
Fix #531967 by creating helpers for PathConflicts when a deletion
1568
            elif conflict_type == 'text conflict':
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1569
                trans_id = conflict[1]
1570
                path = fp.get_path(trans_id)
1571
                file_id = self.tt.final_file_id(trans_id)
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1572
                c = _mod_conflicts.Conflict.factory(conflict_type,
1573
                                                    path=path, file_id=file_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1574
            else:
4597.7.18 by Vincent Ladeuil
Start addressing Andrew's concerns.
1575
                raise AssertionError('bad conflict type: %r' % (conflict,))
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
1576
            cooked_conflicts.append(c)
5988.2.2 by Vincent Ladeuil
Make it clear that we start from an empty cooked_conflicts list.
1577
1578
        self.cooked_conflicts = []
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
1579
        # We want to get rid of path conflicts when a corresponding contents
1580
        # conflict exists. This can occur when one branch deletes a file while
1581
        # the other renames *and* modifies it. In this case, the content
1582
        # conflict is enough.
1583
        for c in cooked_conflicts:
1584
            if (c.typestring == 'path conflict'
7143.15.2 by Jelmer Vernooij
Run autopep8.
1585
                    and c.file_id in content_conflict_file_ids):
5988.2.1 by Vincent Ladeuil
Do not generate path conflicts if a corresponding content conflict exists
1586
                continue
1534.10.19 by Aaron Bentley
Stanza conversion, cooking
1587
            self.cooked_conflicts.append(c)
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1588
        self.cooked_conflicts.sort(key=_mod_conflicts.Conflict.sort_key)
1534.7.141 by Aaron Bentley
Added conflict reporting
1589
1590
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1591
class WeaveMerger(Merge3Merger):
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
1592
    """Three-way tree merger, text weave merger."""
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
1593
    supports_reprocess = True
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1594
    supports_show_base = False
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
1595
    supports_reverse_cherrypick = False
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
1596
    history_based = True
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
1597
    requires_file_merge_plan = True
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1598
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1599
    def _generate_merge_plan(self, this_path, base):
1600
        return self.this_tree.plan_file_merge(this_path, self.other_tree,
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
1601
                                              base=base)
4634.101.7 by John Arbash Meinel
Start working on the ability to drop a .BASE file for --weave and --lca merge.
1602
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1603
    def _merged_lines(self, this_path):
4634.101.7 by John Arbash Meinel
Start working on the ability to drop a .BASE file for --weave and --lca merge.
1604
        """Generate the merged lines.
1605
        There is no distinction between lines that are meant to contain <<<<<<<
1606
        and conflicts.
1607
        """
1608
        if self.cherrypick:
1609
            base = self.base_tree
1610
        else:
1611
            base = None
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1612
        plan = self._generate_merge_plan(this_path, base)
1551.19.17 by Aaron Bentley
Add debugging flag for merges
1613
        if 'merge' in debug.debug_flags:
1614
            plan = list(plan)
1615
            trans_id = self.tt.trans_id_file_id(file_id)
1616
            name = self.tt.final_name(trans_id) + '.plan'
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1617
            contents = (b'%11s|%s' % l for l in plan)
1551.19.17 by Aaron Bentley
Add debugging flag for merges
1618
            self.tt.new_file(name, self.tt.final_parent(trans_id), contents)
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
1619
        textmerge = versionedfile.PlanWeaveMerge(plan, b'<<<<<<< TREE\n',
1620
                                                 b'>>>>>>> MERGE-SOURCE\n')
4634.101.7 by John Arbash Meinel
Start working on the ability to drop a .BASE file for --weave and --lca merge.
1621
        lines, conflicts = textmerge.merge_lines(self.reprocess)
1622
        if conflicts:
1623
            base_lines = textmerge.base_from_plan()
1624
        else:
1625
            base_lines = None
1626
        return lines, base_lines
4869.2.2 by Andrew Bennetts
Remove some duplication.
1627
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1628
    def text_merge(self, trans_id, paths):
1534.7.157 by Aaron Bentley
Added more docs
1629
        """Perform a (weave) text merge for a given file and file-id.
1630
        If conflicts are encountered, .THIS and .OTHER files will be emitted,
1631
        and a conflict will be noted.
1632
        """
6883.10.1 by Jelmer Vernooij
Fix more tets.
1633
        base_path, other_path, this_path = paths
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1634
        lines, base_lines = self._merged_lines(this_path)
1558.15.10 by Aaron Bentley
Merge bzr.dev
1635
        lines = list(lines)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1636
        # Note we're checking whether the OUTPUT is binary in this case,
1558.15.5 by Aaron Bentley
Fixed binary handling in weave merge
1637
        # because we don't want to get into weave merge guts.
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1638
        textfile.check_text_lines(lines)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1639
        self.tt.create_file(lines, trans_id)
4634.101.7 by John Arbash Meinel
Start working on the ability to drop a .BASE file for --weave and --lca merge.
1640
        if base_lines is not None:
1641
            # Conflict
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1642
            self._raw_conflicts.append(('text conflict', trans_id))
1643
            name = self.tt.final_name(trans_id)
1644
            parent_id = self.tt.final_parent(trans_id)
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1645
            file_id = self.tt.final_file_id(trans_id)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1646
            file_group = self._dump_conflicts(name, paths, parent_id, file_id,
4634.101.7 by John Arbash Meinel
Start working on the ability to drop a .BASE file for --weave and --lca merge.
1647
                                              no_base=False,
1648
                                              base_lines=base_lines)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1649
            file_group.append(trans_id)
1650
1651
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1652
class LCAMerger(WeaveMerger):
1653
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
1654
    requires_file_merge_plan = True
1655
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1656
    def _generate_merge_plan(self, this_path, base):
1657
        return self.this_tree.plan_file_lca_merge(this_path, self.other_tree,
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1658
                                                  base=base)
1659
7143.15.2 by Jelmer Vernooij
Run autopep8.
1660
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1661
class Diff3Merger(Merge3Merger):
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
1662
    """Three-way merger using external diff3 for text merging"""
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1663
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
1664
    requires_file_merge_plan = False
1665
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1666
    def dump_file(self, temp_dir, name, tree, path):
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1667
        out_path = osutils.pathjoin(temp_dir, name)
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
1668
        with open(out_path, "wb") as out_file:
7141.7.1 by Jelmer Vernooij
Get rid of file_ids in most of Tree.
1669
            in_file = tree.get_file(path)
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1670
            for line in in_file:
1671
                out_file.write(line)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1672
        return out_path
1673
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1674
    def text_merge(self, trans_id, paths):
1534.7.157 by Aaron Bentley
Added more docs
1675
        """Perform a diff3 merge using a specified file-id and trans-id.
1676
        If conflicts are encountered, .BASE, .THIS. and .OTHER conflict files
1677
        will be dumped, and a will be conflict noted.
1678
        """
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1679
        import breezy.patch
6883.10.1 by Jelmer Vernooij
Fix more tets.
1680
        base_path, other_path, this_path = paths
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
1681
        temp_dir = osutils.mkdtemp(prefix="bzr-")
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1682
        try:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1683
            new_file = osutils.pathjoin(temp_dir, "new")
7143.15.2 by Jelmer Vernooij
Run autopep8.
1684
            this = self.dump_file(
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1685
                temp_dir, "this", self.this_tree, this_path)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1686
            base = self.dump_file(
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1687
                temp_dir, "base", self.base_tree, base_path)
7143.15.2 by Jelmer Vernooij
Run autopep8.
1688
            other = self.dump_file(
7192.5.1 by Jelmer Vernooij
Remove more file ids.
1689
                temp_dir, "other", self.other_tree, other_path)
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1690
            status = breezy.patch.diff3(new_file, this, base, other)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1691
            if status not in (0, 1):
4721.3.1 by Vincent Ladeuil
Cleanup imports.
1692
                raise errors.BzrError("Unhandled diff3 exit code")
6861.2.1 by Jelmer Vernooij
vf Move file planning to breezy.bzr.inventorytree.
1693
            with open(new_file, 'rb') as f:
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1694
                self.tt.create_file(f, trans_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1695
            if status == 1:
1696
                name = self.tt.final_name(trans_id)
1697
                parent_id = self.tt.final_parent(trans_id)
7350.6.4 by Jelmer Vernooij
Drop file_id attribute from MergeHookParams and Tree.plan_file_merge.
1698
                file_id = self.tt.final_file_id(trans_id)
6883.10.1 by Jelmer Vernooij
Fix more tets.
1699
                self._dump_conflicts(name, paths, parent_id, file_id)
1551.8.39 by Aaron Bentley
Fix diff3 conflict-reporting bug
1700
                self._raw_conflicts.append(('text conflict', trans_id))
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1701
        finally:
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
1702
            osutils.rmtree(temp_dir)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1703
1704
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1705
class PathNotInTree(errors.BzrError):
1706
5246.2.28 by Andrew Bennetts
Improve some docstrings.
1707
    _fmt = """Merge-into failed because %(tree)s does not contain %(path)s."""
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1708
5246.2.23 by Andrew Bennetts
Fix XXX by adding a test for that case, and don't use AssertionError for a legitimate user error.
1709
    def __init__(self, path, tree):
1710
        errors.BzrError.__init__(self, path=path, tree=tree)
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1711
1712
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1713
class MergeIntoMerger(Merger):
1714
    """Merger that understands other_tree will be merged into a subdir.
1715
1716
    This also changes the Merger api so that it uses real Branch, revision_id,
1717
    and RevisonTree objects, rather than using revision specs.
1718
    """
1719
1720
    def __init__(self, this_tree, other_branch, other_tree, target_subdir,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1721
                 source_subpath, other_rev_id=None):
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1722
        """Create a new MergeIntoMerger object.
1723
5246.2.6 by Andrew Bennetts
Improve some docstrings. Simplify code slightly.
1724
        source_subpath in other_tree will be effectively copied to
1725
        target_subdir in this_tree.
1726
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1727
        :param this_tree: The tree that we will be merging into.
1728
        :param other_branch: The Branch we will be merging from.
1729
        :param other_tree: The RevisionTree object we want to merge.
1730
        :param target_subdir: The relative path where we want to merge
1731
            other_tree into this_tree
5246.2.6 by Andrew Bennetts
Improve some docstrings. Simplify code slightly.
1732
        :param source_subpath: The relative path specifying the subtree of
1733
            other_tree to merge into this_tree.
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1734
        """
1735
        # It is assumed that we are merging a tree that is not in our current
1736
        # ancestry, which means we are using the "EmptyTree" as our basis.
1737
        null_ancestor_tree = this_tree.branch.repository.revision_tree(
7143.15.2 by Jelmer Vernooij
Run autopep8.
1738
            _mod_revision.NULL_REVISION)
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1739
        super(MergeIntoMerger, self).__init__(
1740
            this_branch=this_tree.branch,
1741
            this_tree=this_tree,
1742
            other_tree=other_tree,
1743
            base_tree=null_ancestor_tree,
1744
            )
1745
        self._target_subdir = target_subdir
1746
        self._source_subpath = source_subpath
1747
        self.other_branch = other_branch
5246.2.22 by Andrew Bennetts
Minor tweaks.
1748
        if other_rev_id is None:
1749
            other_rev_id = other_tree.get_revision_id()
1750
        self.other_rev_id = self.other_basis = other_rev_id
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1751
        self.base_is_ancestor = True
1752
        self.backup_files = True
1753
        self.merge_type = Merge3Merger
1754
        self.show_base = False
1755
        self.reprocess = False
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
1756
        self.interesting_files = None
5246.2.32 by Andrew Bennetts
Rename _Wrapper to _MergeTypeParameterizer.
1757
        self.merge_type = _MergeTypeParameterizer(MergeIntoMergeType,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1758
                                                  target_subdir=self._target_subdir,
1759
                                                  source_subpath=self._source_subpath)
5246.2.11 by Andrew Bennetts
Handle partial tree merges, add more tests, refactor tests a little.
1760
        if self._source_subpath != '':
1761
            # If this isn't a partial merge make sure the revisions will be
1762
            # present.
1763
            self._maybe_fetch(self.other_branch, self.this_branch,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1764
                              self.other_basis)
5246.2.11 by Andrew Bennetts
Handle partial tree merges, add more tests, refactor tests a little.
1765
1766
    def set_pending(self):
1767
        if self._source_subpath != '':
1768
            return
1769
        Merger.set_pending(self)
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1770
1771
5246.2.32 by Andrew Bennetts
Rename _Wrapper to _MergeTypeParameterizer.
1772
class _MergeTypeParameterizer(object):
5246.2.29 by Andrew Bennetts
Improve some docstrings.
1773
    """Wrap a merge-type class to provide extra parameters.
6861.2.3 by Jelmer Vernooij
Mark which merge types require plan_file_merge.
1774
5246.2.29 by Andrew Bennetts
Improve some docstrings.
1775
    This is hack used by MergeIntoMerger to pass some extra parameters to its
1776
    merge_type.  Merger.do_merge() sets up its own set of parameters to pass to
1777
    the 'merge_type' member.  It is difficult override do_merge without
1778
    re-writing the whole thing, so instead we create a wrapper which will pass
1779
    the extra parameters.
1780
    """
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1781
1782
    def __init__(self, merge_type, **kwargs):
1783
        self._extra_kwargs = kwargs
1784
        self._merge_type = merge_type
1785
1786
    def __call__(self, *args, **kwargs):
1787
        kwargs.update(self._extra_kwargs)
1788
        return self._merge_type(*args, **kwargs)
1789
1790
    def __getattr__(self, name):
1791
        return getattr(self._merge_type, name)
1792
1793
5246.2.30 by Andrew Bennetts
Rename Merge3MergeIntoMerger to MergeIntoMergeType.
1794
class MergeIntoMergeType(Merge3Merger):
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1795
    """Merger that incorporates a tree (or part of a tree) into another."""
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1796
1797
    def __init__(self, *args, **kwargs):
5246.2.28 by Andrew Bennetts
Improve some docstrings.
1798
        """Initialize the merger object.
1799
1800
        :param args: See Merge3Merger.__init__'s args.
1801
        :param kwargs: See Merge3Merger.__init__'s keyword args, except for
1802
            source_subpath and target_subdir.
1803
        :keyword source_subpath: The relative path specifying the subtree of
1804
            other_tree to merge into this_tree.
1805
        :keyword target_subdir: The relative path where we want to merge
1806
            other_tree into this_tree
1807
        """
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1808
        # All of the interesting work happens during Merge3Merger.__init__(),
1809
        # so we have have to hack in to get our extra parameters set.
1810
        self._source_subpath = kwargs.pop('source_subpath')
1811
        self._target_subdir = kwargs.pop('target_subdir')
5246.2.30 by Andrew Bennetts
Rename Merge3MergeIntoMerger to MergeIntoMergeType.
1812
        super(MergeIntoMergeType, self).__init__(*args, **kwargs)
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1813
1814
    def _compute_transform(self):
6861.4.1 by Jelmer Vernooij
Make progress bars context managers.
1815
        with ui.ui_factory.nested_progress_bar() as child_pb:
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1816
            entries = self._entries_to_incorporate()
1817
            entries = list(entries)
6874.2.9 by Jelmer Vernooij
Fix test.
1818
            for num, (entry, parent_id, relpath) in enumerate(entries):
7143.15.2 by Jelmer Vernooij
Run autopep8.
1819
                child_pb.update(gettext('Preparing file merge'),
1820
                                num, len(entries))
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1821
                parent_trans_id = self.tt.trans_id_file_id(parent_id)
6874.2.9 by Jelmer Vernooij
Fix test.
1822
                path = osutils.pathjoin(self._source_subpath, relpath)
6874.2.8 by Jelmer Vernooij
Fix test.
1823
                trans_id = transform.new_by_entry(path, self.tt, entry,
7143.15.2 by Jelmer Vernooij
Run autopep8.
1824
                                                  parent_trans_id, self.other_tree)
5246.2.33 by Andrew Bennetts
Rename _finish_transform to _finish_computing_transform.
1825
        self._finish_computing_transform()
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1826
1827
    def _entries_to_incorporate(self):
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1828
        """Yields pairs of (inventory_entry, new_parent)."""
7296.7.3 by Jelmer Vernooij
Expand inventories.
1829
        subdir_id = self.other_tree.path2id(self._source_subpath)
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1830
        if subdir_id is None:
5246.2.20 by Andrew Bennetts
Tweak comments, add NEWS entry.
1831
            # XXX: The error would be clearer if it gave the URL of the source
1832
            # branch, but we don't have a reference to that here.
5246.2.23 by Andrew Bennetts
Fix XXX by adding a test for that case, and don't use AssertionError for a legitimate user error.
1833
            raise PathNotInTree(self._source_subpath, "Source tree")
7296.7.6 by Jelmer Vernooij
Avoid using inventories in merge.
1834
        subdir = next(self.other_tree.iter_entries_by_dir(
1835
            specific_files=[self._source_subpath]))[1]
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1836
        parent_in_target = osutils.dirname(self._target_subdir)
6405.2.10 by Jelmer Vernooij
Fix more tests.
1837
        target_id = self.this_tree.path2id(parent_in_target)
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1838
        if target_id is None:
5246.2.23 by Andrew Bennetts
Fix XXX by adding a test for that case, and don't use AssertionError for a legitimate user error.
1839
            raise PathNotInTree(self._target_subdir, "Target tree")
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1840
        name_in_target = osutils.basename(self._target_subdir)
1841
        merge_into_root = subdir.copy()
1842
        merge_into_root.name = name_in_target
7397.4.7 by Jelmer Vernooij
Remove Tree.has_id.
1843
        try:
1844
            self.this_tree.id2path(merge_into_root.file_id)
1845
        except errors.NoSuchId:
1846
            pass
1847
        else:
5246.2.18 by Andrew Bennetts
Fix traceback if source path does not exist.
1848
            # Give the root a new file-id.
5246.2.23 by Andrew Bennetts
Fix XXX by adding a test for that case, and don't use AssertionError for a legitimate user error.
1849
            # This can happen fairly easily if the directory we are
1850
            # incorporating is the root, and both trees have 'TREE_ROOT' as
1851
            # their root_id.  Users will expect this to Just Work, so we
1852
            # change the file-id here.
1853
            # Non-root file-ids could potentially conflict too.  That's really
1854
            # an edge case, so we don't do anything special for those.  We let
1855
            # them cause conflicts.
5246.2.9 by Andrew Bennetts
Make all the existing tests pass.
1856
            merge_into_root.file_id = generate_ids.gen_file_id(name_in_target)
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
1857
        yield (merge_into_root, target_id, '')
5246.2.10 by Andrew Bennetts
Add more tests.
1858
        if subdir.kind != 'directory':
1859
            # No children, so we are done.
1860
            return
7296.7.3 by Jelmer Vernooij
Expand inventories.
1861
        for path, entry in self.other_tree.root_inventory.iter_entries_by_dir(subdir_id):
5246.2.9 by Andrew Bennetts
Make all the existing tests pass.
1862
            parent_id = entry.parent_id
1863
            if parent_id == subdir.file_id:
1864
                # The root's parent ID has changed, so make sure children of
1865
                # the root refer to the new ID.
1866
                parent_id = merge_into_root.file_id
6809.4.4 by Jelmer Vernooij
Swap arguments for Tree.is_executable.
1867
            yield (entry, parent_id, path)
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1868
1869
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1870
def merge_inner(this_branch, other_tree, base_tree, ignore_zero=False,
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
1871
                backup_files=False,
1872
                merge_type=Merge3Merger,
1873
                show_base=False,
1874
                reprocess=False,
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1875
                other_rev_id=None,
1876
                interesting_files=None,
1534.9.9 by Aaron Bentley
Added progress bar to pull
1877
                this_tree=None,
5993.2.4 by Jelmer Vernooij
Remove feature flag.
1878
                change_reporter=None):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1879
    """Primary interface for merging.
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1880
5246.2.1 by Andrew Bennetts
Very rough first draft of cmd_merge_into from bzr-merge-into. Passes its blackbox tests.
1881
    Typical use is probably::
1882
1883
        merge_inner(branch, branch.get_revision_tree(other_revision),
1884
                    branch.get_revision_tree(base_revision))
1885
    """
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1886
    if this_tree is None:
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1887
        raise errors.BzrError("breezy.merge.merge_inner requires a this_tree "
5993.2.1 by Jelmer Vernooij
Add test for rootless tree merge.
1888
                              "parameter")
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
1889
    merger = Merger(this_branch, other_tree, base_tree, this_tree=this_tree,
6719.1.2 by Jelmer Vernooij
Fix some tests.
1890
                    change_reporter=change_reporter)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1891
    merger.backup_files = backup_files
1892
    merger.merge_type = merge_type
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
1893
    merger.ignore_zero = ignore_zero
6885.5.8 by Jelmer Vernooij
Remove interesting_ids support from merge.
1894
    merger.interesting_files = interesting_files
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
1895
    merger.show_base = show_base
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1896
    merger.reprocess = reprocess
1897
    merger.other_rev_id = other_rev_id
1898
    merger.other_basis = other_rev_id
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
1899
    get_revision_id = getattr(base_tree, 'get_revision_id', None)
1900
    if get_revision_id is None:
1901
        get_revision_id = base_tree.last_revision
4595.13.2 by Alexander Belchenko
[cherrypick revno 4650 from bzr.dev] Fix shelve on windows. (Robert Collins, #305006)
1902
    merger.cache_trees_with_revision_ids([other_tree, base_tree, this_tree])
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
1903
    merger.set_base_revision(get_revision_id(), this_branch)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1904
    return merger.do_merge()
1905
6259.3.1 by Martin Packman
Relocate merge type registry to bzrlib.merge from bzrlib.option
1906
1907
merge_type_registry = registry.Registry()
6259.3.2 by Martin Packman
No longer want register_lazy as passing objects directly
1908
merge_type_registry.register('diff3', Diff3Merger,
6259.3.3 by Martin Packman
Merge bzr.dev to resolve conflicts with updated registry help strings
1909
                             "Merge using external diff3.")
6259.3.2 by Martin Packman
No longer want register_lazy as passing objects directly
1910
merge_type_registry.register('lca', LCAMerger,
6259.3.3 by Martin Packman
Merge bzr.dev to resolve conflicts with updated registry help strings
1911
                             "LCA-newness merge.")
6259.3.2 by Martin Packman
No longer want register_lazy as passing objects directly
1912
merge_type_registry.register('merge3', Merge3Merger,
6259.3.3 by Martin Packman
Merge bzr.dev to resolve conflicts with updated registry help strings
1913
                             "Native diff3-style merge.")
6259.3.2 by Martin Packman
No longer want register_lazy as passing objects directly
1914
merge_type_registry.register('weave', WeaveMerger,
6259.3.3 by Martin Packman
Merge bzr.dev to resolve conflicts with updated registry help strings
1915
                             "Weave-based merge.")
6259.3.1 by Martin Packman
Relocate merge type registry to bzrlib.merge from bzrlib.option
1916
1917
2221.4.15 by Aaron Bentley
Use RegistryOption for merge type
1918
def get_merge_type_registry():
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1919
    """Merge type registry was previously in breezy.option
2221.4.15 by Aaron Bentley
Use RegistryOption for merge type
1920
6259.3.1 by Martin Packman
Relocate merge type registry to bzrlib.merge from bzrlib.option
1921
    This method provides a backwards compatible way to retrieve it.
2221.4.15 by Aaron Bentley
Use RegistryOption for merge type
1922
    """
6259.3.1 by Martin Packman
Relocate merge type registry to bzrlib.merge from bzrlib.option
1923
    return merge_type_registry
1551.15.46 by Aaron Bentley
Move plan merge to tree
1924
1925
1926
def _plan_annotate_merge(annotated_a, annotated_b, ancestors_a, ancestors_b):
1927
    def status_a(revision, text):
1928
        if revision in ancestors_b:
1929
            return 'killed-b', text
1930
        else:
1931
            return 'new-a', text
1932
1933
    def status_b(revision, text):
1934
        if revision in ancestors_a:
1935
            return 'killed-a', text
1936
        else:
1937
            return 'new-b', text
1938
1939
    plain_a = [t for (a, t) in annotated_a]
1940
    plain_b = [t for (a, t) in annotated_b]
1941
    matcher = patiencediff.PatienceSequenceMatcher(None, plain_a, plain_b)
1942
    blocks = matcher.get_matching_blocks()
1943
    a_cur = 0
1944
    b_cur = 0
1945
    for ai, bi, l in blocks:
1946
        # process all mismatched sections
1947
        # (last mismatched section is handled because blocks always
1948
        # includes a 0-length last block)
1949
        for revision, text in annotated_a[a_cur:ai]:
1950
            yield status_a(revision, text)
1951
        for revision, text in annotated_b[b_cur:bi]:
1952
            yield status_b(revision, text)
1953
        # and now the matched section
1954
        a_cur = ai + l
1955
        b_cur = bi + l
3376.2.8 by Martin Pool
Some review cleanups for assertion removal
1956
        for text_a in plain_a[ai:a_cur]:
1551.15.46 by Aaron Bentley
Move plan merge to tree
1957
            yield "unchanged", text_a
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1958
1959
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1960
class _PlanMergeBase(object):
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1961
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1962
    def __init__(self, a_rev, b_rev, vf, key_prefix):
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1963
        """Contructor.
1964
1965
        :param a_rev: Revision-id of one revision to merge
1966
        :param b_rev: Revision-id of the other revision to merge
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1967
        :param vf: A VersionedFiles containing both revisions
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1968
        :param key_prefix: A prefix for accessing keys in vf, typically
1969
            (file_id,).
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1970
        """
1971
        self.a_rev = a_rev
1972
        self.b_rev = b_rev
1973
        self.vf = vf
3062.1.12 by Aaron Bentley
Implement simple text cache
1974
        self._last_lines = None
1975
        self._last_lines_revision_id = None
3144.3.7 by Aaron Bentley
Update from review
1976
        self._cached_matching_blocks = {}
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1977
        self._key_prefix = key_prefix
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1978
        self._precache_tip_lines()
1979
1980
    def _precache_tip_lines(self):
1981
        lines = self.get_lines([self.a_rev, self.b_rev])
1982
        self.lines_a = lines[self.a_rev]
1983
        self.lines_b = lines[self.b_rev]
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1984
1985
    def get_lines(self, revisions):
1986
        """Get lines for revisions from the backing VersionedFiles.
3890.2.9 by John Arbash Meinel
Start using osutils.chunks_as_lines rather than osutils.split_lines.
1987
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1988
        :raises RevisionNotPresent: on absent texts.
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1989
        """
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1990
        keys = [(self._key_prefix + (rev,)) for rev in revisions]
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1991
        result = {}
1992
        for record in self.vf.get_record_stream(keys, 'unordered', True):
1993
            if record.storage_kind == 'absent':
1994
                raise errors.RevisionNotPresent(record.key, self.vf)
7459.3.2 by Jelmer Vernooij
Add a 'lines' storage type.
1995
            result[record.key[-1]] = record.get_bytes_as('lines')
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
1996
        return result
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1997
1998
    def plan_merge(self):
1999
        """Generate a 'plan' for merging the two revisions.
2000
2001
        This involves comparing their texts and determining the cause of
2002
        differences.  If text A has a line and text B does not, then either the
2003
        line was added to text A, or it was deleted from B.  Once the causes
2004
        are combined, they are written out in the format described in
2005
        VersionedFile.plan_merge
2006
        """
2007
        blocks = self._get_matching_blocks(self.a_rev, self.b_rev)
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2008
        unique_a, unique_b = self._unique_lines(blocks)
2009
        new_a, killed_b = self._determine_status(self.a_rev, unique_a)
2010
        new_b, killed_a = self._determine_status(self.b_rev, unique_b)
2011
        return self._iter_plan(blocks, new_a, killed_b, new_b, killed_a)
2012
2013
    def _iter_plan(self, blocks, new_a, killed_b, new_b, killed_a):
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
2014
        last_i = 0
2015
        last_j = 0
2016
        for i, j, n in blocks:
2017
            for a_index in range(last_i, i):
2018
                if a_index in new_a:
3144.3.2 by Aaron Bentley
Get conflict handling working
2019
                    if a_index in killed_b:
2020
                        yield 'conflicted-a', self.lines_a[a_index]
2021
                    else:
2022
                        yield 'new-a', self.lines_a[a_index]
2023
                else:
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2024
                    yield 'killed-b', self.lines_a[a_index]
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
2025
            for b_index in range(last_j, j):
2026
                if b_index in new_b:
3144.3.2 by Aaron Bentley
Get conflict handling working
2027
                    if b_index in killed_a:
3144.3.10 by Aaron Bentley
Use correct index when emitting conflicted-b
2028
                        yield 'conflicted-b', self.lines_b[b_index]
3144.3.2 by Aaron Bentley
Get conflict handling working
2029
                    else:
2030
                        yield 'new-b', self.lines_b[b_index]
2031
                else:
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2032
                    yield 'killed-a', self.lines_b[b_index]
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
2033
            # handle common lines
7143.15.2 by Jelmer Vernooij
Run autopep8.
2034
            for a_index in range(i, i + n):
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2035
                yield 'unchanged', self.lines_a[a_index]
7143.15.2 by Jelmer Vernooij
Run autopep8.
2036
            last_i = i + n
2037
            last_j = j + n
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
2038
2039
    def _get_matching_blocks(self, left_revision, right_revision):
2040
        """Return a description of which sections of two revisions match.
2041
2042
        See SequenceMatcher.get_matching_blocks
2043
        """
3144.3.7 by Aaron Bentley
Update from review
2044
        cached = self._cached_matching_blocks.get((left_revision,
2045
                                                   right_revision))
2046
        if cached is not None:
2047
            return cached
3062.1.12 by Aaron Bentley
Implement simple text cache
2048
        if self._last_lines_revision_id == left_revision:
2049
            left_lines = self._last_lines
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2050
            right_lines = self.get_lines([right_revision])[right_revision]
3062.1.12 by Aaron Bentley
Implement simple text cache
2051
        else:
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
2052
            lines = self.get_lines([left_revision, right_revision])
2053
            left_lines = lines[left_revision]
2054
            right_lines = lines[right_revision]
3062.1.12 by Aaron Bentley
Implement simple text cache
2055
        self._last_lines = right_lines
2056
        self._last_lines_revision_id = right_revision
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
2057
        matcher = patiencediff.PatienceSequenceMatcher(None, left_lines,
2058
                                                       right_lines)
2059
        return matcher.get_matching_blocks()
2060
2061
    def _unique_lines(self, matching_blocks):
2062
        """Analyse matching_blocks to determine which lines are unique
2063
2064
        :return: a tuple of (unique_left, unique_right), where the values are
2065
            sets of line numbers of unique lines.
2066
        """
2067
        last_i = 0
2068
        last_j = 0
2069
        unique_left = []
2070
        unique_right = []
2071
        for i, j, n in matching_blocks:
2072
            unique_left.extend(range(last_i, i))
2073
            unique_right.extend(range(last_j, j))
2074
            last_i = i + n
2075
            last_j = j + n
2076
        return unique_left, unique_right
2077
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2078
    @staticmethod
2079
    def _subtract_plans(old_plan, new_plan):
3144.3.7 by Aaron Bentley
Update from review
2080
        """Remove changes from new_plan that came from old_plan.
2081
2082
        It is assumed that the difference between the old_plan and new_plan
2083
        is their choice of 'b' text.
2084
2085
        All lines from new_plan that differ from old_plan are emitted
2086
        verbatim.  All lines from new_plan that match old_plan but are
2087
        not about the 'b' revision are emitted verbatim.
2088
2089
        Lines that match and are about the 'b' revision are the lines we
2090
        don't want, so we convert 'killed-b' -> 'unchanged', and 'new-b'
2091
        is skipped entirely.
2092
        """
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2093
        matcher = patiencediff.PatienceSequenceMatcher(None, old_plan,
2094
                                                       new_plan)
2095
        last_j = 0
2096
        for i, j, n in matcher.get_matching_blocks():
2097
            for jj in range(last_j, j):
2098
                yield new_plan[jj]
7143.15.2 by Jelmer Vernooij
Run autopep8.
2099
            for jj in range(j, j + n):
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2100
                plan_line = new_plan[jj]
2101
                if plan_line[0] == 'new-b':
2102
                    pass
2103
                elif plan_line[0] == 'killed-b':
2104
                    yield 'unchanged', plan_line[1]
2105
                else:
2106
                    yield plan_line
2107
            last_j = j + n
2108
2109
2110
class _PlanMerge(_PlanMergeBase):
2111
    """Plan an annotate merge using on-the-fly annotation"""
2112
3350.6.10 by Martin Pool
VersionedFiles review cleanups
2113
    def __init__(self, a_rev, b_rev, vf, key_prefix):
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2114
        super(_PlanMerge, self).__init__(a_rev, b_rev, vf, key_prefix)
2115
        self.a_key = self._key_prefix + (self.a_rev,)
2116
        self.b_key = self._key_prefix + (self.b_rev,)
4721.3.1 by Vincent Ladeuil
Cleanup imports.
2117
        self.graph = _mod_graph.Graph(self.vf)
3514.2.11 by John Arbash Meinel
Shortcut the case when one revision is in the ancestry of the other.
2118
        heads = self.graph.heads((self.a_key, self.b_key))
2119
        if len(heads) == 1:
2120
            # one side dominates, so we can just return its values, yay for
2121
            # per-file graphs
2122
            # Ideally we would know that before we get this far
2123
            self._head_key = heads.pop()
2124
            if self._head_key == self.a_key:
2125
                other = b_rev
2126
            else:
2127
                other = a_rev
4721.3.1 by Vincent Ladeuil
Cleanup imports.
2128
            trace.mutter('found dominating revision for %s\n%s > %s', self.vf,
2129
                         self._head_key[-1], other)
3514.2.11 by John Arbash Meinel
Shortcut the case when one revision is in the ancestry of the other.
2130
            self._weave = None
2131
        else:
2132
            self._head_key = None
2133
            self._build_weave()
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2134
2135
    def _precache_tip_lines(self):
2136
        # Turn this into a no-op, because we will do this later
2137
        pass
2138
2139
    def _find_recursive_lcas(self):
2140
        """Find all the ancestors back to a unique lca"""
2141
        cur_ancestors = (self.a_key, self.b_key)
2142
        # graph.find_lca(uncommon, keys) now returns plain NULL_REVISION,
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2143
        # rather than a key tuple. We will just map that directly to no common
2144
        # ancestors.
2145
        parent_map = {}
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2146
        while True:
2147
            next_lcas = self.graph.find_lca(*cur_ancestors)
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2148
            # Map a plain NULL_REVISION to a simple no-ancestors
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
2149
            if next_lcas == {_mod_revision.NULL_REVISION}:
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2150
                next_lcas = ()
3514.2.9 by John Arbash Meinel
Add some debugging, and work on getting the graph right so we get the weave insertion order correct.
2151
            # Order the lca's based on when they were merged into the tip
2152
            # While the actual merge portion of weave merge uses a set() of
2153
            # active revisions, the order of insertion *does* effect the
2154
            # implicit ordering of the texts.
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2155
            for rev_key in cur_ancestors:
3514.2.9 by John Arbash Meinel
Add some debugging, and work on getting the graph right so we get the weave insertion order correct.
2156
                ordered_parents = tuple(self.graph.find_merge_order(rev_key,
2157
                                                                    next_lcas))
2158
                parent_map[rev_key] = ordered_parents
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2159
            if len(next_lcas) == 0:
2160
                break
2161
            elif len(next_lcas) == 1:
3514.2.9 by John Arbash Meinel
Add some debugging, and work on getting the graph right so we get the weave insertion order correct.
2162
                parent_map[list(next_lcas)[0]] = ()
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2163
                break
3514.2.10 by John Arbash Meinel
Handle more edge cases.
2164
            elif len(next_lcas) > 2:
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2165
                # More than 2 lca's, fall back to grabbing all nodes between
2166
                # this and the unique lca.
4721.3.1 by Vincent Ladeuil
Cleanup imports.
2167
                trace.mutter('More than 2 LCAs, falling back to all nodes for:'
2168
                             ' %s, %s\n=> %s',
2169
                             self.a_key, self.b_key, cur_ancestors)
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2170
                cur_lcas = next_lcas
2171
                while len(cur_lcas) > 1:
2172
                    cur_lcas = self.graph.find_lca(*cur_lcas)
2173
                if len(cur_lcas) == 0:
2174
                    # No common base to find, use the full ancestry
2175
                    unique_lca = None
2176
                else:
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
2177
                    unique_lca = list(cur_lcas)[0]
4721.3.1 by Vincent Ladeuil
Cleanup imports.
2178
                    if unique_lca == _mod_revision.NULL_REVISION:
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
2179
                        # find_lca will return a plain 'NULL_REVISION' rather
2180
                        # than a key tuple when there is no common ancestor, we
2181
                        # prefer to just use None, because it doesn't confuse
2182
                        # _get_interesting_texts()
2183
                        unique_lca = None
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2184
                parent_map.update(self._find_unique_parents(next_lcas,
2185
                                                            unique_lca))
2186
                break
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2187
            cur_ancestors = next_lcas
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2188
        return parent_map
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2189
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2190
    def _find_unique_parents(self, tip_keys, base_key):
2191
        """Find ancestors of tip that aren't ancestors of base.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2192
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2193
        :param tip_keys: Nodes that are interesting
2194
        :param base_key: Cull all ancestors of this node
2195
        :return: The parent map for all revisions between tip_keys and
2196
            base_key. base_key will be included. References to nodes outside of
2197
            the ancestor set will also be removed.
2198
        """
2199
        # TODO: this would be simpler if find_unique_ancestors took a list
2200
        #       instead of a single tip, internally it supports it, but it
2201
        #       isn't a "backwards compatible" api change.
2202
        if base_key is None:
2203
            parent_map = dict(self.graph.iter_ancestry(tip_keys))
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
2204
            # We remove NULL_REVISION because it isn't a proper tuple key, and
2205
            # thus confuses things like _get_interesting_texts, and our logic
2206
            # to add the texts into the memory weave.
4721.3.1 by Vincent Ladeuil
Cleanup imports.
2207
            if _mod_revision.NULL_REVISION in parent_map:
2208
                parent_map.pop(_mod_revision.NULL_REVISION)
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2209
        else:
2210
            interesting = set()
2211
            for tip in tip_keys:
2212
                interesting.update(
2213
                    self.graph.find_unique_ancestors(tip, [base_key]))
2214
            parent_map = self.graph.get_parent_map(interesting)
2215
            parent_map[base_key] = ()
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
2216
        culled_parent_map, child_map, tails = self._remove_external_references(
2217
            parent_map)
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
2218
        # Remove all the tails but base_key
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
2219
        if base_key is not None:
2220
            tails.remove(base_key)
2221
            self._prune_tails(culled_parent_map, child_map, tails)
2222
        # Now remove all the uninteresting 'linear' regions
3514.2.15 by John Arbash Meinel
Enable collapsing linear regions.
2223
        simple_map = _mod_graph.collapse_linear_regions(culled_parent_map)
2224
        return simple_map
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
2225
2226
    @staticmethod
2227
    def _remove_external_references(parent_map):
2228
        """Remove references that go outside of the parent map.
2229
2230
        :param parent_map: Something returned from Graph.get_parent_map(keys)
2231
        :return: (filtered_parent_map, child_map, tails)
2232
            filtered_parent_map is parent_map without external references
2233
            child_map is the {parent_key: [child_keys]} mapping
2234
            tails is a list of nodes that do not have any parents in the map
2235
        """
2236
        # TODO: The basic effect of this function seems more generic than
2237
        #       _PlanMerge. But the specific details of building a child_map,
2238
        #       and computing tails seems very specific to _PlanMerge.
2239
        #       Still, should this be in Graph land?
2240
        filtered_parent_map = {}
2241
        child_map = {}
2242
        tails = []
7479.2.1 by Jelmer Vernooij
Drop python2 support.
2243
        for key, parent_keys in parent_map.items():
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
2244
            culled_parent_keys = [p for p in parent_keys if p in parent_map]
2245
            if not culled_parent_keys:
2246
                tails.append(key)
2247
            for parent_key in culled_parent_keys:
2248
                child_map.setdefault(parent_key, []).append(key)
2249
            # TODO: Do we want to do this, it adds overhead for every node,
2250
            #       just to say that the node has no children
2251
            child_map.setdefault(key, [])
2252
            filtered_parent_map[key] = culled_parent_keys
2253
        return filtered_parent_map, child_map, tails
2254
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
2255
    @staticmethod
2256
    def _prune_tails(parent_map, child_map, tails_to_remove):
2257
        """Remove tails from the parent map.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2258
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
2259
        This will remove the supplied revisions until no more children have 0
2260
        parents.
2261
2262
        :param parent_map: A dict of {child: [parents]}, this dictionary will
2263
            be modified in place.
2264
        :param tails_to_remove: A list of tips that should be removed,
2265
            this list will be consumed
2266
        :param child_map: The reverse dict of parent_map ({parent: [children]})
2267
            this dict will be modified
2268
        :return: None, parent_map will be modified in place.
2269
        """
2270
        while tails_to_remove:
2271
            next = tails_to_remove.pop()
2272
            parent_map.pop(next)
2273
            children = child_map.pop(next)
2274
            for child in children:
2275
                child_parents = parent_map[child]
2276
                child_parents.remove(next)
2277
                if len(child_parents) == 0:
2278
                    tails_to_remove.append(child)
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
2279
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2280
    def _get_interesting_texts(self, parent_map):
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2281
        """Return a dict of texts we are interested in.
2282
2283
        Note that the input is in key tuples, but the output is in plain
2284
        revision ids.
2285
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2286
        :param parent_map: The output from _find_recursive_lcas
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2287
        :return: A dict of {'revision_id':lines} as returned by
2288
            _PlanMergeBase.get_lines()
2289
        """
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2290
        all_revision_keys = set(parent_map)
2291
        all_revision_keys.add(self.a_key)
2292
        all_revision_keys.add(self.b_key)
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2293
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2294
        # Everything else is in 'keys' but get_lines is in 'revision_ids'
2295
        all_texts = self.get_lines([k[-1] for k in all_revision_keys])
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2296
        return all_texts
2297
2298
    def _build_weave(self):
6670.4.3 by Jelmer Vernooij
Fix more imports.
2299
        from .bzr import weave
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2300
        self._weave = weave.Weave(weave_name='in_memory_weave',
2301
                                  allow_reserved=True)
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2302
        parent_map = self._find_recursive_lcas()
2303
2304
        all_texts = self._get_interesting_texts(parent_map)
2305
2306
        # Note: Unfortunately, the order given by topo_sort will effect the
2307
        # ordering resolution in the output. Specifically, if you add A then B,
2308
        # then in the output text A lines will show up before B lines. And, of
2309
        # course, topo_sort doesn't guarantee any real ordering.
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
2310
        # So we use merge_sort, and add a fake node on the tip.
2311
        # This ensures that left-hand parents will always be inserted into the
2312
        # weave before right-hand parents.
2313
        tip_key = self._key_prefix + (_mod_revision.CURRENT_REVISION,)
2314
        parent_map[tip_key] = (self.a_key, self.b_key)
2315
2316
        for seq_num, key, depth, eom in reversed(tsort.merge_sort(parent_map,
2317
                                                                  tip_key)):
2318
            if key == tip_key:
2319
                continue
3514.2.9 by John Arbash Meinel
Add some debugging, and work on getting the graph right so we get the weave insertion order correct.
2320
        # for key in tsort.topo_sort(parent_map):
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
2321
            parent_keys = parent_map[key]
2322
            revision_id = key[-1]
2323
            parent_ids = [k[-1] for k in parent_keys]
2324
            self._weave.add_lines(revision_id, parent_ids,
2325
                                  all_texts[revision_id])
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2326
2327
    def plan_merge(self):
2328
        """Generate a 'plan' for merging the two revisions.
2329
2330
        This involves comparing their texts and determining the cause of
2331
        differences.  If text A has a line and text B does not, then either the
2332
        line was added to text A, or it was deleted from B.  Once the causes
2333
        are combined, they are written out in the format described in
2334
        VersionedFile.plan_merge
2335
        """
7143.15.2 by Jelmer Vernooij
Run autopep8.
2336
        if self._head_key is not None:  # There was a single head
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2337
            if self._head_key == self.a_key:
2338
                plan = 'new-a'
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
2339
            else:
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2340
                if self._head_key != self.b_key:
2341
                    raise AssertionError('There was an invalid head: %s != %s'
2342
                                         % (self.b_key, self._head_key))
2343
                plan = 'new-b'
3514.2.16 by John Arbash Meinel
Review feedback from Ian.
2344
            head_rev = self._head_key[-1]
2345
            lines = self.get_lines([head_rev])[head_rev]
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
2346
            return ((plan, line) for line in lines)
2347
        return self._weave.plan_merge(self.a_rev, self.b_rev)
3062.2.1 by Aaron Bentley
Add support for plan-merge with a base
2348
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2349
2350
class _PlanLCAMerge(_PlanMergeBase):
2351
    """
3144.3.7 by Aaron Bentley
Update from review
2352
    This merge algorithm differs from _PlanMerge in that:
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
2353
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2354
    1. comparisons are done against LCAs only
2355
    2. cases where a contested line is new versus one LCA but old versus
3144.3.7 by Aaron Bentley
Update from review
2356
       another are marked as conflicts, by emitting the line as conflicted-a
2357
       or conflicted-b.
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2358
2359
    This is faster, and hopefully produces more useful output.
2360
    """
2361
3350.6.10 by Martin Pool
VersionedFiles review cleanups
2362
    def __init__(self, a_rev, b_rev, vf, key_prefix, graph):
2363
        _PlanMergeBase.__init__(self, a_rev, b_rev, vf, key_prefix)
2364
        lcas = graph.find_lca(key_prefix + (a_rev,), key_prefix + (b_rev,))
3350.6.5 by Robert Collins
Update to bzr.dev.
2365
        self.lcas = set()
2366
        for lca in lcas:
4721.3.1 by Vincent Ladeuil
Cleanup imports.
2367
            if lca == _mod_revision.NULL_REVISION:
3350.6.5 by Robert Collins
Update to bzr.dev.
2368
                self.lcas.add(lca)
2369
            else:
2370
                self.lcas.add(lca[-1])
3144.3.7 by Aaron Bentley
Update from review
2371
        for lca in self.lcas:
3287.17.1 by John Arbash Meinel
Fix bug #235715 by using the empty list as the text for a base of NULL_REVISION.
2372
            if _mod_revision.is_null(lca):
2373
                lca_lines = []
2374
            else:
3350.6.5 by Robert Collins
Update to bzr.dev.
2375
                lca_lines = self.get_lines([lca])[lca]
3144.3.7 by Aaron Bentley
Update from review
2376
            matcher = patiencediff.PatienceSequenceMatcher(None, self.lines_a,
2377
                                                           lca_lines)
2378
            blocks = list(matcher.get_matching_blocks())
2379
            self._cached_matching_blocks[(a_rev, lca)] = blocks
2380
            matcher = patiencediff.PatienceSequenceMatcher(None, self.lines_b,
2381
                                                           lca_lines)
2382
            blocks = list(matcher.get_matching_blocks())
2383
            self._cached_matching_blocks[(b_rev, lca)] = blocks
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2384
3144.3.7 by Aaron Bentley
Update from review
2385
    def _determine_status(self, revision_id, unique_line_numbers):
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2386
        """Determines the status unique lines versus all lcas.
2387
2388
        Basically, determines why the line is unique to this revision.
2389
2390
        A line may be determined new, killed, or both.
2391
3144.3.7 by Aaron Bentley
Update from review
2392
        If a line is determined new, that means it was not present in at least
2393
        one LCA, and is not present in the other merge revision.
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2394
2395
        If a line is determined killed, that means the line was present in
2396
        at least one LCA.
2397
2398
        If a line is killed and new, this indicates that the two merge
2399
        revisions contain differing conflict resolutions.
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
2400
3144.3.7 by Aaron Bentley
Update from review
2401
        :param revision_id: The id of the revision in which the lines are
2402
            unique
2403
        :param unique_line_numbers: The line numbers of unique lines.
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
2404
        :return: a tuple of (new_this, killed_other)
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2405
        """
2406
        new = set()
2407
        killed = set()
3144.3.7 by Aaron Bentley
Update from review
2408
        unique_line_numbers = set(unique_line_numbers)
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2409
        for lca in self.lcas:
2410
            blocks = self._get_matching_blocks(revision_id, lca)
2411
            unique_vs_lca, _ignored = self._unique_lines(blocks)
3144.3.7 by Aaron Bentley
Update from review
2412
            new.update(unique_line_numbers.intersection(unique_vs_lca))
2413
            killed.update(unique_line_numbers.difference(unique_vs_lca))
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
2414
        return new, killed