Commit Diff


commit - e1380e2807453e7f6feedf4b930146b511620427
commit + 0a618912c7bba9bfab2be331204824e4bba303c3
blob - 6f44f1ef778cf17b70dc0b2fb6bc9ae2a49a0ff3
blob + cd5bce6f2ef11d44d4fdf5b929d094051d59464c
--- libexec/got-read-pack/got-read-pack.c
+++ libexec/got-read-pack/got-read-pack.c
@@ -1019,7 +1019,8 @@ recv_object_ids(struct got_object_idset *idset, struct
 }
 
 static const struct got_error *
-recv_object_id_queue(struct got_object_id_queue *queue, struct imsgbuf *ibuf)
+recv_object_id_queue(struct got_object_id_queue *queue,
+    struct got_object_idset *queued_ids, struct imsgbuf *ibuf)
 {
 	const struct got_error *err = NULL;
 	int done = 0;
@@ -1037,6 +1038,9 @@ recv_object_id_queue(struct got_object_id_queue *queue
 				return err;
 			memcpy(&qid->id, &ids[i], sizeof(qid->id));
 			STAILQ_INSERT_TAIL(queue, qid, entry);
+			err = got_object_idset_add(queued_ids, &qid->id, NULL);
+			if (err)
+				return err;
 		}
 	}
 
@@ -1362,7 +1366,7 @@ enumeration_request(struct imsg *imsg, struct imsgbuf 
 	struct got_commit_object *commit = NULL;
 	struct got_object_id *tree_id = NULL;
 	size_t totlen = 0;
-	struct got_object_idset *idset;
+	struct got_object_idset *idset, *queued_ids = NULL;
 	int i, idx, have_all_entries = 1;
 	struct enumerated_tree *trees = NULL;
 	size_t ntrees = 0, nalloc = 16;
@@ -1379,7 +1383,13 @@ enumeration_request(struct imsg *imsg, struct imsgbuf 
 		goto done;
 	}
 
-	err = recv_object_id_queue(&commit_ids, ibuf);
+	queued_ids = got_object_idset_alloc();
+	if (queued_ids == NULL) {
+		err = got_error_from_errno("got_object_idset_alloc");
+		goto done;
+	}
+
+	err = recv_object_id_queue(&commit_ids, queued_ids, ibuf);
 	if (err)
 		goto done;
 
@@ -1497,6 +1507,8 @@ enumeration_request(struct imsg *imsg, struct imsgbuf 
 			STAILQ_FOREACH(pid, parents, entry) {
 				if (got_object_idset_contains(idset, &pid->id))
 					continue;
+				if (got_object_idset_contains(queued_ids, &pid->id))
+					continue;
 				err = got_object_qid_alloc_partial(&qid);
 				if (err)
 					goto done;
@@ -1528,6 +1540,8 @@ done:
 	got_object_id_queue_free(&commit_ids);
 	if (idset)
 		got_object_idset_free(idset);
+	if (queued_ids)
+		got_object_idset_free(queued_ids);
 	for (i = 0; i < ntrees; i++) {
 		struct enumerated_tree *tree = &trees[i];
 		free(tree->buf);