##// END OF EJS Templates
hg: don't complain about missing repo with no args...
mpm@selenic.com -
r206:3295b6b5 default
parent child Browse files
Show More
@@ -1,615 +1,615 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.5b "katje"
4 # v0.5b "katje"
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 a bit faster
11 # the psyco compiler makes commits a bit faster
12 # and makes changegroup merge about 20 times slower!
12 # and makes changegroup merge about 20 times slower!
13 # try:
13 # try:
14 # import psyco
14 # import psyco
15 # psyco.full()
15 # psyco.full()
16 # except:
16 # except:
17 # pass
17 # pass
18
18
19 import sys, os, time
19 import sys, os, time
20 from mercurial import hg, mdiff, fancyopts
20 from mercurial import hg, mdiff, fancyopts
21
21
22 def help():
22 def help():
23 ui.status("""\
23 ui.status("""\
24 commands:
24 commands:
25
25
26 add [files...] add the given files in the next commit
26 add [files...] add the given files in the next commit
27 addremove add all new files, delete all missing files
27 addremove add all new files, delete all missing files
28 annotate [files...] show changeset number per file line
28 annotate [files...] show changeset number per file line
29 branch <path> create a branch of <path> in this directory
29 branch <path> create a branch of <path> in this directory
30 checkout [changeset] checkout the latest or given changeset
30 checkout [changeset] checkout the latest or given changeset
31 commit commit all changes to the repository
31 commit commit all changes to the repository
32 diff [files...] diff working directory (or selected files)
32 diff [files...] diff working directory (or selected files)
33 dump <file> [rev] dump the latest or given revision of a file
33 dump <file> [rev] dump the latest or given revision of a file
34 dumpmanifest [rev] dump the latest or given revision of the manifest
34 dumpmanifest [rev] dump the latest or given revision of the manifest
35 export <rev> dump the changeset header and diffs for a revision
35 export <rev> dump the changeset header and diffs for a revision
36 history show changeset history
36 history show changeset history
37 init create a new repository in this directory
37 init create a new repository in this directory
38 log <file> show revision history of a single file
38 log <file> show revision history of a single file
39 merge <path> merge changes from <path> into local repository
39 merge <path> merge changes from <path> into local repository
40 recover rollback an interrupted transaction
40 recover rollback an interrupted transaction
41 remove [files...] remove the given files in the next commit
41 remove [files...] remove the given files in the next commit
42 serve export the repository via HTTP
42 serve export the repository via HTTP
43 status show new, missing, and changed files in working dir
43 status show new, missing, and changed files in working dir
44 tags show current changeset tags
44 tags show current changeset tags
45 undo undo the last transaction
45 undo undo the last transaction
46 """)
46 """)
47
47
48 def filterfiles(list, files):
48 def filterfiles(list, files):
49 l = [ x for x in list if x in files ]
49 l = [ x for x in list if x in files ]
50
50
51 for f in files:
51 for f in files:
52 if f[-1] != os.sep: f += os.sep
52 if f[-1] != os.sep: f += os.sep
53 l += [ x for x in list if x.startswith(f) ]
53 l += [ x for x in list if x.startswith(f) ]
54 return l
54 return l
55
55
56 def diff(files = None, node1 = None, node2 = None):
56 def diff(files = None, node1 = None, node2 = None):
57 def date(c):
57 def date(c):
58 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
58 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
59
59
60 if node2:
60 if node2:
61 change = repo.changelog.read(node2)
61 change = repo.changelog.read(node2)
62 mmap2 = repo.manifest.read(change[0])
62 mmap2 = repo.manifest.read(change[0])
63 (c, a, d) = repo.diffrevs(node1, node2)
63 (c, a, d) = repo.diffrevs(node1, node2)
64 def read(f): return repo.file(f).read(mmap2[f])
64 def read(f): return repo.file(f).read(mmap2[f])
65 date2 = date(change)
65 date2 = date(change)
66 else:
66 else:
67 date2 = time.asctime()
67 date2 = time.asctime()
68 if not node1:
68 if not node1:
69 node1 = repo.current
69 node1 = repo.current
70 (c, a, d) = repo.diffdir(repo.root, node1)
70 (c, a, d) = repo.diffdir(repo.root, node1)
71 a = [] # ignore unknown files in repo, by popular request
71 a = [] # ignore unknown files in repo, by popular request
72 def read(f): return file(os.path.join(repo.root, f)).read()
72 def read(f): return file(os.path.join(repo.root, f)).read()
73
73
74 change = repo.changelog.read(node1)
74 change = repo.changelog.read(node1)
75 mmap = repo.manifest.read(change[0])
75 mmap = repo.manifest.read(change[0])
76 date1 = date(change)
76 date1 = date(change)
77
77
78 if files:
78 if files:
79 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
79 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
80
80
81 for f in c:
81 for f in c:
82 to = ""
82 to = ""
83 if mmap.has_key(f):
83 if mmap.has_key(f):
84 to = repo.file(f).read(mmap[f])
84 to = repo.file(f).read(mmap[f])
85 tn = read(f)
85 tn = read(f)
86 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
86 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
87 for f in a:
87 for f in a:
88 to = ""
88 to = ""
89 tn = read(f)
89 tn = read(f)
90 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
90 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
91 for f in d:
91 for f in d:
92 to = repo.file(f).read(mmap[f])
92 to = repo.file(f).read(mmap[f])
93 tn = ""
93 tn = ""
94 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
94 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
95
95
96 options = {}
96 options = {}
97 opts = [('v', 'verbose', None, 'verbose'),
97 opts = [('v', 'verbose', None, 'verbose'),
98 ('d', 'debug', None, 'debug'),
98 ('d', 'debug', None, 'debug'),
99 ('q', 'quiet', None, 'quiet'),
99 ('q', 'quiet', None, 'quiet'),
100 ('y', 'noninteractive', None, 'run non-interactively'),
100 ('y', 'noninteractive', None, 'run non-interactively'),
101 ]
101 ]
102
102
103 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
103 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
104 'hg [options] <command> [command options] [files]')
104 'hg [options] <command> [command options] [files]')
105
105
106 try:
106 try:
107 cmd = args[0]
107 cmd = args[0]
108 args = args[1:]
108 args = args[1:]
109 except:
109 except:
110 cmd = ""
110 cmd = "help"
111
111
112 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
112 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
113 not options["noninteractive"])
113 not options["noninteractive"])
114
114
115 if cmd == "init":
115 if cmd == "init":
116 repo = hg.repository(ui, ".", create=1)
116 repo = hg.repository(ui, ".", create=1)
117 sys.exit(0)
117 sys.exit(0)
118 elif cmd == "branch" or cmd == "clone":
118 elif cmd == "branch" or cmd == "clone":
119 os.system("cp -al %s/.hg .hg" % args[0])
119 os.system("cp -al %s/.hg .hg" % args[0])
120 sys.exit(0)
120 sys.exit(0)
121 elif cmd == "help":
121 elif cmd == "help":
122 help()
122 help()
123 sys.exit(0)
123 sys.exit(0)
124 else:
124 else:
125 try:
125 try:
126 repo = hg.repository(ui=ui)
126 repo = hg.repository(ui=ui)
127 except IOError:
127 except IOError:
128 ui.warn("Unable to open repository\n")
128 ui.warn("Unable to open repository\n")
129 sys.exit(0)
129 sys.exit(0)
130
130
131 relpath = None
131 relpath = None
132 if os.getcwd() != repo.root:
132 if os.getcwd() != repo.root:
133 relpath = os.getcwd()[len(repo.root) + 1: ]
133 relpath = os.getcwd()[len(repo.root) + 1: ]
134
134
135 if cmd == "checkout" or cmd == "co":
135 if cmd == "checkout" or cmd == "co":
136 node = repo.changelog.tip()
136 node = repo.changelog.tip()
137 if args:
137 if args:
138 node = repo.lookup(args[0])
138 node = repo.lookup(args[0])
139 repo.checkout(node)
139 repo.checkout(node)
140
140
141 elif cmd == "add":
141 elif cmd == "add":
142 repo.add(args)
142 repo.add(args)
143
143
144 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
144 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
145 repo.remove(args)
145 repo.remove(args)
146
146
147 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
147 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
148 if 1:
148 if 1:
149 if len(args) > 0:
149 if len(args) > 0:
150 repo.commit(repo.current, args)
150 repo.commit(repo.current, args)
151 else:
151 else:
152 repo.commit(repo.current)
152 repo.commit(repo.current)
153 elif cmd == "rawcommit":
153 elif cmd == "rawcommit":
154 "raw commit interface"
154 "raw commit interface"
155 rc = {}
155 rc = {}
156 opts = [('p', 'parent', [], 'parent'),
156 opts = [('p', 'parent', [], 'parent'),
157 ('d', 'date', "", 'data'),
157 ('d', 'date', "", 'data'),
158 ('u', 'user', "", 'user'),
158 ('u', 'user', "", 'user'),
159 ('F', 'files', "", 'file list'),
159 ('F', 'files', "", 'file list'),
160 ('t', 'text', "", 'commit text'),
160 ('t', 'text', "", 'commit text'),
161 ('l', 'logfile', "", 'commit text file')
161 ('l', 'logfile', "", 'commit text file')
162 ]
162 ]
163 args = fancyopts.fancyopts(args, opts, rc,
163 args = fancyopts.fancyopts(args, opts, rc,
164 "hg rawcommit [options] files")
164 "hg rawcommit [options] files")
165 text = rc['text']
165 text = rc['text']
166 if not text and rc['logfile']:
166 if not text and rc['logfile']:
167 try: text = open(rc['logfile']).read()
167 try: text = open(rc['logfile']).read()
168 except IOError: pass
168 except IOError: pass
169 if not text and not rc['logfile']:
169 if not text and not rc['logfile']:
170 print "missing commit text"
170 print "missing commit text"
171 sys.exit(0)
171 sys.exit(0)
172 if rc['files']:
172 if rc['files']:
173 files = open(rc['files']).read().splitlines()
173 files = open(rc['files']).read().splitlines()
174 else:
174 else:
175 files = args
175 files = args
176
176
177 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
177 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
178
178
179
179
180 elif cmd == "import" or cmd == "patch":
180 elif cmd == "import" or cmd == "patch":
181 try:
181 try:
182 import psyco
182 import psyco
183 psyco.full()
183 psyco.full()
184 except:
184 except:
185 pass
185 pass
186
186
187 ioptions = {}
187 ioptions = {}
188 opts = [('p', 'strip', 1, 'path strip'),
188 opts = [('p', 'strip', 1, 'path strip'),
189 ('b', 'base', "", 'base path'),
189 ('b', 'base', "", 'base path'),
190 ('q', 'quiet', "", 'silence diff')
190 ('q', 'quiet', "", 'silence diff')
191 ]
191 ]
192
192
193 args = fancyopts.fancyopts(args, opts, ioptions,
193 args = fancyopts.fancyopts(args, opts, ioptions,
194 'hg import [options] <patch names>')
194 'hg import [options] <patch names>')
195 d = ioptions["base"]
195 d = ioptions["base"]
196 strip = ioptions["strip"]
196 strip = ioptions["strip"]
197 quiet = ioptions["quiet"] and "> /dev/null" or ""
197 quiet = ioptions["quiet"] and "> /dev/null" or ""
198
198
199 for patch in args:
199 for patch in args:
200 ui.status("applying %s\n" % patch)
200 ui.status("applying %s\n" % patch)
201 pf = os.path.join(d, patch)
201 pf = os.path.join(d, patch)
202
202
203 text = ""
203 text = ""
204 for l in file(pf):
204 for l in file(pf):
205 if l[:4] == "--- ": break
205 if l[:4] == "--- ": break
206 text += l
206 text += l
207
207
208 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
208 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
209 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
209 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
210 f.close()
210 f.close()
211
211
212 if files:
212 if files:
213 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
213 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
214 raise "patch failed!"
214 raise "patch failed!"
215 repo.commit(repo.current, files, text)
215 repo.commit(repo.current, files, text)
216
216
217 elif cmd == "status":
217 elif cmd == "status":
218 (c, a, d) = repo.diffdir(repo.root, repo.current)
218 (c, a, d) = repo.diffdir(repo.root, repo.current)
219 if relpath:
219 if relpath:
220 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
220 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
221
221
222 for f in c: print "C", f
222 for f in c: print "C", f
223 for f in a: print "?", f
223 for f in a: print "?", f
224 for f in d: print "R", f
224 for f in d: print "R", f
225
225
226 elif cmd == "diff":
226 elif cmd == "diff":
227 revs = []
227 revs = []
228
228
229 if args:
229 if args:
230 doptions = {}
230 doptions = {}
231 opts = [('r', 'revision', [], 'revision')]
231 opts = [('r', 'revision', [], 'revision')]
232 args = fancyopts.fancyopts(args, opts, doptions,
232 args = fancyopts.fancyopts(args, opts, doptions,
233 'hg diff [options] [files]')
233 'hg diff [options] [files]')
234 revs = map(lambda x: repo.lookup(x), doptions['revision'])
234 revs = map(lambda x: repo.lookup(x), doptions['revision'])
235
235
236 if len(revs) > 2:
236 if len(revs) > 2:
237 self.ui.warn("too many revisions to diff\n")
237 self.ui.warn("too many revisions to diff\n")
238 sys.exit(1)
238 sys.exit(1)
239
239
240 if relpath:
240 if relpath:
241 if not args: args = [ relpath ]
241 if not args: args = [ relpath ]
242 else: args = [ os.path.join(relpath, x) for x in args ]
242 else: args = [ os.path.join(relpath, x) for x in args ]
243
243
244 diff(args, *revs)
244 diff(args, *revs)
245
245
246 elif cmd == "annotate":
246 elif cmd == "annotate":
247 bcache = {}
247 bcache = {}
248
248
249 def getnode(rev):
249 def getnode(rev):
250 return hg.short(repo.changelog.node(rev))
250 return hg.short(repo.changelog.node(rev))
251
251
252 def getname(rev):
252 def getname(rev):
253 try:
253 try:
254 return bcache[rev]
254 return bcache[rev]
255 except KeyError:
255 except KeyError:
256 cl = repo.changelog.read(repo.changelog.node(rev))
256 cl = repo.changelog.read(repo.changelog.node(rev))
257 name = cl[1]
257 name = cl[1]
258 f = name.find('@')
258 f = name.find('@')
259 if f >= 0:
259 if f >= 0:
260 name = name[:f]
260 name = name[:f]
261 bcache[rev] = name
261 bcache[rev] = name
262 return name
262 return name
263
263
264 aoptions = {}
264 aoptions = {}
265 opts = [('r', 'revision', '', 'revision'),
265 opts = [('r', 'revision', '', 'revision'),
266 ('u', 'user', None, 'show user'),
266 ('u', 'user', None, 'show user'),
267 ('n', 'number', None, 'show revision number'),
267 ('n', 'number', None, 'show revision number'),
268 ('c', 'changeset', None, 'show changeset')]
268 ('c', 'changeset', None, 'show changeset')]
269
269
270 args = fancyopts.fancyopts(args, opts, aoptions,
270 args = fancyopts.fancyopts(args, opts, aoptions,
271 'hg annotate [-u] [-c] [-n] [-r id] [files]')
271 'hg annotate [-u] [-c] [-n] [-r id] [files]')
272
272
273 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
273 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
274 if not aoptions['user'] and not aoptions['changeset']:
274 if not aoptions['user'] and not aoptions['changeset']:
275 aoptions['number'] = 1
275 aoptions['number'] = 1
276
276
277 if args:
277 if args:
278 if relpath: args = [ os.path.join(relpath, x) for x in args ]
278 if relpath: args = [ os.path.join(relpath, x) for x in args ]
279 node = repo.current
279 node = repo.current
280 if aoptions['revision']:
280 if aoptions['revision']:
281 node = repo.changelog.lookup(aoptions['revision'])
281 node = repo.changelog.lookup(aoptions['revision'])
282 change = repo.changelog.read(node)
282 change = repo.changelog.read(node)
283 mmap = repo.manifest.read(change[0])
283 mmap = repo.manifest.read(change[0])
284 maxuserlen = 0
284 maxuserlen = 0
285 maxchangelen = 0
285 maxchangelen = 0
286 for f in args:
286 for f in args:
287 lines = repo.file(f).annotate(mmap[f])
287 lines = repo.file(f).annotate(mmap[f])
288 pieces = []
288 pieces = []
289
289
290 for o, f in opmap:
290 for o, f in opmap:
291 if aoptions[o]:
291 if aoptions[o]:
292 l = [ f(n) for n,t in lines ]
292 l = [ f(n) for n,t in lines ]
293 m = max(map(len, l))
293 m = max(map(len, l))
294 pieces.append([ "%*s" % (m, x) for x in l])
294 pieces.append([ "%*s" % (m, x) for x in l])
295
295
296 for p,l in zip(zip(*pieces), lines):
296 for p,l in zip(zip(*pieces), lines):
297 sys.stdout.write(" ".join(p) + ": " + l[1])
297 sys.stdout.write(" ".join(p) + ": " + l[1])
298
298
299 elif cmd == "export":
299 elif cmd == "export":
300 node = repo.lookup(args[0])
300 node = repo.lookup(args[0])
301 prev, other = repo.changelog.parents(node)
301 prev, other = repo.changelog.parents(node)
302 change = repo.changelog.read(node)
302 change = repo.changelog.read(node)
303 print "# HG changeset patch"
303 print "# HG changeset patch"
304 print "# User %s" % change[1]
304 print "# User %s" % change[1]
305 print "# Node ID %s" % hg.hex(node)
305 print "# Node ID %s" % hg.hex(node)
306 print "# Parent %s" % hg.hex(prev)
306 print "# Parent %s" % hg.hex(prev)
307 print
307 print
308 if other != hg.nullid:
308 if other != hg.nullid:
309 print "# Parent %s" % hg.hex(other)
309 print "# Parent %s" % hg.hex(other)
310 print change[4]
310 print change[4]
311
311
312 diff(None, prev, node)
312 diff(None, prev, node)
313
313
314 elif cmd == "debugchangegroup":
314 elif cmd == "debugchangegroup":
315 newer = repo.newer(map(repo.lookup, args))
315 newer = repo.newer(map(repo.lookup, args))
316 for chunk in repo.changegroup(newer):
316 for chunk in repo.changegroup(newer):
317 sys.stdout.write(chunk)
317 sys.stdout.write(chunk)
318
318
319 elif cmd == "debugaddchangegroup":
319 elif cmd == "debugaddchangegroup":
320 data = sys.stdin.read()
320 data = sys.stdin.read()
321 repo.addchangegroup(data)
321 repo.addchangegroup(data)
322
322
323 elif cmd == "addremove":
323 elif cmd == "addremove":
324 (c, a, d) = repo.diffdir(repo.root, repo.current)
324 (c, a, d) = repo.diffdir(repo.root, repo.current)
325 repo.add(a)
325 repo.add(a)
326 repo.remove(d)
326 repo.remove(d)
327
327
328 elif cmd == "history":
328 elif cmd == "history":
329 for i in range(repo.changelog.count()):
329 for i in range(repo.changelog.count()):
330 n = repo.changelog.node(i)
330 n = repo.changelog.node(i)
331 changes = repo.changelog.read(n)
331 changes = repo.changelog.read(n)
332 (p1, p2) = repo.changelog.parents(n)
332 (p1, p2) = repo.changelog.parents(n)
333 (h, h1, h2) = map(hg.hex, (n, p1, p2))
333 (h, h1, h2) = map(hg.hex, (n, p1, p2))
334 (i1, i2) = map(repo.changelog.rev, (p1, p2))
334 (i1, i2) = map(repo.changelog.rev, (p1, p2))
335 print "rev: %4d:%s" % (i, h)
335 print "rev: %4d:%s" % (i, h)
336 print "parents: %4d:%s" % (i1, h1)
336 print "parents: %4d:%s" % (i1, h1)
337 if i2: print " %4d:%s" % (i2, h2)
337 if i2: print " %4d:%s" % (i2, h2)
338 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
338 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
339 hg.hex(changes[0]))
339 hg.hex(changes[0]))
340 print "user:", changes[1]
340 print "user:", changes[1]
341 print "date:", time.asctime(
341 print "date:", time.asctime(
342 time.localtime(float(changes[2].split(' ')[0])))
342 time.localtime(float(changes[2].split(' ')[0])))
343 if ui.verbose: print "files:", " ".join(changes[3])
343 if ui.verbose: print "files:", " ".join(changes[3])
344 print "description:"
344 print "description:"
345 print changes[4]
345 print changes[4]
346
346
347 elif cmd == "tip":
347 elif cmd == "tip":
348 n = repo.changelog.tip()
348 n = repo.changelog.tip()
349 t = repo.changelog.rev(n)
349 t = repo.changelog.rev(n)
350 ui.status("%d:%s\n" % (t, hg.hex(n)))
350 ui.status("%d:%s\n" % (t, hg.hex(n)))
351
351
352 elif cmd == "log":
352 elif cmd == "log":
353
353
354 if len(args) == 1:
354 if len(args) == 1:
355 if relpath:
355 if relpath:
356 args[0] = os.path.join(relpath, args[0])
356 args[0] = os.path.join(relpath, args[0])
357
357
358 r = repo.file(args[0])
358 r = repo.file(args[0])
359 for i in range(r.count()):
359 for i in range(r.count()):
360 n = r.node(i)
360 n = r.node(i)
361 (p1, p2) = r.parents(n)
361 (p1, p2) = r.parents(n)
362 (h, h1, h2) = map(hg.hex, (n, p1, p2))
362 (h, h1, h2) = map(hg.hex, (n, p1, p2))
363 (i1, i2) = map(r.rev, (p1, p2))
363 (i1, i2) = map(r.rev, (p1, p2))
364 cr = r.linkrev(n)
364 cr = r.linkrev(n)
365 cn = hg.hex(repo.changelog.node(cr))
365 cn = hg.hex(repo.changelog.node(cr))
366 print "rev: %4d:%s" % (i, h)
366 print "rev: %4d:%s" % (i, h)
367 print "changeset: %4d:%s" % (cr, cn)
367 print "changeset: %4d:%s" % (cr, cn)
368 print "parents: %4d:%s" % (i1, h1)
368 print "parents: %4d:%s" % (i1, h1)
369 if i2: print " %4d:%s" % (i2, h2)
369 if i2: print " %4d:%s" % (i2, h2)
370 changes = repo.changelog.read(repo.changelog.node(cr))
370 changes = repo.changelog.read(repo.changelog.node(cr))
371 print "user: %s" % changes[1]
371 print "user: %s" % changes[1]
372 print "date: %s" % time.asctime(
372 print "date: %s" % time.asctime(
373 time.localtime(float(changes[2].split(' ')[0])))
373 time.localtime(float(changes[2].split(' ')[0])))
374 print "description:"
374 print "description:"
375 print changes[4]
375 print changes[4]
376 print
376 print
377 elif len(args) > 1:
377 elif len(args) > 1:
378 print "too many args"
378 print "too many args"
379 else:
379 else:
380 print "missing filename"
380 print "missing filename"
381
381
382 elif cmd == "dump":
382 elif cmd == "dump":
383 if args:
383 if args:
384 r = repo.file(args[0])
384 r = repo.file(args[0])
385 n = r.tip()
385 n = r.tip()
386 if len(args) > 1: n = r.lookup(args[1])
386 if len(args) > 1: n = r.lookup(args[1])
387 sys.stdout.write(r.read(n))
387 sys.stdout.write(r.read(n))
388 else:
388 else:
389 print "missing filename"
389 print "missing filename"
390
390
391 elif cmd == "dumpmanifest":
391 elif cmd == "dumpmanifest":
392 n = repo.manifest.tip()
392 n = repo.manifest.tip()
393 if len(args) > 0:
393 if len(args) > 0:
394 n = repo.manifest.lookup(args[0])
394 n = repo.manifest.lookup(args[0])
395 m = repo.manifest.read(n)
395 m = repo.manifest.read(n)
396 files = m.keys()
396 files = m.keys()
397 files.sort()
397 files.sort()
398
398
399 for f in files:
399 for f in files:
400 print hg.hex(m[f]), f
400 print hg.hex(m[f]), f
401
401
402 elif cmd == "debugindex":
402 elif cmd == "debugindex":
403 if ".hg" not in args[0]:
403 if ".hg" not in args[0]:
404 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
404 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
405
405
406 r = hg.revlog(open, args[0], "")
406 r = hg.revlog(open, args[0], "")
407 print " rev offset length base linkrev"+\
407 print " rev offset length base linkrev"+\
408 " p1 p2 nodeid"
408 " p1 p2 nodeid"
409 for i in range(r.count()):
409 for i in range(r.count()):
410 e = r.index[i]
410 e = r.index[i]
411 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
411 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
412 i, e[0], e[1], e[2], e[3],
412 i, e[0], e[1], e[2], e[3],
413 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
413 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
414
414
415 elif cmd == "debugindexdot":
415 elif cmd == "debugindexdot":
416 if ".hg" not in args[0]:
416 if ".hg" not in args[0]:
417 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
417 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
418
418
419 r = hg.revlog(open, args[0], "")
419 r = hg.revlog(open, args[0], "")
420 print "digraph G {"
420 print "digraph G {"
421 for i in range(r.count()):
421 for i in range(r.count()):
422 e = r.index[i]
422 e = r.index[i]
423 print "\t%d -> %d" % (r.rev(e[4]), i)
423 print "\t%d -> %d" % (r.rev(e[4]), i)
424 if e[5] != hg.nullid:
424 if e[5] != hg.nullid:
425 print "\t%d -> %d" % (r.rev(e[5]), i)
425 print "\t%d -> %d" % (r.rev(e[5]), i)
426 print "}"
426 print "}"
427
427
428 elif cmd == "merge":
428 elif cmd == "merge":
429 (c, a, d) = repo.diffdir(repo.root, repo.current)
429 (c, a, d) = repo.diffdir(repo.root, repo.current)
430 if c:
430 if c:
431 ui.warn("aborting (outstanding changes in working directory)\n")
431 ui.warn("aborting (outstanding changes in working directory)\n")
432 sys.exit(1)
432 sys.exit(1)
433
433
434 if args:
434 if args:
435 paths = {}
435 paths = {}
436 try:
436 try:
437 pf = os.path.join(os.environ["HOME"], ".hgpaths")
437 pf = os.path.join(os.environ["HOME"], ".hgpaths")
438 for l in file(pf):
438 for l in file(pf):
439 name, path = l.split()
439 name, path = l.split()
440 paths[name] = path
440 paths[name] = path
441 except:
441 except:
442 pass
442 pass
443
443
444 if args[0] in paths: args[0] = paths[args[0]]
444 if args[0] in paths: args[0] = paths[args[0]]
445
445
446 other = hg.repository(ui, args[0])
446 other = hg.repository(ui, args[0])
447 cg = repo.getchangegroup(other)
447 cg = repo.getchangegroup(other)
448 repo.addchangegroup(cg)
448 repo.addchangegroup(cg)
449 else:
449 else:
450 print "missing source repository"
450 print "missing source repository"
451
451
452 elif cmd == "tags":
452 elif cmd == "tags":
453 repo.lookup(0) # prime the cache
453 repo.lookup(0) # prime the cache
454 i = repo.tags.items()
454 i = repo.tags.items()
455 i.sort()
455 i.sort()
456 for k, n in i:
456 for k, n in i:
457 try:
457 try:
458 r = repo.changelog.rev(n)
458 r = repo.changelog.rev(n)
459 except KeyError:
459 except KeyError:
460 r = "?"
460 r = "?"
461 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
461 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
462
462
463 elif cmd == "recover":
463 elif cmd == "recover":
464 repo.recover()
464 repo.recover()
465
465
466 elif cmd == "undo":
466 elif cmd == "undo":
467 repo.recover("undo")
467 repo.recover("undo")
468
468
469 elif cmd == "verify":
469 elif cmd == "verify":
470 filelinkrevs = {}
470 filelinkrevs = {}
471 filenodes = {}
471 filenodes = {}
472 manifestchangeset = {}
472 manifestchangeset = {}
473 changesets = revisions = files = 0
473 changesets = revisions = files = 0
474 errors = 0
474 errors = 0
475
475
476 ui.status("checking changesets\n")
476 ui.status("checking changesets\n")
477 for i in range(repo.changelog.count()):
477 for i in range(repo.changelog.count()):
478 changesets += 1
478 changesets += 1
479 n = repo.changelog.node(i)
479 n = repo.changelog.node(i)
480 for p in repo.changelog.parents(n):
480 for p in repo.changelog.parents(n):
481 if p not in repo.changelog.nodemap:
481 if p not in repo.changelog.nodemap:
482 ui.warn("changeset %s has unknown parent %s\n" %
482 ui.warn("changeset %s has unknown parent %s\n" %
483 (hg.short(n), hg.short(p)))
483 (hg.short(n), hg.short(p)))
484 errors += 1
484 errors += 1
485 try:
485 try:
486 changes = repo.changelog.read(n)
486 changes = repo.changelog.read(n)
487 except Exception, inst:
487 except Exception, inst:
488 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
488 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
489 errors += 1
489 errors += 1
490
490
491 manifestchangeset[changes[0]] = n
491 manifestchangeset[changes[0]] = n
492 for f in changes[3]:
492 for f in changes[3]:
493 revisions += 1
493 revisions += 1
494 filelinkrevs.setdefault(f, []).append(i)
494 filelinkrevs.setdefault(f, []).append(i)
495
495
496 ui.status("checking manifests\n")
496 ui.status("checking manifests\n")
497 for i in range(repo.manifest.count()):
497 for i in range(repo.manifest.count()):
498 n = repo.manifest.node(i)
498 n = repo.manifest.node(i)
499 for p in repo.manifest.parents(n):
499 for p in repo.manifest.parents(n):
500 if p not in repo.manifest.nodemap:
500 if p not in repo.manifest.nodemap:
501 ui.warn("manifest %s has unknown parent %s\n" %
501 ui.warn("manifest %s has unknown parent %s\n" %
502 (hg.short(n), hg.short(p)))
502 (hg.short(n), hg.short(p)))
503 errors += 1
503 errors += 1
504 ca = repo.changelog.node(repo.manifest.linkrev(n))
504 ca = repo.changelog.node(repo.manifest.linkrev(n))
505 cc = manifestchangeset[n]
505 cc = manifestchangeset[n]
506 if ca != cc:
506 if ca != cc:
507 ui.warn("manifest %s points to %s, not %s\n" %
507 ui.warn("manifest %s points to %s, not %s\n" %
508 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
508 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
509 errors += 1
509 errors += 1
510
510
511 try:
511 try:
512 delta = mdiff.patchtext(repo.manifest.delta(n))
512 delta = mdiff.patchtext(repo.manifest.delta(n))
513 except KeyboardInterrupt:
513 except KeyboardInterrupt:
514 print "aborted"
514 print "aborted"
515 sys.exit(0)
515 sys.exit(0)
516 except Exception, inst:
516 except Exception, inst:
517 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
517 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
518 errors += 1
518 errors += 1
519
519
520 ff = [ l.split('\0') for l in delta.splitlines() ]
520 ff = [ l.split('\0') for l in delta.splitlines() ]
521 for f, fn in ff:
521 for f, fn in ff:
522 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
522 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
523
523
524 ui.status("crosschecking files in changesets and manifests\n")
524 ui.status("crosschecking files in changesets and manifests\n")
525 for f in filenodes:
525 for f in filenodes:
526 if f not in filelinkrevs:
526 if f not in filelinkrevs:
527 ui.warn("file %s in manifest but not in changesets\n" % f)
527 ui.warn("file %s in manifest but not in changesets\n" % f)
528 errors += 1
528 errors += 1
529
529
530 for f in filelinkrevs:
530 for f in filelinkrevs:
531 if f not in filenodes:
531 if f not in filenodes:
532 ui.warn("file %s in changeset but not in manifest\n" % f)
532 ui.warn("file %s in changeset but not in manifest\n" % f)
533 errors += 1
533 errors += 1
534
534
535 ui.status("checking files\n")
535 ui.status("checking files\n")
536 ff = filenodes.keys()
536 ff = filenodes.keys()
537 ff.sort()
537 ff.sort()
538 for f in ff:
538 for f in ff:
539 if f == "/dev/null": continue
539 if f == "/dev/null": continue
540 files += 1
540 files += 1
541 fl = repo.file(f)
541 fl = repo.file(f)
542 nodes = { hg.nullid: 1 }
542 nodes = { hg.nullid: 1 }
543 for i in range(fl.count()):
543 for i in range(fl.count()):
544 n = fl.node(i)
544 n = fl.node(i)
545
545
546 if n not in filenodes[f]:
546 if n not in filenodes[f]:
547 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
547 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
548 print len(filenodes[f].keys()), fl.count(), f
548 print len(filenodes[f].keys()), fl.count(), f
549 errors += 1
549 errors += 1
550 else:
550 else:
551 del filenodes[f][n]
551 del filenodes[f][n]
552
552
553 flr = fl.linkrev(n)
553 flr = fl.linkrev(n)
554 if flr not in filelinkrevs[f]:
554 if flr not in filelinkrevs[f]:
555 ui.warn("%s:%s points to unexpected changeset rev %d\n"
555 ui.warn("%s:%s points to unexpected changeset rev %d\n"
556 % (f, hg.short(n), fl.linkrev(n)))
556 % (f, hg.short(n), fl.linkrev(n)))
557 errors += 1
557 errors += 1
558 else:
558 else:
559 filelinkrevs[f].remove(flr)
559 filelinkrevs[f].remove(flr)
560
560
561 # verify contents
561 # verify contents
562 try:
562 try:
563 t = fl.read(n)
563 t = fl.read(n)
564 except Exception, inst:
564 except Exception, inst:
565 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
565 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
566 errors += 1
566 errors += 1
567
567
568 # verify parents
568 # verify parents
569 (p1, p2) = fl.parents(n)
569 (p1, p2) = fl.parents(n)
570 if p1 not in nodes:
570 if p1 not in nodes:
571 ui.warn("file %s:%s unknown parent 1 %s" %
571 ui.warn("file %s:%s unknown parent 1 %s" %
572 (f, hg.short(n), hg.short(p1)))
572 (f, hg.short(n), hg.short(p1)))
573 errors += 1
573 errors += 1
574 if p2 not in nodes:
574 if p2 not in nodes:
575 ui.warn("file %s:%s unknown parent 2 %s" %
575 ui.warn("file %s:%s unknown parent 2 %s" %
576 (f, hg.short(n), hg.short(p1)))
576 (f, hg.short(n), hg.short(p1)))
577 errors += 1
577 errors += 1
578 nodes[n] = 1
578 nodes[n] = 1
579
579
580 # cross-check
580 # cross-check
581 for flr in filelinkrevs[f]:
581 for flr in filelinkrevs[f]:
582 ui.warn("changeset rev %d not in %s\n" % (flr, f))
582 ui.warn("changeset rev %d not in %s\n" % (flr, f))
583 errors += 1
583 errors += 1
584
584
585 for node in filenodes[f]:
585 for node in filenodes[f]:
586 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
586 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
587 errors += 1
587 errors += 1
588
588
589 ui.status("%d files, %d changesets, %d total revisions\n" %
589 ui.status("%d files, %d changesets, %d total revisions\n" %
590 (files, changesets, revisions))
590 (files, changesets, revisions))
591
591
592 if errors:
592 if errors:
593 ui.warn("%d integrity errors encountered!\n" % errors)
593 ui.warn("%d integrity errors encountered!\n" % errors)
594 sys.exit(1)
594 sys.exit(1)
595
595
596 elif cmd == "serve":
596 elif cmd == "serve":
597 from mercurial import hgweb
597 from mercurial import hgweb
598
598
599 soptions = {}
599 soptions = {}
600 opts = [('p', 'port', 8000, 'listen port'),
600 opts = [('p', 'port', 8000, 'listen port'),
601 ('a', 'address', '', 'interface address'),
601 ('a', 'address', '', 'interface address'),
602 ('n', 'name', os.getcwd(), 'repository name'),
602 ('n', 'name', os.getcwd(), 'repository name'),
603 ('t', 'templates', "", 'template map')
603 ('t', 'templates', "", 'template map')
604 ]
604 ]
605
605
606 args = fancyopts.fancyopts(args, opts, soptions,
606 args = fancyopts.fancyopts(args, opts, soptions,
607 'hg serve [options]')
607 'hg serve [options]')
608
608
609 hgweb.server(repo.root, soptions["name"], soptions["templates"],
609 hgweb.server(repo.root, soptions["name"], soptions["templates"],
610 soptions["address"], soptions["port"])
610 soptions["address"], soptions["port"])
611
611
612 else:
612 else:
613 if cmd: ui.warn("unknown command\n\n")
613 if cmd: ui.warn("unknown command\n\n")
614 help()
614 help()
615 sys.exit(1)
615 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now