Show More
@@ -9,7 +9,7 b' from demandload import *' | |||||
9 | demandload(globals(), "os re sys signal") |
|
9 | demandload(globals(), "os re sys signal") | |
10 | demandload(globals(), "fancyopts ui hg util") |
|
10 | demandload(globals(), "fancyopts ui hg util") | |
11 | demandload(globals(), "hgweb mdiff random signal time traceback") |
|
11 | demandload(globals(), "hgweb mdiff random signal time traceback") | |
12 | demandload(globals(), "errno socket version") |
|
12 | demandload(globals(), "errno socket version struct") | |
13 |
|
13 | |||
14 | class UnknownCommand(Exception): pass |
|
14 | class UnknownCommand(Exception): pass | |
15 |
|
15 | |||
@@ -823,9 +823,67 b' def root(ui, repo):' | |||||
823 |
|
823 | |||
824 | def serve(ui, repo, **opts): |
|
824 | def serve(ui, repo, **opts): | |
825 | """export the repository via HTTP""" |
|
825 | """export the repository via HTTP""" | |
|
826 | ||||
|
827 | if opts["stdio"]: | |||
|
828 | def getarg(): | |||
|
829 | argline = sys.stdin.readline()[:-1] | |||
|
830 | arg, l = argline.split() | |||
|
831 | val = sys.stdin.read(int(l)) | |||
|
832 | return arg, val | |||
|
833 | def respond(v): | |||
|
834 | sys.stdout.write("%d\n" % len(v)) | |||
|
835 | sys.stdout.write(v) | |||
|
836 | sys.stdout.flush() | |||
|
837 | ||||
|
838 | while 1: | |||
|
839 | cmd = sys.stdin.readline()[:-1] | |||
|
840 | if cmd == '': | |||
|
841 | return | |||
|
842 | if cmd == "heads": | |||
|
843 | h = repo.heads() | |||
|
844 | respond(" ".join(map(hg.hex, h)) + "\n") | |||
|
845 | elif cmd == "branches": | |||
|
846 | arg, nodes = getarg() | |||
|
847 | nodes = map(hg.bin, nodes.split(" ")) | |||
|
848 | r = [] | |||
|
849 | for b in repo.branches(nodes): | |||
|
850 | r.append(" ".join(map(hg.hex, b)) + "\n") | |||
|
851 | respond("".join(r)) | |||
|
852 | elif cmd == "between": | |||
|
853 | arg, pairs = getarg() | |||
|
854 | pairs = [ map(hg.bin, p.split("-")) for p in pairs.split(" ") ] | |||
|
855 | r = [] | |||
|
856 | for b in repo.between(pairs): | |||
|
857 | r.append(" ".join(map(hg.hex, b)) + "\n") | |||
|
858 | respond("".join(r)) | |||
|
859 | elif cmd == "changegroup": | |||
|
860 | nodes = [] | |||
|
861 | arg, roots = getarg() | |||
|
862 | nodes = map(hg.bin, roots.split(" ")) | |||
|
863 | ||||
|
864 | b = [] | |||
|
865 | t = 0 | |||
|
866 | for chunk in repo.changegroup(nodes): | |||
|
867 | t += len(chunk) | |||
|
868 | b.append(chunk) | |||
|
869 | if t > 4096: | |||
|
870 | sys.stdout.write(struct.pack(">l", t)) | |||
|
871 | for c in b: | |||
|
872 | sys.stdout.write(c) | |||
|
873 | t = 0 | |||
|
874 | b = [] | |||
|
875 | ||||
|
876 | sys.stdout.write(struct.pack(">l", t)) | |||
|
877 | for c in b: | |||
|
878 | sys.stdout.write(c) | |||
|
879 | ||||
|
880 | sys.stdout.write(struct.pack(">l", -1)) | |||
|
881 | sys.stdout.flush() | |||
|
882 | ||||
826 | def openlog(opt, default): |
|
883 | def openlog(opt, default): | |
827 | if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') |
|
884 | if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') | |
828 | else: return default |
|
885 | else: return default | |
|
886 | ||||
829 | httpd = hgweb.create_server(repo.root, opts["name"], opts["templates"], |
|
887 | httpd = hgweb.create_server(repo.root, opts["name"], opts["templates"], | |
830 | opts["address"], opts["port"], |
|
888 | opts["address"], opts["port"], | |
831 | openlog('accesslog', sys.stdout), |
|
889 | openlog('accesslog', sys.stdout), | |
@@ -1017,6 +1075,7 b' table = {' | |||||
1017 | ('p', 'port', 8000, 'listen port'), |
|
1075 | ('p', 'port', 8000, 'listen port'), | |
1018 | ('a', 'address', '', 'interface address'), |
|
1076 | ('a', 'address', '', 'interface address'), | |
1019 | ('n', 'name', os.getcwd(), 'repository name'), |
|
1077 | ('n', 'name', os.getcwd(), 'repository name'), | |
|
1078 | ('', 'stdio', None, 'for remote clients'), | |||
1020 | ('t', 'templates', "", 'template map')], |
|
1079 | ('t', 'templates', "", 'template map')], | |
1021 | "hg serve [options]"), |
|
1080 | "hg serve [options]"), | |
1022 | "^status": (status, [], 'hg status'), |
|
1081 | "^status": (status, [], 'hg status'), |
@@ -1592,6 +1592,88 b' class httprepository:' | |||||
1592 | yield zd.decompress(d) |
|
1592 | yield zd.decompress(d) | |
1593 | self.ui.note("%d bytes of data transfered\n" % bytes) |
|
1593 | self.ui.note("%d bytes of data transfered\n" % bytes) | |
1594 |
|
1594 | |||
|
1595 | class sshrepository: | |||
|
1596 | def __init__(self, ui, path): | |||
|
1597 | self.url = path | |||
|
1598 | self.ui = ui | |||
|
1599 | ||||
|
1600 | m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path) | |||
|
1601 | if not m: | |||
|
1602 | raise RepoError("couldn't parse destination %s\n" % path) | |||
|
1603 | ||||
|
1604 | self.user = m.group(2) | |||
|
1605 | self.host = m.group(3) | |||
|
1606 | self.port = m.group(5) | |||
|
1607 | self.path = m.group(7) | |||
|
1608 | ||||
|
1609 | args = self.user and ("%s@%s" % (self.user, self.host)) or self.host | |||
|
1610 | args = self.port and ("%s -p %s") % (args, self.port) or args | |||
|
1611 | path = self.path or "" | |||
|
1612 | ||||
|
1613 | cmd = "ssh %s 'hg -R %s serve --stdio'" | |||
|
1614 | cmd = cmd % (args, path) | |||
|
1615 | ||||
|
1616 | self.pipeo, self.pipei = os.popen2(cmd) | |||
|
1617 | ||||
|
1618 | def __del__(self): | |||
|
1619 | self.pipeo.close() | |||
|
1620 | self.pipei.close() | |||
|
1621 | ||||
|
1622 | def do_cmd(self, cmd, **args): | |||
|
1623 | self.ui.debug("sending %s command\n" % cmd) | |||
|
1624 | self.pipeo.write("%s\n" % cmd) | |||
|
1625 | for k, v in args.items(): | |||
|
1626 | self.pipeo.write("%s %d\n" % (k, len(v))) | |||
|
1627 | self.pipeo.write(v) | |||
|
1628 | self.pipeo.flush() | |||
|
1629 | ||||
|
1630 | return self.pipei | |||
|
1631 | ||||
|
1632 | def call(self, cmd, **args): | |||
|
1633 | r = self.do_cmd(cmd, **args) | |||
|
1634 | l = int(r.readline()) | |||
|
1635 | return r.read(l) | |||
|
1636 | ||||
|
1637 | def heads(self): | |||
|
1638 | d = self.call("heads") | |||
|
1639 | try: | |||
|
1640 | return map(bin, d[:-1].split(" ")) | |||
|
1641 | except: | |||
|
1642 | self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |||
|
1643 | raise | |||
|
1644 | ||||
|
1645 | def branches(self, nodes): | |||
|
1646 | n = " ".join(map(hex, nodes)) | |||
|
1647 | d = self.call("branches", nodes=n) | |||
|
1648 | try: | |||
|
1649 | br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] | |||
|
1650 | return br | |||
|
1651 | except: | |||
|
1652 | self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |||
|
1653 | raise | |||
|
1654 | ||||
|
1655 | def between(self, pairs): | |||
|
1656 | n = "\n".join(["-".join(map(hex, p)) for p in pairs]) | |||
|
1657 | d = self.call("between", pairs=n) | |||
|
1658 | try: | |||
|
1659 | p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] | |||
|
1660 | return p | |||
|
1661 | except: | |||
|
1662 | self.ui.warn("unexpected response:\n" + d[:400] + "\n...\n") | |||
|
1663 | raise | |||
|
1664 | ||||
|
1665 | def changegroup(self, nodes): | |||
|
1666 | n = " ".join(map(hex, nodes)) | |||
|
1667 | f = self.do_cmd("changegroup", roots=n) | |||
|
1668 | bytes = 0 | |||
|
1669 | while 1: | |||
|
1670 | l = struct.unpack(">l", f.read(4))[0] | |||
|
1671 | if l == -1: break | |||
|
1672 | d = f.read(l) | |||
|
1673 | bytes += len(d) | |||
|
1674 | yield d | |||
|
1675 | self.ui.note("%d bytes of data transfered\n" % bytes) | |||
|
1676 | ||||
1595 | def repository(ui, path=None, create=0): |
|
1677 | def repository(ui, path=None, create=0): | |
1596 | if path: |
|
1678 | if path: | |
1597 | if path.startswith("http://"): |
|
1679 | if path.startswith("http://"): | |
@@ -1600,5 +1682,7 b' def repository(ui, path=None, create=0):' | |||||
1600 | return httprepository(ui, path.replace("hg://", "http://")) |
|
1682 | return httprepository(ui, path.replace("hg://", "http://")) | |
1601 | if path.startswith("old-http://"): |
|
1683 | if path.startswith("old-http://"): | |
1602 | return localrepository(ui, path.replace("old-http://", "http://")) |
|
1684 | return localrepository(ui, path.replace("old-http://", "http://")) | |
|
1685 | if path.startswith("ssh://"): | |||
|
1686 | return sshrepository(ui, path) | |||
1603 |
|
1687 | |||
1604 | return localrepository(ui, path, create) |
|
1688 | return localrepository(ui, path, create) |
General Comments 0
You need to be logged in to leave comments.
Login now