Show More
@@ -9,7 +9,7 b' from demandload import *' | |||
|
9 | 9 | demandload(globals(), "os re sys signal") |
|
10 | 10 | demandload(globals(), "fancyopts ui hg util") |
|
11 | 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 | 14 | class UnknownCommand(Exception): pass |
|
15 | 15 | |
@@ -823,9 +823,67 b' def root(ui, repo):' | |||
|
823 | 823 | |
|
824 | 824 | def serve(ui, repo, **opts): |
|
825 | 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 | 883 | def openlog(opt, default): |
|
827 | 884 | if opts[opt] and opts[opt] != '-': return open(opts[opt], 'w') |
|
828 | 885 | else: return default |
|
886 | ||
|
829 | 887 | httpd = hgweb.create_server(repo.root, opts["name"], opts["templates"], |
|
830 | 888 | opts["address"], opts["port"], |
|
831 | 889 | openlog('accesslog', sys.stdout), |
@@ -1017,6 +1075,7 b' table = {' | |||
|
1017 | 1075 | ('p', 'port', 8000, 'listen port'), |
|
1018 | 1076 | ('a', 'address', '', 'interface address'), |
|
1019 | 1077 | ('n', 'name', os.getcwd(), 'repository name'), |
|
1078 | ('', 'stdio', None, 'for remote clients'), | |
|
1020 | 1079 | ('t', 'templates', "", 'template map')], |
|
1021 | 1080 | "hg serve [options]"), |
|
1022 | 1081 | "^status": (status, [], 'hg status'), |
@@ -1592,6 +1592,88 b' class httprepository:' | |||
|
1592 | 1592 | yield zd.decompress(d) |
|
1593 | 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 | 1677 | def repository(ui, path=None, create=0): |
|
1596 | 1678 | if path: |
|
1597 | 1679 | if path.startswith("http://"): |
@@ -1600,5 +1682,7 b' def repository(ui, path=None, create=0):' | |||
|
1600 | 1682 | return httprepository(ui, path.replace("hg://", "http://")) |
|
1601 | 1683 | if path.startswith("old-http://"): |
|
1602 | 1684 | return localrepository(ui, path.replace("old-http://", "http://")) |
|
1685 | if path.startswith("ssh://"): | |
|
1686 | return sshrepository(ui, path) | |
|
1603 | 1687 | |
|
1604 | 1688 | return localrepository(ui, path, create) |
General Comments 0
You need to be logged in to leave comments.
Login now