14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from __future__ import absolute_import
17
19
from .lazy_import import lazy_import
18
20
lazy_import(globals(), """
38
40
from .decorators import only_raises
39
41
from .inter import InterObject
40
42
from .lock import _RelockDebugMixin, LogicalLockResult
41
47
from .trace import (
42
48
log_exception_quietly, note, mutter, mutter_callsite, warning)
105
111
if committer is None:
106
112
self._committer = self._config_stack.get('email')
107
elif not isinstance(committer, str):
113
elif not isinstance(committer, text_type):
108
114
self._committer = committer.decode() # throw if non-ascii
110
116
self._committer = committer
146
152
raise ValueError('Invalid value for %s: %r' % (context, text))
148
154
def _validate_revprops(self, revprops):
149
for key, value in revprops.items():
155
for key, value in viewitems(revprops):
150
156
# We know that the XML serializers do not round trip '\r'
151
157
# correctly, so refuse to accept them
152
if not isinstance(value, str):
158
if not isinstance(value, (text_type, str)):
153
159
raise ValueError('revision property (%s) is not a valid'
154
160
' (unicode) string: %r' % (key, value))
155
161
# TODO(jelmer): Make this repository-format specific
885
891
raise NotImplementedError(self.iter_revisions)
893
def get_deltas_for_revisions(self, revisions, specific_fileids=None):
894
"""Produce a generator of revision deltas.
896
Note that the input is a sequence of REVISIONS, not revision_ids.
897
Trees will be held in memory until the generator exits.
898
Each delta is relative to the revision's lefthand predecessor.
900
:param specific_fileids: if not None, the result is filtered
901
so that only those file-ids, their parents and their
902
children are included.
904
raise NotImplementedError(self.get_deltas_for_revisions)
887
906
def get_revision_delta(self, revision_id):
888
907
"""Return the delta for one revision.
893
912
with self.lock_read():
894
913
r = self.get_revision(revision_id)
895
return list(self.get_revision_deltas([r]))[0]
897
def get_revision_deltas(self, revisions, specific_files=None):
898
"""Produce a generator of revision deltas.
900
Note that the input is a sequence of REVISIONS, not revision ids.
901
Trees will be held in memory until the generator exits.
902
Each delta is relative to the revision's lefthand predecessor.
904
specific_files should exist in the first revision.
906
:param specific_files: if not None, the result is filtered
907
so that only those files, their parents and their
908
children are included.
910
from .tree import InterTree
911
# Get the revision-ids of interest
912
required_trees = set()
913
for revision in revisions:
914
required_trees.add(revision.revision_id)
915
required_trees.update(revision.parent_ids[:1])
918
t.get_revision_id(): t
919
for t in self.revision_trees(required_trees)}
921
# Calculate the deltas
922
for revision in revisions:
923
if not revision.parent_ids:
924
old_tree = self.revision_tree(_mod_revision.NULL_REVISION)
926
old_tree = trees[revision.parent_ids[0]]
927
intertree = InterTree.get(old_tree, trees[revision.revision_id])
928
yield intertree.compare(specific_files=specific_files)
929
if specific_files is not None:
931
p for p in intertree.find_source_paths(
932
specific_files).values()
914
return list(self.get_deltas_for_revisions([r]))[0]
935
916
def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
936
917
raise NotImplementedError(self.store_revision_signature)
1072
1053
query_keys.append((revision_id,))
1073
1054
vf = self.revisions.without_fallbacks()
1074
for (revision_id,), parent_keys in (
1075
vf.get_parent_map(query_keys).items()):
1055
for (revision_id,), parent_keys in viewitems(
1056
vf.get_parent_map(query_keys)):
1076
1057
if parent_keys:
1077
1058
result[revision_id] = tuple([parent_revid
1078
1059
for (parent_revid,) in parent_keys])
1203
1184
# weave repositories refuse to store revisionids that are non-ascii.
1204
1185
if revision_id is not None:
1205
1186
# weaves require ascii revision ids.
1206
if isinstance(revision_id, str):
1187
if isinstance(revision_id, text_type):
1208
1189
revision_id.encode('ascii')
1209
1190
except UnicodeEncodeError:
1530
1511
self.target.set_make_working_trees(
1531
1512
self.source.make_working_trees())
1532
except (NotImplementedError, errors.RepositoryUpgradeRequired):
1513
except NotImplementedError:
1534
1515
self.target.fetch(self.source, revision_id=revision_id)
1639
1620
# Filter ghosts, and null:
1640
1621
if _mod_revision.NULL_REVISION in revision_graph:
1641
1622
del revision_graph[_mod_revision.NULL_REVISION]
1642
for key, parents in revision_graph.items():
1623
for key, parents in viewitems(revision_graph):
1643
1624
revision_graph[key] = tuple(parent for parent in parents if parent
1644
1625
in revision_graph)
1645
1626
return revision_graph