# HG changeset patch # User Scott Chacon # Date 1240948011 25200 # Node ID 7046d792dfcd983f328c28605d498eea30198207 # Parent c13c5f8e03fd9cbeb3a513c63bf6054e25c57501 fix bug where it was not writing the git object names properly properly gathers list of needed shas to create packfile, updates server on send-pack next: create and send packfile diff -r c13c5f8e03fd -r 7046d792dfcd dulwich/client.py --- a/dulwich/client.py Tue Apr 28 11:27:35 2009 -0700 +++ b/dulwich/client.py Tue Apr 28 12:46:51 2009 -0700 @@ -105,7 +105,7 @@ refs[ref] = sha return refs, server_capabilities - def send_pack(self, path, generate_pack_contents): + def send_pack(self, path, get_changed_refs, generate_pack_contents): """Upload a pack to a remote repository. :param path: Repository path @@ -114,9 +114,7 @@ """ print 'SEND PACK' refs, server_capabilities = self.read_refs() - print refs - print server_capabilities - changed_refs = [] # FIXME + changed_refs = get_changed_refs(refs) if not changed_refs: print 'got here - nooo' self.proto.write_pkt_line(None) @@ -132,8 +130,8 @@ if changed_ref[0] != "0"*40: have.append(changed_ref[0]) self.proto.write_pkt_line(None) - shas = generate_pack_contents(want, have, None) - write_pack_data(self.write, shas, len(shas)) + shas = generate_pack_contents(want, have) + #write_pack_data(self.write, shas, len(shas)) def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress): """Retrieve a pack from a git smart server. @@ -197,13 +195,13 @@ self.host = host super(TCPGitClient, self).__init__(lambda: _fileno_can_read(self._socket.fileno()), self.rfile.read, self.wfile.write, *args, **kwargs) - def send_pack(self, path, generate_pack_contents): + def send_pack(self, path, changed_refs, generate_pack_contents): """Send a pack to a remote host. :param path: Path of the repository on the remote host """ self.proto.send_cmd("git-receive-pack", path, "host=%s" % self.host) - super(TCPGitClient, self).send_pack(path, generate_pack_contents) + super(TCPGitClient, self).send_pack(path, changed_refs, generate_pack_contents) def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress): """Fetch a pack from the remote host. @@ -238,9 +236,9 @@ self.proc.stdin.flush() return GitClient(lambda: _fileno_can_read(self.proc.stdout.fileno()), read_fn, write_fn, *args, **kwargs) - def send_pack(self, path, generate_pack_contents): + def send_pack(self, path, changed_refs, generate_pack_contents): client = self._connect("git-receive-pack", path) - client.send_pack(path, generate_pack_contents) + client.send_pack(path, changed_refs, generate_pack_contents) def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress): @@ -293,10 +291,10 @@ self._args = args self._kwargs = kwargs - def send_pack(self, path, generate_pack_contents): + def send_pack(self, path, changed_refs, generate_pack_contents): remote = get_ssh_vendor().connect_ssh(self.host, ["git-receive-pack '%s'" % path], port=self.port) client = GitClient(lambda: _fileno_can_read(remote.proc.stdout.fileno()), remote.recv, remote.send, *self._args, **self._kwargs) - client.send_pack(path, generate_pack_contents) + client.send_pack(path, changed_refs, generate_pack_contents) def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress): remote = get_ssh_vendor().connect_ssh(self.host, ["git-upload-pack '%s'" % path], port=self.port) diff -r c13c5f8e03fd -r 7046d792dfcd dulwich/repo.py --- a/dulwich/repo.py Tue Apr 28 11:27:35 2009 -0700 +++ b/dulwich/repo.py Tue Apr 28 12:46:51 2009 -0700 @@ -361,6 +361,7 @@ commit_data += 'committer ' + commit['committer'] + "\n" commit_data += "\n" commit_data += commit['message'] + print commit_data sha = self.write_object('commit', commit_data) return sha @@ -391,7 +392,7 @@ object_dir = os.path.join(self.path, OBJECTDIR, git_hex_sha[0:2]) if not os.path.exists(object_dir): os.mkdir(object_dir) - object_path = os.path.join(object_dir, git_hex_sha[2:38]) + object_path = os.path.join(object_dir, git_hex_sha[2:]) data = zlib.compress(raw_data) open(object_path, 'w').write(data) # write the object return git_hex_sha diff -r c13c5f8e03fd -r 7046d792dfcd git_handler.py --- a/git_handler.py Tue Apr 28 11:27:35 2009 -0700 +++ b/git_handler.py Tue Apr 28 12:46:51 2009 -0700 @@ -154,8 +154,9 @@ p_rev = parent.rev() hgsha = hex(parent.node()) git_sha = self.map_git_get(hgsha) - if not git_sha: - self.export_hg_commit(self, p_rev) + if not p_rev == -1: + if not git_sha: + self.export_hg_commit(p_rev) ctx = self.repo.changectx(rev) tree_sha = self.write_git_tree(ctx) @@ -176,7 +177,8 @@ for parent in parents: hgsha = hex(parent.node()) git_sha = self.map_git_get(hgsha) - commit['parents'].append(git_sha) + if git_sha: + commit['parents'].append(git_sha) commit_sha = self.git.write_commit_hash(commit) # writing new blobs to git self.map_set(commit_sha, phgsha) @@ -253,17 +255,49 @@ def upload_pack(self, remote_name): git_url = self.remote_name_to_url(remote_name) client, path = self.get_transport_and_path(git_url) + changed = self.get_changed_refs genpack = self.generate_pack_contents try: - client.send_pack(path, genpack) + client.send_pack(path, changed, genpack) # TODO : self.git.set_remote_refs(refs, remote_name) except: raise - - def generate_pack_contents(self, want, have, none): - print "WANT: " + str(want) - print "HAVE: " + str(have) - print "NONE: " + str(none) + + # TODO : for now, we'll just push all heads + # * we should have specified push, tracking branches and --all + # takes a dict of refs:shas from the server and returns what should be + # pushed up + def get_changed_refs(self, refs): + keys = refs.keys() + if not keys: + return None + changed = [] + for ref_name in keys: + parts = ref_name.split('/') + if parts[0] == 'refs': # strip off 'refs/heads' + if parts[1] == 'heads': + head = "/".join([v for v in parts[2:]]) + print ref_name + print head + local_ref = self.git.ref(ref_name) + if local_ref: + if not local_ref == refs[ref_name]: + changed.append((refs[ref_name], local_ref, ref_name)) + return changed + + # takes a list of shas the server wants and shas the server has + # and generates a list of commit shas we need to push up + def generate_pack_contents(self, want, have): + graph_walker = SimpleFetchGraphWalker(want, self.git.get_parents) + next = graph_walker.next() + shas = [] + while next: + if next in have: + graph_walker.ack(next) + else: + shas.append(next) + next = graph_walker.next() + return shas def fetch_pack(self, remote_name): git_url = self.remote_name_to_url(remote_name)