diff options
Diffstat (limited to 'reachable.c')
| -rw-r--r-- | reachable.c | 55 | 
1 files changed, 42 insertions, 13 deletions
diff --git a/reachable.c b/reachable.c index 3fc6b1d320..bf7970661f 100644 --- a/reachable.c +++ b/reachable.c @@ -7,11 +7,25 @@  #include "revision.h"  #include "reachable.h"  #include "cache-tree.h" +#include "progress.h" + +struct connectivity_progress { +	struct progress *progress; +	unsigned long count; +}; + +static void update_progress(struct connectivity_progress *cp) +{ +	cp->count++; +	if ((cp->count & 1023) == 0) +		display_progress(cp->progress, cp->count); +}  static void process_blob(struct blob *blob,  			 struct object_array *p,  			 struct name_path *path, -			 const char *name) +			 const char *name, +			 struct connectivity_progress *cp)  {  	struct object *obj = &blob->object; @@ -20,6 +34,7 @@ static void process_blob(struct blob *blob,  	if (obj->flags & SEEN)  		return;  	obj->flags |= SEEN; +	update_progress(cp);  	/* Nothing to do, really .. The blob lookup was the important part */  } @@ -34,7 +49,8 @@ static void process_gitlink(const unsigned char *sha1,  static void process_tree(struct tree *tree,  			 struct object_array *p,  			 struct name_path *path, -			 const char *name) +			 const char *name, +			 struct connectivity_progress *cp)  {  	struct object *obj = &tree->object;  	struct tree_desc desc; @@ -46,6 +62,7 @@ static void process_tree(struct tree *tree,  	if (obj->flags & SEEN)  		return;  	obj->flags |= SEEN; +	update_progress(cp);  	if (parse_tree(tree) < 0)  		die("bad tree object %s", sha1_to_hex(obj->sha1));  	add_object(obj, p, path, name); @@ -57,23 +74,25 @@ static void process_tree(struct tree *tree,  	while (tree_entry(&desc, &entry)) {  		if (S_ISDIR(entry.mode)) -			process_tree(lookup_tree(entry.sha1), p, &me, entry.path); +			process_tree(lookup_tree(entry.sha1), p, &me, entry.path, cp);  		else if (S_ISGITLINK(entry.mode))  			process_gitlink(entry.sha1, p, &me, entry.path);  		else -			process_blob(lookup_blob(entry.sha1), p, &me, entry.path); +			process_blob(lookup_blob(entry.sha1), p, &me, entry.path, cp);  	}  	free(tree->buffer);  	tree->buffer = NULL;  } -static void process_tag(struct tag *tag, struct object_array *p, const char *name) +static void process_tag(struct tag *tag, struct object_array *p, +			const char *name, struct connectivity_progress *cp)  {  	struct object *obj = &tag->object;  	if (obj->flags & SEEN)  		return;  	obj->flags |= SEEN; +	update_progress(cp);  	if (parse_tag(tag) < 0)  		die("bad tag object %s", sha1_to_hex(obj->sha1)); @@ -81,15 +100,18 @@ static void process_tag(struct tag *tag, struct object_array *p, const char *nam  		add_object(tag->tagged, p, NULL, name);  } -static void walk_commit_list(struct rev_info *revs) +static void walk_commit_list(struct rev_info *revs, +			     struct connectivity_progress *cp)  {  	int i;  	struct commit *commit;  	struct object_array objects = OBJECT_ARRAY_INIT;  	/* Walk all commits, process their trees */ -	while ((commit = get_revision(revs)) != NULL) -		process_tree(commit->tree, &objects, NULL, ""); +	while ((commit = get_revision(revs)) != NULL) { +		process_tree(commit->tree, &objects, NULL, "", cp); +		update_progress(cp); +	}  	/* Then walk all the pending objects, recursively processing them too */  	for (i = 0; i < revs->pending.nr; i++) { @@ -97,15 +119,15 @@ static void walk_commit_list(struct rev_info *revs)  		struct object *obj = pending->item;  		const char *name = pending->name;  		if (obj->type == OBJ_TAG) { -			process_tag((struct tag *) obj, &objects, name); +			process_tag((struct tag *) obj, &objects, name, cp);  			continue;  		}  		if (obj->type == OBJ_TREE) { -			process_tree((struct tree *)obj, &objects, NULL, name); +			process_tree((struct tree *)obj, &objects, NULL, name, cp);  			continue;  		}  		if (obj->type == OBJ_BLOB) { -			process_blob((struct blob *)obj, &objects, NULL, name); +			process_blob((struct blob *)obj, &objects, NULL, name, cp);  			continue;  		}  		die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name); @@ -191,8 +213,11 @@ static void add_cache_refs(struct rev_info *revs)  		add_cache_tree(active_cache_tree, revs);  } -void mark_reachable_objects(struct rev_info *revs, int mark_reflog) +void mark_reachable_objects(struct rev_info *revs, int mark_reflog, +			    struct progress *progress)  { +	struct connectivity_progress cp; +  	/*  	 * Set up revision parsing, and mark us as being interested  	 * in all object types, not just commits. @@ -211,11 +236,15 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog)  	if (mark_reflog)  		for_each_reflog(add_one_reflog, revs); +	cp.progress = progress; +	cp.count = 0; +  	/*  	 * Set up the revision walk - this will move all commits  	 * from the pending list to the commit walking list.  	 */  	if (prepare_revision_walk(revs))  		die("revision walk setup failed"); -	walk_commit_list(revs); +	walk_commit_list(revs, &cp); +	display_progress(cp.progress, cp.count);  }  | 
