def handle(self): write = lambda x: self.proto.write_sideband(SIDE_BAND_CHANNEL_DATA, x) graph_walker = ProtocolGraphWalker(self, self.repo.object_store, self.repo.get_peeled) objects_iter = self.repo.fetch_objects(graph_walker.determine_wants, graph_walker, self.progress, get_tagged=self.get_tagged) # Note the fact that client is only processing responses related # to the have lines it sent, and any other data (including side- # band) will be be considered a fatal error. self._processing_have_lines = True # Did the process short-circuit (e.g. in a stateless RPC call)? Note # that the client still expects a 0-object pack in most cases. # Also, if it also happens that the object_iter is instantiated # with a graph walker with an implementation that talks over the # wire (which is this instance of this class) this will actually # iterate through everything and write things out to the wire. if len(objects_iter) == 0: return # The provided haves are processed, and it is safe to send side- # band data now. self._processing_have_lines = False self.progress(b"dul-daemon says what\n") self.progress(("counting objects: %d, done.\n" % len(objects_iter)).encode('ascii')) write_pack_objects(ProtocolFile(None, write), objects_iter) self.progress(b"how was that, then?\n") # we are done self.proto.write_pkt_line(None)
def handle(self): write = lambda x: self.proto.write_sideband(1, x) graph_walker = ProtocolGraphWalker(self, self.repo.object_store, self.repo.get_peeled) objects_iter = self.repo.fetch_objects(graph_walker.determine_wants, graph_walker, self.progress, get_tagged=self.get_tagged) # Do they want any objects? if len(objects_iter) == 0: return #self.progress("dul-daemon says what\n") self.progress("counting objects: %d, done.\n" % len(objects_iter)) write_pack_data(ProtocolFile(None, write), objects_iter, len(objects_iter)) #self.progress("how was that, then?\n") size = self.backend.repository.info.size msg = _('Repository size: %s\n' % filesizeformat(size)) logging.info(msg) self.progress(msg) # we are done self.proto.write("0000")
def handle(self): def determine_wants(heads): keys = heads.keys() if keys: self.proto.write_pkt_line("%s %s\x00%s\n" % ( heads[keys[0]], keys[0], self.capabilities())) for k in keys[1:]: self.proto.write_pkt_line("%s %s\n" % (heads[k], k)) # i'm done.. self.proto.write("0000") # Now client will either send "0000", meaning that it doesnt want to pull. # or it will start sending want want want commands want = self.proto.read_pkt_line() if want == None: return [] want, self.client_capabilities = extract_capabilities(want) want_revs = [] while want and want[:4] == 'want': want_revs.append(want[5:45]) want = self.proto.read_pkt_line() return want_revs progress = lambda x: self.proto.write_sideband(2, x) write = lambda x: self.proto.write_sideband(1, x) class ProtocolGraphWalker(object): def __init__(self, proto): self.proto = proto self._last_sha = None def ack(self, have_ref): self.proto.write_pkt_line("ACK %s continue\n" % have_ref) def next(self): have = self.proto.read_pkt_line() if have[:4] == 'have': return have[5:45] #if have[:4] == 'done': # return None if self._last_sha: # Oddness: Git seems to resend the last ACK, without the "continue" statement self.proto.write_pkt_line("ACK %s\n" % self._last_sha) # The exchange finishes with a NAK self.proto.write_pkt_line("NAK\n") graph_walker = ProtocolGraphWalker(self.proto) (num_objects, objects_iter) = self.backend.fetch_objects(determine_wants, graph_walker, progress) progress("dul-daemon says what\n") progress("counting objects: %d, done.\n" % len(objects)) write_pack_data(ProtocolFile(None, write), objects_iter, num_objects) progress("how was that, then?\n") # we are done self.proto.write("0000")
def handle(self): def write(x): return self.proto.write_sideband(SIDE_BAND_CHANNEL_DATA, x) graph_walker = _ProtocolGraphWalker( self, self.repo.object_store, self.repo.get_peeled, self.repo.refs.get_symrefs, ) wants = [] def wants_wrapper(refs, **kwargs): wants.extend(graph_walker.determine_wants(refs, **kwargs)) return wants objects_iter = self.repo.fetch_objects( wants_wrapper, graph_walker, self.progress, get_tagged=self.get_tagged, ) # Note the fact that client is only processing responses related # to the have lines it sent, and any other data (including side- # band) will be be considered a fatal error. self._processing_have_lines = True # Did the process short-circuit (e.g. in a stateless RPC call)? Note # that the client still expects a 0-object pack in most cases. # Also, if it also happens that the object_iter is instantiated # with a graph walker with an implementation that talks over the # wire (which is this instance of this class) this will actually # iterate through everything and write things out to the wire. if len(wants) == 0: return # The provided haves are processed, and it is safe to send side- # band data now. self._processing_have_lines = False if not graph_walker.handle_done( not self.has_capability(CAPABILITY_NO_DONE), self._done_received ): return self.progress( ("counting objects: %d, done.\n" % len(objects_iter)).encode("ascii") ) write_pack_objects(ProtocolFile(None, write), objects_iter) # we are done self.proto.write_pkt_line(None)
def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress=None): """Retrieve a pack from a git smart server. :param determine_wants: Callback that returns list of commits to fetch :param graph_walker: Object with next() and ack(). :param pack_data: Callback called for each bit of data in the pack :param progress: Callback for progress reports (strings) """ from dulwich.repo import Repo with closing(Repo(path)) as r: objects_iter = r.fetch_objects(determine_wants, graph_walker, progress) # Did the process short-circuit (e.g. in a stateless RPC call)? Note # that the client still expects a 0-object pack in most cases. if objects_iter is None: return write_pack_objects(ProtocolFile(None, pack_data), objects_iter)
def handle(self): write = lambda x: self.proto.write_sideband(1, x) graph_walker = ProtocolGraphWalker(self, self.repo.object_store, self.repo.get_peeled) objects_iter = self.repo.fetch_objects( graph_walker.determine_wants, graph_walker, self.progress, get_tagged=self.get_tagged) # Did the process short-circuit (e.g. in a stateless RPC call)? Note # that the client still expects a 0-object pack in most cases. if len(objects_iter) == 0: return self.progress("dul-daemon says what\n") self.progress("counting objects: %d, done.\n" % len(objects_iter)) write_pack_objects(ProtocolFile(None, write), objects_iter) self.progress("how was that, then?\n") # we are done self.proto.write("0000")