/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/bzr/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:
56
56
    conflicts as _mod_conflicts,
57
57
    globbing,
58
58
    ignores,
 
59
    merge,
59
60
    revision as _mod_revision,
60
61
    rio as _mod_rio,
61
62
    )
1862
1863
                    return False
1863
1864
                return True
1864
1865
 
 
1866
    _marker = object()
 
1867
 
 
1868
    def update(self, change_reporter=None, possible_transports=None,
 
1869
               revision=None, old_tip=_marker, show_base=False):
 
1870
        """Update a working tree along its branch.
 
1871
 
 
1872
        This will update the branch if its bound too, which means we have
 
1873
        multiple trees involved:
 
1874
 
 
1875
        - The new basis tree of the master.
 
1876
        - The old basis tree of the branch.
 
1877
        - The old basis tree of the working tree.
 
1878
        - The current working tree state.
 
1879
 
 
1880
        Pathologically, all three may be different, and non-ancestors of each
 
1881
        other.  Conceptually we want to:
 
1882
 
 
1883
        - Preserve the wt.basis->wt.state changes
 
1884
        - Transform the wt.basis to the new master basis.
 
1885
        - Apply a merge of the old branch basis to get any 'local' changes from
 
1886
          it into the tree.
 
1887
        - Restore the wt.basis->wt.state changes.
 
1888
 
 
1889
        There isn't a single operation at the moment to do that, so we:
 
1890
 
 
1891
        - Merge current state -> basis tree of the master w.r.t. the old tree
 
1892
          basis.
 
1893
        - Do a 'normal' merge of the old branch basis if it is relevant.
 
1894
 
 
1895
        :param revision: The target revision to update to. Must be in the
 
1896
            revision history.
 
1897
        :param old_tip: If branch.update() has already been run, the value it
 
1898
            returned (old tip of the branch or None). _marker is used
 
1899
            otherwise.
 
1900
        """
 
1901
        if self.branch.get_bound_location() is not None:
 
1902
            self.lock_write()
 
1903
            update_branch = (old_tip is self._marker)
 
1904
        else:
 
1905
            self.lock_tree_write()
 
1906
            update_branch = False
 
1907
        try:
 
1908
            if update_branch:
 
1909
                old_tip = self.branch.update(possible_transports)
 
1910
            else:
 
1911
                if old_tip is self._marker:
 
1912
                    old_tip = None
 
1913
            return self._update_tree(old_tip, change_reporter, revision, show_base)
 
1914
        finally:
 
1915
            self.unlock()
 
1916
 
 
1917
    def _update_tree(self, old_tip=None, change_reporter=None, revision=None,
 
1918
                     show_base=False):
 
1919
        """Update a tree to the master branch.
 
1920
 
 
1921
        :param old_tip: if supplied, the previous tip revision the branch,
 
1922
            before it was changed to the master branch's tip.
 
1923
        """
 
1924
        # here if old_tip is not None, it is the old tip of the branch before
 
1925
        # it was updated from the master branch. This should become a pending
 
1926
        # merge in the working tree to preserve the user existing work.  we
 
1927
        # cant set that until we update the working trees last revision to be
 
1928
        # one from the new branch, because it will just get absorbed by the
 
1929
        # parent de-duplication logic.
 
1930
        #
 
1931
        # We MUST save it even if an error occurs, because otherwise the users
 
1932
        # local work is unreferenced and will appear to have been lost.
 
1933
        #
 
1934
        with self.lock_tree_write():
 
1935
            nb_conflicts = 0
 
1936
            try:
 
1937
                last_rev = self.get_parent_ids()[0]
 
1938
            except IndexError:
 
1939
                last_rev = _mod_revision.NULL_REVISION
 
1940
            if revision is None:
 
1941
                revision = self.branch.last_revision()
 
1942
 
 
1943
            old_tip = old_tip or _mod_revision.NULL_REVISION
 
1944
 
 
1945
            if not _mod_revision.is_null(old_tip) and old_tip != last_rev:
 
1946
                # the branch we are bound to was updated
 
1947
                # merge those changes in first
 
1948
                base_tree = self.basis_tree()
 
1949
                other_tree = self.branch.repository.revision_tree(old_tip)
 
1950
                nb_conflicts = merge.merge_inner(self.branch, other_tree,
 
1951
                                                 base_tree, this_tree=self,
 
1952
                                                 change_reporter=change_reporter,
 
1953
                                                 show_base=show_base)
 
1954
                if nb_conflicts:
 
1955
                    self.add_parent_tree((old_tip, other_tree))
 
1956
                    return nb_conflicts
 
1957
 
 
1958
            if last_rev != _mod_revision.ensure_null(revision):
 
1959
                # the working tree is up to date with the branch
 
1960
                # we can merge the specified revision from master
 
1961
                to_tree = self.branch.repository.revision_tree(revision)
 
1962
                to_root_id = to_tree.path2id('')
 
1963
 
 
1964
                basis = self.basis_tree()
 
1965
                with basis.lock_read():
 
1966
                    if (basis.path2id('') is None or basis.path2id('') != to_root_id):
 
1967
                        self.set_root_id(to_root_id)
 
1968
                        self.flush()
 
1969
 
 
1970
                # determine the branch point
 
1971
                graph = self.branch.repository.get_graph()
 
1972
                base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
 
1973
                                                    last_rev)
 
1974
                base_tree = self.branch.repository.revision_tree(base_rev_id)
 
1975
 
 
1976
                nb_conflicts = merge.merge_inner(self.branch, to_tree, base_tree,
 
1977
                                                 this_tree=self,
 
1978
                                                 change_reporter=change_reporter,
 
1979
                                                 show_base=show_base)
 
1980
                self.set_last_revision(revision)
 
1981
                # TODO - dedup parents list with things merged by pull ?
 
1982
                # reuse the tree we've updated to to set the basis:
 
1983
                parent_trees = [(revision, to_tree)]
 
1984
                merges = self.get_parent_ids()[1:]
 
1985
                # Ideally we ask the tree for the trees here, that way the working
 
1986
                # tree can decide whether to give us the entire tree or give us a
 
1987
                # lazy initialised tree. dirstate for instance will have the trees
 
1988
                # in ram already, whereas a last-revision + basis-inventory tree
 
1989
                # will not, but also does not need them when setting parents.
 
1990
                for parent in merges:
 
1991
                    parent_trees.append(
 
1992
                        (parent, self.branch.repository.revision_tree(parent)))
 
1993
                if not _mod_revision.is_null(old_tip):
 
1994
                    parent_trees.append(
 
1995
                        (old_tip, self.branch.repository.revision_tree(old_tip)))
 
1996
                self.set_parent_trees(parent_trees)
 
1997
                last_rev = parent_trees[0][0]
 
1998
            return nb_conflicts
1865
1999
 
1866
2000
 
1867
2001
class WorkingTreeFormatMetaDir(bzrdir.BzrFormat, WorkingTreeFormat):