comparison hg_delta_editor.py @ 316:c3c647aff97c

Merge with danchr's changes.
author Augie Fackler <durin42@gmail.com>
date Sun, 03 May 2009 21:44:53 -0500
parents 2257bfc01749 1d48d9a34c19
children 5dc8fee7fc96
comparison
equal deleted inserted replaced
315:963d27a0b1c2 316:c3c647aff97c
14 from svn import delta 14 from svn import delta
15 from svn import core 15 from svn import core
16 16
17 import svnexternals 17 import svnexternals
18 import util 18 import util
19 from maps import *
19 20
20 def pickle_atomic(data, file_path, dir=None): 21 def pickle_atomic(data, file_path, dir=None):
21 """pickle some data to a path atomically. 22 """pickle some data to a path atomically.
22 23
23 This is present because I kept corrupting my revmap by managing to hit ^C 24 This is present because I kept corrupting my revmap by managing to hit ^C
117 f.close() 118 f.close()
118 else: 119 else:
119 self.tag_locations = tag_locations 120 self.tag_locations = tag_locations
120 pickle_atomic(self.tag_locations, self.tag_locations_file, 121 pickle_atomic(self.tag_locations, self.tag_locations_file,
121 self.meta_data_dir) 122 self.meta_data_dir)
123 # ensure nested paths are handled properly
124 self.tag_locations.sort()
125 self.tag_locations.reverse()
122 126
123 self.clear_current_info() 127 self.clear_current_info()
124 self.author_host = author_host 128 self.authors = AuthorMap(self.ui, self.authors_file,
125 self.authors = {} 129 defaulthost=author_host)
126 if os.path.exists(self.authors_file): 130 if authors: self.authors.load(authors)
127 self.readauthors(self.authors_file)
128 if authors and os.path.exists(authors):
129 self.readauthors(authors)
130 if self.authors:
131 self.writeauthors()
132 131
133 self.lastdate = '1970-01-01 00:00:00 -0000' 132 self.lastdate = '1970-01-01 00:00:00 -0000'
134 self.includepaths = {} 133 self.includepaths = {}
135 self.excludepaths = {} 134 self.excludepaths = {}
136 if filemap and os.path.exists(filemap): 135 if filemap and os.path.exists(filemap):
254 return branches 253 return branches
255 254
256 def _path_and_branch_for_path(self, path, existing=True): 255 def _path_and_branch_for_path(self, path, existing=True):
257 return self._split_branch_path(path, existing=existing)[:2] 256 return self._split_branch_path(path, existing=existing)[:2]
258 257
258 def _branch_for_path(self, path, existing=True):
259 return self._path_and_branch_for_path(path, existing=existing)[1]
260
259 def _localname(self, path): 261 def _localname(self, path):
260 """Compute the local name for a branch located at path. 262 """Compute the local name for a branch located at path.
261 """ 263 """
262 assert not path.startswith('tags/') 264 assert not path.startswith('tags/')
263 if path == 'trunk': 265 if path == 'trunk':
391 Note that it's only a tag if it was copied from the path '' in a branch (or tag) 393 Note that it's only a tag if it was copied from the path '' in a branch (or tag)
392 we have, for our purposes. 394 we have, for our purposes.
393 395
394 Otherwise, returns False. 396 Otherwise, returns False.
395 """ 397 """
398 return self._split_tag_path(path)[1] or False
399
400 def _split_tag_path(self, path):
401 """Figure out which tag inside our repo this path represents, and
402 also figure out which path inside that tag it is.
403
404 Returns a tuple of (path within tag, tag name, server-side tag
405 path).
406 """
396 path = self._normalize_path(path) 407 path = self._normalize_path(path)
397 for tags_path in self.tag_locations: 408 for tags_path in self.tag_locations:
398 if path and (path.startswith(tags_path) and 409 if path and (path.startswith(tags_path) and
399 len(path) > len('%s/' % tags_path)): 410 len(path) > len('%s/' % tags_path)):
400 return path[len(tags_path)+1:] 411 tag, _, subpath = path[len(tags_path)+1:].partition('/')
401 return False 412 return (subpath, tag, '%s/%s' % (tags_path, tag))
413 return (None, None, None)
402 414
403 def get_parent_svn_branch_and_rev(self, number, branch): 415 def get_parent_svn_branch_and_rev(self, number, branch):
404 number -= 1 416 number -= 1
405 if (number, branch) in self.revmap: 417 if (number, branch) in self.revmap:
406 return number, branch 418 return number, branch
624 current_ctx = context.memctx(self.repo, 636 current_ctx = context.memctx(self.repo,
625 parents, 637 parents,
626 rev.message or ' ', 638 rev.message or ' ',
627 files, 639 files,
628 del_all_files, 640 del_all_files,
629 self.authorforsvnauthor(rev.author), 641 self.authors[rev.author],
630 date, 642 date,
631 {'branch': 'closed-branches'}) 643 {'branch': 'closed-branches'})
632 new_hash = self.repo.commitctx(current_ctx) 644 new_hash = self.repo.commitctx(current_ctx)
633 self.ui.status('Marked branch %s as closed.\n' % (branch or 645 self.ui.status('Marked branch %s as closed.\n' % (branch or
634 'default')) 646 'default'))
677 current_ctx = context.memctx(self.repo, 689 current_ctx = context.memctx(self.repo,
678 parents, 690 parents,
679 rev.message or '...', 691 rev.message or '...',
680 files.keys(), 692 files.keys(),
681 filectxfn, 693 filectxfn,
682 self.authorforsvnauthor(rev.author), 694 self.authors[rev.author],
683 date, 695 date,
684 extra) 696 extra)
685 new_hash = self.repo.commitctx(current_ctx) 697 new_hash = self.repo.commitctx(current_ctx)
686 util.describe_commit(self.ui, new_hash, branch) 698 util.describe_commit(self.ui, new_hash, branch)
687 if (rev.revnum, branch) not in self.revmap: 699 if (rev.revnum, branch) not in self.revmap:
704 current_ctx = context.memctx(self.repo, 716 current_ctx = context.memctx(self.repo,
705 (ha, node.nullid), 717 (ha, node.nullid),
706 rev.message or ' ', 718 rev.message or ' ',
707 [], 719 [],
708 del_all_files, 720 del_all_files,
709 self.authorforsvnauthor(rev.author), 721 self.authors[rev.author],
710 date, 722 date,
711 extra) 723 extra)
712 new_hash = self.repo.commitctx(current_ctx) 724 new_hash = self.repo.commitctx(current_ctx)
713 util.describe_commit(self.ui, new_hash, branch) 725 util.describe_commit(self.ui, new_hash, branch)
714 if (rev.revnum, branch) not in self.revmap: 726 if (rev.revnum, branch) not in self.revmap:
715 self.add_to_revmap(rev.revnum, branch, new_hash) 727 self.add_to_revmap(rev.revnum, branch, new_hash)
716 self._save_metadata() 728 self._save_metadata()
717 self.clear_current_info() 729 self.clear_current_info()
718
719 def authorforsvnauthor(self, author):
720 if author in self.authors:
721 return self.authors[author]
722 return '%s%s' % (author, self.author_host)
723
724 def svnauthorforauthor(self, author):
725 for svnauthor, hgauthor in self.authors.iteritems():
726 if author == hgauthor:
727 return svnauthor
728 else:
729 # return the original svn-side author
730 return author.rsplit('@', 1)[0]
731
732 def readauthors(self, authorfile):
733 self.ui.note(('Reading authormap from %s\n') % authorfile)
734 f = open(authorfile, 'r')
735 for line in f:
736 if not line.strip():
737 continue
738 try:
739 srcauth, dstauth = line.split('=', 1)
740 srcauth = srcauth.strip()
741 dstauth = dstauth.strip()
742 if srcauth in self.authors and dstauth != self.authors[srcauth]:
743 self.ui.status(('Overriding author mapping for "%s" ' +
744 'from "%s" to "%s"\n')
745 % (srcauth, self.authors[srcauth], dstauth))
746 else:
747 self.ui.debug(('Mapping author "%s" to "%s"\n')
748 % (srcauth, dstauth))
749 self.authors[srcauth] = dstauth
750 except IndexError:
751 self.ui.warn(
752 ('Ignoring bad line in author map file %s: %s\n')
753 % (authorfile, line.rstrip()))
754 f.close()
755
756 def writeauthors(self):
757 self.ui.debug(('Writing author map to %s\n') % self.authors_file)
758 f = open(self.authors_file, 'w+')
759 for author in self.authors:
760 f.write("%s=%s\n" % (author, self.authors[author]))
761 f.close()
762 730
763 def readfilemap(self, filemapfile): 731 def readfilemap(self, filemapfile):
764 self.ui.note( 732 self.ui.note(
765 ('Reading file map from %s\n') 733 ('Reading file map from %s\n')
766 % filemapfile) 734 % filemapfile)
912 if f in files: 880 if f in files:
913 return False 881 return False
914 # parentctx is not an ancestor of childctx, files are unrelated 882 # parentctx is not an ancestor of childctx, files are unrelated
915 return False 883 return False
916 884
917 def add_file(self, path, parent_baton, copyfrom_path, 885 def add_file(self, path, parent_baton=None, copyfrom_path=None,
918 copyfrom_revision, file_pool=None): 886 copyfrom_revision=None, file_pool=None):
919 self.current_file = None 887 self.current_file = None
920 self.base_revision = None 888 self.base_revision = None
921 if path in self.deleted_files: 889 if path in self.deleted_files:
922 del self.deleted_files[path] 890 del self.deleted_files[path]
923 fpath, branch = self._path_and_branch_for_path(path, existing=False) 891 fpath, branch = self._path_and_branch_for_path(path, existing=False)