Show More
@@ -317,7 +317,7 b' paths::' | |||||
317 | Assigns symbolic names to repositories. The left side is the |
|
317 | Assigns symbolic names to repositories. The left side is the | |
318 | symbolic name, and the right gives the directory or URL that is the |
|
318 | symbolic name, and the right gives the directory or URL that is the | |
319 | location of the repository. Default paths can be declared by |
|
319 | location of the repository. Default paths can be declared by | |
320 | setting the following entries. |
|
320 | setting the following entries. | |
321 | default;; |
|
321 | default;; | |
322 | Directory or URL to use when pulling if no source is specified. |
|
322 | Directory or URL to use when pulling if no source is specified. | |
323 | Default is set to repository from which the current repository |
|
323 | Default is set to repository from which the current repository | |
@@ -326,6 +326,18 b' paths::' | |||||
326 | Optional. Directory or URL to use when pushing if no destination |
|
326 | Optional. Directory or URL to use when pushing if no destination | |
327 | is specified. |
|
327 | is specified. | |
328 |
|
328 | |||
|
329 | server:: | |||
|
330 | Controls generic server settings. | |||
|
331 | stream;; | |||
|
332 | Whether to allow clients to clone a repo using the uncompressed | |||
|
333 | streaming protocol. This transfers about 40% more data than a | |||
|
334 | regular clone, but uses less memory and CPU on both server and | |||
|
335 | client. Over a LAN (100Mbps or better) or a very fast WAN, an | |||
|
336 | uncompressed streaming clone is a lot faster (~10x) than a regular | |||
|
337 | clone. Over most WAN connections (anything slower than about | |||
|
338 | 6Mbps), uncompressed streaming is slower, because of the extra | |||
|
339 | data transfer overhead. Default is False. | |||
|
340 | ||||
329 | ui:: |
|
341 | ui:: | |
330 | User interface controls. |
|
342 | User interface controls. | |
331 | debug;; |
|
343 | debug;; |
@@ -97,7 +97,8 b' def clone(ui, source, dest=None, pull=Fa' | |||||
97 |
|
97 | |||
98 | pull: always pull from source repository, even in local case |
|
98 | pull: always pull from source repository, even in local case | |
99 |
|
99 | |||
100 |
stream: stream from repository (fast over |
|
100 | stream: stream raw data uncompressed from repository (fast over | |
|
101 | LAN, slow over WAN) | |||
101 |
|
102 | |||
102 | rev: revision to clone up to (implies pull=True) |
|
103 | rev: revision to clone up to (implies pull=True) | |
103 |
|
104 |
@@ -860,7 +860,10 b' class hgweb(object):' | |||||
860 | or self.t("error", error="%r not found" % fname)) |
|
860 | or self.t("error", error="%r not found" % fname)) | |
861 |
|
861 | |||
862 | def do_capabilities(self, req): |
|
862 | def do_capabilities(self, req): | |
863 | resp = 'unbundle stream=%d' % (self.repo.revlogversion,) |
|
863 | caps = ['unbundle'] | |
|
864 | if self.repo.ui.configbool('server', 'stream'): | |||
|
865 | caps.append('stream=%d' % self.repo.revlogversion) | |||
|
866 | resp = ' '.join(caps) | |||
864 | req.httphdr("application/mercurial-0.1", length=len(resp)) |
|
867 | req.httphdr("application/mercurial-0.1", length=len(resp)) | |
865 | req.write(resp) |
|
868 | req.write(resp) | |
866 |
|
869 |
@@ -2204,8 +2204,11 b' class localrepository(repo.repository):' | |||||
2204 | return 1 |
|
2204 | return 1 | |
2205 |
|
2205 | |||
2206 | def stream_in(self, remote): |
|
2206 | def stream_in(self, remote): | |
|
2207 | fp = remote.stream_out() | |||
|
2208 | resp = int(fp.readline()) | |||
|
2209 | if resp != 0: | |||
|
2210 | raise util.Abort(_('operation forbidden by server')) | |||
2207 | self.ui.status(_('streaming all changes\n')) |
|
2211 | self.ui.status(_('streaming all changes\n')) | |
2208 | fp = remote.stream_out() |
|
|||
2209 | total_files, total_bytes = map(int, fp.readline().split(' ', 1)) |
|
2212 | total_files, total_bytes = map(int, fp.readline().split(' ', 1)) | |
2210 | self.ui.status(_('%d files to transfer, %s of data\n') % |
|
2213 | self.ui.status(_('%d files to transfer, %s of data\n') % | |
2211 | (total_files, util.bytecount(total_bytes))) |
|
2214 | (total_files, util.bytecount(total_bytes))) | |
@@ -2230,14 +2233,15 b' class localrepository(repo.repository):' | |||||
2230 |
|
2233 | |||
2231 | keyword arguments: |
|
2234 | keyword arguments: | |
2232 | heads: list of revs to clone (forces use of pull) |
|
2235 | heads: list of revs to clone (forces use of pull) | |
2233 | pull: force use of pull, even if remote can stream''' |
|
2236 | stream: use streaming clone if possible''' | |
2234 |
|
2237 | |||
2235 |
# now, all clients that can |
|
2238 | # now, all clients that can request uncompressed clones can | |
2236 |
# supported by all servers that can s |
|
2239 | # read repo formats supported by all servers that can serve | |
|
2240 | # them. | |||
2237 |
|
2241 | |||
2238 | # if revlog format changes, client will have to check version |
|
2242 | # if revlog format changes, client will have to check version | |
2239 |
# and format flags on "stream" capability, and s |
|
2243 | # and format flags on "stream" capability, and use | |
2240 | # compatible. |
|
2244 | # uncompressed only if compatible. | |
2241 |
|
2245 | |||
2242 | if stream and not heads and remote.capable('stream'): |
|
2246 | if stream and not heads and remote.capable('stream'): | |
2243 | return self.stream_in(remote) |
|
2247 | return self.stream_in(remote) |
@@ -60,8 +60,10 b' class sshserver(object):' | |||||
60 | capabilities: space separated list of tokens |
|
60 | capabilities: space separated list of tokens | |
61 | ''' |
|
61 | ''' | |
62 |
|
62 | |||
63 | r = "capabilities: unbundle stream=%d\n" % (self.repo.revlogversion,) |
|
63 | caps = ['unbundle'] | |
64 | self.respond(r) |
|
64 | if self.ui.configbool('server', 'stream'): | |
|
65 | caps.append('stream=%d' % self.repo.revlogversion) | |||
|
66 | self.respond("capabilities: %s\n" % (' '.join(caps),)) | |||
65 |
|
67 | |||
66 | def do_lock(self): |
|
68 | def do_lock(self): | |
67 | '''DEPRECATED - allowing remote client to lock repo is not safe''' |
|
69 | '''DEPRECATED - allowing remote client to lock repo is not safe''' |
@@ -59,6 +59,13 b' def walkrepo(root):' | |||||
59 | def stream_out(repo, fileobj): |
|
59 | def stream_out(repo, fileobj): | |
60 | '''stream out all metadata files in repository. |
|
60 | '''stream out all metadata files in repository. | |
61 | writes to file-like object, must support write() and optional flush().''' |
|
61 | writes to file-like object, must support write() and optional flush().''' | |
|
62 | ||||
|
63 | if not repo.ui.configbool('server', 'stream'): | |||
|
64 | fileobj.write('1\n') | |||
|
65 | return | |||
|
66 | ||||
|
67 | fileobj.write('0\n') | |||
|
68 | ||||
62 | # get consistent snapshot of repo. lock during scan so lock not |
|
69 | # get consistent snapshot of repo. lock during scan so lock not | |
63 | # needed while we stream, and commits can happen. |
|
70 | # needed while we stream, and commits can happen. | |
64 | lock = repo.lock() |
|
71 | lock = repo.lock() |
@@ -1,23 +1,23 b'' | |||||
1 | #!/bin/sh |
|
1 | #!/bin/sh | |
2 |
|
2 | |||
3 | mkdir test |
|
3 | hg init test | |
4 | cd test |
|
4 | cd test | |
5 | echo foo>foo |
|
5 | echo foo>foo | |
6 | hg init |
|
6 | hg commit -A -d '0 0' -m 1 | |
7 | hg addremove |
|
7 | hg --config server.stream=True serve -p 20059 -d --pid-file=hg1.pid | |
8 | hg commit -m 1 |
|
8 | cat hg1.pid >> $DAEMON_PIDS | |
9 | hg verify |
|
9 | hg serve -p 20060 -d --pid-file=hg2.pid | |
10 | hg serve -p 20059 -d --pid-file=hg.pid |
|
10 | cat hg2.pid >> $DAEMON_PIDS | |
11 | cat hg.pid >> $DAEMON_PIDS |
|
|||
12 | cd .. |
|
11 | cd .. | |
13 |
|
12 | |||
14 | echo % clone via stream |
|
13 | echo % clone via stream | |
15 |
http_proxy= hg clone -- |
|
14 | http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \ | |
16 | sed -e 's/[0-9][0-9.]*/XXX/g' |
|
15 | sed -e 's/[0-9][0-9.]*/XXX/g' | |
17 | cd copy |
|
16 | cd copy | |
18 | hg verify |
|
17 | hg verify | |
19 |
|
18 | |||
20 | cd .. |
|
19 | echo % try to clone via stream, should use pull instead | |
|
20 | http_proxy= hg clone --uncompressed http://localhost:20060/ copy2 | |||
21 |
|
21 | |||
22 | echo % clone via pull |
|
22 | echo % clone via pull | |
23 | http_proxy= hg clone http://localhost:20059/ copy-pull |
|
23 | http_proxy= hg clone http://localhost:20059/ copy-pull |
@@ -4,7 +4,7 b' hg init a' | |||||
4 | cd a |
|
4 | cd a | |
5 | echo a > a |
|
5 | echo a > a | |
6 | hg ci -Ama -d '1123456789 0' |
|
6 | hg ci -Ama -d '1123456789 0' | |
7 | hg serve -p 20059 -d --pid-file=hg.pid |
|
7 | hg --config server.stream=True serve -p 20059 -d --pid-file=hg.pid | |
8 | cat hg.pid >> $DAEMON_PIDS |
|
8 | cat hg.pid >> $DAEMON_PIDS | |
9 |
|
9 | |||
10 | cd .. |
|
10 | cd .. | |
@@ -14,7 +14,7 b' cat proxy.pid >> $DAEMON_PIDS' | |||||
14 | sleep 2 |
|
14 | sleep 2 | |
15 |
|
15 | |||
16 | echo %% url for proxy, stream |
|
16 | echo %% url for proxy, stream | |
17 |
http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone -- |
|
17 | http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --uncompressed http://localhost:20059/ b | \ | |
18 | sed -e 's/[0-9][0-9.]*/XXX/g' |
|
18 | sed -e 's/[0-9][0-9.]*/XXX/g' | |
19 | cd b |
|
19 | cd b | |
20 | hg verify |
|
20 | hg verify |
@@ -1,10 +1,4 b'' | |||||
1 | (the addremove command is deprecated; use add and remove --after instead) |
|
|||
2 | adding foo |
|
1 | adding foo | |
3 | checking changesets |
|
|||
4 | checking manifests |
|
|||
5 | crosschecking files in changesets and manifests |
|
|||
6 | checking files |
|
|||
7 | 1 files, 1 changesets, 1 total revisions |
|
|||
8 | % clone via stream |
|
2 | % clone via stream | |
9 | streaming all changes |
|
3 | streaming all changes | |
10 | XXX files to transfer, XXX bytes of data |
|
4 | XXX files to transfer, XXX bytes of data | |
@@ -15,6 +9,13 b' checking manifests' | |||||
15 | crosschecking files in changesets and manifests |
|
9 | crosschecking files in changesets and manifests | |
16 | checking files |
|
10 | checking files | |
17 | 1 files, 1 changesets, 1 total revisions |
|
11 | 1 files, 1 changesets, 1 total revisions | |
|
12 | % try to clone via stream, should use pull instead | |||
|
13 | requesting all changes | |||
|
14 | adding changesets | |||
|
15 | adding manifests | |||
|
16 | adding file changes | |||
|
17 | added 1 changesets with 1 changes to 1 files | |||
|
18 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |||
18 | % clone via pull |
|
19 | % clone via pull | |
19 | requesting all changes |
|
20 | requesting all changes | |
20 | adding changesets |
|
21 | adding changesets |
@@ -27,11 +27,13 b' hg init remote' | |||||
27 | cd remote |
|
27 | cd remote | |
28 | echo this > foo |
|
28 | echo this > foo | |
29 | hg ci -A -m "init" -d "1000000 0" foo |
|
29 | hg ci -A -m "init" -d "1000000 0" foo | |
|
30 | echo '[server]' > .hg/hgrc | |||
|
31 | echo 'stream = True' >> .hg/hgrc | |||
30 |
|
32 | |||
31 | cd .. |
|
33 | cd .. | |
32 |
|
34 | |||
33 | echo "# clone remote via stream" |
|
35 | echo "# clone remote via stream" | |
34 |
hg clone -e ./dummyssh -- |
|
36 | hg clone -e ./dummyssh --uncompressed ssh://user@dummy/remote local-stream 2>&1 | \ | |
35 | sed -e 's/[0-9][0-9.]*/XXX/g' |
|
37 | sed -e 's/[0-9][0-9.]*/XXX/g' | |
36 | cd local-stream |
|
38 | cd local-stream | |
37 | hg verify |
|
39 | hg verify |
General Comments 0
You need to be logged in to leave comments.
Login now