20
from tempfile import mkdtemp
25
23
from bzrlib.branch import Branch
26
24
from bzrlib.conflicts import ConflictList, Conflict
27
25
from bzrlib.errors import (BzrCommandError,
40
38
from bzrlib.merge3 import Merge3
41
39
import bzrlib.osutils
42
from bzrlib.osutils import rename, pathjoin
40
from bzrlib.osutils import rename, pathjoin, rmtree
43
41
from progress import DummyProgress, ProgressPhase
44
42
from bzrlib.revision import common_ancestor, is_ancestor, NULL_REVISION
45
43
from bzrlib.textfile import check_text_lines
46
44
from bzrlib.trace import mutter, warning, note
47
45
from bzrlib.transform import (TreeTransform, resolve_conflicts, cook_conflicts,
48
FinalPaths, create_by_entry, unique_add,
46
FinalPaths, create_by_entry, unique_add)
50
47
from bzrlib.versionedfile import WeaveMerge
51
48
from bzrlib import ui
53
50
# TODO: Report back as changes are merged in
55
52
def _get_tree(treespec, local_branch=None):
56
from bzrlib import workingtree
57
53
location, revno = treespec
54
branch = Branch.open_containing(location)[0]
59
tree = workingtree.WorkingTree.open_containing(location)[0]
60
return tree.branch, tree
61
branch = Branch.open_containing(location)[0]
63
58
revision = branch.last_revision()
65
60
revision = branch.get_rev_id(revno)
186
181
ancestry = self.this_branch.repository.get_ancestry(self.this_basis)
187
182
if self.other_rev_id in ancestry:
189
self.this_tree.add_parent_tree((self.other_rev_id, self.other_tree))
184
self.this_tree.add_pending_merge(self.other_rev_id)
191
186
def set_other(self, other_revision):
192
"""Set the revision and tree to merge from.
194
This sets the other_tree, other_rev_id, other_basis attributes.
196
:param other_revision: The [path, revision] list to merge from.
198
other_branch, self.other_tree = _get_tree(other_revision,
187
other_branch, self.other_tree = _get_tree(other_revision,
199
188
self.this_branch)
200
189
if other_revision[1] == -1:
201
190
self.other_rev_id = other_branch.last_revision()
217
206
self.set_base([None, None])
219
208
def set_base(self, base_revision):
220
"""Set the base revision to use for the merge.
222
:param base_revision: A 2-list containing a path and revision number.
224
209
mutter("doing merge() with no base_revision specified")
225
210
if base_revision == [None, None]:
377
362
all_ids = set(base_tree)
378
363
all_ids.update(other_tree)
379
working_tree.lock_tree_write()
364
working_tree.lock_write()
380
365
self.tt = TreeTransform(working_tree, self.pb)
382
367
self.pp.next_phase()
411
396
working_tree.unlock()
416
self.tt.final_kind(self.tt.root)
418
self.tt.cancel_deletion(self.tt.root)
419
if self.tt.final_file_id(self.tt.root) is None:
420
self.tt.version_file(self.tt.tree_file_id(self.tt.root),
422
if self.other_tree.inventory.root is None:
424
other_root_file_id = self.other_tree.inventory.root.file_id
425
other_root = self.tt.trans_id_file_id(other_root_file_id)
426
if other_root == self.tt.root:
429
self.tt.final_kind(other_root)
432
self.reparent_children(self.other_tree.inventory.root, self.tt.root)
433
self.tt.cancel_creation(other_root)
434
self.tt.cancel_versioning(other_root)
436
def reparent_children(self, ie, target):
437
for thing, child in ie.children.iteritems():
438
trans_id = self.tt.trans_id_file_id(child.file_id)
439
self.tt.adjust_path(self.tt.final_name(trans_id), target, trans_id)
441
399
def write_modified(self, results):
442
400
modified_hashes = {}
443
401
for path in results.modified_paths:
548
506
"conflict": other_entry}
549
507
trans_id = self.tt.trans_id_file_id(file_id)
550
508
parent_id = winner_entry[parent_id_winner].parent_id
551
if parent_id is not None:
552
parent_trans_id = self.tt.trans_id_file_id(parent_id)
553
self.tt.adjust_path(winner_entry[name_winner].name,
554
parent_trans_id, trans_id)
509
parent_trans_id = self.tt.trans_id_file_id(parent_id)
510
self.tt.adjust_path(winner_entry[name_winner].name, parent_trans_id,
556
513
def merge_contents(self, file_id):
557
514
"""Performa a merge on file_id contents."""
899
858
will be dumped, and a will be conflict noted.
901
860
import bzrlib.patch
902
temp_dir = osutils.mkdtemp(prefix="bzr-")
861
temp_dir = mkdtemp(prefix="bzr-")
904
863
new_file = pathjoin(temp_dir, "new")
905
864
this = self.dump_file(temp_dir, "this", self.this_tree, file_id)
917
876
name = self.tt.final_name(trans_id)
918
877
parent_id = self.tt.final_parent(trans_id)
919
878
self._dump_conflicts(name, parent_id, file_id)
920
self._raw_conflicts.append(('text conflict', trans_id))
879
self._raw_conflicts.append(('text conflict', trans_id))
922
osutils.rmtree(temp_dir)
925
884
def merge_inner(this_branch, other_tree, base_tree, ignore_zero=False,
954
913
assert not interesting_ids, ('Only supply interesting_ids'
955
914
' or interesting_files')
956
915
merger._set_interesting_files(interesting_files)
957
merger.show_base = show_base
916
merger.show_base = show_base
958
917
merger.reprocess = reprocess
959
918
merger.other_rev_id = other_rev_id
960
919
merger.other_basis = other_rev_id