/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 breezy/merge.py

  • Committer: Jelmer Vernooij
  • Date: 2020-08-10 15:00:17 UTC
  • mfrom: (7490.40.99 work)
  • mto: This revision was merged to the branch mainline in revision 7521.
  • Revision ID: jelmer@jelmer.uk-20200810150017-vs7xnrd1vat4iktg
Merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
    workingtree,
37
37
    )
38
38
from breezy.bzr import (
 
39
    conflicts as _mod_bzr_conflicts,
39
40
    generate_ids,
40
41
    versionedfile,
41
42
    )
42
43
from breezy.i18n import gettext
43
44
""")
 
45
from breezy.bzr.conflicts import Conflict as BzrConflict
44
46
from . import (
45
47
    decorators,
46
48
    errors,
1302
1304
                # This is a contents conflict, because none of the available
1303
1305
                # functions could merge it.
1304
1306
                file_group = self._dump_conflicts(
1305
 
                    name, (base_path, other_path, this_path), parent_id,
1306
 
                    file_id, set_version=True)
 
1307
                    name, (base_path, other_path, this_path), parent_id)
 
1308
                for tid in file_group:
 
1309
                    self.tt.version_file(tid, file_id=file_id)
 
1310
                    break
1307
1311
                self._raw_conflicts.append(('contents conflict', file_group))
1308
1312
        elif hook_status == 'success':
1309
1313
            self.tt.create_file(lines, trans_id)
1315
1319
            name = self.tt.final_name(trans_id)
1316
1320
            parent_id = self.tt.final_parent(trans_id)
1317
1321
            self._dump_conflicts(
1318
 
                name, (base_path, other_path, this_path), parent_id, file_id)
 
1322
                name, (base_path, other_path, this_path), parent_id)
1319
1323
        elif hook_status == 'delete':
1320
1324
            self.tt.unversion_file(trans_id)
1321
1325
            result = "deleted"
1421
1425
            self._raw_conflicts.append(('text conflict', trans_id))
1422
1426
            name = self.tt.final_name(trans_id)
1423
1427
            parent_id = self.tt.final_parent(trans_id)
1424
 
            file_id = self.tt.final_file_id(trans_id)
1425
 
            file_group = self._dump_conflicts(name, paths, parent_id, file_id,
1426
 
                                              this_lines, base_lines,
1427
 
                                              other_lines)
 
1428
            file_group = self._dump_conflicts(
 
1429
                name, paths, parent_id,
 
1430
                lines=(base_lines, other_lines, this_lines))
1428
1431
            file_group.append(trans_id)
1429
1432
 
1430
1433
    def _get_filter_tree_path(self, path):
1441
1444
        # Skip the lookup for older formats
1442
1445
        return None
1443
1446
 
1444
 
    def _dump_conflicts(self, name, paths, parent_id, file_id, this_lines=None,
1445
 
                        base_lines=None, other_lines=None, set_version=False,
 
1447
    def _dump_conflicts(self, name, paths, parent_id, lines=None,
1446
1448
                        no_base=False):
1447
1449
        """Emit conflict files.
1448
1450
        If this_lines, base_lines, or other_lines are omitted, they will be
1450
1452
        or .BASE (in that order) will be created as versioned files.
1451
1453
        """
1452
1454
        base_path, other_path, this_path = paths
 
1455
        if lines:
 
1456
            base_lines, other_lines, this_lines = lines
 
1457
        else:
 
1458
            base_lines = other_lines = this_lines = None
1453
1459
        data = [('OTHER', self.other_tree, other_path, other_lines),
1454
1460
                ('THIS', self.this_tree, this_path, this_lines)]
1455
1461
        if not no_base:
1462
1468
            # Skip the id2path lookup for older formats
1463
1469
            filter_tree_path = None
1464
1470
 
1465
 
        versioned = False
1466
1471
        file_group = []
1467
1472
        for suffix, tree, path, lines in data:
1468
1473
            if path is not None:
1470
1475
                    name, parent_id, path, tree, suffix, lines,
1471
1476
                    filter_tree_path)
1472
1477
                file_group.append(trans_id)
1473
 
                if set_version and not versioned:
1474
 
                    self.tt.version_file(trans_id, file_id=file_id)
1475
 
                    versioned = True
1476
1478
        return file_group
1477
1479
 
1478
1480
    def _conflict_file(self, name, parent_id, path, tree, suffix,
1519
1521
 
1520
1522
    def cook_conflicts(self, fs_conflicts):
1521
1523
        """Convert all conflicts into a form that doesn't depend on trans_id"""
1522
 
        content_conflict_file_ids = set()
1523
 
        cooked_conflicts = transform.cook_conflicts(fs_conflicts, self.tt)
1524
 
        fp = transform.FinalPaths(self.tt)
1525
 
        for conflict in self._raw_conflicts:
1526
 
            conflict_type = conflict[0]
1527
 
            if conflict_type == 'path conflict':
1528
 
                (trans_id, file_id,
1529
 
                 this_parent, this_name,
1530
 
                 other_parent, other_name) = conflict[1:]
1531
 
                if this_parent is None or this_name is None:
1532
 
                    this_path = '<deleted>'
1533
 
                else:
1534
 
                    parent_path = fp.get_path(
1535
 
                        self.tt.trans_id_file_id(this_parent))
1536
 
                    this_path = osutils.pathjoin(parent_path, this_name)
1537
 
                if other_parent is None or other_name is None:
1538
 
                    other_path = '<deleted>'
1539
 
                else:
1540
 
                    if other_parent == self.other_tree.path2id(''):
1541
 
                        # The tree transform doesn't know about the other root,
1542
 
                        # so we special case here to avoid a NoFinalPath
1543
 
                        # exception
1544
 
                        parent_path = ''
1545
 
                    else:
1546
 
                        parent_path = fp.get_path(
1547
 
                            self.tt.trans_id_file_id(other_parent))
1548
 
                    other_path = osutils.pathjoin(parent_path, other_name)
1549
 
                c = _mod_conflicts.Conflict.factory(
1550
 
                    'path conflict', path=this_path,
1551
 
                    conflict_path=other_path,
1552
 
                    file_id=file_id)
1553
 
            elif conflict_type == 'contents conflict':
1554
 
                for trans_id in conflict[1]:
1555
 
                    file_id = self.tt.final_file_id(trans_id)
1556
 
                    if file_id is not None:
1557
 
                        # Ok we found the relevant file-id
1558
 
                        break
1559
 
                path = fp.get_path(trans_id)
1560
 
                for suffix in ('.BASE', '.THIS', '.OTHER'):
1561
 
                    if path.endswith(suffix):
1562
 
                        # Here is the raw path
1563
 
                        path = path[:-len(suffix)]
1564
 
                        break
1565
 
                c = _mod_conflicts.Conflict.factory(conflict_type,
1566
 
                                                    path=path, file_id=file_id)
1567
 
                content_conflict_file_ids.add(file_id)
1568
 
            elif conflict_type == 'text conflict':
1569
 
                trans_id = conflict[1]
1570
 
                path = fp.get_path(trans_id)
1571
 
                file_id = self.tt.final_file_id(trans_id)
1572
 
                c = _mod_conflicts.Conflict.factory(conflict_type,
1573
 
                                                    path=path, file_id=file_id)
1574
 
            else:
1575
 
                raise AssertionError('bad conflict type: %r' % (conflict,))
1576
 
            cooked_conflicts.append(c)
1577
 
 
1578
 
        self.cooked_conflicts = []
1579
 
        # We want to get rid of path conflicts when a corresponding contents
1580
 
        # conflict exists. This can occur when one branch deletes a file while
1581
 
        # the other renames *and* modifies it. In this case, the content
1582
 
        # conflict is enough.
1583
 
        for c in cooked_conflicts:
1584
 
            if (c.typestring == 'path conflict'
1585
 
                    and c.file_id in content_conflict_file_ids):
1586
 
                continue
1587
 
            self.cooked_conflicts.append(c)
1588
 
        self.cooked_conflicts.sort(key=_mod_conflicts.Conflict.sort_key)
 
1524
        self.cooked_conflicts = list(self.tt.cook_conflicts(
 
1525
            list(fs_conflicts) + self._raw_conflicts))
1589
1526
 
1590
1527
 
1591
1528
class WeaveMerger(Merge3Merger):
1642
1579
            self._raw_conflicts.append(('text conflict', trans_id))
1643
1580
            name = self.tt.final_name(trans_id)
1644
1581
            parent_id = self.tt.final_parent(trans_id)
1645
 
            file_id = self.tt.final_file_id(trans_id)
1646
 
            file_group = self._dump_conflicts(name, paths, parent_id, file_id,
1647
 
                                              no_base=False,
1648
 
                                              base_lines=base_lines)
 
1582
            file_group = self._dump_conflicts(name, paths, parent_id,
 
1583
                                              (base_lines, None, None),
 
1584
                                              no_base=False)
1649
1585
            file_group.append(trans_id)
1650
1586
 
1651
1587
 
1695
1631
            if status == 1:
1696
1632
                name = self.tt.final_name(trans_id)
1697
1633
                parent_id = self.tt.final_parent(trans_id)
1698
 
                file_id = self.tt.final_file_id(trans_id)
1699
 
                self._dump_conflicts(name, paths, parent_id, file_id)
 
1634
                self._dump_conflicts(name, paths, parent_id)
1700
1635
                self._raw_conflicts.append(('text conflict', trans_id))
1701
1636
        finally:
1702
1637
            osutils.rmtree(temp_dir)