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