Mercurial > hgsubversion
comparison hg_delta_editor.py @ 59:430af23bef4a
Performance fix for branches-from-tags in real replay, which is tied up with
changes that fix problems when trunk is not the oldest branch. Also includes
fixes for copying from a tag that we chose not to create (eg tagging a vendor
branch) and includes tests for all of those things.
author | Augie Fackler <durin42@gmail.com> |
---|---|
date | Tue, 04 Nov 2008 16:38:16 -0600 |
parents | 987e44afa71e |
children | e319c9168910 |
comparison
equal
deleted
inserted
replaced
58:a8b9c7e7c2ac | 59:430af23bef4a |
---|---|
244 def update_branch_tag_map_for_rev(self, revision): | 244 def update_branch_tag_map_for_rev(self, revision): |
245 paths = revision.paths | 245 paths = revision.paths |
246 added_branches = {} | 246 added_branches = {} |
247 added_tags = {} | 247 added_tags = {} |
248 tags_to_delete = set() | 248 tags_to_delete = set() |
249 branches_to_delete = set() | |
249 for p in paths: | 250 for p in paths: |
250 if self._is_path_valid(p): | 251 if self._is_path_valid(p): |
251 fi, br = self._path_and_branch_for_path(p) | 252 fi, br = self._path_and_branch_for_path(p) |
252 if fi == '' and br not in self.branches: | 253 if fi == '' and br not in self.branches: |
253 # TODO handle creating a branch from a tag | |
254 src_p = paths[p].copyfrom_path | 254 src_p = paths[p].copyfrom_path |
255 src_rev = paths[p].copyfrom_rev | 255 src_rev = paths[p].copyfrom_rev |
256 src_tag = self._is_path_tag(src_p) | 256 src_tag = self._is_path_tag(src_p) |
257 | 257 |
258 if not src_p or not (self._is_path_valid(src_p) or src_tag): | 258 if not ((src_p and self._is_path_valid(src_p)) or |
259 (src_tag and src_tag in self.tags)): | |
259 # we'll imply you're a branch off of trunk | 260 # we'll imply you're a branch off of trunk |
260 # if you have no path, but if you do, it must be valid | 261 # if you have no path, but if you do, it must be valid |
261 # or else we assume trunk as well | 262 # or else we assume trunk as well |
262 src_branch = None | 263 src_branch = None |
263 src_rev = revision.revnum | 264 src_rev = revision.revnum |
270 else: | 271 else: |
271 # Not from a tag, and from a valid repo path | 272 # Not from a tag, and from a valid repo path |
272 (src_p, | 273 (src_p, |
273 src_branch) = self._path_and_branch_for_path(src_p) | 274 src_branch) = self._path_and_branch_for_path(src_p) |
274 added_branches[br] = src_branch, src_rev, revision.revnum | 275 added_branches[br] = src_branch, src_rev, revision.revnum |
276 elif fi == '' and br in self.branches: | |
277 br2 = br or 'default' | |
278 if br2 not in self.repo.branchtags() and paths[p].action == 'D': | |
279 branches_to_delete.add(br) | |
275 elif br in added_branches: | 280 elif br in added_branches: |
276 if paths[p].copyfrom_rev > added_branches[br][1]: | 281 if paths[p].copyfrom_rev > added_branches[br][1]: |
277 x,y,z = added_branches[br] | 282 x,y,z = added_branches[br] |
278 added_branches[br] = x, paths[p].copyfrom_rev, z | 283 added_branches[br] = x, paths[p].copyfrom_rev, z |
279 else: | 284 else: |
300 elif (paths[p].action == 'D' and p.endswith(t_name) | 305 elif (paths[p].action == 'D' and p.endswith(t_name) |
301 and t_name in self.tags): | 306 and t_name in self.tags): |
302 tags_to_delete.add(t_name) | 307 tags_to_delete.add(t_name) |
303 for t in tags_to_delete: | 308 for t in tags_to_delete: |
304 del self.tags[t] | 309 del self.tags[t] |
310 for br in branches_to_delete: | |
311 del self.branches[br] | |
305 self.tags.update(added_tags) | 312 self.tags.update(added_tags) |
306 self.branches.update(added_branches) | 313 self.branches.update(added_branches) |
307 self._save_metadata() | 314 self._save_metadata() |
308 | 315 |
309 def commit_current_delta(self): | 316 def commit_current_delta(self): |
337 files = dict(files) | 344 files = dict(files) |
338 | 345 |
339 parents = (self.get_parent_revision(rev.revnum, branch), | 346 parents = (self.get_parent_revision(rev.revnum, branch), |
340 revlog.nullid) | 347 revlog.nullid) |
341 if branch is not None: | 348 if branch is not None: |
342 if branch not in self.branches: | 349 if branch not in self.branches and branch not in self.repo.branchtags(): |
343 continue | 350 continue |
344 if parents == (revlog.nullid, revlog.nullid): | |
345 assert False, ('a non-trunk branch should probably have' | |
346 ' parents figured out by this point') | |
347 extra['branch'] = branch | 351 extra['branch'] = branch |
348 parent_ctx = self.repo.changectx(parents[0]) | 352 parent_ctx = self.repo.changectx(parents[0]) |
349 def filectxfn(repo, memctx, path): | 353 def filectxfn(repo, memctx, path): |
350 copied = None | 354 copied = None |
351 current_file = files[path] | 355 current_file = files[path] |
352 if current_file in self.deleted_files: | 356 if current_file in self.deleted_files: |
353 raise IOError() | 357 raise IOError() |
354 # TODO(augie) tag copies from files | 358 # TODO(augie) tag copies from files |
355 flags = parent_ctx.flags(path) | 359 flags = parent_ctx.flags(path) |
356 is_exec = self.current_files_exec.get(current_file, | 360 is_exec = self.current_files_exec.get(current_file, |
357 'x' in flags) | 361 'x' in flags) |
358 is_link = self.current_files_symlink.get(current_file, | 362 is_link = self.current_files_symlink.get(current_file, |
359 'l' in flags) | 363 'l' in flags) |
360 if current_file in self.current_files: | 364 if current_file in self.current_files: |
361 data = self.current_files[current_file] | 365 data = self.current_files[current_file] |
362 if is_link: | 366 if is_link: |
363 assert data.startswith('link ') | 367 assert data.startswith('link ') |
495 copyfrom_revision, file_pool=None): | 499 copyfrom_revision, file_pool=None): |
496 self.current_file = 'foobaz' | 500 self.current_file = 'foobaz' |
497 self.base_revision = None | 501 self.base_revision = None |
498 if path in self.deleted_files: | 502 if path in self.deleted_files: |
499 del self.deleted_files[path] | 503 del self.deleted_files[path] |
500 if (self._is_path_valid(path) and | 504 if (self._is_path_valid(path) and |
501 self._path_and_branch_for_path(path)[0]): | 505 self._path_and_branch_for_path(path)[0]): |
502 self.current_file = path | 506 self.current_file = path |
503 self.should_edit_most_recent_plaintext = False | 507 self.should_edit_most_recent_plaintext = False |
504 if copyfrom_path: | 508 if copyfrom_path: |
505 self.ui.status('A+ %s\n' % path) | 509 self.ui.status('A+ %s\n' % path) |
531 self.commit_branches_empty[branch] = True | 535 self.commit_branches_empty[branch] = True |
532 else: | 536 else: |
533 self.commit_branches_empty[branch] = False | 537 self.commit_branches_empty[branch] = False |
534 if not self._is_path_valid(path) or not copyfrom_path: | 538 if not self._is_path_valid(path) or not copyfrom_path: |
535 return | 539 return |
536 if copyfrom_path and not self._is_path_valid(copyfrom_path): | 540 if copyfrom_path: |
537 self.missing_plaintexts.add('%s/' % path) | 541 tag = self._is_path_tag(copyfrom_path) |
538 return | 542 if tag not in self.tags: |
539 | 543 tag = None |
540 cp_f, br_from = self._path_and_branch_for_path(copyfrom_path) | 544 if not self._is_path_valid(copyfrom_path) and not tag: |
541 new_hash = self.get_parent_revision(copyfrom_revision + 1, br_from) | 545 self.missing_plaintexts.add('%s/' % path) |
546 return | |
547 | |
548 if tag: | |
549 source_branch, source_rev = self.tags[tag] | |
550 cp_f = '' | |
551 else: | |
552 source_rev = copyfrom_revision | |
553 cp_f, source_branch = self._path_and_branch_for_path(copyfrom_path) | |
554 new_hash = self.get_parent_revision(source_rev + 1, | |
555 source_branch) | |
542 if new_hash == node.nullid: | 556 if new_hash == node.nullid: |
543 self.missing_plaintexts.add('%s/' % path) | 557 self.missing_plaintexts.add('%s/' % path) |
544 return | 558 return |
545 cp_f_ctx = self.repo.changectx(new_hash) | 559 cp_f_ctx = self.repo.changectx(new_hash) |
546 if cp_f != '/' and cp_f != '': | 560 if cp_f != '/' and cp_f != '': |