~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/merge.py

  • Committer: Matt Nordhoff
  • Date: 2009-04-04 02:50:01 UTC
  • mfrom: (4253 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4256.
  • Revision ID: mnordhoff@mattnordhoff.com-20090404025001-z1403k0tatmc8l91
Merge bzr.dev, fixing conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
 
18
18
import errno
70
70
 
71
71
class Merger(object):
72
72
    def __init__(self, this_branch, other_tree=None, base_tree=None,
73
 
                 this_tree=None, pb=DummyProgress(), change_reporter=None,
 
73
                 this_tree=None, pb=None, change_reporter=None,
74
74
                 recurse='down', revision_graph=None):
75
75
        object.__init__(self)
76
76
        self.this_branch = this_branch
89
89
        self.interesting_files = None
90
90
        self.show_base = False
91
91
        self.reprocess = False
 
92
        if pb is None:
 
93
            pb = DummyProgress()
92
94
        self._pb = pb
93
95
        self.pp = None
94
96
        self.recurse = recurse
132
134
                                      _set_base_is_other_ancestor)
133
135
 
134
136
    @staticmethod
135
 
    def from_uncommitted(tree, other_tree, pb, base_tree=None):
 
137
    def from_uncommitted(tree, other_tree, pb=None, base_tree=None):
136
138
        """Return a Merger for uncommitted changes in other_tree.
137
139
 
138
140
        :param tree: The tree to merge into
477
479
                    sub_tree.branch.repository.revision_tree(base_revision)
478
480
                sub_merge.base_rev_id = base_revision
479
481
                sub_merge.do_merge()
480
 
        
 
482
 
481
483
    def do_merge(self):
482
484
        self.this_tree.lock_tree_write()
483
485
        try:
534
536
    winner_idx = {"this": 2, "other": 1, "conflict": 1}
535
537
    supports_lca_trees = True
536
538
 
537
 
    def __init__(self, working_tree, this_tree, base_tree, other_tree, 
 
539
    def __init__(self, working_tree, this_tree, base_tree, other_tree,
538
540
                 interesting_ids=None, reprocess=False, show_base=False,
539
541
                 pb=DummyProgress(), pp=None, change_reporter=None,
540
542
                 interesting_files=None, do_merge=True,
874
876
        except NoSuchFile:
875
877
            self.tt.cancel_deletion(self.tt.root)
876
878
        if self.tt.final_file_id(self.tt.root) is None:
877
 
            self.tt.version_file(self.tt.tree_file_id(self.tt.root), 
 
879
            self.tt.version_file(self.tt.tree_file_id(self.tt.root),
878
880
                                 self.tt.root)
879
881
        other_root_file_id = self.other_tree.get_root_id()
880
882
        if other_root_file_id is None:
923
925
        if entry is None:
924
926
            return None
925
927
        return entry.name
926
 
    
 
928
 
927
929
    @staticmethod
928
930
    def contents_sha1(tree, file_id):
929
931
        """Determine the sha1 of the file contents (used as a key method)."""
1069
1071
            return
1070
1072
        if name_winner == "conflict":
1071
1073
            trans_id = self.tt.trans_id_file_id(file_id)
1072
 
            self._raw_conflicts.append(('name conflict', trans_id, 
 
1074
            self._raw_conflicts.append(('name conflict', trans_id,
1073
1075
                                        this_name, other_name))
1074
1076
        if parent_id_winner == "conflict":
1075
1077
            trans_id = self.tt.trans_id_file_id(file_id)
1076
 
            self._raw_conflicts.append(('parent conflict', trans_id, 
 
1078
            self._raw_conflicts.append(('parent conflict', trans_id,
1077
1079
                                        this_parent, other_parent))
1078
1080
        if other_name is None:
1079
 
            # it doesn't matter whether the result was 'other' or 
 
1081
            # it doesn't matter whether the result was 'other' or
1080
1082
            # 'conflict'-- if there's no 'other', we leave it alone.
1081
1083
            return
1082
1084
        # if we get here, name_winner and parent_winner are set to safe values.
1109
1111
                self.tt.unversion_file(trans_id)
1110
1112
                if file_id in self.this_tree:
1111
1113
                    self.tt.delete_contents(trans_id)
1112
 
            file_group = self._dump_conflicts(name, parent_id, file_id, 
 
1114
            file_group = self._dump_conflicts(name, parent_id, file_id,
1113
1115
                                              set_version=True)
1114
1116
            self._raw_conflicts.append(('contents conflict', file_group))
1115
1117
 
1202
1204
 
1203
1205
        def iter_merge3(retval):
1204
1206
            retval["text_conflicts"] = False
1205
 
            for line in m3.merge_lines(name_a = "TREE", 
1206
 
                                       name_b = "MERGE-SOURCE", 
 
1207
            for line in m3.merge_lines(name_a = "TREE",
 
1208
                                       name_b = "MERGE-SOURCE",
1207
1209
                                       name_base = "BASE-REVISION",
1208
 
                                       start_marker=start_marker, 
 
1210
                                       start_marker=start_marker,
1209
1211
                                       base_marker=base_marker,
1210
1212
                                       reprocess=self.reprocess):
1211
1213
                if line.startswith(start_marker):
1220
1222
            self._raw_conflicts.append(('text conflict', trans_id))
1221
1223
            name = self.tt.final_name(trans_id)
1222
1224
            parent_id = self.tt.final_parent(trans_id)
1223
 
            file_group = self._dump_conflicts(name, parent_id, file_id, 
 
1225
            file_group = self._dump_conflicts(name, parent_id, file_id,
1224
1226
                                              this_lines, base_lines,
1225
1227
                                              other_lines)
1226
1228
            file_group.append(trans_id)
1227
1229
 
1228
 
    def _dump_conflicts(self, name, parent_id, file_id, this_lines=None, 
 
1230
    def _dump_conflicts(self, name, parent_id, file_id, this_lines=None,
1229
1231
                        base_lines=None, other_lines=None, set_version=False,
1230
1232
                        no_base=False):
1231
1233
        """Emit conflict files.
1233
1235
        determined automatically.  If set_version is true, the .OTHER, .THIS
1234
1236
        or .BASE (in that order) will be created as versioned files.
1235
1237
        """
1236
 
        data = [('OTHER', self.other_tree, other_lines), 
 
1238
        data = [('OTHER', self.other_tree, other_lines),
1237
1239
                ('THIS', self.this_tree, this_lines)]
1238
1240
        if not no_base:
1239
1241
            data.append(('BASE', self.base_tree, base_lines))
1248
1250
                    self.tt.version_file(file_id, trans_id)
1249
1251
                    versioned = True
1250
1252
        return file_group
1251
 
           
 
1253
 
1252
1254
    def _conflict_file(self, name, parent_id, tree, file_id, suffix,
1253
1255
                       lines=None):
1254
1256
        """Emit a single conflict file."""
1312
1314
                conflict_args = conflict[2:]
1313
1315
                if trans_id not in name_conflicts:
1314
1316
                    name_conflicts[trans_id] = {}
1315
 
                unique_add(name_conflicts[trans_id], conflict_type, 
 
1317
                unique_add(name_conflicts[trans_id], conflict_type,
1316
1318
                           conflict_args)
1317
1319
            if conflict_type == 'contents conflict':
1318
1320
                for trans_id in conflict[1]:
1396
1398
        """
1397
1399
        lines, conflicts = self._merged_lines(file_id)
1398
1400
        lines = list(lines)
1399
 
        # Note we're checking whether the OUTPUT is binary in this case, 
 
1401
        # Note we're checking whether the OUTPUT is binary in this case,
1400
1402
        # because we don't want to get into weave merge guts.
1401
1403
        check_text_lines(lines)
1402
1404
        self.tt.create_file(lines, trans_id)
1404
1406
            self._raw_conflicts.append(('text conflict', trans_id))
1405
1407
            name = self.tt.final_name(trans_id)
1406
1408
            parent_id = self.tt.final_parent(trans_id)
1407
 
            file_group = self._dump_conflicts(name, parent_id, file_id, 
 
1409
            file_group = self._dump_conflicts(name, parent_id, file_id,
1408
1410
                                              no_base=True)
1409
1411
            file_group.append(trans_id)
1410
1412
 
1487
1489
                this_tree=None,
1488
1490
                pb=DummyProgress(),
1489
1491
                change_reporter=None):
1490
 
    """Primary interface for merging. 
 
1492
    """Primary interface for merging.
1491
1493
 
1492
 
        typical use is probably 
 
1494
        typical use is probably
1493
1495
        'merge_inner(branch, branch.get_revision_tree(other_revision),
1494
1496
                     branch.get_revision_tree(base_revision))'
1495
1497
        """
1792
1794
 
1793
1795
    def _find_unique_parents(self, tip_keys, base_key):
1794
1796
        """Find ancestors of tip that aren't ancestors of base.
1795
 
        
 
1797
 
1796
1798
        :param tip_keys: Nodes that are interesting
1797
1799
        :param base_key: Cull all ancestors of this node
1798
1800
        :return: The parent map for all revisions between tip_keys and
1858
1860
    @staticmethod
1859
1861
    def _prune_tails(parent_map, child_map, tails_to_remove):
1860
1862
        """Remove tails from the parent map.
1861
 
        
 
1863
 
1862
1864
        This will remove the supplied revisions until no more children have 0
1863
1865
        parents.
1864
1866