mercurial/sshrepo.py
author Mads Kiilerich <mads@kiilerich.com>
Fri, 13 Jan 2012 01:19:08 +0100
changeset 15884 cc8287d51680
parent 15624 be43234a6d60
child 16683 525fdb738975
permissions -rw-r--r--
localrepo: remove spurious updatebranchcache return value - it was left over from the refactoring in d01e28657429.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1096
ae4f1f48c569 sshrepo: adjust file comment
mpm@selenic.com
parents: 1094 1089
diff changeset
     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
#
2859
345bac2bc4ec update copyrights.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2740
diff changeset
     3
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8210
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9878
diff changeset
     6
# GNU General Public License version 2 or any later version.
0
9117c6561b0b Add back links from file revisions to changeset revisions
mpm@selenic.com
parents:
diff changeset
     7
15622
86fc364ca5f8 sshrepo: don't quote obviously safe strings (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15581
diff changeset
     8
import re
3891
6b4127c7d52a Simplify i18n imports
Matt Mackall <mpm@selenic.com>
parents: 3877
diff changeset
     9
from i18n import _
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 14004
diff changeset
    10
import util, error, wireproto
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
    11
6313
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    12
class remotelock(object):
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    13
    def __init__(self, repo):
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    14
        self.repo = repo
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    15
    def release(self):
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    16
        self.repo.unlock()
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    17
        self.repo = None
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    18
    def __del__(self):
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    19
        if self.repo:
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    20
            self.release()
c5580db9c3aa remoterepo: no longer needed
Matt Mackall <mpm@selenic.com>
parents: 6212
diff changeset
    21
15581
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    22
def _serverquote(s):
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    23
    '''quote a string for the remote shell ... which we assume is sh'''
15624
be43234a6d60 sshrepo: add more safe characters (issue2983)
Thomas Arendsen Hein <thomas@intevation.de>
parents: 15622
diff changeset
    24
    if re.match('[a-zA-Z0-9@%_+=:,./-]*$', s):
15622
86fc364ca5f8 sshrepo: don't quote obviously safe strings (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15581
diff changeset
    25
        return s
15581
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    26
    return "'%s'" % s.replace("'", "'\\''")
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    27
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
    28
class sshrepository(wireproto.wirerepository):
14363
82f3b0f3f0a5 localrepo, sshrepo: use Boolean create argument in __init__
Martin Geisler <mg@lazybytes.net>
parents: 14076
diff changeset
    29
    def __init__(self, ui, path, create=False):
2673
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
    30
        self._url = path
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
    31
        self.ui = ui
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
    32
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 14004
diff changeset
    33
        u = util.url(path, parsequery=False, parsefragment=False)
13819
d16894e29f91 httprepo/sshrepo: use url.url
Brodie Rao <brodie@bitheap.org>
parents: 13721
diff changeset
    34
        if u.scheme != 'ssh' or not u.host or u.path is None:
11590
0b15aee0a306 protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents: 11589
diff changeset
    35
            self._abort(error.RepoError(_("couldn't parse location %s") % path))
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
    36
13819
d16894e29f91 httprepo/sshrepo: use url.url
Brodie Rao <brodie@bitheap.org>
parents: 13721
diff changeset
    37
        self.user = u.user
d16894e29f91 httprepo/sshrepo: use url.url
Brodie Rao <brodie@bitheap.org>
parents: 13721
diff changeset
    38
        if u.passwd is not None:
13464
da0ddd62b9d8 sshrepo: catch passwords in ssh urls
Adrian Buehlmann <adrian@cadifra.com>
parents: 13084
diff changeset
    39
            self._abort(error.RepoError(_("password in URL not supported")))
13819
d16894e29f91 httprepo/sshrepo: use url.url
Brodie Rao <brodie@bitheap.org>
parents: 13721
diff changeset
    40
        self.host = u.host
d16894e29f91 httprepo/sshrepo: use url.url
Brodie Rao <brodie@bitheap.org>
parents: 13721
diff changeset
    41
        self.port = u.port
d16894e29f91 httprepo/sshrepo: use url.url
Brodie Rao <brodie@bitheap.org>
parents: 13721
diff changeset
    42
        self.path = u.path or "."
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
    43
961
3e11d5038649 Add --ssh and --remotecmd to push
mpm@selenic.com
parents: 934
diff changeset
    44
        sshcmd = self.ui.config("ui", "ssh", "ssh")
3e11d5038649 Add --ssh and --remotecmd to push
mpm@selenic.com
parents: 934
diff changeset
    45
        remotecmd = self.ui.config("ui", "remotecmd", "hg")
2549
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    46
5644
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5293
diff changeset
    47
        args = util.sshargs(sshcmd, self.host, self.user, self.port)
e2e8e977a6cb win32: fix ssh://host:port when using Plink
Steve Borho <steve@borho.org>
parents: 5293
diff changeset
    48
2549
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    49
        if create:
15581
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    50
            cmd = '%s %s %s' % (sshcmd, args,
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    51
                util.shellquote("%s init %s" %
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    52
                    (_serverquote(remotecmd), _serverquote(self.path))))
6953
63b5f4c73c98 i18n: mark strings for translation in Mercurial
Martin Geisler <mg@daimi.au.dk>
parents: 6313
diff changeset
    53
            ui.note(_('running %s\n') % cmd)
5292
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5190
diff changeset
    54
            res = util.system(cmd)
2549
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    55
            if res != 0:
11590
0b15aee0a306 protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents: 11589
diff changeset
    56
                self._abort(error.RepoError(_("could not create remote repo")))
2549
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    57
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    58
        self.validate_repo(ui, sshcmd, args, remotecmd)
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    59
2673
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
    60
    def url(self):
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
    61
        return self._url
109a22f5434a hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2612
diff changeset
    62
2549
e1831f06eef1 Added ability to clone from a local repository to a (new) remote one.
Sean Meiners <sean.meiners@linspire.com>
parents: 2484
diff changeset
    63
    def validate_repo(self, ui, sshcmd, args, remotecmd):
3034
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
    64
        # cleanup up previous run
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
    65
        self.cleanup()
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
    66
15581
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    67
        cmd = '%s %s %s' % (sshcmd, args,
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    68
            util.shellquote("%s -R %s serve --stdio" %
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    69
                (_serverquote(remotecmd), _serverquote(self.path))))
d8fa35c28335 ssh: quote remote paths (issue2983)
Mads Kiilerich <mads@kiilerich.com>
parents: 15017
diff changeset
    70
        ui.note(_('running %s\n') % cmd)
5292
5a65d870871d sshrepo: fix Windows command quoting
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5190
diff changeset
    71
        cmd = util.quotecommand(cmd)
8339
f55869abb5c3 util: remove ignored mode argument in popen[23]
Martin Geisler <mg@lazybytes.net>
parents: 8312
diff changeset
    72
        self.pipeo, self.pipei, self.pipee = util.popen3(cmd)
646
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
    73
2028
1f1fc418a96c ssh: skip noise generated by remote shell
Matt Mackall <mpm@selenic.com>
parents: 2019
diff changeset
    74
        # skip any noise generated by remote shell
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
    75
        self._callstream("hello")
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
    76
        r = self._callstream("between", pairs=("%s-%s" % ("0"*40, "0"*40)))
2420
144280f1578f ssh: gather initial output so we can do capability detection
Matt Mackall <mpm@selenic.com>
parents: 2230
diff changeset
    77
        lines = ["", "dummy"]
2046
d14497cbd668 Show remote ssh noise only with --debug and increase the limit to 500 lines.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2040
diff changeset
    78
        max_noise = 500
2420
144280f1578f ssh: gather initial output so we can do capability detection
Matt Mackall <mpm@selenic.com>
parents: 2230
diff changeset
    79
        while lines[-1] and max_noise:
144280f1578f ssh: gather initial output so we can do capability detection
Matt Mackall <mpm@selenic.com>
parents: 2230
diff changeset
    80
            l = r.readline()
2028
1f1fc418a96c ssh: skip noise generated by remote shell
Matt Mackall <mpm@selenic.com>
parents: 2019
diff changeset
    81
            self.readerr()
2420
144280f1578f ssh: gather initial output so we can do capability detection
Matt Mackall <mpm@selenic.com>
parents: 2230
diff changeset
    82
            if lines[-1] == "1\n" and l == "\n":
2028
1f1fc418a96c ssh: skip noise generated by remote shell
Matt Mackall <mpm@selenic.com>
parents: 2019
diff changeset
    83
                break
2420
144280f1578f ssh: gather initial output so we can do capability detection
Matt Mackall <mpm@selenic.com>
parents: 2230
diff changeset
    84
            if l:
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 8563
diff changeset
    85
                ui.debug("remote: ", l)
2420
144280f1578f ssh: gather initial output so we can do capability detection
Matt Mackall <mpm@selenic.com>
parents: 2230
diff changeset
    86
            lines.append(l)
2040
cd7711268774 Don't enter an endless loop if remote hg doesn't answer, show remote noise.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2028
diff changeset
    87
            max_noise -= 1
cd7711268774 Don't enter an endless loop if remote hg doesn't answer, show remote noise.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2028
diff changeset
    88
        else:
11590
0b15aee0a306 protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents: 11589
diff changeset
    89
            self._abort(error.RepoError(_("no suitable response from remote hg")))
2028
1f1fc418a96c ssh: skip noise generated by remote shell
Matt Mackall <mpm@selenic.com>
parents: 2019
diff changeset
    90
8150
bbc24c0753a0 util: use built-in set and frozenset
Martin Geisler <mg@lazybytes.net>
parents: 7873
diff changeset
    91
        self.capabilities = set()
8210
344751cd8cb8 replace various uses of list.reverse()
Matt Mackall <mpm@selenic.com>
parents: 8150
diff changeset
    92
        for l in reversed(lines):
2421
a1cfe679192c ssh: add capability detection at startup
Matt Mackall <mpm@selenic.com>
parents: 2420
diff changeset
    93
            if l.startswith("capabilities:"):
5258
b534c502bfb3 Turn capabilities into a mutable set, instead of a fixed tuple.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5196
diff changeset
    94
                self.capabilities.update(l[:-1].split(":")[1].split())
2421
a1cfe679192c ssh: add capability detection at startup
Matt Mackall <mpm@selenic.com>
parents: 2420
diff changeset
    95
                break
a1cfe679192c ssh: add capability detection at startup
Matt Mackall <mpm@selenic.com>
parents: 2420
diff changeset
    96
646
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
    97
    def readerr(self):
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14363
diff changeset
    98
        while True:
2176
9b42304d9896 fix file handling bugs on windows.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2046
diff changeset
    99
            size = util.fstat(self.pipee).st_size
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   100
            if size == 0:
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   101
                break
13084
c97ded7b6e79 sshrepo: don't use readline() on the stderr pipe
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12062
diff changeset
   102
            s = self.pipee.read(size)
c97ded7b6e79 sshrepo: don't use readline() on the stderr pipe
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12062
diff changeset
   103
            if not s:
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 10263
diff changeset
   104
                break
13084
c97ded7b6e79 sshrepo: don't use readline() on the stderr pipe
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12062
diff changeset
   105
            for l in s.splitlines():
c97ded7b6e79 sshrepo: don't use readline() on the stderr pipe
Dan Villiom Podlaski Christiansen <danchr@gmail.com>
parents: 12062
diff changeset
   106
                self.ui.status(_("remote: "), l, '\n')
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   107
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
   108
    def _abort(self, exception):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
   109
        self.cleanup()
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
   110
        raise exception
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11369
diff changeset
   111
3034
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   112
    def cleanup(self):
817
cf1d9a01dd92 Make ssh URL parsing more robust
mpm@selenic.com
parents: 816
diff changeset
   113
        try:
cf1d9a01dd92 Make ssh URL parsing more robust
mpm@selenic.com
parents: 816
diff changeset
   114
            self.pipeo.close()
cf1d9a01dd92 Make ssh URL parsing more robust
mpm@selenic.com
parents: 816
diff changeset
   115
            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
   116
            # 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
   117
            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
   118
                self.ui.status(_("remote: "), l)
817
cf1d9a01dd92 Make ssh URL parsing more robust
mpm@selenic.com
parents: 816
diff changeset
   119
            self.pipee.close()
cf1d9a01dd92 Make ssh URL parsing more robust
mpm@selenic.com
parents: 816
diff changeset
   120
        except:
cf1d9a01dd92 Make ssh URL parsing more robust
mpm@selenic.com
parents: 816
diff changeset
   121
            pass
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   122
3034
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   123
    __del__ = cleanup
2b0bc36a48d8 sshrepo: flush stderr before connecting to the hg server
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 2859
diff changeset
   124
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   125
    def _callstream(self, cmd, **args):
9467
4c041f1ee1b4 do not attempt to translate ui.debug output
Martin Geisler <mg@lazybytes.net>
parents: 8563
diff changeset
   126
        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
   127
        self.pipeo.write("%s\n" % cmd)
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   128
        _func, names = wireproto.commands[cmd]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   129
        keys = names.split()
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   130
        wireargs = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   131
        for k in keys:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   132
            if k == '*':
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   133
                wireargs['*'] = args
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   134
                break
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   135
            else:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   136
                wireargs[k] = args[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   137
                del args[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   138
        for k, v in sorted(wireargs.iteritems()):
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   139
            self.pipeo.write("%s %d\n" % (k, len(v)))
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   140
            if isinstance(v, dict):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   141
                for dk, dv in v.iteritems():
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   142
                    self.pipeo.write("%s %d\n" % (dk, len(dv)))
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   143
                    self.pipeo.write(dv)
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   144
            else:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13464
diff changeset
   145
                self.pipeo.write(v)
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   146
        self.pipeo.flush()
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   147
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   148
        return self.pipei
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   149
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   150
    def _call(self, cmd, **args):
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   151
        self._callstream(cmd, **args)
5978
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   152
        return self._recv()
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   153
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   154
    def _callpush(self, cmd, fp, **args):
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   155
        r = self._call(cmd, **args)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   156
        if r:
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   157
            return '', r
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14363
diff changeset
   158
        while True:
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   159
            d = fp.read(4096)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   160
            if not d:
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   161
                break
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   162
            self._send(d)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   163
        self._send("", flush=True)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   164
        r = self._recv()
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   165
        if r:
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   166
            return '', r
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   167
        return self._recv(), ''
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
   168
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11590
diff changeset
   169
    def _decompress(self, stream):
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11590
diff changeset
   170
        return stream
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11590
diff changeset
   171
5978
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   172
    def _recv(self):
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   173
        l = self.pipei.readline()
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   174
        if l == '\n':
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   175
            err = []
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   176
            while True:
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   177
                line = self.pipee.readline()
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   178
                if line == '-\n':
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   179
                    break
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   180
                err.extend([line])
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   181
            if len(err) > 0:
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   182
                # strip the trailing newline added to the last line server-side
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   183
                err[-1] = err[-1][:-1]
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14537
diff changeset
   184
            self._abort(error.OutOfBandError(*err))
646
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
   185
        self.readerr()
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
   186
        try:
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
   187
            l = int(l)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13827
diff changeset
   188
        except ValueError:
11590
0b15aee0a306 protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents: 11589
diff changeset
   189
            self._abort(error.ResponseError(_("unexpected response:"), l))
5978
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   190
        return self.pipei.read(l)
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   191
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   192
    def _send(self, data, flush=False):
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   193
        self.pipeo.write("%d\n" % len(data))
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   194
        if data:
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   195
            self.pipeo.write(data)
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   196
        if flush:
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   197
            self.pipeo.flush()
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   198
        self.readerr()
624
876333a295ff Add an sshrepository class and hg serve --stdio
Matt Mackall <mpm@selenic.com>
parents: 623
diff changeset
   199
638
35f7adfefa69 Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents: 637
diff changeset
   200
    def lock(self):
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   201
        self._call("lock")
638
35f7adfefa69 Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents: 637
diff changeset
   202
        return remotelock(self)
35f7adfefa69 Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents: 637
diff changeset
   203
35f7adfefa69 Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents: 637
diff changeset
   204
    def unlock(self):
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   205
        self._call("unlock")
638
35f7adfefa69 Add a scheme for handling remote locking
Matt Mackall <mpm@selenic.com>
parents: 637
diff changeset
   206
14537
3c7907dc95ca sshrepo: fix addchangegroup's signature
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14494
diff changeset
   207
    def addchangegroup(self, cg, source, url, lock=None):
11153
9936ed1d04f4 push: document return values between various repo methods.
Greg Ward <greg-hg@gerg.ca>
parents: 10282
diff changeset
   208
        '''Send a changegroup to the remote server.  Return an integer
9936ed1d04f4 push: document return values between various repo methods.
Greg Ward <greg-hg@gerg.ca>
parents: 10282
diff changeset
   209
        similar to unbundle(). DEPRECATED, since it requires locking the
9936ed1d04f4 push: document return values between various repo methods.
Greg Ward <greg-hg@gerg.ca>
parents: 10282
diff changeset
   210
        remote.'''
11589
e8d22fe2ddab protocol: clean up call-like functions in http and ssh clients
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
   211
        d = self._call("addchangegroup")
639
31cebba881a0 Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents: 638
diff changeset
   212
        if d:
11590
0b15aee0a306 protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents: 11589
diff changeset
   213
            self._abort(error.RepoError(_("push refused: %s") % d))
14494
1ffeeb91c55d check-code: flag 0/1 used as constant Boolean expression
Martin Geisler <mg@lazybytes.net>
parents: 14363
diff changeset
   214
        while True:
639
31cebba881a0 Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents: 638
diff changeset
   215
            d = cg.read(4096)
5978
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   216
            if not d:
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   217
                break
639
31cebba881a0 Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents: 638
diff changeset
   218
            self.pipeo.write(d)
646
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
   219
            self.readerr()
639
31cebba881a0 Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents: 638
diff changeset
   220
31cebba881a0 Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents: 638
diff changeset
   221
        self.pipeo.flush()
31cebba881a0 Add addchangegroup to the ssh protocol
Matt Mackall <mpm@selenic.com>
parents: 638
diff changeset
   222
646
342927da4f4c Show remote client output with "remote:"
Matt Mackall <mpm@selenic.com>
parents: 644
diff changeset
   223
        self.readerr()
5978
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   224
        r = self._recv()
2019
ced2d3620f95 add merge command. means same thing as "update -m".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1736
diff changeset
   225
        if not r:
ced2d3620f95 add merge command. means same thing as "update -m".
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1736
diff changeset
   226
            return 1
5978
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   227
        try:
7939c71f3132 sshrepo: be more careful while reading data
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5293
diff changeset
   228
            return int(r)
14004
97ed99d1f419 eliminate various naked except clauses
Idan Kamara <idankk86@gmail.com>
parents: 13827
diff changeset
   229
        except ValueError:
11590
0b15aee0a306 protocol: convert some ssh abort calls
Matt Mackall <mpm@selenic.com>
parents: 11589
diff changeset
   230
            self._abort(error.ResponseError(_("unexpected response:"), r))
2612
ffb895f16925 add support for streaming clone.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2549
diff changeset
   231
2740
386f04d6ecb3 clean up hg.py: move repo constructor code into each repo module
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 2673
diff changeset
   232
instance = sshrepository