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 |