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