Subject: Re: [PATCH 00/14] WIP Partial clone part 3: clone, fetch, fetch-pack, upload-pack, and tests

From: Junio C Hamano <[email-masked]>
Date: Sat, 04 Nov 2017 00:12:25 +0900

Jeff Hostetler <[email-masked]> writes:

> From: Jeff Hostetler <[email-masked]>
>
> This is part 3 of 3 for partial clone.
> It assumes that part 1 [1] and part 2 [2] are in place.

Thanks.  As planned these replaced the partial clone with size
filter thing from Jonathan.  The resulting integration passed the
tests locally so I pushed it out.

By the way, the enhancement in this series made to list-objects.c
had a bit of interaction with the last round of Stefan's "describe
blob" topic when both were merged to 'pu'.  I think I resolved it
correctly, but the merge resolution can use extra sets of eyes.

diff --cc list-objects.c
index 5390a7440d,07a92f35fe..e05de01af1
--- a/list-objects.c
+++ b/list-objects.c
@@@ -220,32 -183,20 +220,22 @@@ static void add_pending_tree(struct rev
  	add_pending_object(revs, &tree->object, "");
  }
  
- static void do_traverse(struct rev_info *revs,
- 			show_commit_fn show_commit,
- 			show_object_fn show_object,
- 			void *show_data,
- 			filter_object_fn filter_fn,
- 			void *filter_data)
+ static void traverse_trees_and_blobs(struct rev_info *revs,
+ 				     struct strbuf *base,
+ 				     show_object_fn show_object,
 -				     void *data)
++				     void *show_data,
++				     filter_object_fn filter_fn,
++				     void *filter_data)
  {
  	int i;
- 	struct commit *commit;
- 	struct strbuf base;
  
- 	strbuf_init(&base, PATH_MAX);
- 	while ((commit = get_revision(revs)) != NULL) {
- 		/*
- 		 * an uninteresting boundary commit may not have its tree
- 		 * parsed yet, but we are not going to show them anyway
- 		 */
- 		if (commit->tree)
- 			add_pending_tree(revs, commit->tree);
- 		show_commit(commit, show_data);
- 	}
 -	assert(base->len == 0);
 -
++	assert(!base->len);
  	for (i = 0; i < revs->pending.nr; i++) {
  		struct object_array_entry *pending = revs->pending.objects + i;
  		struct object *obj = pending->item;
  		const char *name = pending->name;
  		const char *path = pending->path;
++
  		if (obj->flags & (UNINTERESTING | SEEN))
  			continue;
  		if (obj->type == OBJ_TAG) {
@@@ -257,47 -208,41 +247,76 @@@
  			path = "";
  		if (obj->type == OBJ_TREE) {
  			process_tree(revs, (struct tree *)obj, show_object,
- 				     &base, path, show_data,
 -				     base, path, data);
++				     base, path, show_data,
 +				     filter_fn, filter_data);
  			continue;
  		}
  		if (obj->type == OBJ_BLOB) {
  			process_blob(revs, (struct blob *)obj, show_object,
- 				     &base, path, show_data,
 -				     base, path, data);
++				     base, path, show_data,
 +				     filter_fn, filter_data);
  			continue;
  		}
  		die("unknown pending object %s (%s)",
  		    oid_to_hex(&obj->oid), name);
  	}
  	object_array_clear(&revs->pending);
- 	strbuf_release(&base);
+ }
+ 
 -void traverse_commit_list(struct rev_info *revs,
 -			  show_commit_fn show_commit,
 -			  show_object_fn show_object,
 -			  void *data)
++static void do_traverse(struct rev_info *revs,
++			show_commit_fn show_commit,
++			show_object_fn show_object,
++			void *show_data,
++			filter_object_fn filter_fn,
++			void *filter_data)
+ {
+ 	struct commit *commit;
+ 	struct strbuf csp; /* callee's scratch pad */
 -	strbuf_init(&csp, PATH_MAX);
+ 
++	strbuf_init(&csp, PATH_MAX);
+ 	while ((commit = get_revision(revs)) != NULL) {
+ 		/*
+ 		 * an uninteresting boundary commit may not have its tree
+ 		 * parsed yet, but we are not going to show them anyway
+ 		 */
+ 		if (commit->tree)
+ 			add_pending_tree(revs, commit->tree);
 -		show_commit(commit, data);
++		show_commit(commit, show_data);
+ 		if (revs->tree_blobs_in_commit_order)
 -			traverse_trees_and_blobs(revs, &csp, show_object, data);
++			traverse_trees_and_blobs(revs, &csp,
++						 show_object, show_data,
++						 filter_fn, filter_data);
+ 	}
 -	traverse_trees_and_blobs(revs, &csp, show_object, data);
 -
++	traverse_trees_and_blobs(revs, &csp,
++				 show_object, show_data,
++				 filter_fn, filter_data);
+ 	strbuf_release(&csp);
  }
 +
 +void traverse_commit_list(struct rev_info *revs,
 +			  show_commit_fn show_commit,
 +			  show_object_fn show_object,
 +			  void *show_data)
 +{
 +	do_traverse(revs, show_commit, show_object, show_data, NULL, NULL);
 +}
 +
 +void traverse_commit_list_filtered(
 +	struct list_objects_filter_options *filter_options,
 +	struct rev_info *revs,
 +	show_commit_fn show_commit,
 +	show_object_fn show_object,
 +	void *show_data,
 +	struct oidset *omitted)
 +{
 +	filter_object_fn filter_fn = NULL;
 +	filter_free_fn filter_free_fn = NULL;
 +	void *filter_data = NULL;
 +
 +	filter_data = list_objects_filter__init(omitted, filter_options,
 +						&filter_fn, &filter_free_fn);
 +	do_traverse(revs, show_commit, show_object, show_data,
 +		    filter_fn, filter_data);
 +	if (filter_data && filter_free_fn)
 +		filter_free_fn(filter_data);
 +}