/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/git/workingtree.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2020-11-19 19:46:23 UTC
  • mfrom: (7524.2.5 merge-3.1)
  • Revision ID: breezy.the.bot@gmail.com-20201119194623-5tfi4z6ktdzo0z3y
Merge lp:brz/3.1.

Merged from https://code.launchpad.net/~jelmer/brz/merge-3.1/+merge/394038

Show diffs side-by-side

added added

removed removed

Lines of Context:
1448
1448
        config.write_to_path(path)
1449
1449
        self.add('.gitmodules')
1450
1450
 
 
1451
    _marker = object()
 
1452
 
 
1453
    def update(self, change_reporter=None, possible_transports=None,
 
1454
               revision=None, old_tip=_marker, show_base=False):
 
1455
        """Update a working tree along its branch.
 
1456
 
 
1457
        This will update the branch if its bound too, which means we have
 
1458
        multiple trees involved:
 
1459
 
 
1460
        - The new basis tree of the master.
 
1461
        - The old basis tree of the branch.
 
1462
        - The old basis tree of the working tree.
 
1463
        - The current working tree state.
 
1464
 
 
1465
        Pathologically, all three may be different, and non-ancestors of each
 
1466
        other.  Conceptually we want to:
 
1467
 
 
1468
        - Preserve the wt.basis->wt.state changes
 
1469
        - Transform the wt.basis to the new master basis.
 
1470
        - Apply a merge of the old branch basis to get any 'local' changes from
 
1471
          it into the tree.
 
1472
        - Restore the wt.basis->wt.state changes.
 
1473
 
 
1474
        There isn't a single operation at the moment to do that, so we:
 
1475
 
 
1476
        - Merge current state -> basis tree of the master w.r.t. the old tree
 
1477
          basis.
 
1478
        - Do a 'normal' merge of the old branch basis if it is relevant.
 
1479
 
 
1480
        :param revision: The target revision to update to. Must be in the
 
1481
            revision history.
 
1482
        :param old_tip: If branch.update() has already been run, the value it
 
1483
            returned (old tip of the branch or None). _marker is used
 
1484
            otherwise.
 
1485
        """
 
1486
        if self.branch.get_bound_location() is not None:
 
1487
            self.lock_write()
 
1488
            update_branch = (old_tip is self._marker)
 
1489
        else:
 
1490
            self.lock_tree_write()
 
1491
            update_branch = False
 
1492
        try:
 
1493
            if update_branch:
 
1494
                old_tip = self.branch.update(possible_transports)
 
1495
            else:
 
1496
                if old_tip is self._marker:
 
1497
                    old_tip = None
 
1498
            return self._update_tree(old_tip, change_reporter, revision, show_base)
 
1499
        finally:
 
1500
            self.unlock()
 
1501
 
 
1502
    def _update_tree(self, old_tip=None, change_reporter=None, revision=None,
 
1503
                     show_base=False):
 
1504
        """Update a tree to the master branch.
 
1505
 
 
1506
        :param old_tip: if supplied, the previous tip revision the branch,
 
1507
            before it was changed to the master branch's tip.
 
1508
        """
 
1509
        # here if old_tip is not None, it is the old tip of the branch before
 
1510
        # it was updated from the master branch. This should become a pending
 
1511
        # merge in the working tree to preserve the user existing work.  we
 
1512
        # cant set that until we update the working trees last revision to be
 
1513
        # one from the new branch, because it will just get absorbed by the
 
1514
        # parent de-duplication logic.
 
1515
        #
 
1516
        # We MUST save it even if an error occurs, because otherwise the users
 
1517
        # local work is unreferenced and will appear to have been lost.
 
1518
        #
 
1519
        with self.lock_tree_write():
 
1520
            from .. import merge
 
1521
            nb_conflicts = 0
 
1522
            try:
 
1523
                last_rev = self.get_parent_ids()[0]
 
1524
            except IndexError:
 
1525
                last_rev = _mod_revision.NULL_REVISION
 
1526
            if revision is None:
 
1527
                revision = self.branch.last_revision()
 
1528
 
 
1529
            old_tip = old_tip or _mod_revision.NULL_REVISION
 
1530
 
 
1531
            if not _mod_revision.is_null(old_tip) and old_tip != last_rev:
 
1532
                # the branch we are bound to was updated
 
1533
                # merge those changes in first
 
1534
                base_tree = self.basis_tree()
 
1535
                other_tree = self.branch.repository.revision_tree(old_tip)
 
1536
                nb_conflicts = merge.merge_inner(self.branch, other_tree,
 
1537
                                                 base_tree, this_tree=self,
 
1538
                                                 change_reporter=change_reporter,
 
1539
                                                 show_base=show_base)
 
1540
                if nb_conflicts:
 
1541
                    self.add_parent_tree((old_tip, other_tree))
 
1542
                    return nb_conflicts
 
1543
 
 
1544
            if last_rev != _mod_revision.ensure_null(revision):
 
1545
                to_tree = self.branch.repository.revision_tree(revision)
 
1546
 
 
1547
                # determine the branch point
 
1548
                graph = self.branch.repository.get_graph()
 
1549
                base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
 
1550
                                                    last_rev)
 
1551
                base_tree = self.branch.repository.revision_tree(base_rev_id)
 
1552
 
 
1553
                nb_conflicts = merge.merge_inner(self.branch, to_tree, base_tree,
 
1554
                                                 this_tree=self,
 
1555
                                                 change_reporter=change_reporter,
 
1556
                                                 show_base=show_base)
 
1557
                self.set_last_revision(revision)
 
1558
                # TODO - dedup parents list with things merged by pull ?
 
1559
                # reuse the tree we've updated to to set the basis:
 
1560
                parent_trees = [(revision, to_tree)]
 
1561
                merges = self.get_parent_ids()[1:]
 
1562
                # Ideally we ask the tree for the trees here, that way the working
 
1563
                # tree can decide whether to give us the entire tree or give us a
 
1564
                # lazy initialised tree. dirstate for instance will have the trees
 
1565
                # in ram already, whereas a last-revision + basis-inventory tree
 
1566
                # will not, but also does not need them when setting parents.
 
1567
                for parent in merges:
 
1568
                    parent_trees.append(
 
1569
                        (parent, self.branch.repository.revision_tree(parent)))
 
1570
                if not _mod_revision.is_null(old_tip):
 
1571
                    parent_trees.append(
 
1572
                        (old_tip, self.branch.repository.revision_tree(old_tip)))
 
1573
                self.set_parent_trees(parent_trees)
 
1574
                last_rev = parent_trees[0][0]
 
1575
            return nb_conflicts
 
1576
 
1451
1577
 
1452
1578
class GitWorkingTreeFormat(workingtree.WorkingTreeFormat):
1453
1579