6 # of the GNU General Public License, incorporated herein by reference. |
6 # of the GNU General Public License, incorporated herein by reference. |
7 |
7 |
8 import os, re, sys, signal |
8 import os, re, sys, signal |
9 import fancyopts, ui, hg |
9 import fancyopts, ui, hg |
10 from demandload import * |
10 from demandload import * |
11 demandload(globals(), "mdiff time hgweb traceback") |
11 demandload(globals(), "mdiff time hgweb traceback random signal") |
12 |
12 |
13 class UnknownCommand(Exception): pass |
13 class UnknownCommand(Exception): pass |
14 |
14 |
15 def filterfiles(filters, files): |
15 def filterfiles(filters, files): |
16 l = [ x for x in files if x in filters ] |
16 l = [ x for x in files if x in filters ] |
409 if source in paths: source = paths[source] |
409 if source in paths: source = paths[source] |
410 |
410 |
411 other = hg.repository(ui, source) |
411 other = hg.repository(ui, source) |
412 cg = repo.getchangegroup(other) |
412 cg = repo.getchangegroup(other) |
413 repo.addchangegroup(cg) |
413 repo.addchangegroup(cg) |
|
414 |
|
415 def push(ui, repo, dest): |
|
416 """push changes to the specified destination""" |
|
417 paths = {} |
|
418 for name, path in ui.configitems("paths"): |
|
419 paths[name] = path |
|
420 |
|
421 if dest in paths: dest = paths[dest] |
|
422 |
|
423 if not dest.startswith("ssh://"): |
|
424 ui.warn("abort: can only push to ssh:// destinations currently\n") |
|
425 return 1 |
|
426 |
|
427 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest) |
|
428 if not m: |
|
429 ui.warn("abort: couldn't parse destination %s\n" % dest) |
|
430 return 1 |
|
431 |
|
432 user, host, port, path = map(m.group, (2, 3, 5, 7)) |
|
433 host = user and ("%s@%s" % (user, host)) or host |
|
434 port = port and (" -p %s") % port or "" |
|
435 path = path or "" |
|
436 |
|
437 sport = random.randrange(30000, 60000) |
|
438 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'" |
|
439 cmd = cmd % (host, port, sport+1, sport, path, sport+1) |
|
440 |
|
441 child = os.fork() |
|
442 if not child: |
|
443 sys.stdout = file("/dev/null", "w") |
|
444 sys.stderr = sys.stdout |
|
445 hgweb.server(repo.root, "pull", "", "localhost", sport) |
|
446 else: |
|
447 r = os.system(cmd) |
|
448 os.kill(child, signal.SIGTERM) |
414 |
449 |
415 def rawcommit(ui, repo, files, **rc): |
450 def rawcommit(ui, repo, files, **rc): |
416 "raw commit interface" |
451 "raw commit interface" |
417 |
452 |
418 text = rc['text'] |
453 text = rc['text'] |
547 [('p', 'strip', 1, 'path strip'), |
582 [('p', 'strip', 1, 'path strip'), |
548 ('b', 'base', "", 'base path'), |
583 ('b', 'base', "", 'base path'), |
549 ('q', 'quiet', "", 'silence diff')], |
584 ('q', 'quiet', "", 'silence diff')], |
550 "hg import [options] patches"), |
585 "hg import [options] patches"), |
551 "pull|merge": (pull, [], 'hg pull [source]'), |
586 "pull|merge": (pull, [], 'hg pull [source]'), |
|
587 "push": (push, [], 'hg push <destination>'), |
552 "rawcommit": (rawcommit, |
588 "rawcommit": (rawcommit, |
553 [('p', 'parent', [], 'parent'), |
589 [('p', 'parent', [], 'parent'), |
554 ('d', 'date', "", 'data'), |
590 ('d', 'date', "", 'data'), |
555 ('u', 'user', "", 'user'), |
591 ('u', 'user', "", 'user'), |
556 ('F', 'files', "", 'file list'), |
592 ('F', 'files', "", 'file list'), |