Beispiel #1
0
    def add_objects(self, objects):
        """Add a set of objects to this object store.

        :param objects: Iterable over a list of objects.
        """
        if len(objects) == 0:
            return
        f, commit = self.add_pack()
        write_pack_data(f, objects, len(objects))
        commit()
Beispiel #2
0
    def send_pack(self, path, determine_wants, generate_pack_contents):
        """Upload a pack to a remote repository.

        :param path: Repository path
        :param generate_pack_contents: Function that can return the shas of the 
            objects to upload.
        """
        refs, server_capabilities = self.read_refs()
        changed_refs = determine_wants(refs)
        if not changed_refs:
            self.proto.write_pkt_line(None)
            return {}
        want = []
        have = []
        sent_capabilities = False
        for changed_ref, new_sha1 in changed_refs.iteritems():
            old_sha1 = refs.get(changed_ref, "0" * 40)
            if sent_capabilities:
                self.proto.write_pkt_line("%s %s %s" % (old_sha1, new_sha1, changed_ref))
            else:
                self.proto.write_pkt_line("%s %s %s\0%s" % (old_sha1, new_sha1, changed_ref, self.capabilities()))
                sent_capabilities = True
            want.append(new_sha1)
            if old_sha1 != "0"*40:
                have.append(old_sha1)
        self.proto.write_pkt_line(None)
        objects = generate_pack_contents(want, have)
        (entries, sha) = write_pack_data(self.proto.write_file(), objects, len(objects))
        self.proto.write(sha)
        
        # read the final confirmation sha
        client_sha = self.proto.read(20)
        # TODO : do something here that doesn't break
        #if not client_sha in (None, sha):
        # print "warning: local %s and server %s differ" % (sha_to_hex(sha), sha_to_hex(client_sha))
            
        return changed_refs
Beispiel #3
0
    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)

        # Do they want any objects?
        if num_objects == 0:
            return

        progress("dul-daemon says what\n")
        progress("counting objects: %d, done.\n" % num_objects)
        write_pack_data(ProtocolFile(None, write), objects_iter, num_objects)
        progress("how was that, then?\n")
        # we are done
        self.proto.write("0000")