##// END OF EJS Templates
merge
Vadim Gelfer -
r2638:8dadff05 merge default
parent child Browse files
Show More
@@ -317,7 +317,7 b' paths::'
317 317 Assigns symbolic names to repositories. The left side is the
318 318 symbolic name, and the right gives the directory or URL that is the
319 319 location of the repository. Default paths can be declared by
320 setting the following entries.
320 setting the following entries.
321 321 default;;
322 322 Directory or URL to use when pulling if no source is specified.
323 323 Default is set to repository from which the current repository
@@ -326,6 +326,18 b' paths::'
326 326 Optional. Directory or URL to use when pushing if no destination
327 327 is specified.
328 328
329 server::
330 Controls generic server settings.
331 uncompressed;;
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 341 ui::
330 342 User interface controls.
331 343 debug;;
@@ -128,13 +128,17 b' def walkchangerevs(ui, repo, pats, opts)'
128 128 if not slowpath:
129 129 # Only files, no patterns. Check the history of each file.
130 130 def filerevgen(filelog):
131 cl_count = repo.changelog.count()
131 132 for i, window in increasing_windows(filelog.count()-1, -1):
132 133 revs = []
133 134 for j in xrange(i - window, i + 1):
134 135 revs.append(filelog.linkrev(filelog.node(j)))
135 136 revs.reverse()
136 137 for rev in revs:
137 yield rev
138 # only yield rev for which we have the changelog, it can
139 # happen while doing "hg log" during a pull or commit
140 if rev < cl_count:
141 yield rev
138 142
139 143 minrev, maxrev = min(revs), max(revs)
140 144 for file_ in files:
@@ -970,7 +974,7 b' def clone(ui, source, dest=None, **opts)'
970 974 ui.setconfig_remoteopts(**opts)
971 975 hg.clone(ui, ui.expandpath(source), dest,
972 976 pull=opts['pull'],
973 stream=opts['stream'],
977 stream=opts['uncompressed'],
974 978 rev=opts['rev'],
975 979 update=not opts['noupdate'])
976 980
@@ -2863,7 +2867,8 b' table = {'
2863 2867 ('r', 'rev', [],
2864 2868 _('a changeset you would like to have after cloning')),
2865 2869 ('', 'pull', None, _('use pull protocol to copy metadata')),
2866 ('', 'stream', None, _('use streaming protocol (fast over LAN)')),
2870 ('', 'uncompressed', None,
2871 _('use uncompressed transfer (fast over LAN)')),
2867 2872 ('e', 'ssh', '', _('specify ssh command to use')),
2868 2873 ('', 'remotecmd', '',
2869 2874 _('specify hg command to run on the remote side'))],
@@ -3322,7 +3327,7 b' def dispatch(args):'
3322 3327 except (util.SignalInterrupt, KeyboardInterrupt):
3323 3328 raise
3324 3329 except Exception, inst:
3325 u.warn(_("*** failed to import extension %s: %s\n") % (x[0], inst))
3330 u.warn(_("*** failed to import extension %s: %s\n") % (ext_name, inst))
3326 3331 if u.print_exc():
3327 3332 return 1
3328 3333
@@ -3513,7 +3518,9 b' def dispatch(args):'
3513 3518 return inst.code
3514 3519 except:
3515 3520 u.warn(_("** unknown exception encountered, details follow\n"))
3516 u.warn(_("** report bug details to mercurial@selenic.com\n"))
3521 u.warn(_("** report bug details to "
3522 "http://www.selenic.com/mercurial/bts\n"))
3523 u.warn(_("** or mercurial@selenic.com\n"))
3517 3524 u.warn(_("** Mercurial Distributed SCM (version %s)\n")
3518 3525 % version.get_version())
3519 3526 raise
@@ -39,21 +39,23 b' class changectx(object):'
39 39
40 40 def parents(self):
41 41 """return contexts for each parent changeset"""
42 p = self.repo.changelog.parents(self._node)
42 p = self._repo.changelog.parents(self._node)
43 43 return [ changectx(self._repo, x) for x in p ]
44 44
45 45 def children(self):
46 46 """return contexts for each child changeset"""
47 c = self.repo.changelog.children(self._node)
47 c = self._repo.changelog.children(self._node)
48 48 return [ changectx(self._repo, x) for x in c ]
49 49
50 50 def filenode(self, path):
51 51 node, flag = self._repo.manifest.find(self.changeset()[0], path)
52 52 return node
53 53
54 def filectx(self, path):
54 def filectx(self, path, fileid=None):
55 55 """get a file context from this changeset"""
56 return filectx(self._repo, path, fileid=self.filenode(path))
56 if fileid is None:
57 fileid = self.filenode(path)
58 return filectx(self._repo, path, fileid=fileid)
57 59
58 60 def filectxs(self):
59 61 """generate a file context for each file in this changeset's
@@ -77,10 +79,10 b' class filectx(object):'
77 79
78 80 if self._id:
79 81 # if given a changeset id, go ahead and look up the file
80 self._changeset = changectx(repo, self._id)
82 self._changeset = self._repo.changelog.read(self._id)
81 83 node, flag = self._repo.manifest.find(self._changeset[0], path)
82 self._node = node
83 self._filelog = self.repo.file(self._path)
84 self._filelog = self._repo.file(self._path)
85 self._filenode = node
84 86 elif self._fileid:
85 87 # else be lazy
86 88 self._filelog = self._repo.file(self._path)
@@ -97,7 +97,8 b' def clone(ui, source, dest=None, pull=Fa'
97 97
98 98 pull: always pull from source repository, even in local case
99 99
100 stream: stream from repository (fast over LAN, slow over WAN)
100 stream: stream raw data uncompressed from repository (fast over
101 LAN, slow over WAN)
101 102
102 103 rev: revision to clone up to (implies pull=True)
103 104
@@ -156,9 +157,9 b' def clone(ui, source, dest=None, pull=Fa'
156 157 # we lock here to avoid premature writing to the target
157 158 dest_lock = lock.lock(os.path.join(dest_path, ".hg", "lock"))
158 159
159 # we need to remove the (empty) data dir in dest so copyfiles
160 # can do its work
161 os.rmdir(os.path.join(dest_path, ".hg", "data"))
160 # we need to remove the (empty) data dir in dest so copyfiles
161 # can do its work
162 os.rmdir(os.path.join(dest_path, ".hg", "data"))
162 163 files = "data 00manifest.d 00manifest.i 00changelog.d 00changelog.i"
163 164 for f in files.split():
164 165 src = os.path.join(source, ".hg", f)
@@ -169,8 +170,8 b' def clone(ui, source, dest=None, pull=Fa'
169 170 if inst.errno != errno.ENOENT:
170 171 raise
171 172
172 # we need to re-init the repo after manually copying the data
173 # into it
173 # we need to re-init the repo after manually copying the data
174 # into it
174 175 dest_repo = repository(ui, dest)
175 176
176 177 else:
@@ -860,7 +860,10 b' class hgweb(object):'
860 860 or self.t("error", error="%r not found" % fname))
861 861
862 862 def do_capabilities(self, req):
863 resp = 'unbundle stream=%d' % (self.repo.revlogversion,)
863 caps = ['unbundle']
864 if self.repo.ui.configbool('server', 'uncompressed'):
865 caps.append('stream=%d' % self.repo.revlogversion)
866 resp = ' '.join(caps)
864 867 req.httphdr("application/mercurial-0.1", length=len(resp))
865 868 req.write(resp)
866 869
@@ -2204,8 +2204,11 b' class localrepository(repo.repository):'
2204 2204 return 1
2205 2205
2206 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 2211 self.ui.status(_('streaming all changes\n'))
2208 fp = remote.stream_out()
2209 2212 total_files, total_bytes = map(int, fp.readline().split(' ', 1))
2210 2213 self.ui.status(_('%d files to transfer, %s of data\n') %
2211 2214 (total_files, util.bytecount(total_bytes)))
@@ -2230,14 +2233,15 b' class localrepository(repo.repository):'
2230 2233
2231 2234 keyword arguments:
2232 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 stream can read repo formats
2236 # supported by all servers that can stream.
2238 # now, all clients that can request uncompressed clones can
2239 # read repo formats supported by all servers that can serve
2240 # them.
2237 2241
2238 2242 # if revlog format changes, client will have to check version
2239 # and format flags on "stream" capability, and stream only if
2240 # compatible.
2243 # and format flags on "stream" capability, and use
2244 # uncompressed only if compatible.
2241 2245
2242 2246 if stream and not heads and remote.capable('stream'):
2243 2247 return self.stream_in(remote)
@@ -60,8 +60,10 b' class sshserver(object):'
60 60 capabilities: space separated list of tokens
61 61 '''
62 62
63 r = "capabilities: unbundle stream=%d\n" % (self.repo.revlogversion,)
64 self.respond(r)
63 caps = ['unbundle']
64 if self.ui.configbool('server', 'uncompressed'):
65 caps.append('stream=%d' % self.repo.revlogversion)
66 self.respond("capabilities: %s\n" % (' '.join(caps),))
65 67
66 68 def do_lock(self):
67 69 '''DEPRECATED - allowing remote client to lock repo is not safe'''
@@ -40,7 +40,8 b' def walkrepo(root):'
40 40 yield x
41 41 # write manifest before changelog
42 42 meta = list(walk(root, False))
43 meta.sort(reverse=True)
43 meta.sort()
44 meta.reverse()
44 45 for x in meta:
45 46 yield x
46 47
@@ -59,6 +60,13 b' def walkrepo(root):'
59 60 def stream_out(repo, fileobj):
60 61 '''stream out all metadata files in repository.
61 62 writes to file-like object, must support write() and optional flush().'''
63
64 if not repo.ui.configbool('server', 'uncompressed'):
65 fileobj.write('1\n')
66 return
67
68 fileobj.write('0\n')
69
62 70 # get consistent snapshot of repo. lock during scan so lock not
63 71 # needed while we stream, and commits can happen.
64 72 lock = repo.lock()
@@ -209,7 +209,7 b' class ui(object):'
209 209
210 210 def expandpath(self, loc, default=None):
211 211 """Return repository location relative to cwd or from [paths]"""
212 if "://" in loc or os.path.exists(loc):
212 if "://" in loc or os.path.isdir(loc):
213 213 return loc
214 214
215 215 path = self.config("paths", loc)
@@ -29,3 +29,23 b' changeset 3:4cbb1e70196a backs out chang'
29 29 the backout changeset is a new head - do not forget to merge
30 30 (use "backout -m" if you want to auto-merge)
31 31 b: No such file or directory
32 adding a
33 adding b
34 adding c
35 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
36 adding d
37 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
38 (branch merge, don't forget to commit)
39 # backout of merge should fail
40 abort: cannot back out a merge changeset without --parent
41 # backout of merge with bad parent should fail
42 abort: cb9a9f314b8b is not a parent of b2f3bb92043e
43 # backout of non-merge with parent should fail
44 abort: cannot use --parent on non-merge changeset
45 # backout with valid parent should be ok
46 removing d
47 changeset 5:11fbd9be634c backs out changeset 4:b2f3bb92043e
48 rolling back last transaction
49 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
50 removing c
51 changeset 5:1a5f1a63bf2c backs out changeset 4:b2f3bb92043e
@@ -1,23 +1,23 b''
1 1 #!/bin/sh
2 2
3 mkdir test
3 hg init test
4 4 cd test
5 5 echo foo>foo
6 hg init
7 hg addremove
8 hg commit -m 1
9 hg verify
10 hg serve -p 20059 -d --pid-file=hg.pid
11 cat hg.pid >> $DAEMON_PIDS
6 hg commit -A -d '0 0' -m 1
7 hg --config server.uncompressed=True serve -p 20059 -d --pid-file=hg1.pid
8 cat hg1.pid >> $DAEMON_PIDS
9 hg serve -p 20060 -d --pid-file=hg2.pid
10 cat hg2.pid >> $DAEMON_PIDS
12 11 cd ..
13 12
14 13 echo % clone via stream
15 http_proxy= hg clone --stream http://localhost:20059/ copy 2>&1 | \
14 http_proxy= hg clone --uncompressed http://localhost:20059/ copy 2>&1 | \
16 15 sed -e 's/[0-9][0-9.]*/XXX/g'
17 16 cd copy
18 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 22 echo % clone via pull
23 23 http_proxy= hg clone http://localhost:20059/ copy-pull
@@ -4,7 +4,7 b' hg init a'
4 4 cd a
5 5 echo a > a
6 6 hg ci -Ama -d '1123456789 0'
7 hg serve -p 20059 -d --pid-file=hg.pid
7 hg --config server.uncompressed=True serve -p 20059 -d --pid-file=hg.pid
8 8 cat hg.pid >> $DAEMON_PIDS
9 9
10 10 cd ..
@@ -14,7 +14,7 b' cat proxy.pid >> $DAEMON_PIDS'
14 14 sleep 2
15 15
16 16 echo %% url for proxy, stream
17 http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --stream http://localhost:20059/ b | \
17 http_proxy=http://localhost:20060/ hg --config http_proxy.always=True clone --uncompressed http://localhost:20059/ b | \
18 18 sed -e 's/[0-9][0-9.]*/XXX/g'
19 19 cd b
20 20 hg verify
@@ -1,10 +1,4 b''
1 (the addremove command is deprecated; use add and remove --after instead)
2 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 2 % clone via stream
9 3 streaming all changes
10 4 XXX files to transfer, XXX bytes of data
@@ -15,6 +9,13 b' checking manifests'
15 9 crosschecking files in changesets and manifests
16 10 checking files
17 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 19 % clone via pull
19 20 requesting all changes
20 21 adding changesets
@@ -27,11 +27,13 b' hg init remote'
27 27 cd remote
28 28 echo this > foo
29 29 hg ci -A -m "init" -d "1000000 0" foo
30 echo '[server]' > .hg/hgrc
31 echo 'uncompressed = True' >> .hg/hgrc
30 32
31 33 cd ..
32 34
33 35 echo "# clone remote via stream"
34 hg clone -e ./dummyssh --stream ssh://user@dummy/remote local-stream 2>&1 | \
36 hg clone -e ./dummyssh --uncompressed ssh://user@dummy/remote local-stream 2>&1 | \
35 37 sed -e 's/[0-9][0-9.]*/XXX/g'
36 38 cd local-stream
37 39 hg verify
General Comments 0
You need to be logged in to leave comments. Login now