487
488
def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
488
489
raise NotImplementedError('store_revision_signature is abstract')
491
def fileid_involved_between_revs(self, from_revid, to_revid):
492
""" This function returns the file_id(s) involved in the
493
changes between the from_revid revision and the to_revid
496
raise NotImplementedError('fileid_involved_between_revs is abstract')
498
def fileid_involved(self, last_revid=None):
499
""" This function returns the file_id(s) involved in the
500
changes up to the revision last_revid
501
If no parametr is passed, then all file_id[s] present in the
502
repository are returned
504
raise NotImplementedError('fileid_involved is abstract')
506
def fileid_involved_by_set(self, changes):
507
""" This function returns the file_id(s) involved in the
508
changes present in the set 'changes'
510
raise NotImplementedError('fileid_involved_by_set is abstract')
490
512
class BzrBranch(Branch):
491
513
"""A branch stored in the actual filesystem.
1114
1136
self.revision_store.add(StringIO(gpg_strategy.sign(plaintext)),
1115
1137
revision_id, "sig")
1139
def fileid_involved_between_revs(self, from_revid, to_revid):
1140
"""Find file_id(s) which are involved in the changes between revisions.
1142
This determines the set of revisions which are involved, and then
1143
finds all file ids affected by those revisions.
1145
# TODO: jam 20060119 This code assumes that w.inclusions will
1146
# always be correct. But because of the presence of ghosts
1147
# it is possible to be wrong.
1148
# One specific example from Robert Collins:
1149
# Two branches, with revisions ABC, and AD
1150
# C is a ghost merge of D.
1151
# Inclusions doesn't recognize D as an ancestor.
1152
# If D is ever merged in the future, the weave
1153
# won't be fixed, because AD never saw revision C
1154
# to cause a conflict which would force a reweave.
1155
w = self._get_inventory_weave( )
1156
from_set = set(w.inclusions([w.lookup(from_revid)]))
1157
to_set = set(w.inclusions([w.lookup(to_revid)]))
1158
included = to_set.difference(from_set)
1159
changed = map(w.idx_to_name,included)
1160
return self._fileid_involved_by_set(changed)
1162
def fileid_involved(self, last_revid=None):
1163
"""Find all file_ids modified in the ancestry of last_revid.
1165
:param last_revid: If None, last_revision() will be used.
1167
w = self._get_inventory_weave( )
1169
changed = set(w._names)
1171
included = w.inclusions([w.lookup(last_revid)])
1172
changed = map(w.idx_to_name, included)
1173
return self._fileid_involved_by_set(changed)
1175
def fileid_involved_by_set(self, changes):
1176
"""Find all file_ids modified by the set of revisions passed in.
1178
:param changes: A set() of revision ids
1180
# TODO: jam 20060119 This line does *nothing*, remove it.
1181
# or better yet, change _fileid_involved_by_set so
1182
# that it takes the inventory weave, rather than
1183
# pulling it out by itself.
1184
w = self._get_inventory_weave( )
1185
return self._fileid_involved_by_set(changes)
1187
def _fileid_involved_by_set(self, changes):
1188
"""Find the set of file-ids affected by the set of revisions.
1190
:param changes: A set() of revision ids.
1191
:return: A set() of file ids.
1193
This peaks at the Weave, interpreting each line, looking to
1194
see if it mentions one of the revisions. And if so, includes
1195
the file id mentioned.
1196
This expects both the Weave format, and the serialization
1197
to have a single line per file/directory, and to have
1198
fileid="" and revision="" on that line.
1200
assert self._branch_format in (5,6), \
1201
"fileid_involved only supported for branches which store inventory as xml"
1203
w = self._get_inventory_weave( )
1205
for line in w._weave:
1207
# it is ugly, but it is due to the weave structure
1208
if not isinstance(line,basestring): continue
1210
start = line.find('file_id="')+9
1211
if start < 9: continue
1212
end = line.find('"',start)
1214
file_id = xml.sax.saxutils.unescape(line[start:end])
1216
# check if file_id is already present
1217
if file_id in file_ids: continue
1219
start = line.find('revision="')+10
1220
if start < 10: continue
1221
end = line.find('"',start)
1223
revision_id = xml.sax.saxutils.unescape(line[start:end])
1225
if revision_id in changes:
1226
file_ids.add(file_id)
1118
1231
class ScratchBranch(BzrBranch):
1119
1232
"""Special test class: a branch that cleans up after itself.