Mercurial > hgsubversion
comparison rebuildmeta.py @ 155:ba801f44d240
utility_commands: Implement rebuildmeta so that metadata can be rebuilt.
hg_delta_editor: Fixed some longstanding branch_info bugs detected while
rebuilding meta.
| author | Augie Fackler <durin42@gmail.com> |
|---|---|
| date | Tue, 23 Dec 2008 22:19:26 -0600 |
| parents | |
| children | e37f9d3fd5e7 |
comparison
equal
deleted
inserted
replaced
| 154:6fa97cfbf62f | 155:ba801f44d240 |
|---|---|
| 1 import os | |
| 2 import pickle | |
| 3 | |
| 4 from mercurial import node | |
| 5 | |
| 6 import svnwrap | |
| 7 import util | |
| 8 | |
| 9 @util.register_subcommand('rebuildmeta') | |
| 10 def rebuildmeta(ui, repo, hg_repo_path, args, **opts): | |
| 11 """Rebuild hgsubversion metadata using values stored in revisions. | |
| 12 """ | |
| 13 assert len(args) == 1, 'You must pass the svn URI used to create this repo.' | |
| 14 uuid = None | |
| 15 svn = svnwrap.SubversionRepo(url=args[0]) | |
| 16 subdir = svn.subdir | |
| 17 svnmetadir = os.path.join(repo.path, 'svn') | |
| 18 if not os.path.exists(svnmetadir): | |
| 19 os.makedirs(svnmetadir) | |
| 20 | |
| 21 revmap = open(os.path.join(svnmetadir, 'rev_map'), 'w') | |
| 22 revmap.write('1\n') | |
| 23 last_rev = -1 | |
| 24 branchinfo = {} | |
| 25 noderevnums = {} | |
| 26 for rev in repo: | |
| 27 ctx = repo[rev] | |
| 28 convinfo = ctx.extra().get('convert_revision', None) | |
| 29 if convinfo: | |
| 30 assert convinfo.startswith('svn:') | |
| 31 revpath, revision = convinfo[40:].split('@') | |
| 32 if subdir and subdir[0] != '/': | |
| 33 subdir = '/' + subdir | |
| 34 if subdir and subdir[-1] == '/': | |
| 35 subdir = subdir[:-1] | |
| 36 assert revpath.startswith(subdir), ('That does not look like the ' | |
| 37 'right location in the repo.') | |
| 38 if uuid is None: | |
| 39 uuid = convinfo[4:40] | |
| 40 assert uuid == svn.uuid, 'UUIDs did not match!' | |
| 41 urlfile = open(os.path.join(svnmetadir, 'url'), 'w') | |
| 42 urlfile.write(args[0]) | |
| 43 urlfile.close() | |
| 44 uuidfile = open(os.path.join(svnmetadir, 'uuid'), 'w') | |
| 45 uuidfile.write(uuid) | |
| 46 uuidfile.close() | |
| 47 commitpath = revpath[len(subdir)+1:] | |
| 48 if commitpath.startswith('branches'): | |
| 49 commitpath = commitpath[len('branches/'):] | |
| 50 elif commitpath == 'trunk': | |
| 51 commitpath = '' | |
| 52 else: | |
| 53 assert False, 'Unhandled case in rebuildmeta' | |
| 54 revmap.write('%s %s %s\n' % (revision, | |
| 55 node.hex(ctx.node()), | |
| 56 commitpath)) | |
| 57 revision = int(revision) | |
| 58 noderevnums[ctx.node()] = revision | |
| 59 if revision > last_rev: | |
| 60 last_rev = revision | |
| 61 branch = ctx.branch() | |
| 62 if branch == 'default': | |
| 63 branch = None | |
| 64 if branch not in branchinfo: | |
| 65 parent = ctx.parents()[0] | |
| 66 if (parent.node() in noderevnums | |
| 67 and parent.branch() != ctx.branch()): | |
| 68 parentbranch = parent.branch() | |
| 69 if parentbranch == 'default': | |
| 70 parentbranch = None | |
| 71 else: | |
| 72 parentbranch = None | |
| 73 branchinfo[branch] = (parentbranch, | |
| 74 noderevnums.get(parent.node(), 0), | |
| 75 revision) | |
| 76 for c in ctx.children(): | |
| 77 if c.branch() == 'closed-branches': | |
| 78 if branch in branchinfo: | |
| 79 del branchinfo[branch] | |
| 80 lastrevfile = open(os.path.join(svnmetadir, 'last_rev'), 'w') | |
| 81 lastrevfile.write(str(last_rev)) | |
| 82 lastrevfile.close() | |
| 83 branchinfofile = open(os.path.join(svnmetadir, 'branch_info'), 'w') | |
| 84 pickle.dump(branchinfo, branchinfofile) | |
| 85 branchinfofile.close() | |
| 86 tagsinfo = {} | |
| 87 realtags = svn.tags | |
| 88 tagsleft = realtags.items() | |
| 89 while tagsleft: | |
| 90 tag, tagparent = tagsleft.pop(0) | |
| 91 source, rev = tagparent | |
| 92 if source.startswith('tags/'): | |
| 93 src = source[len('tags/'):] | |
| 94 if src in tagsinfo: | |
| 95 tagsinfo[tag] = tagsinfo[src] | |
| 96 elif src in realtags: | |
| 97 if (realtags[src][1] <= last_rev | |
| 98 or realtags[src][0].startswith('tags/')): | |
| 99 tagsleft.append(src) | |
| 100 else: | |
| 101 older_tags = svn.tags_at_rev(rev) | |
| 102 newsrc, newrev = older_tags[src] | |
| 103 tagsleft.append((tag, (newsrc, newrev))) | |
| 104 if source.startswith('branches/') or source == 'trunk': | |
| 105 source = determinebranch(source) | |
| 106 if rev <= last_rev: | |
| 107 tagsinfo[tag] = source, rev | |
| 108 tagsinfofile = open(os.path.join(svnmetadir, 'tag_info'), 'w') | |
| 109 pickle.dump(tagsinfo, tagsinfofile) | |
| 110 tagsinfofile.close() | |
| 111 | |
| 112 | |
| 113 def determinebranch(branch): | |
| 114 if branch.startswith('branches'): | |
| 115 branch = branch[len('branches/'):] | |
| 116 elif branch == 'trunk': | |
| 117 branch = None | |
| 118 else: | |
| 119 assert False, 'Unhandled case while regenerating metadata.' | |
| 120 return branch |
