Mercurial > public > mercurial-scm > hg-stable
annotate mercurial/sshrepo.py @ 2019:ced2d3620f95
add merge command. means same thing as "update -m".
repo.addchangegroup method now returns number of heads modified and added,
so command line can tell whether update or merge needed. this makes
tiny change to ssh wire protocol, but change is backwards compatible.
pull command now returns 0 if no changes to pull.
author | Vadim Gelfer <vadim.gelfer@gmail.com> |
---|---|
date | Wed, 29 Mar 2006 10:27:16 -0800 |
parents | 50de0887bbcd |
children | 1f1fc418a96c |
rev | line source |
---|---|
1096 | 1 # sshrepo.py - ssh repository proxy class for mercurial |
0
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
2 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
3 # Copyright 2005 Matt Mackall <mpm@selenic.com> |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
4 # |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
5 # This software may be used and distributed according to the terms |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
6 # of the GNU General Public License, incorporated herein by reference. |
9117c6561b0b
Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff
changeset
|
7 |
1103 | 8 from node import * |
9 from remoterepo import * | |
1400
cf9a1233738a
i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents:
1358
diff
changeset
|
10 from i18n import gettext as _ |
1251
84cf8834efb5
Fix lots of exception-related problems.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1103
diff
changeset
|
11 from demandload import * |
1357
94586af53d2f
Replacing select.select() with os.fstat() which works also on windows.
zbynek@alex.kolej.mff.cuni.cz
parents:
1332
diff
changeset
|
12 demandload(globals(), "hg os re stat") |
60 | 13 |
926 | 14 class sshrepository(remoterepository): |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
15 def __init__(self, ui, path): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
16 self.url = path |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
17 self.ui = ui |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
18 |
1069
4337cd845a2a
Allow using a ssh repository without a path.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1062
diff
changeset
|
19 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', path) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
20 if not m: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
21 raise hg.RepoError(_("couldn't parse destination %s") % path) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
22 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
23 self.user = m.group(2) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
24 self.host = m.group(3) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
25 self.port = m.group(5) |
1069
4337cd845a2a
Allow using a ssh repository without a path.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1062
diff
changeset
|
26 self.path = m.group(7) or "." |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
27 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
28 args = self.user and ("%s@%s" % (self.user, self.host)) or self.host |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
29 args = self.port and ("%s -p %s") % (args, self.port) or args |
817 | 30 |
961 | 31 sshcmd = self.ui.config("ui", "ssh", "ssh") |
32 remotecmd = self.ui.config("ui", "remotecmd", "hg") | |
1330
0fcde73dc3ca
Give ssh a better chance of working on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1251
diff
changeset
|
33 cmd = '%s %s "%s -R %s serve --stdio"' |
1069
4337cd845a2a
Allow using a ssh repository without a path.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
1062
diff
changeset
|
34 cmd = cmd % (sshcmd, args, remotecmd, self.path) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
35 |
1332
404484c9628e
Help debugability: print ssh command being used when --verbose.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1330
diff
changeset
|
36 ui.note('running %s\n' % cmd) |
1330
0fcde73dc3ca
Give ssh a better chance of working on Windows.
Bryan O'Sullivan <bos@serpentine.com>
parents:
1251
diff
changeset
|
37 self.pipeo, self.pipei, self.pipee = os.popen3(cmd, 'b') |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
38 |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
39 def readerr(self): |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
40 while 1: |
1357
94586af53d2f
Replacing select.select() with os.fstat() which works also on windows.
zbynek@alex.kolej.mff.cuni.cz
parents:
1332
diff
changeset
|
41 size = os.fstat(self.pipee.fileno())[stat.ST_SIZE] |
94586af53d2f
Replacing select.select() with os.fstat() which works also on windows.
zbynek@alex.kolej.mff.cuni.cz
parents:
1332
diff
changeset
|
42 if size == 0: break |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
43 l = self.pipee.readline() |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
44 if not l: break |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
45 self.ui.status(_("remote: "), l) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
46 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
47 def __del__(self): |
817 | 48 try: |
49 self.pipeo.close() | |
50 self.pipei.close() | |
1358
20abfd48e21c
Partially revert ssh change so we read all of remote ssh stream
Matt Mackall <mpm@selenic.com>
parents:
1357
diff
changeset
|
51 # read the error descriptor until EOF |
20abfd48e21c
Partially revert ssh change so we read all of remote ssh stream
Matt Mackall <mpm@selenic.com>
parents:
1357
diff
changeset
|
52 for l in self.pipee: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
53 self.ui.status(_("remote: "), l) |
817 | 54 self.pipee.close() |
55 except: | |
56 pass | |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
57 |
634
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
58 def dev(self): |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
59 return -1 |
da5378d39269
Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents:
627
diff
changeset
|
60 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
61 def do_cmd(self, cmd, **args): |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
62 self.ui.debug(_("sending %s command\n") % cmd) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
63 self.pipeo.write("%s\n" % cmd) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
64 for k, v in args.items(): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
65 self.pipeo.write("%s %d\n" % (k, len(v))) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
66 self.pipeo.write(v) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
67 self.pipeo.flush() |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
68 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
69 return self.pipei |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
70 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
71 def call(self, cmd, **args): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
72 r = self.do_cmd(cmd, **args) |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
73 l = r.readline() |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
74 self.readerr() |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
75 try: |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
76 l = int(l) |
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
77 except: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
78 raise hg.RepoError(_("unexpected response '%s'") % l) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
79 return r.read(l) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
80 |
638
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
81 def lock(self): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
82 self.call("lock") |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
83 return remotelock(self) |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
84 |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
85 def unlock(self): |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
86 self.call("unlock") |
35f7adfefa69
Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents:
637
diff
changeset
|
87 |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
88 def heads(self): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
89 d = self.call("heads") |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
90 try: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
91 return map(bin, d[:-1].split(" ")) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
92 except: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
93 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "...")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
94 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
95 def branches(self, nodes): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
96 n = " ".join(map(hex, nodes)) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
97 d = self.call("branches", nodes=n) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
98 try: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
99 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
100 return br |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
101 except: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
102 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "...")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
103 |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
104 def between(self, pairs): |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
105 n = "\n".join(["-".join(map(hex, p)) for p in pairs]) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
106 d = self.call("between", pairs=n) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
107 try: |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
108 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ] |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
109 return p |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
110 except: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
111 raise hg.RepoError(_("unexpected response '%s'") % (d[:400] + "...")) |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
112 |
1736
50de0887bbcd
add preoutgoing and outgoing hooks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1402
diff
changeset
|
113 def changegroup(self, nodes, kind): |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
114 n = " ".join(map(hex, nodes)) |
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
115 f = self.do_cmd("changegroup", roots=n) |
635
85e2209d401c
Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents:
634
diff
changeset
|
116 return self.pipei |
624
876333a295ff
Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents:
623
diff
changeset
|
117 |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
118 def addchangegroup(self, cg): |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
119 d = self.call("addchangegroup") |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
120 if d: |
1402
9d2c2e6b32b5
i18n part2: use '_' for all strings who are part of the user interface
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents:
1400
diff
changeset
|
121 raise hg.RepoError(_("push refused: %s"), d) |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
122 |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
123 while 1: |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
124 d = cg.read(4096) |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
125 if not d: break |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
126 self.pipeo.write(d) |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
127 self.readerr() |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
128 |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
129 self.pipeo.flush() |
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
130 |
646
342927da4f4c
Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents:
644
diff
changeset
|
131 self.readerr() |
639
31cebba881a0
Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents:
638
diff
changeset
|
132 l = int(self.pipei.readline()) |
2019
ced2d3620f95
add merge command. means same thing as "update -m".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1736
diff
changeset
|
133 r = self.pipei.read(l) |
ced2d3620f95
add merge command. means same thing as "update -m".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1736
diff
changeset
|
134 if not r: |
ced2d3620f95
add merge command. means same thing as "update -m".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1736
diff
changeset
|
135 return 1 |
ced2d3620f95
add merge command. means same thing as "update -m".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents:
1736
diff
changeset
|
136 return int(r) |