Show More
@@ -1948,3 +1948,117 b' class revlog(object):' | |||||
1948 | if not self._inline: |
|
1948 | if not self._inline: | |
1949 | res.append(self.datafile) |
|
1949 | res.append(self.datafile) | |
1950 | return res |
|
1950 | return res | |
|
1951 | ||||
|
1952 | DELTAREUSEALWAYS = 'always' | |||
|
1953 | DELTAREUSESAMEREVS = 'samerevs' | |||
|
1954 | DELTAREUSENEVER = 'never' | |||
|
1955 | ||||
|
1956 | DELTAREUSEALL = set(['always', 'samerevs', 'never']) | |||
|
1957 | ||||
|
1958 | def clone(self, tr, destrevlog, addrevisioncb=None, | |||
|
1959 | deltareuse=DELTAREUSESAMEREVS, aggressivemergedeltas=None): | |||
|
1960 | """Copy this revlog to another, possibly with format changes. | |||
|
1961 | ||||
|
1962 | The destination revlog will contain the same revisions and nodes. | |||
|
1963 | However, it may not be bit-for-bit identical due to e.g. delta encoding | |||
|
1964 | differences. | |||
|
1965 | ||||
|
1966 | The ``deltareuse`` argument control how deltas from the existing revlog | |||
|
1967 | are preserved in the destination revlog. The argument can have the | |||
|
1968 | following values: | |||
|
1969 | ||||
|
1970 | DELTAREUSEALWAYS | |||
|
1971 | Deltas will always be reused (if possible), even if the destination | |||
|
1972 | revlog would not select the same revisions for the delta. This is the | |||
|
1973 | fastest mode of operation. | |||
|
1974 | DELTAREUSESAMEREVS | |||
|
1975 | Deltas will be reused if the destination revlog would pick the same | |||
|
1976 | revisions for the delta. This mode strikes a balance between speed | |||
|
1977 | and optimization. | |||
|
1978 | DELTAREUSENEVER | |||
|
1979 | Deltas will never be reused. This is the slowest mode of execution. | |||
|
1980 | This mode can be used to recompute deltas (e.g. if the diff/delta | |||
|
1981 | algorithm changes). | |||
|
1982 | ||||
|
1983 | Delta computation can be slow, so the choice of delta reuse policy can | |||
|
1984 | significantly affect run time. | |||
|
1985 | ||||
|
1986 | The default policy (``DELTAREUSESAMEREVS``) strikes a balance between | |||
|
1987 | two extremes. Deltas will be reused if they are appropriate. But if the | |||
|
1988 | delta could choose a better revision, it will do so. This means if you | |||
|
1989 | are converting a non-generaldelta revlog to a generaldelta revlog, | |||
|
1990 | deltas will be recomputed if the delta's parent isn't a parent of the | |||
|
1991 | revision. | |||
|
1992 | ||||
|
1993 | In addition to the delta policy, the ``aggressivemergedeltas`` argument | |||
|
1994 | controls whether to compute deltas against both parents for merges. | |||
|
1995 | By default, the current default is used. | |||
|
1996 | """ | |||
|
1997 | if deltareuse not in self.DELTAREUSEALL: | |||
|
1998 | raise ValueError(_('value for deltareuse invalid: %s') % deltareuse) | |||
|
1999 | ||||
|
2000 | if len(destrevlog): | |||
|
2001 | raise ValueError(_('destination revlog is not empty')) | |||
|
2002 | ||||
|
2003 | if getattr(self, 'filteredrevs', None): | |||
|
2004 | raise ValueError(_('source revlog has filtered revisions')) | |||
|
2005 | if getattr(destrevlog, 'filteredrevs', None): | |||
|
2006 | raise ValueError(_('destination revlog has filtered revisions')) | |||
|
2007 | ||||
|
2008 | # lazydeltabase controls whether to reuse a cached delta, if possible. | |||
|
2009 | oldlazydeltabase = destrevlog._lazydeltabase | |||
|
2010 | oldamd = destrevlog._aggressivemergedeltas | |||
|
2011 | ||||
|
2012 | try: | |||
|
2013 | if deltareuse == self.DELTAREUSEALWAYS: | |||
|
2014 | destrevlog._lazydeltabase = True | |||
|
2015 | elif deltareuse == self.DELTAREUSESAMEREVS: | |||
|
2016 | destrevlog._lazydeltabase = False | |||
|
2017 | ||||
|
2018 | destrevlog._aggressivemergedeltas = aggressivemergedeltas or oldamd | |||
|
2019 | ||||
|
2020 | populatecachedelta = deltareuse in (self.DELTAREUSEALWAYS, | |||
|
2021 | self.DELTAREUSESAMEREVS) | |||
|
2022 | ||||
|
2023 | index = self.index | |||
|
2024 | for rev in self: | |||
|
2025 | entry = index[rev] | |||
|
2026 | ||||
|
2027 | # Some classes override linkrev to take filtered revs into | |||
|
2028 | # account. Use raw entry from index. | |||
|
2029 | flags = entry[0] & 0xffff | |||
|
2030 | linkrev = entry[4] | |||
|
2031 | p1 = index[entry[5]][7] | |||
|
2032 | p2 = index[entry[6]][7] | |||
|
2033 | node = entry[7] | |||
|
2034 | ||||
|
2035 | # (Possibly) reuse the delta from the revlog if allowed and | |||
|
2036 | # the revlog chunk is a delta. | |||
|
2037 | cachedelta = None | |||
|
2038 | text = None | |||
|
2039 | if populatecachedelta: | |||
|
2040 | dp = self.deltaparent(rev) | |||
|
2041 | if dp != nullrev: | |||
|
2042 | cachedelta = (dp, str(self._chunk(rev))) | |||
|
2043 | ||||
|
2044 | if not cachedelta: | |||
|
2045 | text = self.revision(rev) | |||
|
2046 | ||||
|
2047 | ifh = destrevlog.opener(destrevlog.indexfile, 'a+', | |||
|
2048 | checkambig=False) | |||
|
2049 | dfh = None | |||
|
2050 | if not destrevlog._inline: | |||
|
2051 | dfh = destrevlog.opener(destrevlog.datafile, 'a+') | |||
|
2052 | try: | |||
|
2053 | destrevlog._addrevision(node, text, tr, linkrev, p1, p2, | |||
|
2054 | flags, cachedelta, ifh, dfh) | |||
|
2055 | finally: | |||
|
2056 | if dfh: | |||
|
2057 | dfh.close() | |||
|
2058 | ifh.close() | |||
|
2059 | ||||
|
2060 | if addrevisioncb: | |||
|
2061 | addrevisioncb(self, rev, node) | |||
|
2062 | finally: | |||
|
2063 | destrevlog._lazydeltabase = oldlazydeltabase | |||
|
2064 | destrevlog._aggressivemergedeltas = oldamd |
General Comments 0
You need to be logged in to leave comments.
Login now