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