47
46
def transform_tree(from_tree, to_tree, interesting_ids=None):
48
47
from_tree.lock_tree_write()
49
operation = OperationWithCleanups(merge_inner)
50
operation.add_cleanup(from_tree.unlock)
51
operation.run_simple(from_tree.branch, to_tree, from_tree,
52
ignore_zero=True, interesting_ids=interesting_ids, this_tree=from_tree)
49
merge_inner(from_tree.branch, to_tree, from_tree, ignore_zero=True,
50
interesting_ids=interesting_ids, this_tree=from_tree)
55
55
class MergeHooks(hooks.Hooks):
99
99
This is a base class for concrete custom file merging logic. Concrete
100
100
classes should implement ``merge_text``.
102
See ``bzrlib.plugins.news_merge.news_merge`` for an example concrete class.
104
102
:ivar affected_files: The configured file paths to merge.
106
103
:cvar name_prefix: The prefix to use when looking up configuration
107
details. <name_prefix>_merge_files describes the files targeted by the
110
105
:cvar default_files: The default file paths to merge when no configuration
123
118
raise ValueError("name_prefix must be set.")
125
120
def filename_matches_config(self, params):
126
"""Check whether the file should call the merge hook.
128
<name_prefix>_merge_files configuration variable is a list of files
129
that should use the hook.
131
121
affected_files = self.affected_files
132
122
if affected_files is None:
133
123
config = self.merger.this_tree.branch.get_config()
161
151
not self.filename_matches_config(params)):
162
152
return 'not_applicable', None
163
return self.merge_text(params)
153
return self.merge_text(self, params)
165
155
def merge_text(self, params):
166
156
"""Merge the byte contents of a single file.
465
operation.add_cleanup(tree.unlock)
466
455
new_parent_trees.append((revision_id, tree))
467
operation.run_simple(new_parent_trees, allow_leftmost_as_ghost=True)
457
self.this_tree.set_parent_trees(new_parent_trees,
458
allow_leftmost_as_ghost=True)
460
for _revision_id, tree in new_parent_trees:
469
464
def set_other(self, other_revision, possible_transports=None):
470
465
"""Set the revision and tree to merge from.
593
588
'other_tree': self.other_tree,
594
589
'interesting_ids': self.interesting_ids,
595
590
'interesting_files': self.interesting_files,
596
'this_branch': self.this_branch,
591
'pp': self.pp, 'this_branch': self.this_branch,
597
592
'do_merge': False}
598
593
if self.merge_type.requires_base:
599
594
kwargs['base_tree'] = self.base_tree
617
612
if self._is_criss_cross and getattr(self.merge_type,
618
613
'supports_lca_trees', False):
619
614
kwargs['lca_trees'] = self._lca_trees
620
return self.merge_type(pb=None,
615
return self.merge_type(pb=self._pb,
621
616
change_reporter=self.change_reporter,
624
def _do_merge_to(self):
625
merge = self.make_merger()
619
def _do_merge_to(self, merge):
626
620
if self.other_branch is not None:
627
621
self.other_branch.update_references(self.this_branch)
642
636
sub_tree.branch.repository.revision_tree(base_revision)
643
637
sub_merge.base_rev_id = base_revision
644
638
sub_merge.do_merge()
647
640
def do_merge(self):
648
operation = OperationWithCleanups(self._do_merge_to)
649
641
self.this_tree.lock_tree_write()
650
operation.add_cleanup(self.this_tree.unlock)
651
if self.base_tree is not None:
652
self.base_tree.lock_read()
653
operation.add_cleanup(self.base_tree.unlock)
654
if self.other_tree is not None:
655
self.other_tree.lock_read()
656
operation.add_cleanup(self.other_tree.unlock)
657
merge = operation.run_simple()
643
if self.base_tree is not None:
644
self.base_tree.lock_read()
646
if self.other_tree is not None:
647
self.other_tree.lock_read()
649
merge = self.make_merger()
650
self._do_merge_to(merge)
652
if self.other_tree is not None:
653
self.other_tree.unlock()
655
if self.base_tree is not None:
656
self.base_tree.unlock()
658
self.this_tree.unlock()
658
659
if len(merge.cooked_conflicts) == 0:
659
660
if not self.ignore_zero and not trace.is_quiet():
660
661
trace.note("All changes applied successfully.")
696
697
def __init__(self, working_tree, this_tree, base_tree, other_tree,
697
698
interesting_ids=None, reprocess=False, show_base=False,
698
pb=None, pp=None, change_reporter=None,
699
pb=progress.DummyProgress(), pp=None, change_reporter=None,
699
700
interesting_files=None, do_merge=True,
700
701
cherrypick=False, lca_trees=None, this_branch=None):
701
702
"""Initialize the merger object and perform the merge.
711
712
:param: reprocess If True, perform conflict-reduction processing.
712
713
:param show_base: If True, show the base revision in text conflicts.
713
714
(incompatible with reprocess)
715
:param pb: A Progress bar
715
716
:param pp: A ProgressPhase object
716
717
:param change_reporter: An object that should report changes made
717
718
:param interesting_files: The tree-relative paths of files that should
744
745
# making sure we haven't missed any corner cases.
745
746
# if lca_trees is None:
746
747
# self._lca_trees = [self.base_tree]
747
750
self.change_reporter = change_reporter
748
751
self.cherrypick = cherrypick
753
self.pp = progress.ProgressPhase("Merge phase", 3, self.pb)
752
warnings.warn("pp argument to Merge3Merger is deprecated")
754
warnings.warn("pb argument to Merge3Merger is deprecated")
756
757
def do_merge(self):
757
operation = OperationWithCleanups(self._do_merge)
758
758
self.this_tree.lock_tree_write()
759
operation.add_cleanup(self.this_tree.unlock)
760
759
self.base_tree.lock_read()
761
operation.add_cleanup(self.base_tree.unlock)
762
760
self.other_tree.lock_read()
763
operation.add_cleanup(self.other_tree.unlock)
766
def _do_merge(self, operation):
767
self.tt = transform.TreeTransform(self.this_tree, None)
768
operation.add_cleanup(self.tt.finalize)
769
self._compute_transform()
770
results = self.tt.apply(no_conflicts=True)
771
self.write_modified(results)
773
self.this_tree.add_conflicts(self.cooked_conflicts)
774
except errors.UnsupportedOperation:
762
self.tt = transform.TreeTransform(self.this_tree, self.pb)
765
self._compute_transform()
767
results = self.tt.apply(no_conflicts=True)
768
self.write_modified(results)
770
self.this_tree.add_conflicts(self.cooked_conflicts)
771
except errors.UnsupportedOperation:
776
self.other_tree.unlock()
777
self.base_tree.unlock()
778
self.this_tree.unlock()
777
781
def make_preview_transform(self):
778
operation = OperationWithCleanups(self._make_preview_transform)
779
782
self.base_tree.lock_read()
780
operation.add_cleanup(self.base_tree.unlock)
781
783
self.other_tree.lock_read()
782
operation.add_cleanup(self.other_tree.unlock)
783
return operation.run_simple()
785
def _make_preview_transform(self):
786
784
self.tt = transform.TransformPreview(self.this_tree)
787
self._compute_transform()
787
self._compute_transform()
790
self.other_tree.unlock()
791
self.base_tree.unlock()
790
795
def _compute_transform(self):