/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1
# Copyright (C) 2005, 2006, 2008 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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1545.2.3 by Aaron Bentley
Updated following j-a-meinel's comments
17
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.
18
import errno
19
from itertools import chain
1185.1.2 by Martin Pool
- merge various windows and other fixes from Ollie Rutherfurd
20
import os
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
21
import warnings
1113 by Martin Pool
- fix is_ancestor import problem in merge
22
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
23
from bzrlib import (
1551.19.17 by Aaron Bentley
Add debugging flag for merges
24
    debug,
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
25
    errors,
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
26
    graph as _mod_graph,
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
27
    osutils,
1551.15.46 by Aaron Bentley
Move plan merge to tree
28
    patiencediff,
2221.4.15 by Aaron Bentley
Use RegistryOption for merge type
29
    registry,
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
30
    revision as _mod_revision,
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
31
    tsort,
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
32
    )
1185.11.5 by John Arbash Meinel
Merged up-to-date against mainline, still broken.
33
from bzrlib.branch import Branch
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
34
from bzrlib.conflicts import ConflictList, Conflict
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
35
from bzrlib.errors import (BzrCommandError,
1534.4.28 by Robert Collins
first cut at merge from integration.
36
                           BzrError,
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
37
                           NoCommonAncestor,
38
                           NoCommits,
1534.4.28 by Robert Collins
first cut at merge from integration.
39
                           NoSuchRevision,
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
40
                           NoSuchFile,
1545.2.6 by Aaron Bentley
Removed _merge, renamed MergeConflictHandler to _MergeConflictHandler
41
                           NotBranchError,
1185.33.27 by Martin Pool
[merge] much integrated work from robert and john
42
                           NotVersionedError,
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
43
                           UnrelatedBranches,
1534.10.12 by Aaron Bentley
Merge produces new conflicts
44
                           UnsupportedOperation,
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
45
                           WorkingTreeNotRevision,
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
46
                           BinaryFile,
1534.4.28 by Robert Collins
first cut at merge from integration.
47
                           )
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.
48
from bzrlib.graph import Graph
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
49
from bzrlib.merge3 import Merge3
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
50
from bzrlib.osutils import rename, pathjoin
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
51
from progress import DummyProgress, ProgressPhase
3052.1.3 by John Arbash Meinel
deprecate revision.is_ancestor, update the callers and the tests.
52
from bzrlib.revision import (NULL_REVISION, ensure_null)
1558.15.5 by Aaron Bentley
Fixed binary handling in weave merge
53
from bzrlib.textfile import check_text_lines
3200.1.1 by James Westby
Make pull --quiet more quiet. Fixes #185907.
54
from bzrlib.trace import mutter, warning, note, is_quiet
3008.1.9 by Michael Hudson
wanton hacking that lets me write an efficient version of get_diff_as_merged
55
from bzrlib.transform import (TransformPreview, TreeTransform,
56
                              resolve_conflicts, cook_conflicts,
2590.2.8 by Aaron Bentley
Restore conflict handling changes
57
                              conflict_pass, FinalPaths, create_by_entry,
58
                              unique_add, ROOT_PARENT)
1551.15.46 by Aaron Bentley
Move plan merge to tree
59
from bzrlib.versionedfile import PlanWeaveMerge
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
60
from bzrlib import ui
1545.2.6 by Aaron Bentley
Removed _merge, renamed MergeConflictHandler to _MergeConflictHandler
61
62
# TODO: Report back as changes are merged in
63
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.
64
1185.35.4 by Aaron Bentley
Implemented remerge
65
def transform_tree(from_tree, to_tree, interesting_ids=None):
66
    merge_inner(from_tree.branch, to_tree, from_tree, ignore_zero=True,
1558.1.3 by Aaron Bentley
Fixed deprecated op use in test suite
67
                interesting_ids=interesting_ids, this_tree=from_tree)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
68
1457.1.12 by Robert Collins
Update comment to reflect author.
69
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
70
class Merger(object):
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
71
    def __init__(self, this_branch, other_tree=None, base_tree=None,
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
72
                 this_tree=None, pb=DummyProgress(), change_reporter=None,
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
73
                 recurse='down', revision_graph=None):
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
74
        object.__init__(self)
75
        self.this_branch = this_branch
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
76
        self.this_basis = _mod_revision.ensure_null(
77
            this_branch.last_revision())
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
78
        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.
79
        self.this_tree = this_tree
1185.12.83 by Aaron Bentley
Preliminary weave merge support
80
        self.this_revision_tree = None
1185.35.5 by Aaron Bentley
Made weave merge succeed if interesting files match history
81
        self.this_basis_tree = None
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
82
        self.other_tree = other_tree
2100.3.29 by Aaron Bentley
Get merge working initially
83
        self.other_branch = None
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
84
        self.base_tree = base_tree
85
        self.ignore_zero = False
86
        self.backup_files = False
87
        self.interesting_ids = None
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
88
        self.interesting_files = None
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
89
        self.show_base = False
1185.24.3 by Aaron Bentley
Integrated reprocessing into the rest of the merge stuff
90
        self.reprocess = False
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
91
        self._pb = pb
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
92
        self.pp = None
2100.3.29 by Aaron Bentley
Get merge working initially
93
        self.recurse = recurse
1551.11.9 by Aaron Bentley
Apply change reporting to merge
94
        self.change_reporter = change_reporter
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
95
        self._cached_trees = {}
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
96
        self._revision_graph = revision_graph
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
97
        self._base_is_ancestor = None
98
        self._base_is_other_ancestor = None
99
100
    @property
101
    def revision_graph(self):
102
        if self._revision_graph is None:
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
103
            self._revision_graph = self.this_branch.repository.get_graph()
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
104
        return self._revision_graph
105
106
    def _set_base_is_ancestor(self, value):
107
        self._base_is_ancestor = value
108
109
    def _get_base_is_ancestor(self):
110
        if self._base_is_ancestor is None:
111
            self._base_is_ancestor = self.revision_graph.is_ancestor(
112
                self.base_rev_id, self.this_basis)
113
        return self._base_is_ancestor
114
115
    base_is_ancestor = property(_get_base_is_ancestor, _set_base_is_ancestor)
116
117
    def _set_base_is_other_ancestor(self, value):
118
        self._base_is_other_ancestor = value
119
120
    def _get_base_is_other_ancestor(self):
121
        if self._base_is_other_ancestor is None:
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
122
            if self.other_basis is None:
123
                return True
124
            self._base_is_other_ancestor = self.revision_graph.is_ancestor(
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
125
                self.base_rev_id, self.other_basis)
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
126
        return self._base_is_other_ancestor
127
128
    base_is_other_ancestor = property(_get_base_is_other_ancestor,
129
                                      _set_base_is_other_ancestor)
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
130
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
131
    @staticmethod
132
    def from_uncommitted(tree, other_tree, pb):
1551.15.74 by Aaron Bentley
Textual updates from review
133
        """Return a Merger for uncommitted changes in other_tree.
134
135
        :param tree: The tree to merge into
136
        :param other_tree: The tree to get uncommitted changes from
137
        :param pb: A progress indicator
138
        """
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
139
        merger = Merger(tree.branch, other_tree, other_tree.basis_tree(), tree,
140
                        pb)
141
        merger.base_rev_id = merger.base_tree.get_revision_id()
142
        merger.other_rev_id = None
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
143
        merger.other_basis = merger.base_rev_id
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
144
        return merger
145
146
    @classmethod
147
    def from_mergeable(klass, tree, mergeable, pb):
1551.15.74 by Aaron Bentley
Textual updates from review
148
        """Return a Merger for a bundle or merge directive.
149
150
        :param tree: The tree to merge changes into
151
        :param mergeable: A merge directive or bundle
152
        :param pb: A progress indicator
153
        """
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
154
        mergeable.install_revisions(tree.branch.repository)
155
        base_revision_id, other_revision_id, verified =\
156
            mergeable.get_merge_request(tree.branch.repository)
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
157
        revision_graph = tree.branch.repository.get_graph()
1551.19.44 by Aaron Bentley
Fix handling of old merge directives with stricter get_parent_map
158
        if base_revision_id is not None:
159
            if (base_revision_id != _mod_revision.NULL_REVISION and
160
                revision_graph.is_ancestor(
161
                base_revision_id, tree.branch.last_revision())):
162
                base_revision_id = None
163
            else:
164
                warning('Performing cherrypick')
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
165
        merger = klass.from_revision_ids(pb, tree, other_revision_id,
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
166
                                         base_revision_id, revision_graph=
167
                                         revision_graph)
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
168
        return merger, verified
169
170
    @staticmethod
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
171
    def from_revision_ids(pb, tree, other, base=None, other_branch=None,
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
172
                          base_branch=None, revision_graph=None,
173
                          tree_branch=None):
1551.15.74 by Aaron Bentley
Textual updates from review
174
        """Return a Merger for revision-ids.
175
176
        :param tree: The tree to merge changes into
177
        :param other: The revision-id to use as OTHER
178
        :param base: The revision-id to use as BASE.  If not specified, will
179
            be auto-selected.
180
        :param other_branch: A branch containing the other revision-id.  If
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
181
            not supplied, tree.branch is used.
1551.15.74 by Aaron Bentley
Textual updates from review
182
        :param base_branch: A branch containing the base revision-id.  If
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
183
            not supplied, other_branch or tree.branch will be used.
184
        :param revision_graph: If you have a revision_graph precomputed, pass
185
            it in, otherwise it will be created for you.
1551.15.74 by Aaron Bentley
Textual updates from review
186
        :param pb: A progress indicator
187
        """
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
188
        if tree_branch is None:
189
            tree_branch = tree.branch
190
        merger = Merger(tree_branch, this_tree=tree, pb=pb,
3146.5.3 by Aaron Bentley
Avoid retrieving revision graph twice
191
                        revision_graph=revision_graph)
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
192
        if other_branch is None:
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
193
            other_branch = tree.branch
1551.15.67 by Aaron Bentley
Stop using _merge_helper for merging
194
        merger.set_other_revision(other, other_branch)
195
        if base is None:
196
            merger.find_base()
197
        else:
198
            if base_branch is None:
199
                base_branch = other_branch
200
            merger.set_base_revision(base, base_branch)
201
        return merger
202
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
203
    def revision_tree(self, revision_id, branch=None):
204
        if revision_id not in self._cached_trees:
205
            if branch is None:
206
                branch = self.this_branch
207
            try:
208
                tree = self.this_tree.revision_tree(revision_id)
209
            except errors.NoSuchRevisionInTree:
210
                tree = branch.repository.revision_tree(revision_id)
211
            self._cached_trees[revision_id] = tree
212
        return self._cached_trees[revision_id]
213
2485.8.58 by Vincent Ladeuil
merge bzr.dev@1617
214
    def _get_tree(self, treespec, possible_transports=None):
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
215
        from bzrlib import workingtree
216
        location, revno = treespec
217
        if revno is None:
218
            tree = workingtree.WorkingTree.open_containing(location)[0]
219
            return tree.branch, tree
2485.8.58 by Vincent Ladeuil
merge bzr.dev@1617
220
        branch = Branch.open_containing(location, possible_transports)[0]
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
221
        if revno == -1:
222
            revision_id = branch.last_revision()
223
        else:
224
            revision_id = branch.get_rev_id(revno)
225
        revision_id = ensure_null(revision_id)
226
        return branch, self.revision_tree(revision_id, branch)
1185.12.83 by Aaron Bentley
Preliminary weave merge support
227
228
    def ensure_revision_trees(self):
229
        if self.this_revision_tree is None:
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
230
            self.this_basis_tree = self.revision_tree(self.this_basis)
1185.35.5 by Aaron Bentley
Made weave merge succeed if interesting files match history
231
            if self.this_basis == self.this_rev_id:
232
                self.this_revision_tree = self.this_basis_tree
233
1185.12.83 by Aaron Bentley
Preliminary weave merge support
234
        if self.other_rev_id is None:
235
            other_basis_tree = self.revision_tree(self.other_basis)
1852.10.3 by Robert Collins
Remove all uses of compare_trees and replace with Tree.changes_from throughout bzrlib.
236
            changes = other_basis_tree.changes_from(self.other_tree)
1185.12.83 by Aaron Bentley
Preliminary weave merge support
237
            if changes.has_changed():
238
                raise WorkingTreeNotRevision(self.this_tree)
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
239
            other_rev_id = self.other_basis
1185.12.83 by Aaron Bentley
Preliminary weave merge support
240
            self.other_tree = other_basis_tree
241
242
    def file_revisions(self, file_id):
243
        self.ensure_revision_trees()
244
        def get_id(tree, file_id):
245
            revision_id = tree.inventory[file_id].revision
246
            return revision_id
1185.35.5 by Aaron Bentley
Made weave merge succeed if interesting files match history
247
        if self.this_rev_id is None:
248
            if self.this_basis_tree.get_file_sha1(file_id) != \
249
                self.this_tree.get_file_sha1(file_id):
250
                raise WorkingTreeNotRevision(self.this_tree)
251
252
        trees = (self.this_basis_tree, self.other_tree)
1185.12.83 by Aaron Bentley
Preliminary weave merge support
253
        return [get_id(tree, file_id) for tree in trees]
254
1185.82.44 by Aaron Bentley
Switch to merge_changeset in test suite
255
    def check_basis(self, check_clean, require_commits=True):
256
        if self.this_basis is None and require_commits is True:
2249.3.1 by John Arbash Meinel
Mention using 'bzr pull' if there are no commits in current branch
257
            raise BzrCommandError("This branch has no commits."
258
                                  " (perhaps you would prefer 'bzr pull')")
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
259
        if check_clean:
260
            self.compare_basis()
261
            if self.this_basis != self.this_rev_id:
2796.2.1 by Aaron Bentley
Begin work on reconfigure command
262
                raise errors.UncommittedChanges(self.this_tree)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
263
264
    def compare_basis(self):
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
265
        try:
266
            basis_tree = self.revision_tree(self.this_tree.last_revision())
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.
267
        except errors.NoSuchRevision:
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
268
            basis_tree = self.this_tree.basis_tree()
269
        changes = self.this_tree.changes_from(basis_tree)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
270
        if not changes.has_changed():
271
            self.this_rev_id = self.this_basis
272
273
    def set_interesting_files(self, file_list):
2590.2.7 by Aaron Bentley
Misc cleanup
274
        self.interesting_files = file_list
1457.1.8 by Robert Collins
Replace the WorkingTree.revert method algorithm with a call to merge_inner.
275
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
276
    def set_pending(self):
2644.1.1 by Wouter van Heyst
Fix bug #127115 by checking for self.other_rev_id being None in Merger.set_pending()
277
        if not self.base_is_ancestor or not self.base_is_other_ancestor or self.other_rev_id is None:
1185.12.77 by Aaron Bentley
Prevented all ancestors from being marked as pending merges
278
            return
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
279
        self._add_parent()
280
281
    def _add_parent(self):
282
        new_parents = self.this_tree.get_parent_ids() + [self.other_rev_id]
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
283
        new_parent_trees = []
284
        for revision_id in new_parents:
285
            try:
286
                tree = self.revision_tree(revision_id)
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.
287
            except errors.NoSuchRevision:
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
288
                tree = None
289
            else:
290
                tree.lock_read()
291
            new_parent_trees.append((revision_id, tree))
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
292
        try:
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
293
            self.this_tree.set_parent_trees(new_parent_trees,
294
                                            allow_leftmost_as_ghost=True)
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
295
        finally:
296
            for _revision_id, tree in new_parent_trees:
2590.2.20 by Aaron Bentley
Fix handling of ghost base trees
297
                if tree is not None:
298
                    tree.unlock()
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
299
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
300
    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.
301
        """Set the revision and tree to merge from.
302
303
        This sets the other_tree, other_rev_id, other_basis attributes.
304
305
        :param other_revision: The [path, revision] list to merge from.
306
        """
2485.8.58 by Vincent Ladeuil
merge bzr.dev@1617
307
        self.other_branch, self.other_tree = self._get_tree(other_revision,
308
                                                            possible_transports)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
309
        if other_revision[1] == -1:
2598.5.4 by Aaron Bentley
Restore original Branch.last_revision behavior, fix bits that care
310
            self.other_rev_id = _mod_revision.ensure_null(
311
                self.other_branch.last_revision())
2598.5.1 by Aaron Bentley
Start eliminating the use of None to indicate null revision
312
            if _mod_revision.is_null(self.other_rev_id):
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
313
                raise NoCommits(self.other_branch)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
314
            self.other_basis = self.other_rev_id
315
        elif other_revision[1] is not None:
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
316
            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
317
            self.other_basis = self.other_rev_id
318
        else:
319
            self.other_rev_id = None
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
320
            self.other_basis = self.other_branch.last_revision()
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
321
            if self.other_basis is None:
2100.3.31 by Aaron Bentley
Merged bzr.dev (17 tests failing)
322
                raise NoCommits(self.other_branch)
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
323
        if self.other_rev_id is not None:
324
            self._cached_trees[self.other_rev_id] = self.other_tree
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
325
        self._maybe_fetch(self.other_branch,self.this_branch, self.other_basis)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
326
2100.3.29 by Aaron Bentley
Get merge working initially
327
    def set_other_revision(self, revision_id, other_branch):
328
        """Set 'other' based on a branch and revision id
329
330
        :param revision_id: The revision to use for a tree
331
        :param other_branch: The branch containing this tree
332
        """
333
        self.other_rev_id = revision_id
334
        self.other_branch = other_branch
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
335
        self._maybe_fetch(other_branch, self.this_branch, self.other_rev_id)
2100.3.29 by Aaron Bentley
Get merge working initially
336
        self.other_tree = self.revision_tree(revision_id)
337
        self.other_basis = revision_id
338
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
339
    def set_base_revision(self, revision_id, branch):
340
        """Set 'base' based on a branch and revision id
341
342
        :param revision_id: The revision to use for a tree
343
        :param branch: The branch containing this tree
344
        """
345
        self.base_rev_id = revision_id
346
        self.base_branch = branch
2520.4.132 by Aaron Bentley
Merge from bzr.dev
347
        self._maybe_fetch(branch, self.this_branch, revision_id)
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
348
        self.base_tree = self.revision_tree(revision_id)
2520.4.132 by Aaron Bentley
Merge from bzr.dev
349
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
350
    def _maybe_fetch(self, source, target, revision_id):
2665.5.2 by Aaron Bentley
Switch commit and merge to Repository.has_same_location
351
        if not source.repository.has_same_location(target.repository):
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
352
            target.fetch(source, revision_id)
2520.4.110 by Aaron Bentley
Implement cherrypick support for merge directives
353
1185.82.25 by Aaron Bentley
Added changeset-merging functionality
354
    def find_base(self):
2590.2.22 by Aaron Bentley
Remove cruft
355
        revisions = [ensure_null(self.this_basis),
356
                     ensure_null(self.other_basis)]
357
        if NULL_REVISION in revisions:
358
            self.base_rev_id = NULL_REVISION
359
        else:
3146.5.1 by Aaron Bentley
Make merge --uncommitted work with merge-type weave
360
            self.base_rev_id, steps = self.revision_graph.find_unique_lca(
361
                revisions[0], revisions[1], count_steps=True)
2590.2.22 by Aaron Bentley
Remove cruft
362
            if self.base_rev_id == NULL_REVISION:
363
                raise UnrelatedBranches()
1551.19.10 by Aaron Bentley
Merge now warns when it encounters a criss-cross
364
            if steps > 1:
1551.19.11 by Aaron Bentley
Add criss-cross help topic
365
                warning('Warning: criss-cross merge encountered.  See bzr'
366
                        ' help criss-cross.')
2590.2.13 by Aaron Bentley
Make find_base implement the base_finding code
367
        self.base_tree = self.revision_tree(self.base_rev_id)
368
        self.base_is_ancestor = True
2590.2.18 by Aaron Bentley
Merge is_ancestor fix
369
        self.base_is_other_ancestor = True
1185.82.25 by Aaron Bentley
Added changeset-merging functionality
370
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
371
    def set_base(self, base_revision):
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
372
        """Set the base revision to use for the merge.
373
374
        :param base_revision: A 2-list containing a path and revision number.
375
        """
1185.12.96 by Aaron Bentley
Merge from mpool
376
        mutter("doing merge() with no base_revision specified")
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
377
        if base_revision == [None, None]:
2590.2.13 by Aaron Bentley
Make find_base implement the base_finding code
378
            self.find_base()
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
379
        else:
2590.2.11 by Aaron Bentley
Aggressively cache trees, use dirstate. re-mplement _add_parent.
380
            base_branch, self.base_tree = self._get_tree(base_revision)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
381
            if base_revision[1] == -1:
382
                self.base_rev_id = base_branch.last_revision()
383
            elif base_revision[1] is None:
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
384
                self.base_rev_id = _mod_revision.NULL_REVISION
493 by Martin Pool
- Merge aaron's merge command
385
            else:
2598.5.3 by Aaron Bentley
Push NULL_REVISION deeper
386
                self.base_rev_id = _mod_revision.ensure_null(
387
                    base_branch.get_rev_id(base_revision[1]))
2590.2.19 by Aaron Bentley
Avoid fetch within a repository
388
            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
389
3008.1.8 by Michael Hudson
extract merger creation into a method
390
    def make_merger(self):
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
391
        kwargs = {'working_tree':self.this_tree, 'this_tree': self.this_tree,
392
                  'other_tree': self.other_tree,
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
393
                  'interesting_ids': self.interesting_ids,
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
394
                  'interesting_files': self.interesting_files,
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
395
                  'pp': self.pp,
396
                  'do_merge': False}
1534.7.84 by Aaron Bentley
Added reprocess support, support for varying merge types
397
        if self.merge_type.requires_base:
398
            kwargs['base_tree'] = self.base_tree
1534.7.137 by Aaron Bentley
Avoided generating a new tree for every weave merge
399
        if self.merge_type.supports_reprocess:
400
            kwargs['reprocess'] = self.reprocess
401
        elif self.reprocess:
1551.6.14 by Aaron Bentley
Tweaks from merge review
402
            raise BzrError("Conflict reduction is not supported for merge"
403
                                  " type %s." % self.merge_type)
1534.7.137 by Aaron Bentley
Avoided generating a new tree for every weave merge
404
        if self.merge_type.supports_show_base:
405
            kwargs['show_base'] = self.show_base
406
        elif self.show_base:
1534.8.2 by Aaron Bentley
Implemented weave merge
407
            raise BzrError("Showing base is not supported for this"
3008.1.14 by Michael Hudson
trivial commit for testing
408
                           " merge type. %s" % self.merge_type)
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
409
        if (not getattr(self.merge_type, 'supports_reverse_cherrypick', True)
410
            and not self.base_is_other_ancestor):
411
            raise errors.CannotReverseCherrypick()
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
412
        if self.merge_type.supports_cherrypick:
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
413
            kwargs['cherrypick'] = (not self.base_is_ancestor or
414
                                    not self.base_is_other_ancestor)
3008.1.8 by Michael Hudson
extract merger creation into a method
415
        return self.merge_type(pb=self._pb,
416
                               change_reporter=self.change_reporter,
417
                               **kwargs)
418
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
419
    def _do_merge_to(self, merge):
420
        merge.do_merge()
421
        if self.recurse == 'down':
422
            for relpath, file_id in self.this_tree.iter_references():
423
                sub_tree = self.this_tree.get_nested_tree(file_id, relpath)
424
                other_revision = self.other_tree.get_reference_revision(
425
                    file_id, relpath)
426
                if  other_revision == sub_tree.last_revision():
427
                    continue
428
                sub_merge = Merger(sub_tree.branch, this_tree=sub_tree)
429
                sub_merge.merge_type = self.merge_type
430
                other_branch = self.other_branch.reference_parent(file_id, relpath)
431
                sub_merge.set_other_revision(other_revision, other_branch)
432
                base_revision = self.base_tree.get_reference_revision(file_id)
433
                sub_merge.base_tree = \
434
                    sub_tree.branch.repository.revision_tree(base_revision)
435
                sub_merge.base_rev_id = base_revision
436
                sub_merge.do_merge()
437
        
3008.1.8 by Michael Hudson
extract merger creation into a method
438
    def do_merge(self):
2255.2.50 by John Arbash Meinel
merge only needs a lock_tree_write() on the working tree, not a full lock_write()
439
        self.this_tree.lock_tree_write()
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
440
        try:
441
            if self.base_tree is not None:
3619.6.4 by Mark Hammond
do_merge gets one 'finally' per lock so locks always released on failure.
442
                self.base_tree.lock_read()
443
            try:
444
                if self.other_tree is not None:
445
                    self.other_tree.lock_read()
446
                try:
447
                    merge = self.make_merger()
448
                    self._do_merge_to(merge)
449
                finally:
450
                    if self.other_tree is not None:
451
                        self.other_tree.unlock()
452
            finally:
453
                if self.base_tree is not None:
454
                    self.base_tree.unlock()
455
        finally:
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
456
            self.this_tree.unlock()
1534.7.151 by Aaron Bentley
Fixed all changes applied successfully
457
        if len(merge.cooked_conflicts) == 0:
3200.1.1 by James Westby
Make pull --quiet more quiet. Fixes #185907.
458
            if not self.ignore_zero and not is_quiet():
1534.7.141 by Aaron Bentley
Added conflict reporting
459
                note("All changes applied successfully.")
460
        else:
461
            note("%d conflicts encountered." % len(merge.cooked_conflicts))
462
1534.7.134 by Aaron Bentley
Hid raw conflicts
463
        return len(merge.cooked_conflicts)
1185.12.76 by Aaron Bentley
Refactored merge and merge_inner to use Merger
464
1545.2.4 by Aaron Bentley
PEP8 fixes
465
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
466
class Merge3Merger(object):
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
467
    """Three-way merger that uses the merge3 text merger"""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
468
    requires_base = True
469
    supports_reprocess = True
470
    supports_show_base = True
471
    history_based = False
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
472
    supports_cherrypick = True
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
473
    supports_reverse_cherrypick = True
2590.2.7 by Aaron Bentley
Misc cleanup
474
    winner_idx = {"this": 2, "other": 1, "conflict": 1}
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
475
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
476
    def __init__(self, working_tree, this_tree, base_tree, other_tree, 
1558.2.2 by Aaron Bentley
Make remerge honour interesting-ids
477
                 interesting_ids=None, reprocess=False, show_base=False,
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
478
                 pb=DummyProgress(), pp=None, change_reporter=None,
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
479
                 interesting_files=None, do_merge=True,
480
                 cherrypick=False):
2590.2.10 by Aaron Bentley
Updates from review
481
        """Initialize the merger object and perform the merge.
482
483
        :param working_tree: The working tree to apply the merge to
484
        :param this_tree: The local tree in the merge operation
485
        :param base_tree: The common tree in the merge operation
486
        :param other_tree: The other other tree to merge changes from
487
        :param interesting_ids: The file_ids of files that should be
488
            participate in the merge.  May not be combined with
489
            interesting_files.
490
        :param: reprocess If True, perform conflict-reduction processing.
491
        :param show_base: If True, show the base revision in text conflicts.
492
            (incompatible with reprocess)
493
        :param pb: A Progress bar
494
        :param pp: A ProgressPhase object
495
        :param change_reporter: An object that should report changes made
496
        :param interesting_files: The tree-relative paths of files that should
497
            participate in the merge.  If these paths refer to directories,
498
            the contents of those directories will also be included.  May not
499
            be combined with interesting_ids.  If neither interesting_files nor
500
            interesting_ids is specified, all files may participate in the
501
            merge.
502
        """
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
503
        object.__init__(self)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
504
        if interesting_files is not None and interesting_ids is not None:
505
            raise ValueError(
506
                'specify either interesting_ids or interesting_files')
2590.2.4 by Aaron Bentley
Move entry generation to a helper
507
        self.interesting_ids = interesting_ids
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
508
        self.interesting_files = interesting_files
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
509
        self.this_tree = working_tree
510
        self.base_tree = base_tree
511
        self.other_tree = other_tree
512
        self._raw_conflicts = []
513
        self.cooked_conflicts = []
514
        self.reprocess = reprocess
515
        self.show_base = show_base
1534.9.1 by Aaron Bentley
Added progress bars to merge
516
        self.pb = pb
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
517
        self.pp = pp
1551.11.9 by Aaron Bentley
Apply change reporting to merge
518
        self.change_reporter = change_reporter
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
519
        self.cherrypick = cherrypick
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
520
        if self.pp is None:
521
            self.pp = ProgressPhase("Merge phase", 3, self.pb)
3008.1.11 by Michael Hudson
restore the default behaviour of Merge3Merger.__init__().
522
        if do_merge:
523
            self.do_merge()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
524
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
525
    def do_merge(self):
526
        self.this_tree.lock_tree_write()
527
        self.base_tree.lock_read()
528
        self.other_tree.lock_read()
529
        self.tt = TreeTransform(self.this_tree, self.pb)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
530
        try:
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
531
            self.pp.next_phase()
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
532
            self._compute_transform()
1551.2.32 by Aaron Bentley
Handle progress phases more nicely in merge
533
            self.pp.next_phase()
2590.2.17 by Aaron Bentley
Avoid redundant conflict check
534
            results = self.tt.apply(no_conflicts=True)
1558.4.3 by Aaron Bentley
Merge_modified performance/concurrency fix
535
            self.write_modified(results)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
536
            try:
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
537
                self.this_tree.add_conflicts(self.cooked_conflicts)
1534.10.12 by Aaron Bentley
Merge produces new conflicts
538
            except UnsupportedOperation:
539
                pass
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
540
        finally:
1711.7.7 by John Arbash Meinel
Don't squelch errors in tt.finalize()
541
            self.tt.finalize()
2255.7.52 by Robert Collins
Lock trees in Merge3Merger correctly.
542
            self.other_tree.unlock()
543
            self.base_tree.unlock()
544
            self.this_tree.unlock()
1551.2.31 by Aaron Bentley
Got merge and revert using nested pbs
545
            self.pb.clear()
1534.7.192 by Aaron Bentley
Record hashes produced by merges
546
3008.1.9 by Michael Hudson
wanton hacking that lets me write an efficient version of get_diff_as_merged
547
    def make_preview_transform(self):
548
        self.base_tree.lock_read()
549
        self.other_tree.lock_read()
550
        self.tt = TransformPreview(self.this_tree)
551
        try:
552
            self.pp.next_phase()
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
553
            self._compute_transform()
3008.1.9 by Michael Hudson
wanton hacking that lets me write an efficient version of get_diff_as_merged
554
            self.pp.next_phase()
555
        finally:
556
            self.other_tree.unlock()
557
            self.base_tree.unlock()
558
            self.pb.clear()
559
        return self.tt
560
3008.1.21 by Aaron Bentley
Make compute_transform private, test make_preview_transform
561
    def _compute_transform(self):
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
562
        entries = self._entries3()
563
        child_pb = ui.ui_factory.nested_progress_bar()
564
        try:
565
            for num, (file_id, changed, parents3, names3,
566
                      executable3) in enumerate(entries):
567
                child_pb.update('Preparing file merge', num, len(entries))
568
                self._merge_names(file_id, parents3, names3)
569
                if changed:
570
                    file_status = self.merge_contents(file_id)
571
                else:
572
                    file_status = 'unmodified'
573
                self._merge_executable(file_id,
574
                    executable3, file_status)
575
        finally:
576
            child_pb.finished()
577
        self.fix_root()
578
        self.pp.next_phase()
579
        child_pb = ui.ui_factory.nested_progress_bar()
580
        try:
581
            fs_conflicts = resolve_conflicts(self.tt, child_pb,
582
                lambda t, c: conflict_pass(t, c, self.other_tree))
583
        finally:
584
            child_pb.finished()
585
        if self.change_reporter is not None:
586
            from bzrlib import delta
587
            delta.report_changes(
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
588
                self.tt.iter_changes(), self.change_reporter)
3008.1.6 by Michael Hudson
chop up Merge3Merger.__init__ into pieces
589
        self.cook_conflicts(fs_conflicts)
590
        for conflict in self.cooked_conflicts:
591
            warning(conflict)
592
2590.2.4 by Aaron Bentley
Move entry generation to a helper
593
    def _entries3(self):
2590.2.7 by Aaron Bentley
Misc cleanup
594
        """Gather data about files modified between three trees.
595
596
        Return a list of tuples of file_id, changed, parents3, names3,
597
        executable3.  changed is a boolean indicating whether the file contents
598
        or kind were changed.  parents3 is a tuple of parent ids for base,
599
        other and this.  names3 is a tuple of names for base, other and this.
600
        executable3 is a tuple of execute-bit values for base, other and this.
601
        """
2590.2.4 by Aaron Bentley
Move entry generation to a helper
602
        result = []
3254.1.1 by Aaron Bentley
Make Tree.iter_changes a public method
603
        iterator = self.other_tree.iter_changes(self.base_tree,
3514.2.16 by John Arbash Meinel
Review feedback from Ian.
604
                include_unchanged=True, specific_files=self.interesting_files,
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
605
                extra_trees=[self.this_tree])
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
606
        this_entries = dict((e.file_id, e) for p, e in
607
                            self.this_tree.iter_entries_by_dir(
608
                            self.interesting_ids))
2590.2.4 by Aaron Bentley
Move entry generation to a helper
609
        for (file_id, paths, changed, versioned, parents, names, kind,
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
610
             executable) in iterator:
2590.2.4 by Aaron Bentley
Move entry generation to a helper
611
            if (self.interesting_ids is not None and
612
                file_id not in self.interesting_ids):
613
                continue
3363.17.1 by Aaron Bentley
Avoid inventory for merge and transform code
614
            entry = this_entries.get(file_id)
615
            if entry is not None:
2590.2.4 by Aaron Bentley
Move entry generation to a helper
616
                this_name = entry.name
617
                this_parent = entry.parent_id
618
                this_executable = entry.executable
619
            else:
620
                this_name = None
621
                this_parent = None
622
                this_executable = None
623
            parents3 = parents + (this_parent,)
624
            names3 = names + (this_name,)
625
            executable3 = executable + (this_executable,)
626
            result.append((file_id, changed, parents3, names3, executable3))
627
        return result
628
1731.1.33 by Aaron Bentley
Revert no-special-root changes
629
    def fix_root(self):
630
        try:
631
            self.tt.final_kind(self.tt.root)
632
        except NoSuchFile:
633
            self.tt.cancel_deletion(self.tt.root)
634
        if self.tt.final_file_id(self.tt.root) is None:
635
            self.tt.version_file(self.tt.tree_file_id(self.tt.root), 
636
                                 self.tt.root)
637
        if self.other_tree.inventory.root is None:
638
            return
2946.3.3 by John Arbash Meinel
Prefer tree.get_root_id() as more explicit than tree.path2id('')
639
        other_root_file_id = self.other_tree.get_root_id()
1731.1.33 by Aaron Bentley
Revert no-special-root changes
640
        other_root = self.tt.trans_id_file_id(other_root_file_id)
641
        if other_root == self.tt.root:
642
            return
643
        try:
644
            self.tt.final_kind(other_root)
645
        except NoSuchFile:
646
            return
3649.3.1 by Jelmer Vernooij
Merging from a previously joined branch will no longer cause a traceback.
647
        if self.other_tree.inventory.root.file_id in self.this_tree.inventory:
648
            # the other tree's root is a non-root in the current tree
649
            return
1731.1.33 by Aaron Bentley
Revert no-special-root changes
650
        self.reparent_children(self.other_tree.inventory.root, self.tt.root)
651
        self.tt.cancel_creation(other_root)
652
        self.tt.cancel_versioning(other_root)
653
654
    def reparent_children(self, ie, target):
655
        for thing, child in ie.children.iteritems():
656
            trans_id = self.tt.trans_id_file_id(child.file_id)
657
            self.tt.adjust_path(self.tt.final_name(trans_id), target, trans_id)
658
1534.7.192 by Aaron Bentley
Record hashes produced by merges
659
    def write_modified(self, results):
660
        modified_hashes = {}
661
        for path in results.modified_paths:
662
            file_id = self.this_tree.path2id(self.this_tree.relpath(path))
663
            if file_id is None:
664
                continue
665
            hash = self.this_tree.get_file_sha1(file_id)
666
            if hash is None:
667
                continue
668
            modified_hashes[file_id] = hash
669
        self.this_tree.set_merge_modified(modified_hashes)
670
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
671
    @staticmethod
672
    def parent(entry, file_id):
1534.7.157 by Aaron Bentley
Added more docs
673
        """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
674
        if entry is None:
675
            return None
676
        return entry.parent_id
677
678
    @staticmethod
679
    def name(entry, file_id):
1534.7.157 by Aaron Bentley
Added more docs
680
        """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
681
        if entry is None:
682
            return None
683
        return entry.name
684
    
685
    @staticmethod
686
    def contents_sha1(tree, file_id):
1534.7.157 by Aaron Bentley
Added more docs
687
        """Determine the sha1 of the file contents (used as a key method)."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
688
        if file_id not in tree:
689
            return None
690
        return tree.get_file_sha1(file_id)
691
692
    @staticmethod
693
    def executable(tree, file_id):
1534.7.157 by Aaron Bentley
Added more docs
694
        """Determine the executability of a file-id (used as a key method)."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
695
        if file_id not in tree:
696
            return None
697
        if tree.kind(file_id) != "file":
698
            return False
699
        return tree.is_executable(file_id)
700
701
    @staticmethod
702
    def kind(tree, file_id):
1534.7.157 by Aaron Bentley
Added more docs
703
        """Determine the kind of a file-id (used as a key method)."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
704
        if file_id not in tree:
705
            return None
706
        return tree.kind(file_id)
707
708
    @staticmethod
2590.2.8 by Aaron Bentley
Restore conflict handling changes
709
    def _three_way(base, other, this):
710
        #if base == other, either they all agree, or only THIS has changed.
711
        if base == other:
712
            return 'this'
2590.2.10 by Aaron Bentley
Updates from review
713
        elif this not in (base, other):
2590.2.8 by Aaron Bentley
Restore conflict handling changes
714
            return 'conflict'
2590.2.10 by Aaron Bentley
Updates from review
715
        # "Ambiguous clean merge" -- both sides have made the same change.
2590.2.8 by Aaron Bentley
Restore conflict handling changes
716
        elif this == other:
717
            return "this"
2590.2.10 by Aaron Bentley
Updates from review
718
        # this == base: only other has changed.
2590.2.8 by Aaron Bentley
Restore conflict handling changes
719
        else:
720
            return "other"
721
722
    @staticmethod
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
723
    def scalar_three_way(this_tree, base_tree, other_tree, file_id, key):
724
        """Do a three-way test on a scalar.
725
        Return "this", "other" or "conflict", depending whether a value wins.
726
        """
727
        key_base = key(base_tree, file_id)
728
        key_other = key(other_tree, file_id)
729
        #if base == other, either they all agree, or only THIS has changed.
730
        if key_base == key_other:
731
            return "this"
732
        key_this = key(this_tree, file_id)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
733
        # "Ambiguous clean merge"
734
        if key_this == key_other:
735
            return "this"
736
        elif key_this == key_base:
737
            return "other"
738
        else:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
739
            return "conflict"
740
741
    def merge_names(self, file_id):
742
        def get_entry(tree):
743
            if file_id in tree.inventory:
744
                return tree.inventory[file_id]
745
            else:
746
                return None
747
        this_entry = get_entry(self.this_tree)
748
        other_entry = get_entry(self.other_tree)
749
        base_entry = get_entry(self.base_tree)
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
750
        entries = (base_entry, other_entry, this_entry)
751
        names = []
752
        parents = []
753
        for entry in entries:
754
            if entry is None:
755
                names.append(None)
756
                parents.append(None)
757
            else:
758
                names.append(entry.name)
759
                parents.append(entry.parent_id)
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
760
        return self._merge_names(file_id, parents, names)
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
761
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
762
    def _merge_names(self, file_id, parents, names):
2590.2.7 by Aaron Bentley
Misc cleanup
763
        """Perform a merge on file_id names and parents"""
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
764
        base_name, other_name, this_name = names
765
        base_parent, other_parent, this_parent = parents
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
766
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
767
        name_winner = self._three_way(*names)
768
769
        parent_id_winner = self._three_way(*parents)
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
770
        if this_name is None:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
771
            if name_winner == "this":
772
                name_winner = "other"
773
            if parent_id_winner == "this":
774
                parent_id_winner = "other"
775
        if name_winner == "this" and parent_id_winner == "this":
776
            return
777
        if name_winner == "conflict":
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
778
            trans_id = self.tt.trans_id_file_id(file_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
779
            self._raw_conflicts.append(('name conflict', trans_id, 
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
780
                                        this_name, other_name))
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
781
        if parent_id_winner == "conflict":
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
782
            trans_id = self.tt.trans_id_file_id(file_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
783
            self._raw_conflicts.append(('parent conflict', trans_id, 
2590.2.1 by Aaron Bentley
Start work on merging names based on iter_changes
784
                                        this_parent, other_parent))
2590.2.2 by Aaron Bentley
Do most name merging from iter_changes output
785
        if other_name is None:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
786
            # it doesn't matter whether the result was 'other' or 
787
            # 'conflict'-- if there's no 'other', we leave it alone.
788
            return
789
        # if we get here, name_winner and parent_winner are set to safe values.
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
790
        trans_id = self.tt.trans_id_file_id(file_id)
2590.2.7 by Aaron Bentley
Misc cleanup
791
        parent_id = parents[self.winner_idx[parent_id_winner]]
1731.1.33 by Aaron Bentley
Revert no-special-root changes
792
        if parent_id is not None:
793
            parent_trans_id = self.tt.trans_id_file_id(parent_id)
2590.2.7 by Aaron Bentley
Misc cleanup
794
            self.tt.adjust_path(names[self.winner_idx[name_winner]],
1731.1.33 by Aaron Bentley
Revert no-special-root changes
795
                                parent_trans_id, trans_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
796
797
    def merge_contents(self, file_id):
1534.7.157 by Aaron Bentley
Added more docs
798
        """Performa a merge on file_id contents."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
799
        def contents_pair(tree):
800
            if file_id not in tree:
801
                return (None, None)
802
            kind = tree.kind(file_id)
803
            if kind == "file":
804
                contents = tree.get_file_sha1(file_id)
805
            elif kind == "symlink":
806
                contents = tree.get_symlink_target(file_id)
807
            else:
808
                contents = None
809
            return kind, contents
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
810
811
        def contents_conflict():
812
            trans_id = self.tt.trans_id_file_id(file_id)
813
            name = self.tt.final_name(trans_id)
814
            parent_id = self.tt.final_parent(trans_id)
815
            if file_id in self.this_tree.inventory:
816
                self.tt.unversion_file(trans_id)
1551.10.2 by Aaron Bentley
Handle merge with dangling inventory entries
817
                if file_id in self.this_tree:
818
                    self.tt.delete_contents(trans_id)
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
819
            file_group = self._dump_conflicts(name, parent_id, file_id, 
820
                                              set_version=True)
821
            self._raw_conflicts.append(('contents conflict', file_group))
822
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
823
        # See SPOT run.  run, SPOT, run.
824
        # So we're not QUITE repeating ourselves; we do tricky things with
825
        # file kind...
826
        base_pair = contents_pair(self.base_tree)
827
        other_pair = contents_pair(self.other_tree)
828
        if base_pair == other_pair:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
829
            # OTHER introduced no changes
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
830
            return "unmodified"
831
        this_pair = contents_pair(self.this_tree)
832
        if this_pair == other_pair:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
833
            # THIS and OTHER introduced the same changes
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
834
            return "unmodified"
835
        else:
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
836
            trans_id = self.tt.trans_id_file_id(file_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
837
            if this_pair == base_pair:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
838
                # only OTHER introduced changes
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
839
                if file_id in self.this_tree:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
840
                    # Remove any existing contents
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
841
                    self.tt.delete_contents(trans_id)
1534.7.147 by Aaron Bentley
Tweak to check inventory, not tree for file ids
842
                if file_id in self.other_tree:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
843
                    # OTHER changed the file
3363.17.5 by Aaron Bentley
Update merge to not use inventory
844
                    create_by_entry(self.tt,
845
                                    self.other_tree.inventory[file_id],
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
846
                                    self.other_tree, trans_id)
3363.17.5 by Aaron Bentley
Update merge to not use inventory
847
                    if file_id not in self.this_tree:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
848
                        self.tt.version_file(file_id, trans_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
849
                    return "modified"
1534.7.147 by Aaron Bentley
Tweak to check inventory, not tree for file ids
850
                elif file_id in self.this_tree.inventory:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
851
                    # OTHER deleted the file
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
852
                    self.tt.unversion_file(trans_id)
853
                    return "deleted"
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
854
            #BOTH THIS and OTHER introduced changes; scalar conflict
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
855
            elif this_pair[0] == "file" and other_pair[0] == "file":
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
856
                # THIS and OTHER are both files, so text merge.  Either
857
                # BASE is a file, or both converted to files, so at least we
858
                # have agreement that output should be a file.
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
859
                try:
860
                    self.text_merge(file_id, trans_id)
861
                except BinaryFile:
862
                    return contents_conflict()
3363.17.8 by Aaron Bentley
Get merge into a preview tree working
863
                if file_id not in self.this_tree:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
864
                    self.tt.version_file(file_id, trans_id)
1534.7.152 by Aaron Bentley
Fixed overwrites
865
                try:
866
                    self.tt.tree_kind(trans_id)
867
                    self.tt.delete_contents(trans_id)
868
                except NoSuchFile:
869
                    pass
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
870
                return "modified"
871
            else:
1534.7.145 by Aaron Bentley
More fixups after get_trans_id
872
                # Scalar conflict, can't text merge.  Dump conflicts
1558.15.3 by Aaron Bentley
Handle binary files for diff3 merges
873
                return contents_conflict()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
874
875
    def get_lines(self, tree, file_id):
1534.7.157 by Aaron Bentley
Added more docs
876
        """Return the lines in a file, or an empty list."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
877
        if file_id in tree:
878
            return tree.get_file(file_id).readlines()
879
        else:
880
            return []
881
882
    def text_merge(self, file_id, trans_id):
883
        """Perform a three-way text merge on a file_id"""
884
        # it's possible that we got here with base as a different type.
885
        # if so, we just want two-way text conflicts.
886
        if file_id in self.base_tree and \
887
            self.base_tree.kind(file_id) == "file":
888
            base_lines = self.get_lines(self.base_tree, file_id)
889
        else:
890
            base_lines = []
891
        other_lines = self.get_lines(self.other_tree, file_id)
892
        this_lines = self.get_lines(self.this_tree, file_id)
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
893
        m3 = Merge3(base_lines, this_lines, other_lines,
894
                    is_cherrypick=self.cherrypick)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
895
        start_marker = "!START OF MERGE CONFLICT!" + "I HOPE THIS IS UNIQUE"
896
        if self.show_base is True:
897
            base_marker = '|' * 7
898
        else:
899
            base_marker = None
900
901
        def iter_merge3(retval):
902
            retval["text_conflicts"] = False
903
            for line in m3.merge_lines(name_a = "TREE", 
904
                                       name_b = "MERGE-SOURCE", 
905
                                       name_base = "BASE-REVISION",
906
                                       start_marker=start_marker, 
907
                                       base_marker=base_marker,
908
                                       reprocess=self.reprocess):
909
                if line.startswith(start_marker):
910
                    retval["text_conflicts"] = True
911
                    yield line.replace(start_marker, '<' * 7)
912
                else:
913
                    yield line
914
        retval = {}
915
        merge3_iterator = iter_merge3(retval)
916
        self.tt.create_file(merge3_iterator, trans_id)
917
        if retval["text_conflicts"] is True:
918
            self._raw_conflicts.append(('text conflict', trans_id))
919
            name = self.tt.final_name(trans_id)
920
            parent_id = self.tt.final_parent(trans_id)
921
            file_group = self._dump_conflicts(name, parent_id, file_id, 
922
                                              this_lines, base_lines,
923
                                              other_lines)
924
            file_group.append(trans_id)
925
926
    def _dump_conflicts(self, name, parent_id, file_id, this_lines=None, 
927
                        base_lines=None, other_lines=None, set_version=False,
928
                        no_base=False):
1534.7.157 by Aaron Bentley
Added more docs
929
        """Emit conflict files.
930
        If this_lines, base_lines, or other_lines are omitted, they will be
931
        determined automatically.  If set_version is true, the .OTHER, .THIS
932
        or .BASE (in that order) will be created as versioned files.
933
        """
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
934
        data = [('OTHER', self.other_tree, other_lines), 
935
                ('THIS', self.this_tree, this_lines)]
936
        if not no_base:
937
            data.append(('BASE', self.base_tree, base_lines))
938
        versioned = False
939
        file_group = []
940
        for suffix, tree, lines in data:
941
            if file_id in tree:
942
                trans_id = self._conflict_file(name, parent_id, tree, file_id,
943
                                               suffix, lines)
944
                file_group.append(trans_id)
945
                if set_version and not versioned:
946
                    self.tt.version_file(file_id, trans_id)
947
                    versioned = True
948
        return file_group
949
           
950
    def _conflict_file(self, name, parent_id, tree, file_id, suffix, 
951
                       lines=None):
1534.7.157 by Aaron Bentley
Added more docs
952
        """Emit a single conflict file."""
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
953
        name = name + '.' + suffix
954
        trans_id = self.tt.create_path(name, parent_id)
955
        entry = tree.inventory[file_id]
956
        create_by_entry(self.tt, entry, tree, trans_id, lines)
957
        return trans_id
958
959
    def merge_executable(self, file_id, file_status):
1534.7.157 by Aaron Bentley
Added more docs
960
        """Perform a merge on the execute bit."""
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
961
        executable = [self.executable(t, file_id) for t in (self.base_tree,
962
                      self.other_tree, self.this_tree)]
963
        self._merge_executable(file_id, executable, file_status)
964
965
    def _merge_executable(self, file_id, executable, file_status):
966
        """Perform a merge on the execute bit."""
967
        base_executable, other_executable, this_executable = executable
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
968
        if file_status == "deleted":
969
            return
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
970
        winner = self._three_way(*executable)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
971
        if winner == "conflict":
972
        # There must be a None in here, if we have a conflict, but we
973
        # need executability since file status was not deleted.
1534.10.35 by Aaron Bentley
Merge handles contents + executable + deletion conflict
974
            if self.executable(self.other_tree, file_id) is None:
1534.7.142 by Aaron Bentley
Fixed executability conflicts
975
                winner = "this"
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
976
            else:
1534.7.142 by Aaron Bentley
Fixed executability conflicts
977
                winner = "other"
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
978
        if winner == 'this' and file_status != "modified":
979
            return
980
        trans_id = self.tt.trans_id_file_id(file_id)
981
        try:
982
            if self.tt.final_kind(trans_id) != "file":
983
                return
984
        except NoSuchFile:
985
            return
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
986
        if winner == "this":
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
987
            executability = this_executable
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
988
        else:
989
            if file_id in self.other_tree:
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
990
                executability = other_executable
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
991
            elif file_id in self.this_tree:
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
992
                executability = this_executable
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
993
            elif file_id in self.base_tree:
2590.2.3 by Aaron Bentley
Merge the execute bit based on iter_changes
994
                executability = base_executable
1551.19.30 by Aaron Bentley
Accelerate merge by skipping file existence check when merging execute bit
995
        if executability is not None:
996
            trans_id = self.tt.trans_id_file_id(file_id)
997
            self.tt.set_executability(executability, trans_id)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
998
1534.7.172 by Aaron Bentley
Integrated fs conflicts with merge conflicts.
999
    def cook_conflicts(self, fs_conflicts):
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1000
        """Convert all conflicts into a form that doesn't depend on trans_id"""
1534.10.19 by Aaron Bentley
Stanza conversion, cooking
1001
        from conflicts import Conflict
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1002
        name_conflicts = {}
1534.7.172 by Aaron Bentley
Integrated fs conflicts with merge conflicts.
1003
        self.cooked_conflicts.extend(cook_conflicts(fs_conflicts, self.tt))
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1004
        fp = FinalPaths(self.tt)
1005
        for conflict in self._raw_conflicts:
1006
            conflict_type = conflict[0]
1007
            if conflict_type in ('name conflict', 'parent conflict'):
1008
                trans_id = conflict[1]
1009
                conflict_args = conflict[2:]
1010
                if trans_id not in name_conflicts:
1011
                    name_conflicts[trans_id] = {}
1012
                unique_add(name_conflicts[trans_id], conflict_type, 
1013
                           conflict_args)
1014
            if conflict_type == 'contents conflict':
1015
                for trans_id in conflict[1]:
1016
                    file_id = self.tt.final_file_id(trans_id)
1017
                    if file_id is not None:
1018
                        break
1019
                path = fp.get_path(trans_id)
1020
                for suffix in ('.BASE', '.THIS', '.OTHER'):
1021
                    if path.endswith(suffix):
1022
                        path = path[:-len(suffix)]
1023
                        break
1534.10.19 by Aaron Bentley
Stanza conversion, cooking
1024
                c = Conflict.factory(conflict_type, path=path, file_id=file_id)
1025
                self.cooked_conflicts.append(c)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1026
            if conflict_type == 'text conflict':
1027
                trans_id = conflict[1]
1028
                path = fp.get_path(trans_id)
1029
                file_id = self.tt.final_file_id(trans_id)
1534.10.19 by Aaron Bentley
Stanza conversion, cooking
1030
                c = Conflict.factory(conflict_type, path=path, file_id=file_id)
1031
                self.cooked_conflicts.append(c)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1032
1033
        for trans_id, conflicts in name_conflicts.iteritems():
1034
            try:
1035
                this_parent, other_parent = conflicts['parent conflict']
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1036
                if this_parent == other_parent:
1037
                    raise AssertionError()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1038
            except KeyError:
1039
                this_parent = other_parent = \
1040
                    self.tt.final_file_id(self.tt.final_parent(trans_id))
1041
            try:
1042
                this_name, other_name = conflicts['name conflict']
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1043
                if this_name == other_name:
1044
                    raise AssertionError()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1045
            except KeyError:
1046
                this_name = other_name = self.tt.final_name(trans_id)
1047
            other_path = fp.get_path(trans_id)
1551.16.2 by Aaron Bentley
Don't crash on merging renamed deleted files (#110279)
1048
            if this_parent is not None and this_name is not None:
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1049
                this_parent_path = \
1534.7.181 by Aaron Bentley
Renamed a bunch of functions
1050
                    fp.get_path(self.tt.trans_id_file_id(this_parent))
1534.7.166 by Aaron Bentley
Swapped os.path.join for pathjoin everywhere
1051
                this_path = pathjoin(this_parent_path, this_name)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1052
            else:
1053
                this_path = "<deleted>"
1054
            file_id = self.tt.final_file_id(trans_id)
1534.10.20 by Aaron Bentley
Got all tests passing
1055
            c = Conflict.factory('path conflict', path=this_path,
1534.10.19 by Aaron Bentley
Stanza conversion, cooking
1056
                                 conflict_path=other_path, file_id=file_id)
1057
            self.cooked_conflicts.append(c)
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
1058
        self.cooked_conflicts.sort(key=Conflict.sort_key)
1534.7.141 by Aaron Bentley
Added conflict reporting
1059
1060
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1061
class WeaveMerger(Merge3Merger):
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
1062
    """Three-way tree merger, text weave merger."""
1551.6.8 by Aaron Bentley
Implemented reprocess for weave
1063
    supports_reprocess = True
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1064
    supports_show_base = False
3062.2.7 by Aaron Bentley
Prevent reverse cherry-picking with weave
1065
    supports_reverse_cherrypick = False
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
1066
    history_based = True
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1067
1068
    def _merged_lines(self, file_id):
1069
        """Generate the merged lines.
1070
        There is no distinction between lines that are meant to contain <<<<<<<
1071
        and conflicts.
1072
        """
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
1073
        if self.cherrypick:
1074
            base = self.base_tree
1075
        else:
1076
            base = None
3062.2.4 by Aaron Bentley
Start supporting merge-with-base
1077
        plan = self.this_tree.plan_file_merge(file_id, self.other_tree,
3062.2.9 by Aaron Bentley
Don't use the base if not cherrypicking
1078
                                              base=base)
1551.19.17 by Aaron Bentley
Add debugging flag for merges
1079
        if 'merge' in debug.debug_flags:
1080
            plan = list(plan)
1081
            trans_id = self.tt.trans_id_file_id(file_id)
1082
            name = self.tt.final_name(trans_id) + '.plan'
1083
            contents = ('%10s|%s' % l for l in plan)
1084
            self.tt.new_file(name, self.tt.final_parent(trans_id), contents)
1551.15.52 by Aaron Bentley
Tweak from review comments
1085
        textmerge = PlanWeaveMerge(plan, '<<<<<<< TREE\n',
1086
            '>>>>>>> MERGE-SOURCE\n')
1087
        return textmerge.merge_lines(self.reprocess)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1088
1089
    def text_merge(self, file_id, trans_id):
1534.7.157 by Aaron Bentley
Added more docs
1090
        """Perform a (weave) text merge for a given file and file-id.
1091
        If conflicts are encountered, .THIS and .OTHER files will be emitted,
1092
        and a conflict will be noted.
1093
        """
1551.6.12 by Aaron Bentley
Indicate conflicts from merge_lines, insead of guessing
1094
        lines, conflicts = self._merged_lines(file_id)
1558.15.10 by Aaron Bentley
Merge bzr.dev
1095
        lines = list(lines)
1558.15.5 by Aaron Bentley
Fixed binary handling in weave merge
1096
        # Note we're checking whether the OUTPUT is binary in this case, 
1097
        # because we don't want to get into weave merge guts.
1098
        check_text_lines(lines)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1099
        self.tt.create_file(lines, trans_id)
1100
        if conflicts:
1101
            self._raw_conflicts.append(('text conflict', trans_id))
1102
            name = self.tt.final_name(trans_id)
1103
            parent_id = self.tt.final_parent(trans_id)
1104
            file_group = self._dump_conflicts(name, parent_id, file_id, 
1105
                                              no_base=True)
1106
            file_group.append(trans_id)
1107
1108
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1109
class LCAMerger(WeaveMerger):
1110
1111
    def _merged_lines(self, file_id):
1112
        """Generate the merged lines.
1113
        There is no distinction between lines that are meant to contain <<<<<<<
1114
        and conflicts.
1115
        """
1116
        if self.cherrypick:
1117
            base = self.base_tree
1118
        else:
1119
            base = None
1120
        plan = self.this_tree.plan_file_lca_merge(file_id, self.other_tree,
1121
                                                  base=base)
1122
        if 'merge' in debug.debug_flags:
1123
            plan = list(plan)
1124
            trans_id = self.tt.trans_id_file_id(file_id)
1125
            name = self.tt.final_name(trans_id) + '.plan'
1126
            contents = ('%10s|%s' % l for l in plan)
1127
            self.tt.new_file(name, self.tt.final_parent(trans_id), contents)
1128
        textmerge = PlanWeaveMerge(plan, '<<<<<<< TREE\n',
1129
            '>>>>>>> MERGE-SOURCE\n')
1130
        return textmerge.merge_lines(self.reprocess)
1131
1132
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1133
class Diff3Merger(Merge3Merger):
1534.7.167 by Aaron Bentley
PEP8 and comment cleanups
1134
    """Three-way merger using external diff3 for text merging"""
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1135
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1136
    def dump_file(self, temp_dir, name, tree, file_id):
1137
        out_path = pathjoin(temp_dir, name)
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1138
        out_file = open(out_path, "wb")
1139
        try:
1140
            in_file = tree.get_file(file_id)
1141
            for line in in_file:
1142
                out_file.write(line)
1143
        finally:
1144
            out_file.close()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1145
        return out_path
1146
1147
    def text_merge(self, file_id, trans_id):
1534.7.157 by Aaron Bentley
Added more docs
1148
        """Perform a diff3 merge using a specified file-id and trans-id.
1149
        If conflicts are encountered, .BASE, .THIS. and .OTHER conflict files
1150
        will be dumped, and a will be conflict noted.
1151
        """
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1152
        import bzrlib.patch
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
1153
        temp_dir = osutils.mkdtemp(prefix="bzr-")
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1154
        try:
1534.7.166 by Aaron Bentley
Swapped os.path.join for pathjoin everywhere
1155
            new_file = pathjoin(temp_dir, "new")
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1156
            this = self.dump_file(temp_dir, "this", self.this_tree, file_id)
1157
            base = self.dump_file(temp_dir, "base", self.base_tree, file_id)
1158
            other = self.dump_file(temp_dir, "other", self.other_tree, file_id)
1159
            status = bzrlib.patch.diff3(new_file, this, base, other)
1160
            if status not in (0, 1):
1161
                raise BzrError("Unhandled diff3 exit code")
1711.7.20 by John Arbash Meinel
always close files, minor PEP8 cleanup
1162
            f = open(new_file, 'rb')
1163
            try:
1164
                self.tt.create_file(f, trans_id)
1165
            finally:
1166
                f.close()
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1167
            if status == 1:
1168
                name = self.tt.final_name(trans_id)
1169
                parent_id = self.tt.final_parent(trans_id)
1170
                self._dump_conflicts(name, parent_id, file_id)
1551.8.39 by Aaron Bentley
Fix diff3 conflict-reporting bug
1171
                self._raw_conflicts.append(('text conflict', trans_id))
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1172
        finally:
1996.3.18 by John Arbash Meinel
Now that mkdtemp and rmtree are lazy, they should not be directly improted.
1173
            osutils.rmtree(temp_dir)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1174
1175
1176
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.
1177
                backup_files=False,
1178
                merge_type=Merge3Merger,
1179
                interesting_ids=None,
1180
                show_base=False,
1181
                reprocess=False,
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1182
                other_rev_id=None,
1183
                interesting_files=None,
1534.9.9 by Aaron Bentley
Added progress bar to pull
1184
                this_tree=None,
1551.11.10 by Aaron Bentley
Add change reporting to pull
1185
                pb=DummyProgress(),
1186
                change_reporter=None):
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1187
    """Primary interface for merging. 
1188
1189
        typical use is probably 
1190
        'merge_inner(branch, branch.get_revision_tree(other_revision),
1191
                     branch.get_revision_tree(base_revision))'
1192
        """
1193
    if this_tree is None:
2367.2.1 by Robert Collins
Remove bzrlib 0.8 compatability where it was making the code unclear or messy. (Robert Collins)
1194
        raise BzrError("bzrlib.merge.merge_inner requires a this_tree "
1195
            "parameter as of bzrlib version 0.8.")
2255.2.31 by Robert Collins
Work in progress to make merge_inner work with dirstate trees.
1196
    merger = Merger(this_branch, other_tree, base_tree, this_tree=this_tree,
1551.11.10 by Aaron Bentley
Add change reporting to pull
1197
                    pb=pb, change_reporter=change_reporter)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1198
    merger.backup_files = backup_files
1199
    merger.merge_type = merge_type
1200
    merger.interesting_ids = interesting_ids
1551.2.23 by Aaron Bentley
Got merge_inner's ignore_zero parameter working
1201
    merger.ignore_zero = ignore_zero
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1202
    if interesting_files:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1203
        if interesting_ids:
1204
            raise ValueError('Only supply interesting_ids'
1205
                             ' or interesting_files')
2590.2.5 by Aaron Bentley
Allow selected files to be specified instead of selected ids
1206
        merger.interesting_files = interesting_files
1979.2.1 by Robert Collins
(robertc) adds a convenience method "merge_from_branch" to WorkingTree.
1207
    merger.show_base = show_base
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1208
    merger.reprocess = reprocess
1209
    merger.other_rev_id = other_rev_id
1210
    merger.other_basis = other_rev_id
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
1211
    get_revision_id = getattr(base_tree, 'get_revision_id', None)
1212
    if get_revision_id is None:
1213
        get_revision_id = base_tree.last_revision
1214
    merger.set_base_revision(get_revision_id(), this_branch)
1534.7.140 by Aaron Bentley
Moved the merge stuff into merge.py
1215
    return merger.do_merge()
1216
2221.4.15 by Aaron Bentley
Use RegistryOption for merge type
1217
def get_merge_type_registry():
2221.4.17 by Aaron Bentley
PEP8-ness
1218
    """Merge type registry is in bzrlib.option to avoid circular imports.
2221.4.15 by Aaron Bentley
Use RegistryOption for merge type
1219
1220
    This method provides a sanctioned way to retrieve it.
1221
    """
1222
    from bzrlib import option
2221.4.16 by Aaron Bentley
Add tests for get_merge_type_registry
1223
    return option._merge_type_registry
1551.15.46 by Aaron Bentley
Move plan merge to tree
1224
1225
1226
def _plan_annotate_merge(annotated_a, annotated_b, ancestors_a, ancestors_b):
1227
    def status_a(revision, text):
1228
        if revision in ancestors_b:
1229
            return 'killed-b', text
1230
        else:
1231
            return 'new-a', text
1232
1233
    def status_b(revision, text):
1234
        if revision in ancestors_a:
1235
            return 'killed-a', text
1236
        else:
1237
            return 'new-b', text
1238
1239
    plain_a = [t for (a, t) in annotated_a]
1240
    plain_b = [t for (a, t) in annotated_b]
1241
    matcher = patiencediff.PatienceSequenceMatcher(None, plain_a, plain_b)
1242
    blocks = matcher.get_matching_blocks()
1243
    a_cur = 0
1244
    b_cur = 0
1245
    for ai, bi, l in blocks:
1246
        # process all mismatched sections
1247
        # (last mismatched section is handled because blocks always
1248
        # includes a 0-length last block)
1249
        for revision, text in annotated_a[a_cur:ai]:
1250
            yield status_a(revision, text)
1251
        for revision, text in annotated_b[b_cur:bi]:
1252
            yield status_b(revision, text)
1253
        # and now the matched section
1254
        a_cur = ai + l
1255
        b_cur = bi + l
3376.2.8 by Martin Pool
Some review cleanups for assertion removal
1256
        for text_a in plain_a[ai:a_cur]:
1551.15.46 by Aaron Bentley
Move plan merge to tree
1257
            yield "unchanged", text_a
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1258
1259
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1260
class _PlanMergeBase(object):
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1261
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1262
    def __init__(self, a_rev, b_rev, vf, key_prefix):
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1263
        """Contructor.
1264
1265
        :param a_rev: Revision-id of one revision to merge
1266
        :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.
1267
        :param vf: A VersionedFiles containing both revisions
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1268
        :param key_prefix: A prefix for accessing keys in vf, typically
1269
            (file_id,).
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1270
        """
1271
        self.a_rev = a_rev
1272
        self.b_rev = b_rev
1273
        self.vf = vf
3062.1.12 by Aaron Bentley
Implement simple text cache
1274
        self._last_lines = None
1275
        self._last_lines_revision_id = None
3144.3.7 by Aaron Bentley
Update from review
1276
        self._cached_matching_blocks = {}
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1277
        self._key_prefix = key_prefix
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1278
        self._precache_tip_lines()
1279
1280
    def _precache_tip_lines(self):
1281
        lines = self.get_lines([self.a_rev, self.b_rev])
1282
        self.lines_a = lines[self.a_rev]
1283
        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.
1284
1285
    def get_lines(self, revisions):
1286
        """Get lines for revisions from the backing VersionedFiles.
1287
        
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1288
        :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.
1289
        """
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1290
        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.
1291
        result = {}
1292
        for record in self.vf.get_record_stream(keys, 'unordered', True):
1293
            if record.storage_kind == 'absent':
1294
                raise errors.RevisionNotPresent(record.key, self.vf)
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1295
            result[record.key[-1]] = osutils.split_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.
1296
                record.get_bytes_as('fulltext'))
1297
        return result
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1298
1299
    def plan_merge(self):
1300
        """Generate a 'plan' for merging the two revisions.
1301
1302
        This involves comparing their texts and determining the cause of
1303
        differences.  If text A has a line and text B does not, then either the
1304
        line was added to text A, or it was deleted from B.  Once the causes
1305
        are combined, they are written out in the format described in
1306
        VersionedFile.plan_merge
1307
        """
1308
        blocks = self._get_matching_blocks(self.a_rev, self.b_rev)
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1309
        unique_a, unique_b = self._unique_lines(blocks)
1310
        new_a, killed_b = self._determine_status(self.a_rev, unique_a)
1311
        new_b, killed_a = self._determine_status(self.b_rev, unique_b)
1312
        return self._iter_plan(blocks, new_a, killed_b, new_b, killed_a)
1313
1314
    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
1315
        last_i = 0
1316
        last_j = 0
1317
        for i, j, n in blocks:
1318
            for a_index in range(last_i, i):
1319
                if a_index in new_a:
3144.3.2 by Aaron Bentley
Get conflict handling working
1320
                    if a_index in killed_b:
1321
                        yield 'conflicted-a', self.lines_a[a_index]
1322
                    else:
1323
                        yield 'new-a', self.lines_a[a_index]
1324
                else:
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1325
                    yield 'killed-b', self.lines_a[a_index]
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1326
            for b_index in range(last_j, j):
1327
                if b_index in new_b:
3144.3.2 by Aaron Bentley
Get conflict handling working
1328
                    if b_index in killed_a:
3144.3.10 by Aaron Bentley
Use correct index when emitting conflicted-b
1329
                        yield 'conflicted-b', self.lines_b[b_index]
3144.3.2 by Aaron Bentley
Get conflict handling working
1330
                    else:
1331
                        yield 'new-b', self.lines_b[b_index]
1332
                else:
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1333
                    yield 'killed-a', self.lines_b[b_index]
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1334
            # handle common lines
1335
            for a_index in range(i, i+n):
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1336
                yield 'unchanged', self.lines_a[a_index]
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1337
            last_i = i+n
1338
            last_j = j+n
1339
1340
    def _get_matching_blocks(self, left_revision, right_revision):
1341
        """Return a description of which sections of two revisions match.
1342
1343
        See SequenceMatcher.get_matching_blocks
1344
        """
3144.3.7 by Aaron Bentley
Update from review
1345
        cached = self._cached_matching_blocks.get((left_revision,
1346
                                                   right_revision))
1347
        if cached is not None:
1348
            return cached
3062.1.12 by Aaron Bentley
Implement simple text cache
1349
        if self._last_lines_revision_id == left_revision:
1350
            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.
1351
            right_lines = self.get_lines([right_revision])[right_revision]
3062.1.12 by Aaron Bentley
Implement simple text cache
1352
        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.
1353
            lines = self.get_lines([left_revision, right_revision])
1354
            left_lines = lines[left_revision]
1355
            right_lines = lines[right_revision]
3062.1.12 by Aaron Bentley
Implement simple text cache
1356
        self._last_lines = right_lines
1357
        self._last_lines_revision_id = right_revision
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1358
        matcher = patiencediff.PatienceSequenceMatcher(None, left_lines,
1359
                                                       right_lines)
1360
        return matcher.get_matching_blocks()
1361
1362
    def _unique_lines(self, matching_blocks):
1363
        """Analyse matching_blocks to determine which lines are unique
1364
1365
        :return: a tuple of (unique_left, unique_right), where the values are
1366
            sets of line numbers of unique lines.
1367
        """
1368
        last_i = 0
1369
        last_j = 0
1370
        unique_left = []
1371
        unique_right = []
1372
        for i, j, n in matching_blocks:
1373
            unique_left.extend(range(last_i, i))
1374
            unique_right.extend(range(last_j, j))
1375
            last_i = i + n
1376
            last_j = j + n
1377
        return unique_left, unique_right
1378
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1379
    @staticmethod
1380
    def _subtract_plans(old_plan, new_plan):
3144.3.7 by Aaron Bentley
Update from review
1381
        """Remove changes from new_plan that came from old_plan.
1382
1383
        It is assumed that the difference between the old_plan and new_plan
1384
        is their choice of 'b' text.
1385
1386
        All lines from new_plan that differ from old_plan are emitted
1387
        verbatim.  All lines from new_plan that match old_plan but are
1388
        not about the 'b' revision are emitted verbatim.
1389
1390
        Lines that match and are about the 'b' revision are the lines we
1391
        don't want, so we convert 'killed-b' -> 'unchanged', and 'new-b'
1392
        is skipped entirely.
1393
        """
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1394
        matcher = patiencediff.PatienceSequenceMatcher(None, old_plan,
1395
                                                       new_plan)
1396
        last_j = 0
1397
        for i, j, n in matcher.get_matching_blocks():
1398
            for jj in range(last_j, j):
1399
                yield new_plan[jj]
1400
            for jj in range(j, j+n):
1401
                plan_line = new_plan[jj]
1402
                if plan_line[0] == 'new-b':
1403
                    pass
1404
                elif plan_line[0] == 'killed-b':
1405
                    yield 'unchanged', plan_line[1]
1406
                else:
1407
                    yield plan_line
1408
            last_j = j + n
1409
1410
1411
class _PlanMerge(_PlanMergeBase):
1412
    """Plan an annotate merge using on-the-fly annotation"""
1413
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1414
    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'.
1415
        super(_PlanMerge, self).__init__(a_rev, b_rev, vf, key_prefix)
1416
        self.a_key = self._key_prefix + (self.a_rev,)
1417
        self.b_key = self._key_prefix + (self.b_rev,)
1418
        self.graph = Graph(self.vf)
3514.2.11 by John Arbash Meinel
Shortcut the case when one revision is in the ancestry of the other.
1419
        heads = self.graph.heads((self.a_key, self.b_key))
1420
        if len(heads) == 1:
1421
            # one side dominates, so we can just return its values, yay for
1422
            # per-file graphs
1423
            # Ideally we would know that before we get this far
1424
            self._head_key = heads.pop()
1425
            if self._head_key == self.a_key:
1426
                other = b_rev
1427
            else:
1428
                other = a_rev
1429
            mutter('found dominating revision for %s\n%s > %s', self.vf,
1430
                   self._head_key[-1], other)
1431
            self._weave = None
1432
        else:
1433
            self._head_key = None
1434
            self._build_weave()
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1435
1436
    def _precache_tip_lines(self):
1437
        # Turn this into a no-op, because we will do this later
1438
        pass
1439
1440
    def _find_recursive_lcas(self):
1441
        """Find all the ancestors back to a unique lca"""
1442
        cur_ancestors = (self.a_key, self.b_key)
1443
        # 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.
1444
        # rather than a key tuple. We will just map that directly to no common
1445
        # ancestors.
1446
        parent_map = {}
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1447
        while True:
1448
            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.
1449
            # Map a plain NULL_REVISION to a simple no-ancestors
1450
            if next_lcas == set([NULL_REVISION]):
1451
                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.
1452
            # Order the lca's based on when they were merged into the tip
1453
            # While the actual merge portion of weave merge uses a set() of
1454
            # active revisions, the order of insertion *does* effect the
1455
            # implicit ordering of the texts.
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1456
            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.
1457
                ordered_parents = tuple(self.graph.find_merge_order(rev_key,
1458
                                                                    next_lcas))
1459
                parent_map[rev_key] = ordered_parents
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1460
            if len(next_lcas) == 0:
1461
                break
1462
            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.
1463
                parent_map[list(next_lcas)[0]] = ()
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1464
                break
3514.2.10 by John Arbash Meinel
Handle more edge cases.
1465
            elif len(next_lcas) > 2:
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1466
                # More than 2 lca's, fall back to grabbing all nodes between
1467
                # this and the unique lca.
3514.2.16 by John Arbash Meinel
Review feedback from Ian.
1468
                mutter('More than 2 LCAs, falling back to all nodes for:'
1469
                       ' %s, %s\n=> %s', self.a_key, self.b_key, cur_ancestors)
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1470
                cur_lcas = next_lcas
1471
                while len(cur_lcas) > 1:
1472
                    cur_lcas = self.graph.find_lca(*cur_lcas)
1473
                if len(cur_lcas) == 0:
1474
                    # No common base to find, use the full ancestry
1475
                    unique_lca = None
1476
                else:
3514.2.8 by John Arbash Meinel
The insertion ordering into the weave has an impact on conflicts.
1477
                    unique_lca = list(cur_lcas)[0]
3514.2.14 by John Arbash Meinel
Bring in the code to collapse linear portions of the graph.
1478
                    if unique_lca == NULL_REVISION:
1479
                        # find_lca will return a plain 'NULL_REVISION' rather
1480
                        # than a key tuple when there is no common ancestor, we
1481
                        # prefer to just use None, because it doesn't confuse
1482
                        # _get_interesting_texts()
1483
                        unique_lca = None
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1484
                parent_map.update(self._find_unique_parents(next_lcas,
1485
                                                            unique_lca))
1486
                break
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1487
            cur_ancestors = next_lcas
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1488
        return parent_map
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1489
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1490
    def _find_unique_parents(self, tip_keys, base_key):
1491
        """Find ancestors of tip that aren't ancestors of base.
1492
        
1493
        :param tip_keys: Nodes that are interesting
1494
        :param base_key: Cull all ancestors of this node
1495
        :return: The parent map for all revisions between tip_keys and
1496
            base_key. base_key will be included. References to nodes outside of
1497
            the ancestor set will also be removed.
1498
        """
1499
        # TODO: this would be simpler if find_unique_ancestors took a list
1500
        #       instead of a single tip, internally it supports it, but it
1501
        #       isn't a "backwards compatible" api change.
1502
        if base_key is None:
1503
            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.
1504
            # We remove NULL_REVISION because it isn't a proper tuple key, and
1505
            # thus confuses things like _get_interesting_texts, and our logic
1506
            # to add the texts into the memory weave.
1507
            if NULL_REVISION in parent_map:
1508
                parent_map.pop(NULL_REVISION)
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1509
        else:
1510
            interesting = set()
1511
            for tip in tip_keys:
1512
                interesting.update(
1513
                    self.graph.find_unique_ancestors(tip, [base_key]))
1514
            parent_map = self.graph.get_parent_map(interesting)
1515
            parent_map[base_key] = ()
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1516
        culled_parent_map, child_map, tails = self._remove_external_references(
1517
            parent_map)
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
1518
        # 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.
1519
        if base_key is not None:
1520
            tails.remove(base_key)
1521
            self._prune_tails(culled_parent_map, child_map, tails)
1522
        # Now remove all the uninteresting 'linear' regions
3514.2.15 by John Arbash Meinel
Enable collapsing linear regions.
1523
        simple_map = _mod_graph.collapse_linear_regions(culled_parent_map)
1524
        return simple_map
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1525
1526
    @staticmethod
1527
    def _remove_external_references(parent_map):
1528
        """Remove references that go outside of the parent map.
1529
1530
        :param parent_map: Something returned from Graph.get_parent_map(keys)
1531
        :return: (filtered_parent_map, child_map, tails)
1532
            filtered_parent_map is parent_map without external references
1533
            child_map is the {parent_key: [child_keys]} mapping
1534
            tails is a list of nodes that do not have any parents in the map
1535
        """
1536
        # TODO: The basic effect of this function seems more generic than
1537
        #       _PlanMerge. But the specific details of building a child_map,
1538
        #       and computing tails seems very specific to _PlanMerge.
1539
        #       Still, should this be in Graph land?
1540
        filtered_parent_map = {}
1541
        child_map = {}
1542
        tails = []
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1543
        for key, parent_keys in parent_map.iteritems():
3514.2.12 by John Arbash Meinel
Start refactoring into helper functions
1544
            culled_parent_keys = [p for p in parent_keys if p in parent_map]
1545
            if not culled_parent_keys:
1546
                tails.append(key)
1547
            for parent_key in culled_parent_keys:
1548
                child_map.setdefault(parent_key, []).append(key)
1549
            # TODO: Do we want to do this, it adds overhead for every node,
1550
            #       just to say that the node has no children
1551
            child_map.setdefault(key, [])
1552
            filtered_parent_map[key] = culled_parent_keys
1553
        return filtered_parent_map, child_map, tails
1554
3514.2.13 by John Arbash Meinel
Add the ability to prune extra tails from the parent_map.
1555
    @staticmethod
1556
    def _prune_tails(parent_map, child_map, tails_to_remove):
1557
        """Remove tails from the parent map.
1558
        
1559
        This will remove the supplied revisions until no more children have 0
1560
        parents.
1561
1562
        :param parent_map: A dict of {child: [parents]}, this dictionary will
1563
            be modified in place.
1564
        :param tails_to_remove: A list of tips that should be removed,
1565
            this list will be consumed
1566
        :param child_map: The reverse dict of parent_map ({parent: [children]})
1567
            this dict will be modified
1568
        :return: None, parent_map will be modified in place.
1569
        """
1570
        while tails_to_remove:
1571
            next = tails_to_remove.pop()
1572
            parent_map.pop(next)
1573
            children = child_map.pop(next)
1574
            for child in children:
1575
                child_parents = parent_map[child]
1576
                child_parents.remove(next)
1577
                if len(child_parents) == 0:
1578
                    tails_to_remove.append(child)
3514.2.7 by John Arbash Meinel
Fix the failing test by implementing the fallback logic.
1579
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1580
    def _get_interesting_texts(self, parent_map):
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1581
        """Return a dict of texts we are interested in.
1582
1583
        Note that the input is in key tuples, but the output is in plain
1584
        revision ids.
1585
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1586
        :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'.
1587
        :return: A dict of {'revision_id':lines} as returned by
1588
            _PlanMergeBase.get_lines()
1589
        """
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1590
        all_revision_keys = set(parent_map)
1591
        all_revision_keys.add(self.a_key)
1592
        all_revision_keys.add(self.b_key)
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1593
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1594
        # Everything else is in 'keys' but get_lines is in 'revision_ids'
1595
        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'.
1596
        return all_texts
1597
1598
    def _build_weave(self):
1599
        from bzrlib import weave
1600
        self._weave = weave.Weave(weave_name='in_memory_weave',
1601
                                  allow_reserved=True)
3514.2.5 by John Arbash Meinel
Switch to the get_parent_map design I had settled on.
1602
        parent_map = self._find_recursive_lcas()
1603
1604
        all_texts = self._get_interesting_texts(parent_map)
1605
1606
        # Note: Unfortunately, the order given by topo_sort will effect the
1607
        # ordering resolution in the output. Specifically, if you add A then B,
1608
        # then in the output text A lines will show up before B lines. And, of
1609
        # 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.
1610
        # So we use merge_sort, and add a fake node on the tip.
1611
        # This ensures that left-hand parents will always be inserted into the
1612
        # weave before right-hand parents.
1613
        tip_key = self._key_prefix + (_mod_revision.CURRENT_REVISION,)
1614
        parent_map[tip_key] = (self.a_key, self.b_key)
1615
1616
        for seq_num, key, depth, eom in reversed(tsort.merge_sort(parent_map,
1617
                                                                  tip_key)):
1618
            if key == tip_key:
1619
                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.
1620
        # 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.
1621
            parent_keys = parent_map[key]
1622
            revision_id = key[-1]
1623
            parent_ids = [k[-1] for k in parent_keys]
1624
            self._weave.add_lines(revision_id, parent_ids,
1625
                                  all_texts[revision_id])
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1626
1627
    def plan_merge(self):
1628
        """Generate a 'plan' for merging the two revisions.
1629
1630
        This involves comparing their texts and determining the cause of
1631
        differences.  If text A has a line and text B does not, then either the
1632
        line was added to text A, or it was deleted from B.  Once the causes
1633
        are combined, they are written out in the format described in
1634
        VersionedFile.plan_merge
1635
        """
1636
        if self._head_key is not None: # There was a single head
1637
            if self._head_key == self.a_key:
1638
                plan = 'new-a'
3062.1.9 by Aaron Bentley
Move PlanMerge into merge and _PlanMergeVersionedFile into versionedfile
1639
            else:
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1640
                if self._head_key != self.b_key:
1641
                    raise AssertionError('There was an invalid head: %s != %s'
1642
                                         % (self.b_key, self._head_key))
1643
                plan = 'new-b'
3514.2.16 by John Arbash Meinel
Review feedback from Ian.
1644
            head_rev = self._head_key[-1]
1645
            lines = self.get_lines([head_rev])[head_rev]
3514.2.2 by John Arbash Meinel
Restore a real weave merge to 'bzr merge --weave'.
1646
            return ((plan, line) for line in lines)
1647
        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
1648
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1649
1650
class _PlanLCAMerge(_PlanMergeBase):
1651
    """
3144.3.7 by Aaron Bentley
Update from review
1652
    This merge algorithm differs from _PlanMerge in that:
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1653
    1. comparisons are done against LCAs only
1654
    2. cases where a contested line is new versus one LCA but old versus
3144.3.7 by Aaron Bentley
Update from review
1655
       another are marked as conflicts, by emitting the line as conflicted-a
1656
       or conflicted-b.
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1657
1658
    This is faster, and hopefully produces more useful output.
1659
    """
1660
3350.6.10 by Martin Pool
VersionedFiles review cleanups
1661
    def __init__(self, a_rev, b_rev, vf, key_prefix, graph):
1662
        _PlanMergeBase.__init__(self, a_rev, b_rev, vf, key_prefix)
1663
        lcas = graph.find_lca(key_prefix + (a_rev,), key_prefix + (b_rev,))
3350.6.5 by Robert Collins
Update to bzr.dev.
1664
        self.lcas = set()
1665
        for lca in lcas:
1666
            if lca == NULL_REVISION:
1667
                self.lcas.add(lca)
1668
            else:
1669
                self.lcas.add(lca[-1])
3144.3.7 by Aaron Bentley
Update from review
1670
        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.
1671
            if _mod_revision.is_null(lca):
1672
                lca_lines = []
1673
            else:
3350.6.5 by Robert Collins
Update to bzr.dev.
1674
                lca_lines = self.get_lines([lca])[lca]
3144.3.7 by Aaron Bentley
Update from review
1675
            matcher = patiencediff.PatienceSequenceMatcher(None, self.lines_a,
1676
                                                           lca_lines)
1677
            blocks = list(matcher.get_matching_blocks())
1678
            self._cached_matching_blocks[(a_rev, lca)] = blocks
1679
            matcher = patiencediff.PatienceSequenceMatcher(None, self.lines_b,
1680
                                                           lca_lines)
1681
            blocks = list(matcher.get_matching_blocks())
1682
            self._cached_matching_blocks[(b_rev, lca)] = blocks
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1683
3144.3.7 by Aaron Bentley
Update from review
1684
    def _determine_status(self, revision_id, unique_line_numbers):
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1685
        """Determines the status unique lines versus all lcas.
1686
1687
        Basically, determines why the line is unique to this revision.
1688
1689
        A line may be determined new, killed, or both.
1690
3144.3.7 by Aaron Bentley
Update from review
1691
        If a line is determined new, that means it was not present in at least
1692
        one LCA, and is not present in the other merge revision.
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1693
1694
        If a line is determined killed, that means the line was present in
1695
        at least one LCA.
1696
1697
        If a line is killed and new, this indicates that the two merge
1698
        revisions contain differing conflict resolutions.
3144.3.7 by Aaron Bentley
Update from review
1699
        :param revision_id: The id of the revision in which the lines are
1700
            unique
1701
        :param unique_line_numbers: The line numbers of unique lines.
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1702
        :return a tuple of (new_this, killed_other):
1703
        """
1704
        new = set()
1705
        killed = set()
3144.3.7 by Aaron Bentley
Update from review
1706
        unique_line_numbers = set(unique_line_numbers)
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1707
        for lca in self.lcas:
1708
            blocks = self._get_matching_blocks(revision_id, lca)
1709
            unique_vs_lca, _ignored = self._unique_lines(blocks)
3144.3.7 by Aaron Bentley
Update from review
1710
            new.update(unique_line_numbers.intersection(unique_vs_lca))
1711
            killed.update(unique_line_numbers.difference(unique_vs_lca))
3144.3.1 by Aaron Bentley
Implement LCA merge, with problematic conflict markers
1712
        return new, killed