##// END OF EJS Templates
Add debughash and debugindex commands
mpm@selenic.com -
r24:57a1eef7 default
parent child Browse files
Show More
@@ -1,303 +1,317 b''
1 1 #!/usr/bin/env python
2 2 #
3 3 # mercurial - a minimal scalable distributed SCM
4 4 # v0.4d "oedipa maas"
5 5 #
6 6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
7 7 #
8 8 # This software may be used and distributed according to the terms
9 9 # of the GNU General Public License, incorporated herein by reference.
10 10
11 11 # the psyco compiler makes commits about twice as fast
12 12 try:
13 13 import psyco
14 14 psyco.full()
15 15 except:
16 16 pass
17 17
18 18 import sys, os, time
19 19 from mercurial import hg, mdiff, fancyopts
20 20
21 21 def help():
22 22 print """\
23 23 commands:
24 24
25 25 init create a new repository in this directory
26 26 branch <path> create a branch of <path> in this directory
27 27 merge <path> merge changes from <path> into local repository
28 28 checkout [changeset] checkout the latest or given changeset
29 29 status show new, missing, and changed files in working dir
30 30 add [files...] add the given files in the next commit
31 31 remove [files...] remove the given files in the next commit
32 32 addremove add all new files, delete all missing files
33 33 commit commit all changes to the repository
34 34 history show changeset history
35 35 log <file> show revision history of a single file
36 36 dump <file> [rev] dump the latest or given revision of a file
37 37 dumpmanifest [rev] dump the latest or given revision of the manifest
38 38 diff [files...] diff working directory (or selected files)
39 39 """
40 40
41 41 options = {}
42 42 opts = [('v', 'verbose', None, 'verbose'),
43 43 ('d', 'debug', None, 'debug')]
44 44
45 45 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
46 46 'hg [options] <command> [command options] [files]')
47 47
48 48 try:
49 49 cmd = args[0]
50 50 args = args[1:]
51 51 except:
52 52 cmd = ""
53 53
54 54 ui = hg.ui(options["verbose"], options["debug"])
55 55
56 56 if cmd == "init":
57 57 repo = hg.repository(ui, ".", create=1)
58 58 sys.exit(0)
59 59 elif cmd == "branch" or cmd == "clone":
60 60 os.system("cp -al %s/.hg .hg" % args[0])
61 61 sys.exit(0)
62 62 elif cmd == "help":
63 63 help()
64 64 sys.exit(0)
65 65 else:
66 66 try:
67 67 repo = hg.repository(ui=ui)
68 68 except:
69 69 print "Unable to open repository"
70 70 sys.exit(0)
71 71
72 72 if cmd == "checkout" or cmd == "co":
73 73 node = repo.changelog.tip()
74 74 if len(args):
75 75 if len(args[0]) < 40:
76 76 rev = int(args[0])
77 77 node = repo.changelog.node(rev)
78 78 else:
79 79 node = args[0]
80 80 repo.checkout(node)
81 81
82 82 elif cmd == "add":
83 83 repo.add(args)
84 84
85 85 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
86 86 repo.remove(args)
87 87
88 88 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
89 89 if 1:
90 90 if len(args) > 0:
91 91 repo.commit(args)
92 92 else:
93 93 repo.commit()
94 94
95 95 elif cmd == "import" or cmd == "patch":
96 96 ioptions = {}
97 97 opts = [('p', 'strip', 1, 'path strip'),
98 98 ('b', 'base', "", 'base path')]
99 99
100 100 args = fancyopts.fancyopts(args, opts, ioptions,
101 101 'hg import [options] <patch names>')
102 102 d = ioptions["base"]
103 103 strip = ioptions["strip"]
104 104
105 105 for patch in args:
106 106 ui.status("applying %s\n" % patch)
107 107 pf = d + patch
108 108 os.system("patch -p%d < %s > /dev/null" % (strip, pf))
109 109 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
110 110 files = f.read().splitlines()
111 111 f.close()
112 112 repo.commit(files)
113 113
114 114 elif cmd == "status":
115 115 (c, a, d) = repo.diffdir(repo.root)
116 116 for f in c: print "C", f
117 117 for f in a: print "?", f
118 118 for f in d: print "R", f
119 119
120 120 elif cmd == "diff":
121 121 mmap = {}
122 122 if repo.current:
123 123 change = repo.changelog.read(repo.current)
124 124 mmap = repo.manifest.read(change[0])
125 125
126 126 (c, a, d) = repo.diffdir(repo.root)
127 127
128 128 if args:
129 129 nc = [ x for x in c if x in args ]
130 130 na = [ x for x in a if x in args ]
131 131 nd = [ x for x in d if x in args ]
132 132 for arg in args:
133 133 if not os.path.isdir(arg): continue
134 134 if arg[-1] != os.sep: arg += os.sep
135 135 nc += [ x for x in c if x.startswith(arg) ]
136 136 na += [ x for x in a if x.startswith(arg) ]
137 137 nd += [ x for x in d if x.startswith(arg) ]
138 138 (c, a, d) = (nc, na, nd)
139 139
140 140 for f in c:
141 141 to = repo.file(f).read(mmap[f])
142 142 tn = file(f).read()
143 143 sys.stdout.write(mdiff.unidiff(to, tn, f))
144 144 for f in a:
145 145 to = ""
146 146 tn = file(f).read()
147 147 sys.stdout.write(mdiff.unidiff(to, tn, f))
148 148 for f in d:
149 149 to = repo.file(f).read(mmap[f])
150 150 tn = ""
151 151 sys.stdout.write(mdiff.unidiff(to, tn, f))
152 152
153 153 elif cmd == "addremove":
154 154 (c, a, d) = repo.diffdir(repo.root)
155 155 repo.add(a)
156 156 repo.remove(d)
157 157
158 158 elif cmd == "history":
159 159 for i in range(repo.changelog.count()):
160 160 n = repo.changelog.node(i)
161 161 changes = repo.changelog.read(n)
162 162 (p1, p2) = repo.changelog.parents(n)
163 163 (h, h1, h2) = map(hg.hex, (n, p1, p2))
164 164 (i1, i2) = map(repo.changelog.rev, (p1, p2))
165 165 print "rev: %4d:%s" % (i, h)
166 166 print "parents: %4d:%s" % (i1, h1)
167 167 if i2: print " %4d:%s" % (i2, h2)
168 168 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
169 169 hg.hex(changes[0]))
170 170 print "user:", changes[1]
171 171 print "date:", time.asctime(
172 172 time.localtime(float(changes[2].split(' ')[0])))
173 173 print "files:", " ".join(changes[3])
174 174 print "description:"
175 175 print changes[4]
176 176
177 177 elif cmd == "log":
178 178 if args:
179 179 r = repo.file(args[0])
180 180 for i in range(r.count()):
181 181 n = r.node(i)
182 182 (p1, p2) = r.parents(n)
183 183 (h, h1, h2) = map(hg.hex, (n, p1, p2))
184 184 (i1, i2) = map(r.rev, (p1, p2))
185 185 cr = r.linkrev(n)
186 186 cn = hg.hex(repo.changelog.node(cr))
187 187 print "rev: %4d:%s" % (i, h)
188 188 print "changeset: %4d:%s" % (cr, cn)
189 189 print "parents: %4d:%s" % (i1, h1)
190 190 if i2: print " %4d:%s" % (i2, h2)
191 191 else:
192 192 print "missing filename"
193 193
194 194 elif cmd == "dump":
195 195 if args:
196 196 r = repo.file(args[0])
197 197 n = r.tip()
198 198 if len(args) > 1: n = hg.bin(args[1])
199 199 sys.stdout.write(r.read(n))
200 200 else:
201 201 print "missing filename"
202 202
203 203 elif cmd == "dumpmanifest":
204 204 n = repo.manifest.tip()
205 205 if len(args) > 0:
206 206 n = hg.bin(args[0])
207 207 m = repo.manifest.read(n)
208 208 files = m.keys()
209 209 files.sort()
210 210
211 211 for f in files:
212 212 print hg.hex(m[f]), f
213 213
214 elif cmd == "debughash":
215 f = repo.file(args[0])
216 print f.encodepath(args[0])
217
218 elif cmd == "debugindex":
219 r = hg.revlog(open, args[0], "")
220 print " rev offset length base linkrev"+\
221 " p1 p2 nodeid"
222 for i in range(r.count()):
223 e = r.index[i]
224 print "% 6d % 9d % 7d % 5d % 7d %s.. %s.. %s.." % (
225 i, e[0], e[1], e[2], e[3],
226 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
227
214 228 elif cmd == "merge":
215 229 if args:
216 230 other = hg.repository(ui, args[0])
217 231 repo.merge(other)
218 232 else:
219 233 print "missing source repository"
220 234
221 235 elif cmd == "verify":
222 236 filelinkrevs = {}
223 237 filenodes = {}
224 238 manifestchangeset = {}
225 239 changesets = revisions = files = 0
226 240
227 241 print "checking changesets"
228 242 for i in range(repo.changelog.count()):
229 243 changesets += 1
230 244 n = repo.changelog.node(i)
231 245 changes = repo.changelog.read(n)
232 246 manifestchangeset[changes[0]] = n
233 247 for f in changes[3]:
234 248 revisions += 1
235 249 filelinkrevs.setdefault(f, []).append(i)
236 250
237 251 print "checking manifests"
238 252 for i in range(repo.manifest.count()):
239 253 n = repo.manifest.node(i)
240 254 ca = repo.changelog.node(repo.manifest.linkrev(n))
241 255 cc = manifestchangeset[n]
242 256 if ca != cc:
243 257 print "manifest %s points to %s, not %s" % \
244 258 (hg.hex(n), hg.hex(ca), hg.hex(cc))
245 259 m = repo.manifest.read(n)
246 260 for f, fn in m.items():
247 261 filenodes.setdefault(f, {})[fn] = 1
248 262
249 263 print "crosschecking files in changesets and manifests"
250 264 for f in filenodes:
251 265 if f not in filelinkrevs:
252 266 print "file %s in manifest but not in changesets"
253 267
254 268 for f in filelinkrevs:
255 269 if f not in filenodes:
256 270 print "file %s in changeset but not in manifest"
257 271
258 272 print "checking files"
259 273 for f in filenodes:
260 274 files += 1
261 275 fl = repo.file(f)
262 276 nodes = {"\0"*20: 1}
263 277 for i in range(fl.count()):
264 278 n = fl.node(i)
265 279
266 280 if n not in filenodes[f]:
267 281 print "%s:%s not in manifests" % (f, hg.hex(n))
268 282 else:
269 283 del filenodes[f][n]
270 284
271 285 flr = fl.linkrev(n)
272 286 if flr not in filelinkrevs[f]:
273 287 print "%s:%s points to unexpected changeset rev %d" \
274 288 % (f, hg.hex(n), fl.linkrev(n))
275 289 else:
276 290 filelinkrevs[f].remove(flr)
277 291
278 292 # verify contents
279 293 t = fl.read(n)
280 294
281 295 # verify parents
282 296 (p1, p2) = fl.parents(n)
283 297 if p1 not in nodes:
284 298 print "%s:%s unknown parent 1 %s" % (f, hg.hex(n), hg.hex(p1))
285 299 if p2 not in nodes:
286 300 print "file %s:%s unknown parent %s" % (f, hg.hex(n), hg.hex(p1))
287 301 nodes[n] = 1
288 302
289 303 # cross-check
290 304 for flr in filelinkrevs[f]:
291 305 print "changeset rev %d not in %s" % (flr, f)
292 306
293 307 for node in filenodes[f]:
294 308 print "node %s in manifests not in %s" % (hg.hex(n), f)
295 309
296 310
297 311 print "%d files, %d changesets, %d total revisions" % (files, changesets,
298 312 revisions)
299 313
300 314 else:
301 315 print "unknown command\n"
302 316 help()
303 317 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now