summaryrefslogtreecommitdiff
path: root/sys/lib/python/mercurial/streamclone.py
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@localhost>2011-05-03 11:25:13 +0000
committercinap_lenrek <cinap_lenrek@localhost>2011-05-03 11:25:13 +0000
commit458120dd40db6b4df55a4e96b650e16798ef06a0 (patch)
tree8f82685be24fef97e715c6f5ca4c68d34d5074ee /sys/lib/python/mercurial/streamclone.py
parent3a742c699f6806c1145aea5149bf15de15a0afd7 (diff)
add hg and python
Diffstat (limited to 'sys/lib/python/mercurial/streamclone.py')
-rw-r--r--sys/lib/python/mercurial/streamclone.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/sys/lib/python/mercurial/streamclone.py b/sys/lib/python/mercurial/streamclone.py
new file mode 100644
index 000000000..82cd2f730
--- /dev/null
+++ b/sys/lib/python/mercurial/streamclone.py
@@ -0,0 +1,67 @@
+# streamclone.py - streaming clone server support for mercurial
+#
+# Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import util, error
+from i18n import _
+
+from mercurial import store
+
+class StreamException(Exception):
+ def __init__(self, code):
+ Exception.__init__(self)
+ self.code = code
+ def __str__(self):
+ return '%i\n' % self.code
+
+# if server supports streaming clone, it advertises "stream"
+# capability with value that is version+flags of repo it is serving.
+# client only streams if it can read that repo format.
+
+# stream file format is simple.
+#
+# server writes out line that says how many files, how many total
+# bytes. separator is ascii space, byte counts are strings.
+#
+# then for each file:
+#
+# server writes out line that says filename, how many bytes in
+# file. separator is ascii nul, byte count is string.
+#
+# server writes out raw file data.
+
+def stream_out(repo, untrusted=False):
+ '''stream out all metadata files in repository.
+ writes to file-like object, must support write() and optional flush().'''
+
+ if not repo.ui.configbool('server', 'uncompressed', untrusted=untrusted):
+ raise StreamException(1)
+
+ entries = []
+ total_bytes = 0
+ try:
+ # get consistent snapshot of repo, lock during scan
+ lock = repo.lock()
+ try:
+ repo.ui.debug(_('scanning\n'))
+ for name, ename, size in repo.store.walk():
+ # for backwards compat, name was partially encoded
+ entries.append((store.encodedir(name), size))
+ total_bytes += size
+ finally:
+ lock.release()
+ except error.LockError:
+ raise StreamException(2)
+
+ yield '0\n'
+ repo.ui.debug(_('%d files, %d bytes to transfer\n') %
+ (len(entries), total_bytes))
+ yield '%d %d\n' % (len(entries), total_bytes)
+ for name, size in entries:
+ repo.ui.debug(_('sending %s (%d bytes)\n') % (name, size))
+ yield '%s\0%d\n' % (name, size)
+ for chunk in util.filechunkiter(repo.sopener(name), limit=size):
+ yield chunk