Commit Diff


commit - d6bda086e66c6fbfd9f3507048713d2e5942fbb2
commit + cfd633c2f10c03df8d5970fe61e67cb365af4dff
blob - f37d59860962d9ba6610ce564206b13bddd1f756
blob + 901a18c9afa705668a612325a0956997aaf7ba9e
--- lib/got_lib_object_parse.h
+++ lib/got_lib_object_parse.h
@@ -40,3 +40,5 @@ struct got_packidx;
 const struct got_error *got_object_packed_read_privsep(struct got_object **,
     struct got_repository *, struct got_pack *, struct got_packidx *, int,
     struct got_object_id *);
+const struct got_error *got_object_read_packed_commit_privsep(
+    struct got_commit_object **, struct got_object *, struct got_pack *);
blob - bd788e1cf8afe72c07db5ba44934534ace650175
blob + 7a9837d0906b4e613b5d2adf36530508388b9473
--- lib/got_lib_privsep.h
+++ lib/got_lib_privsep.h
@@ -213,6 +213,8 @@ const struct got_error *got_privsep_send_obj_req(struc
 const struct got_error *got_privsep_send_blob_req(struct imsgbuf *, int, int);
 const struct got_error *got_privsep_send_obj(struct imsgbuf *,
     struct got_object *);
+const struct got_error *got_privsep_get_imsg_obj(struct got_object **,
+    struct imsg *, struct imsgbuf *);
 const struct got_error *got_privsep_recv_obj(struct got_object **,
     struct imsgbuf *);
 const struct got_error *got_privsep_send_commit(struct imsgbuf *,
blob - a7327c30c72cf05bcb5f66bd7533321a2618c7f6
blob + f98a68d7aefb8d527e59df0042970aa88632262b
--- lib/object.c
+++ lib/object.c
@@ -365,14 +365,15 @@ got_object_commit_open(struct got_commit_object **comm
 		return got_error(GOT_ERR_OBJ_TYPE);
 
 	if (obj->flags & GOT_OBJ_FLAG_PACKED) {
-		uint8_t *buf;
-		size_t len;
-		err = extract_packed_object_to_mem(&buf, &len, obj, repo);
-		if (err)
-			return err;
-		obj->size = len;
-		err = got_object_parse_commit(commit, buf, len);
-		free(buf);
+		struct got_pack *pack;
+		pack = got_repo_get_cached_pack(repo, obj->path_packfile);
+		if (pack == NULL) {
+			err = got_repo_cache_pack(&pack, repo,
+			    obj->path_packfile, NULL);
+			if (err)
+				return err;
+		}
+		err = got_object_read_packed_commit_privsep(commit, obj, pack);
 	} else {
 		int fd;
 		err = open_loose_object(&fd, obj, repo);
blob - e65fda042d9ca8b020b2446672505c315fe8f146
blob + 823f934f9ebd17a1d15e557e8fc0bfb4fe6e554d
--- lib/object_parse.c
+++ lib/object_parse.c
@@ -712,7 +712,7 @@ request_commit(struct got_commit_object **commit, stru
 
 	ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_COMMIT].ibuf;
 
-	err = got_privsep_send_obj_req(ibuf, fd,obj);
+	err = got_privsep_send_obj_req(ibuf, fd, obj);
 	if (err)
 		return err;
 
@@ -720,6 +720,19 @@ request_commit(struct got_commit_object **commit, stru
 }
 
 const struct got_error *
+got_object_read_packed_commit_privsep(struct got_commit_object **commit,
+    struct got_object *obj, struct got_pack *pack)
+{
+	const struct got_error *err = NULL;
+
+	err = got_privsep_send_obj_req(pack->privsep_child->ibuf, -1, obj);
+	if (err)
+		return err;
+
+	return got_privsep_recv_commit(commit, pack->privsep_child->ibuf);
+}
+
+const struct got_error *
 got_object_read_commit_privsep(struct got_commit_object **commit,
     struct got_object *obj, int obj_fd, struct got_repository *repo)
 {
@@ -765,7 +778,7 @@ request_tree(struct got_tree_object **tree, struct got
 
 	ibuf = repo->privsep_children[GOT_REPO_PRIVSEP_CHILD_TREE].ibuf;
 
-	err = got_privsep_send_obj_req(ibuf, fd,obj);
+	err = got_privsep_send_obj_req(ibuf, fd, obj);
 	if (err)
 		return err;
 
blob - 74df15b8d2d97fd7e31a1761bdab804b87c5f40e
blob + 068c8e85f99c20da787c879fe813eef62ffb12ce
--- lib/privsep.c
+++ lib/privsep.c
@@ -443,6 +443,51 @@ receive_delta(struct got_delta **delta, struct imsgbuf
 	if (*delta == NULL) {
 		err = got_error_from_errno();
 		free(delta_buf);
+	}
+
+	return err;
+}
+
+const struct got_error *
+got_privsep_get_imsg_obj(struct got_object **obj, struct imsg *imsg,
+    struct imsgbuf *ibuf)
+{
+	const struct got_error *err = NULL;
+	struct got_imsg_object iobj;
+	size_t datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
+	int i;
+
+	if (datalen != sizeof(iobj))
+		return got_error(GOT_ERR_PRIVSEP_LEN);
+
+	memcpy(&iobj, imsg->data, sizeof(iobj));
+	if (iobj.ndeltas < 0 ||
+	    iobj.ndeltas > GOT_DELTA_CHAIN_RECURSION_MAX)
+		return got_error(GOT_ERR_PRIVSEP_LEN);
+
+	if (iobj.ndeltas > 0 &&
+	    (iobj.flags & GOT_OBJ_FLAG_DELTIFIED) == 0)
+		return got_error(GOT_ERR_BAD_OBJ_DATA);
+
+	*obj = calloc(1, sizeof(**obj));
+	if (*obj == NULL)
+		return got_error_from_errno();
+
+	(*obj)->type = iobj.type;
+	(*obj)->flags = iobj.flags;
+	(*obj)->hdrlen = iobj.hdrlen;
+	(*obj)->size = iobj.size;
+	/* id and path_packfile might be copied in by caller */
+	(*obj)->pack_offset = iobj.pack_offset;
+	SIMPLEQ_INIT(&(*obj)->deltas.entries);
+	for (i = 0; i < iobj.ndeltas; i++) {
+		struct got_delta *delta;
+		err = receive_delta(&delta, ibuf);
+		if (err)
+			break;
+		(*obj)->deltas.nentries++;
+		SIMPLEQ_INSERT_TAIL(&(*obj)->deltas.entries, delta,
+		    entry);
 	}
 
 	return err;
@@ -453,9 +498,7 @@ got_privsep_recv_obj(struct got_object **obj, struct i
 {
 	const struct got_error *err = NULL;
 	struct imsg imsg;
-	struct got_imsg_object iobj;
 	size_t datalen;
-	int i;
 	const size_t min_datalen =
 	    MIN(sizeof(struct got_imsg_error), sizeof(struct got_imsg_object));
 
@@ -472,45 +515,7 @@ got_privsep_recv_obj(struct got_object **obj, struct i
 		err = recv_imsg_error(&imsg, datalen);
 		break;
 	case GOT_IMSG_OBJECT:
-		if (datalen != sizeof(iobj)) {
-			err = got_error(GOT_ERR_PRIVSEP_LEN);
-			break;
-		}
-
-		memcpy(&iobj, imsg.data, sizeof(iobj));
-		if (iobj.ndeltas < 0 ||
-		    iobj.ndeltas > GOT_DELTA_CHAIN_RECURSION_MAX) {
-			err = got_error(GOT_ERR_PRIVSEP_LEN);
-			break;
-		}
-		if (iobj.ndeltas > 0 &&
-		    (iobj.flags & GOT_OBJ_FLAG_DELTIFIED) == 0) {
-			err = got_error(GOT_ERR_BAD_OBJ_DATA);
-			break;
-		}
-
-		*obj = calloc(1, sizeof(**obj));
-		if (*obj == NULL) {
-			err = got_error_from_errno();
-			break;
-		}
-
-		(*obj)->type = iobj.type;
-		(*obj)->flags = iobj.flags;
-		(*obj)->hdrlen = iobj.hdrlen;
-		(*obj)->size = iobj.size;
-		/* id and path_packfile might be copied in by caller */
-		(*obj)->pack_offset = iobj.pack_offset;
-		SIMPLEQ_INIT(&(*obj)->deltas.entries);
-		for (i = 0; i < iobj.ndeltas; i++) {
-			struct got_delta *delta;
-			err = receive_delta(&delta, ibuf);
-			if (err)
-				break;
-			(*obj)->deltas.nentries++;
-			SIMPLEQ_INSERT_TAIL(&(*obj)->deltas.entries, delta,
-			    entry);
-		}
+		err = got_privsep_get_imsg_obj(obj, &imsg, ibuf);
 		break;
 	default:
 		err = got_error(GOT_ERR_PRIVSEP_MSG);
@@ -576,6 +581,7 @@ done:
 	free(buf);
 	return err;
 }
+
 const struct got_error *
 got_privsep_recv_commit(struct got_commit_object **commit, struct imsgbuf *ibuf)
 {
blob - f243749639d228ffa0c9ee34ec70c83ce07e3b5d
blob + 19b70b7eca7c7b30d93de4b0a36aa5587df4816f
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
@@ -68,7 +68,39 @@ static const struct got_error *
 commit_request(struct imsg *imsg, struct imsgbuf *ibuf, struct got_pack *pack,
     struct got_packidx *packidx)
 {
-	return got_error(GOT_ERR_NOT_IMPL);
+	const struct got_error *err = NULL;
+	struct got_object *obj = NULL;
+	struct got_commit_object *commit = NULL;
+	uint8_t *buf;
+	size_t len;
+
+	err = got_privsep_get_imsg_obj(&obj, imsg, ibuf);
+	if (err)
+		return err;
+
+	if (obj->type != GOT_OBJ_TYPE_COMMIT)
+		return got_error(GOT_ERR_OBJ_TYPE);
+
+	err = got_packfile_extract_object_to_mem(&buf, &len, obj, pack);
+	if (err)
+		return err;
+
+	obj->size = len;
+	err = got_object_parse_commit(&commit, buf, len);
+	free(buf);
+
+	err = got_privsep_send_commit(ibuf, commit);
+	if (obj)
+		got_object_close(obj);
+	got_object_commit_close(commit);
+	if (err) {
+		if (err->code == GOT_ERR_PRIVSEP_PIPE)
+			err = NULL;
+		else
+			got_privsep_send_error(ibuf, err);
+	}
+
+	return err;
 }
 
 static const struct got_error *