/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Robert Collins
  • Date: 2008-04-04 00:43:07 UTC
  • mfrom: (3331 +trunk)
  • mto: This revision was merged to the branch mainline in revision 3333.
  • Revision ID: robertc@robertcollins.net-20080404004307-0whomfhm3yal2rvw
Resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
116
116
 
117
117
    def _get_base_is_other_ancestor(self):
118
118
        if self._base_is_other_ancestor is None:
119
 
            self.base_is_other_ancestor = self.revision_graph.is_ancestor(
 
119
            if self.other_basis is None:
 
120
                return True
 
121
            self._base_is_other_ancestor = self.revision_graph.is_ancestor(
120
122
                self.base_rev_id, self.other_basis)
121
123
        return self._base_is_other_ancestor
122
124
 
162
164
        return merger, verified
163
165
 
164
166
    @staticmethod
165
 
    def from_revision_ids(pb, this, other, base=None, other_branch=None,
 
167
    def from_revision_ids(pb, tree, other, base=None, other_branch=None,
166
168
                          base_branch=None, revision_graph=None):
167
169
        """Return a Merger for revision-ids.
168
170
 
171
173
        :param base: The revision-id to use as BASE.  If not specified, will
172
174
            be auto-selected.
173
175
        :param other_branch: A branch containing the other revision-id.  If
174
 
            not supplied, this.branch is used.
 
176
            not supplied, tree.branch is used.
175
177
        :param base_branch: A branch containing the base revision-id.  If
176
 
            not supplied, other_branch or this.branch will be used.
 
178
            not supplied, other_branch or tree.branch will be used.
 
179
        :param revision_graph: If you have a revision_graph precomputed, pass
 
180
            it in, otherwise it will be created for you.
177
181
        :param pb: A progress indicator
178
182
        """
179
 
        merger = Merger(this.branch, this_tree=this, pb=pb,
 
183
        merger = Merger(tree.branch, this_tree=tree, pb=pb,
180
184
                        revision_graph=revision_graph)
181
185
        if other_branch is None:
182
 
            other_branch = this.branch
 
186
            other_branch = tree.branch
183
187
        merger.set_other_revision(other, other_branch)
184
188
        if base is None:
185
189
            merger.find_base()
399
403
        if (not getattr(self.merge_type, 'supports_reverse_cherrypick', True)
400
404
            and not self.base_is_other_ancestor):
401
405
            raise errors.CannotReverseCherrypick()
402
 
        if self.merge_type.history_based:
 
406
        if self.merge_type.supports_cherrypick:
403
407
            kwargs['cherrypick'] = (not self.base_is_ancestor or
404
408
                                    not self.base_is_other_ancestor)
405
409
        return self.merge_type(pb=self._pb,
407
411
                               **kwargs)
408
412
 
409
413
    def do_merge(self):
410
 
        merge = self.make_merger()
411
414
        self.this_tree.lock_tree_write()
412
415
        if self.base_tree is not None:
413
416
            self.base_tree.lock_read()
414
417
        if self.other_tree is not None:
415
418
            self.other_tree.lock_read()
416
419
        try:
 
420
            merge = self.make_merger()
417
421
            merge.do_merge()
418
422
            if self.recurse == 'down':
419
423
                for path, file_id in self.this_tree.iter_references():
430
434
                    base_revision = self.base_tree.get_reference_revision(file_id)
431
435
                    sub_merge.base_tree = \
432
436
                        sub_tree.branch.repository.revision_tree(base_revision)
 
437
                    sub_merge.base_rev_id = base_revision
433
438
                    sub_merge.do_merge()
434
439
 
435
440
        finally:
453
458
    supports_reprocess = True
454
459
    supports_show_base = True
455
460
    history_based = False
 
461
    supports_cherrypick = True
456
462
    supports_reverse_cherrypick = True
457
463
    winner_idx = {"this": 2, "other": 1, "conflict": 1}
458
464
 
459
465
    def __init__(self, working_tree, this_tree, base_tree, other_tree, 
460
466
                 interesting_ids=None, reprocess=False, show_base=False,
461
467
                 pb=DummyProgress(), pp=None, change_reporter=None,
462
 
                 interesting_files=None, do_merge=True):
 
468
                 interesting_files=None, do_merge=True,
 
469
                 cherrypick=False):
463
470
        """Initialize the merger object and perform the merge.
464
471
 
465
472
        :param working_tree: The working tree to apply the merge to
497
504
        self.pb = pb
498
505
        self.pp = pp
499
506
        self.change_reporter = change_reporter
 
507
        self.cherrypick = cherrypick
500
508
        if self.pp is None:
501
509
            self.pp = ProgressPhase("Merge phase", 3, self.pb)
502
510
        if do_merge:
565
573
        if self.change_reporter is not None:
566
574
            from bzrlib import delta
567
575
            delta.report_changes(
568
 
                self.tt._iter_changes(), self.change_reporter)
 
576
                self.tt.iter_changes(), self.change_reporter)
569
577
        self.cook_conflicts(fs_conflicts)
570
578
        for conflict in self.cooked_conflicts:
571
579
            warning(conflict)
580
588
        executable3 is a tuple of execute-bit values for base, other and this.
581
589
        """
582
590
        result = []
583
 
        iterator = self.other_tree._iter_changes(self.base_tree,
 
591
        iterator = self.other_tree.iter_changes(self.base_tree,
584
592
                include_unchanged=True, specific_files=self.interesting_files,
585
593
                extra_trees=[self.this_tree])
586
594
        for (file_id, paths, changed, versioned, parents, names, kind,
865
873
            base_lines = []
866
874
        other_lines = self.get_lines(self.other_tree, file_id)
867
875
        this_lines = self.get_lines(self.this_tree, file_id)
868
 
        m3 = Merge3(base_lines, this_lines, other_lines)
 
876
        m3 = Merge3(base_lines, this_lines, other_lines,
 
877
                    is_cherrypick=self.cherrypick)
869
878
        start_marker = "!START OF MERGE CONFLICT!" + "I HOPE THIS IS UNIQUE"
870
879
        if self.show_base is True:
871
880
            base_marker = '|' * 7
941
950
        base_executable, other_executable, this_executable = executable
942
951
        if file_status == "deleted":
943
952
            return
944
 
        trans_id = self.tt.trans_id_file_id(file_id)
945
 
        try:
946
 
            if self.tt.final_kind(trans_id) != "file":
947
 
                return
948
 
        except NoSuchFile:
949
 
            return
950
953
        winner = self._three_way(*executable)
951
954
        if winner == "conflict":
952
955
        # There must be a None in here, if we have a conflict, but we
955
958
                winner = "this"
956
959
            else:
957
960
                winner = "other"
 
961
        if winner == 'this' and file_status != "modified":
 
962
            return
 
963
        trans_id = self.tt.trans_id_file_id(file_id)
 
964
        try:
 
965
            if self.tt.final_kind(trans_id) != "file":
 
966
                return
 
967
        except NoSuchFile:
 
968
            return
958
969
        if winner == "this":
959
 
            if file_status == "modified":
960
 
                executability = this_executable
961
 
                if executability is not None:
962
 
                    trans_id = self.tt.trans_id_file_id(file_id)
963
 
                    self.tt.set_executability(executability, trans_id)
 
970
            executability = this_executable
964
971
        else:
965
972
            assert winner == "other"
966
973
            if file_id in self.other_tree:
969
976
                executability = this_executable
970
977
            elif file_id in self.base_tree:
971
978
                executability = base_executable
972
 
            if executability is not None:
973
 
                trans_id = self.tt.trans_id_file_id(file_id)
974
 
                self.tt.set_executability(executability, trans_id)
 
979
        if executability is not None:
 
980
            trans_id = self.tt.trans_id_file_id(file_id)
 
981
            self.tt.set_executability(executability, trans_id)
975
982
 
976
983
    def cook_conflicts(self, fs_conflicts):
977
984
        """Convert all conflicts into a form that doesn't depend on trans_id"""
1040
1047
    supports_reverse_cherrypick = False
1041
1048
    history_based = True
1042
1049
 
1043
 
    def __init__(self, working_tree, this_tree, base_tree, other_tree, 
1044
 
                 interesting_ids=None, pb=DummyProgress(), pp=None,
1045
 
                 reprocess=False, change_reporter=None,
1046
 
                 interesting_files=None, cherrypick=False, do_merge=True):
1047
 
        self.cherrypick = cherrypick
1048
 
        super(WeaveMerger, self).__init__(working_tree, this_tree, 
1049
 
                                          base_tree, other_tree, 
1050
 
                                          interesting_ids=interesting_ids, 
1051
 
                                          pb=pb, pp=pp, reprocess=reprocess,
1052
 
                                          change_reporter=change_reporter,
1053
 
                                          do_merge=do_merge)
1054
 
 
1055
1050
    def _merged_lines(self, file_id):
1056
1051
        """Generate the merged lines.
1057
1052
        There is no distinction between lines that are meant to contain <<<<<<<
1194
1189
    merger.reprocess = reprocess
1195
1190
    merger.other_rev_id = other_rev_id
1196
1191
    merger.other_basis = other_rev_id
 
1192
    get_revision_id = getattr(base_tree, 'get_revision_id', None)
 
1193
    if get_revision_id is None:
 
1194
        get_revision_id = base_tree.last_revision
 
1195
    merger.set_base_revision(get_revision_id(), this_branch)
1197
1196
    return merger.do_merge()
1198
1197
 
1199
1198
def get_merge_type_registry():
1289
1288
            for b_index in range(last_j, j):
1290
1289
                if b_index in new_b:
1291
1290
                    if b_index in killed_a:
1292
 
                        yield 'conflicted-b', self.lines_b[a_index]
 
1291
                        yield 'conflicted-b', self.lines_b[b_index]
1293
1292
                    else:
1294
1293
                        yield 'new-b', self.lines_b[b_index]
1295
1294
                else:
1402
1401
        """
1403
1402
        if version_id not in self.uncommon:
1404
1403
            return set()
1405
 
        parents = self.vf.get_parents(version_id)
 
1404
        parents = self.vf.get_parent_map([version_id])[version_id]
1406
1405
        if len(parents) == 0:
1407
1406
            return set(range(len(self.vf.get_lines(version_id))))
1408
1407
        new = None