annotate mercurial/httprepo.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 1a09814a5b1f
children 7761597b5da3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
1 # httprepo.py - HTTP repository proxy classes 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
1089
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
8 from node import *
142b5d5ec9cc Break apart hg.py
mpm@selenic.com
parents: 1072
diff changeset
9 from remoterepo import *
1400
cf9a1233738a i18n first part: make '_' available for files who need it
Benoit Boissinot <benoit.boissinot@ens-lyon.org
parents: 1377
diff changeset
10 from i18n import gettext as _
1251
84cf8834efb5 Fix lots of exception-related problems.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1089
diff changeset
11 from demandload import *
2015
1a09814a5b1f Catch HTTPException when reading from remote http repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1870
diff changeset
12 demandload(globals(), "hg os urllib urllib2 urlparse zlib util httplib")
926
b765e970c9ff Add a local() method to repository classes
mpm@selenic.com
parents: 923
diff changeset
13
b765e970c9ff Add a local() method to repository classes
mpm@selenic.com
parents: 923
diff changeset
14 class httprepository(remoterepository):
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
15 def __init__(self, ui, path):
765
1e31d97c3d70 Hack to fix missing '/' problem in URLs
mpm@selenic.com
parents: 764
diff changeset
16 # fix missing / after hostname
1e31d97c3d70 Hack to fix missing '/' problem in URLs
mpm@selenic.com
parents: 764
diff changeset
17 s = urlparse.urlsplit(path)
1e31d97c3d70 Hack to fix missing '/' problem in URLs
mpm@selenic.com
parents: 764
diff changeset
18 partial = s[2]
1e31d97c3d70 Hack to fix missing '/' problem in URLs
mpm@selenic.com
parents: 764
diff changeset
19 if not partial: partial = "/"
1e31d97c3d70 Hack to fix missing '/' problem in URLs
mpm@selenic.com
parents: 764
diff changeset
20 self.url = urlparse.urlunsplit((s[0], s[1], partial, '', ''))
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
21 self.ui = ui
321
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
22 no_list = [ "localhost", "127.0.0.1" ]
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
23 host = ui.config("http_proxy", "host")
424
9294dce4b633 Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 385
diff changeset
24 if host is None:
9294dce4b633 Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 385
diff changeset
25 host = os.environ.get("http_proxy")
426
8c90ab5644c9 Allow hgrc's proxy host and $http_proxy env var to start with http://
Thomas Arendsen Hein <thomas@intevation.de>
parents: 424
diff changeset
26 if host and host.startswith('http://'):
8c90ab5644c9 Allow hgrc's proxy host and $http_proxy env var to start with http://
Thomas Arendsen Hein <thomas@intevation.de>
parents: 424
diff changeset
27 host = host[7:]
321
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
28 user = ui.config("http_proxy", "user")
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
29 passwd = ui.config("http_proxy", "passwd")
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
30 no = ui.config("http_proxy", "no")
424
9294dce4b633 Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 385
diff changeset
31 if no is None:
9294dce4b633 Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 385
diff changeset
32 no = os.environ.get("no_proxy")
321
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
33 if no:
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
34 no_list = no_list + no.split(",")
515
03f27b1381f9 Whitespace cleanups
mpm@selenic.com
parents: 514
diff changeset
35
321
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
36 no_proxy = 0
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
37 for h in no_list:
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
38 if (path.startswith("http://" + h + "/") or
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
39 path.startswith("http://" + h + ":") or
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
40 path == "http://" + h):
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
41 no_proxy = 1
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
42
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
43 # Note: urllib2 takes proxy values from the environment and those will
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
44 # take precedence
424
9294dce4b633 Allow override of HTTP_PROXY, http_proxy and no_proxy; make no_proxy work.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 385
diff changeset
45 for env in ["HTTP_PROXY", "http_proxy", "no_proxy"]:
859
6390c377a9e6 Trap OSError when deleting env vars
Edouard Gomez <ed.gomez@free.fr>
parents: 856
diff changeset
46 try:
6390c377a9e6 Trap OSError when deleting env vars
Edouard Gomez <ed.gomez@free.fr>
parents: 856
diff changeset
47 if os.environ.has_key(env):
6390c377a9e6 Trap OSError when deleting env vars
Edouard Gomez <ed.gomez@free.fr>
parents: 856
diff changeset
48 del os.environ[env]
6390c377a9e6 Trap OSError when deleting env vars
Edouard Gomez <ed.gomez@free.fr>
parents: 856
diff changeset
49 except OSError:
6390c377a9e6 Trap OSError when deleting env vars
Edouard Gomez <ed.gomez@free.fr>
parents: 856
diff changeset
50 pass
321
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
51
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
52 proxy_handler = urllib2.BaseHandler()
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
53 if host and not no_proxy:
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
54 proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host})
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
55
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
56 authinfo = None
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
57 if user and passwd:
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
58 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
59 passmgr.add_password(None, host, user, passwd)
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
60 authinfo = urllib2.ProxyBasicAuthHandler(passmgr)
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
61
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
62 opener = urllib2.build_opener(proxy_handler, authinfo)
1359
51ac9a79f3e5 Set the user agent for httprepo communication
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
63 # 1.0 here is the _protocol_ version
51ac9a79f3e5 Set the user agent for httprepo communication
Matt Mackall <mpm@selenic.com>
parents: 1251
diff changeset
64 opener.addheaders = [('User-agent', 'mercurial/proto-1.0')]
321
73b8a8a059ec Transparent proxy support
mpm@selenic.com
parents: 317
diff changeset
65 urllib2.install_opener(opener)
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
66
634
da5378d39269 Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents: 627
diff changeset
67 def dev(self):
da5378d39269 Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents: 627
diff changeset
68 return -1
da5378d39269 Add a repo method to report repo device
Matt Mackall <mpm@selenic.com>
parents: 627
diff changeset
69
1870
8a8ab47cccde make push over http print good error message.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1736
diff changeset
70 def lock(self):
8a8ab47cccde make push over http print good error message.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1736
diff changeset
71 raise util.Abort(_('operation not supported over http'))
8a8ab47cccde make push over http print good error message.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1736
diff changeset
72
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
73 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
74 self.ui.debug(_("sending %s command\n") % cmd)
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
75 q = {"cmd": cmd}
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
76 q.update(args)
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
77 qs = urllib.urlencode(q)
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
78 cu = "%s?%s" % (self.url, qs)
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
79 resp = urllib2.urlopen(cu)
753
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
80 proto = resp.headers['content-type']
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
81
753
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
82 # accept old "text/plain" and "application/hg-changegroup" for now
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
83 if not proto.startswith('application/mercurial') and \
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
84 not proto.startswith('text/plain') and \
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
85 not proto.startswith('application/hg-changegroup'):
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
86 raise hg.RepoError(_("'%s' does not appear to be an hg repository") %
1251
84cf8834efb5 Fix lots of exception-related problems.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1089
diff changeset
87 self.url)
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
88
753
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
89 if proto.startswith('application/mercurial'):
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
90 version = proto[22:]
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
91 if float(version) > 0.1:
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
92 raise hg.RepoError(_("'%s' uses newer protocol %s") %
1251
84cf8834efb5 Fix lots of exception-related problems.
Bryan O'Sullivan <bos@serpentine.com>
parents: 1089
diff changeset
93 (self.url, version))
753
8760d0c83b9b Check protocol versions
mpm@selenic.com
parents: 752
diff changeset
94
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
95 return resp
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
96
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
97 def heads(self):
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
98 d = self.do_cmd("heads").read()
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
99 try:
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
100 return map(bin, d[:-1].split(" "))
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
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 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n")
222
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
103 raise
87484f627422 make pull work for multiple heads
mpm@selenic.com
parents: 220
diff changeset
104
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
105 def branches(self, nodes):
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
106 n = " ".join(map(hex, nodes))
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
107 d = self.do_cmd("branches", nodes=n).read()
217
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
108 try:
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
109 br = [ tuple(map(bin, b.split(" "))) for b in d.splitlines() ]
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
110 return br
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
111 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
112 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n")
217
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
113 raise
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
114
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
115 def between(self, pairs):
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
116 n = "\n".join(["-".join(map(hex, p)) for p in pairs])
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
117 d = self.do_cmd("between", pairs=n).read()
217
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
118 try:
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
119 p = [ l and map(bin, l.split(" ")) or [] for l in d.splitlines() ]
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
120 return p
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
121 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
122 self.ui.warn(_("unexpected response:\n") + d[:400] + "\n...\n")
217
e6d6497a6331 merge: catch unexpected responses
mpm@selenic.com
parents: 216
diff changeset
123 raise
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
124
1736
50de0887bbcd add preoutgoing and outgoing hooks.
Vadim Gelfer <vadim.gelfer@gmail.com>
parents: 1402
diff changeset
125 def changegroup(self, nodes, kind):
60
e32fdbd97839 Add hg:// protocol
mpm@selenic.com
parents: 56
diff changeset
126 n = " ".join(map(hex, nodes))
752
c693eafd5967 Simplify content type checking
mpm@selenic.com
parents: 751
diff changeset
127 f = self.do_cmd("changegroup", roots=n)
192
5d8553352d2e Changes to network protocol
mpm@selenic.com
parents: 191
diff changeset
128 bytes = 0
635
85e2209d401c Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents: 634
diff changeset
129
1376
524ca4a06f70 Fix same performance bug as c3654cfaa77 but for httprepo.py instead.
Eric Hopper <hopper@omnifarious.org>
parents: 1359
diff changeset
130 def zgenerator(f):
524ca4a06f70 Fix same performance bug as c3654cfaa77 but for httprepo.py instead.
Eric Hopper <hopper@omnifarious.org>
parents: 1359
diff changeset
131 zd = zlib.decompressobj()
2015
1a09814a5b1f Catch HTTPException when reading from remote http repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1870
diff changeset
132 try:
1a09814a5b1f Catch HTTPException when reading from remote http repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1870
diff changeset
133 for chnk in f:
1a09814a5b1f Catch HTTPException when reading from remote http repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1870
diff changeset
134 yield zd.decompress(chnk)
1a09814a5b1f Catch HTTPException when reading from remote http repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1870
diff changeset
135 except httplib.HTTPException, inst:
1a09814a5b1f Catch HTTPException when reading from remote http repository.
Thomas Arendsen Hein <thomas@intevation.de>
parents: 1870
diff changeset
136 raise IOError(None, _('connection ended unexpectedly'))
1376
524ca4a06f70 Fix same performance bug as c3654cfaa77 but for httprepo.py instead.
Eric Hopper <hopper@omnifarious.org>
parents: 1359
diff changeset
137 yield zd.flush()
635
85e2209d401c Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents: 634
diff changeset
138
1376
524ca4a06f70 Fix same performance bug as c3654cfaa77 but for httprepo.py instead.
Eric Hopper <hopper@omnifarious.org>
parents: 1359
diff changeset
139 return util.chunkbuffer(zgenerator(util.filechunkiter(f)))
635
85e2209d401c Protocol switch from using generators to stream-like objects.
Matt Mackall <mpm@selenic.com>
parents: 634
diff changeset
140
923
c7a3b88505cd Add basic https support for pull
mpm@selenic.com
parents: 919
diff changeset
141 class httpsrepository(httprepository):
c7a3b88505cd Add basic https support for pull
mpm@selenic.com
parents: 919
diff changeset
142 pass