##// END OF EJS Templates
strip: make repair.strip transactional to avoid repository corruption...
strip: make repair.strip transactional to avoid repository corruption Uses a transaction instance from the local repository to journal the truncation of revlog files, such that if a strip only partially completes, hg recover will be able to finish the truncate of all the files. The potential unbundling of changes that have been backed up to be restored later will, in case of an error, have to be unbundled manually. The difference is that it will be possible to recover the repository state so the unbundle can actually succeed.

File last commit:

r7875:553aa0cb default
r8073:e8a28556 default
Show More
sshserver.py
211 lines | 6.1 KiB | text/x-python | PythonLexer
Vadim Gelfer
fix comment.
r2399 # sshserver.py - ssh protocol server support for mercurial
Vadim Gelfer
refactor ssh server.
r2396 #
Thomas Arendsen Hein
Updated copyright notices and add "and others" to "hg version"
r4635 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
Vadim Gelfer
update copyrights.
r2859 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
Vadim Gelfer
refactor ssh server.
r2396 #
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Matt Mackall
Simplify i18n imports
r3891 from i18n import _
Joel Rosdahl
Expand import * to allow Pyflakes to find problems
r6211 from node import bin, hex
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 import os, streamclone, sys, tempfile, util, hook
Vadim Gelfer
refactor ssh server.
r2396
class sshserver(object):
def __init__(self, ui, repo):
self.ui = ui
self.repo = repo
self.lock = None
self.fin = sys.stdin
self.fout = sys.stdout
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 hook.redirect(True)
Vadim Gelfer
refactor ssh server.
r2396 sys.stdout = sys.stderr
# Prevent insertion/deletion of CRs
util.set_binary(self.fin)
util.set_binary(self.fout)
def getarg(self):
argline = self.fin.readline()[:-1]
arg, l = argline.split()
val = self.fin.read(int(l))
return arg, val
def respond(self, v):
self.fout.write("%d\n" % len(v))
self.fout.write(v)
self.fout.flush()
def serve_forever(self):
while self.serve_one(): pass
sys.exit(0)
def serve_one(self):
cmd = self.fin.readline()[:-1]
if cmd:
impl = getattr(self, 'do_' + cmd, None)
if impl: impl()
Vadim Gelfer
merge change to ssh protocol.
r2397 else: self.respond("")
Vadim Gelfer
refactor ssh server.
r2396 return cmd != ''
Eric Hopper
Adding changegroupsubset and lookup to ssh protocol so pull -r and...
r3446 def do_lookup(self):
arg, key = self.getarg()
assert arg == 'key'
Eric Hopper
sshrepo: add passing of lookup exceptions
r3447 try:
r = hex(self.repo.lookup(key))
success = 1
except Exception,inst:
r = str(inst)
success = 0
self.respond("%s %s\n" % (success, r))
Eric Hopper
Adding changegroupsubset and lookup to ssh protocol so pull -r and...
r3446
Vadim Gelfer
refactor ssh server.
r2396 def do_heads(self):
h = self.repo.heads()
self.respond(" ".join(map(hex, h)) + "\n")
Matt Mackall
Initial implementation of hello command for ssh
r2419 def do_hello(self):
'''the hello command returns a set of lines describing various
interesting things about the server, in an RFC822-like format.
Currently the only one defined is "capabilities", which
consists of a line in the form:
capabilities: space separated list of tokens
'''
Eric Hopper
Adding changegroupsubset and lookup to ssh protocol so pull -r and...
r3446 caps = ['unbundle', 'lookup', 'changegroupsubset']
Vadim Gelfer
rename stream hgrc option to compressed.
r2622 if self.ui.configbool('server', 'uncompressed'):
Matt Mackall
revlog: simplify revlog version handling...
r4258 caps.append('stream=%d' % self.repo.changelog.version)
Vadim Gelfer
clone: disable stream support on server side by default....
r2621 self.respond("capabilities: %s\n" % (' '.join(caps),))
Matt Mackall
Initial implementation of hello command for ssh
r2419
Vadim Gelfer
refactor ssh server.
r2396 def do_lock(self):
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 '''DEPRECATED - allowing remote client to lock repo is not safe'''
Vadim Gelfer
refactor ssh server.
r2396 self.lock = self.repo.lock()
self.respond("")
def do_unlock(self):
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 '''DEPRECATED'''
Vadim Gelfer
refactor ssh server.
r2396 if self.lock:
self.lock.release()
self.lock = None
self.respond("")
def do_branches(self):
arg, nodes = self.getarg()
nodes = map(bin, nodes.split(" "))
r = []
for b in self.repo.branches(nodes):
r.append(" ".join(map(hex, b)) + "\n")
self.respond("".join(r))
def do_between(self):
arg, pairs = self.getarg()
pairs = [map(bin, p.split("-")) for p in pairs.split(" ")]
r = []
for b in self.repo.between(pairs):
r.append(" ".join(map(hex, b)) + "\n")
self.respond("".join(r))
def do_changegroup(self):
nodes = []
arg, roots = self.getarg()
nodes = map(bin, roots.split(" "))
cg = self.repo.changegroup(nodes, 'serve')
while True:
d = cg.read(4096)
if not d:
break
self.fout.write(d)
self.fout.flush()
Eric Hopper
Adding changegroupsubset and lookup to ssh protocol so pull -r and...
r3446 def do_changegroupsubset(self):
argmap = dict([self.getarg(), self.getarg()])
bases = [bin(n) for n in argmap['bases'].split(' ')]
heads = [bin(n) for n in argmap['heads'].split(' ')]
cg = self.repo.changegroupsubset(bases, heads, 'serve')
while True:
d = cg.read(4096)
if not d:
break
self.fout.write(d)
self.fout.flush()
Vadim Gelfer
refactor ssh server.
r2396 def do_addchangegroup(self):
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 '''DEPRECATED'''
Vadim Gelfer
refactor ssh server.
r2396 if not self.lock:
self.respond("not locked")
return
self.respond("")
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 r = self.repo.addchangegroup(self.fin, 'serve', self.client_url())
Vadim Gelfer
refactor ssh server.
r2396 self.respond(str(r))
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 def client_url(self):
client = os.environ.get('SSH_CLIENT', '').split(' ', 1)[0]
return 'remote:ssh:' + client
Thomas Arendsen Hein
Whitespace/Tab cleanup
r3223
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 def do_unbundle(self):
their_heads = self.getarg()[1].split()
def check_heads():
heads = map(hex, self.repo.heads())
return their_heads == [hex('force')] or their_heads == heads
# fail early if possible
if not check_heads():
self.respond(_('unsynced changes'))
return
self.respond('')
# write bundle data to temporary file because it can be big
Thomas Arendsen Hein
sshserver: Don't try to close fp if mkstemp failed
r6563 tempname = fp = None
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 try:
fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
fp = os.fdopen(fd, 'wb+')
count = int(self.fin.readline())
while count:
fp.write(self.fin.read(count))
count = int(self.fin.readline())
was_locked = self.lock is not None
if not was_locked:
self.lock = self.repo.lock()
try:
if not check_heads():
# someone else committed/pushed/unbundled while we
# were transferring data
self.respond(_('unsynced changes'))
return
self.respond('')
# push can proceed
fp.seek(0)
Vadim Gelfer
hooks: add url to changegroup, incoming, prechangegroup, pretxnchangegroup hooks...
r2673 r = self.repo.addchangegroup(fp, 'serve', self.client_url())
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439 self.respond(str(r))
finally:
if not was_locked:
self.lock.release()
self.lock = None
finally:
Thomas Arendsen Hein
sshserver: Don't try to close fp if mkstemp failed
r6563 if fp is not None:
fp.close()
if tempname is not None:
os.unlink(tempname)
Vadim Gelfer
extend network protocol to stop clients from locking servers...
r2439
Vadim Gelfer
add support for streaming clone....
r2612 def do_stream_out(self):
Dirkjan Ochtman
make streamclone.stream_out() a generator
r6925 try:
for chunk in streamclone.stream_out(self.repo):
self.fout.write(chunk)
self.fout.flush()
except streamclone.StreamException, inst:
self.fout.write(str(inst))
self.fout.flush()