url_match = re.match(
'%s(?:%s%s)?%s' % (protocol, host, port, path), remote, re.I)
if url_match:
- assert(url_match.group(1) in ('ssh', 'bup', 'file'))
+ if not url_match.group(1) in ('ssh', 'bup', 'file'):
+ raise ClientError, 'unexpected protocol: %s' % url_match.group(1)
return url_match.group(1,3,4,5)
else:
rs = remote.split(':', 1)
if is_reverse:
self.pout = os.fdopen(3, 'rb')
self.pin = os.fdopen(4, 'wb')
+ self.conn = Conn(self.pout, self.pin)
else:
if self.protocol in ('ssh', 'file'):
try:
self.p = ssh.connect(self.host, self.port, 'server')
self.pout = self.p.stdout
self.pin = self.p.stdin
+ self.conn = Conn(self.pout, self.pin)
except OSError, e:
raise ClientError, 'connect: %s' % e, sys.exc_info()[2]
elif self.protocol == 'bup':
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.sock.connect((self.host, self.port or 1982))
- self.pout = self.sock.makefile('rb')
- self.pin = self.sock.makefile('wb')
- self.conn = Conn(self.pout, self.pin)
+ self.sock.connect((self.host, atoi(self.port) or 1982))
+ self.sockw = self.sock.makefile('wb')
+ self.conn = DemuxConn(self.sock.fileno(), self.sockw)
if self.dir:
self.dir = re.sub(r'[\r\n]', ' ', self.dir)
if create:
def close(self):
if self.conn and not self._busy:
self.conn.write('quit\n')
- if self.pin and self.pout:
+ if self.pin:
self.pin.close()
- while self.pout.read(65536):
- pass
+ if self.sock and self.sockw:
+ self.sockw.close()
+ self.sock.shutdown(socket.SHUT_WR)
+ if self.conn:
+ self.conn.close()
+ if self.pout:
self.pout.close()
if self.sock:
self.sock.close()
self.sync_index(idx)
git.auto_midx(self.cachedir)
-
def sync_index(self, name):
#debug1('requesting %r\n' % name)
self.check_busy()
mkdirp(self.cachedir)
+ fn = os.path.join(self.cachedir, name)
+ if os.path.exists(fn):
+ msg = "won't request existing .idx, try `bup bloom --check %s`" % fn
+ raise ClientError(msg)
self.conn.write('send-index %s\n' % name)
n = struct.unpack('!I', self.conn.read(4))[0]
assert(n)
- fn = os.path.join(self.cachedir, name)
- f = open(fn + '.tmp', 'w')
- count = 0
- progress('Receiving index from server: %d/%d\r' % (count, n))
- for b in chunkyreader(self.conn, n):
- f.write(b)
- count += len(b)
+ with atomically_replaced_file(fn, 'w') as f:
+ count = 0
progress('Receiving index from server: %d/%d\r' % (count, n))
- progress('Receiving index from server: %d/%d, done.\n' % (count, n))
- self.check_ok()
- f.close()
- os.rename(fn + '.tmp', fn)
+ for b in chunkyreader(self.conn, n):
+ f.write(b)
+ count += len(b)
+ qprogress('Receiving index from server: %d/%d\r' % (count, n))
+ progress('Receiving index from server: %d/%d, done.\n' % (count, n))
+ self.check_ok()
def _make_objcache(self):
return git.PackIdxList(self.cachedir)
debug2('%s\n' % line)
if line.startswith('index '):
idx = line[6:]
- debug1('client: received index suggestion: %s\n' % idx)
+ debug1('client: received index suggestion: %s\n'
+ % git.shorten_hash(idx))
suggested.append(idx)
else:
assert(line.endswith('.idx'))
- debug1('client: completed writing pack, idx: %s\n' % line)
+ debug1('client: completed writing pack, idx: %s\n'
+ % git.shorten_hash(line))
suggested.append(line)
self.check_ok()
if ob:
self._busy = None
+ idx = None
for idx in suggested:
self.sync_index(idx)
git.auto_midx(self.cachedir)
self.conn.write('%s\n' % ob)
return idx
- def new_packwriter(self):
+ def new_packwriter(self, compression_level = 1):
self.check_busy()
def _set_busy():
self._busy = 'receive-objects-v2'
suggest_packs = self._suggest_packs,
onopen = _set_busy,
onclose = self._not_busy,
- ensure_busy = self.ensure_busy)
+ ensure_busy = self.ensure_busy,
+ compression_level = compression_level)
def read_ref(self, refname):
self.check_busy()
class PackWriter_Remote(git.PackWriter):
def __init__(self, conn, objcache_maker, suggest_packs,
onopen, onclose,
- ensure_busy):
+ ensure_busy,
+ compression_level=1):
git.PackWriter.__init__(self, objcache_maker)
self.file = conn
self.filename = 'remote socket'
return id
def abort(self):
- raise GitError("don't know how to abort remote pack writing")
+ raise ClientError("don't know how to abort remote pack writing")
def _raw_write(self, datalist, sha):
assert(self.file)
sha,
struct.pack('!I', crc),
data))
- (self._bwcount, self._bwtime) = \
- _raw_write_bwlimit(self.file, outbuf, self._bwcount, self._bwtime)
- self.outbytes += len(data) - 20 - 4 # Don't count sha1+crc
+ try:
+ (self._bwcount, self._bwtime) = _raw_write_bwlimit(
+ self.file, outbuf, self._bwcount, self._bwtime)
+ except IOError, e:
+ raise ClientError, e, sys.exc_info()[2]
+ self.outbytes += len(data)
self.count += 1
if self.file.has_input():