[WIP PATCH] revision-walking: allow iterating revisions multiple times

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



---
Hi,

On Mon, Aug 22, 2011 at 03:22:31PM -0700, Junio C Hamano wrote:
> Heiko Voigt <hvoigt@xxxxxxxxxx> writes:
> 
> > Junio since you are one person listed in the api docs could you maybe
> > quickly explain to me what this flag is used for?
> 
> It is used in order to avoid walking the object we have walked already.
> 
> Which in turn means that once you walk chain of objects, unless you
> remember the ones you walked and clear the marks after you are done, you
> cannot walk the object chain for unrelated purposes.  See how functions
> like get_merge_bases_many() walk portions of graph for their own purpose
> and then avoid disrupting others by calling clear_commit_marks(). The use
> of TMP_MARK (and its clearing after the function is done with the marked
> objects) in remove_duplicate_parents() serve the same purpose.

What do you think about this approach ? Its not yet correctly collecting
revisions for all situations but it fixes the demonstrated test failure.

 revision.c  |   24 ++++++++++++++++++++++++
 revision.h  |    3 +++
 submodule.c |    3 +++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/revision.c b/revision.c
index c46cfaa..e374c4a 100644
--- a/revision.c
+++ b/revision.c
@@ -500,6 +500,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
 				continue;
 			p->object.flags |= SEEN;
 			commit_list_insert_by_date_cached(p, list, cached_base, cache_ptr);
+			if (revs->fill_reset_list)
+				add_object_array(&p->object, NULL, &revs->walked);
 		}
 		return 0;
 	}
@@ -527,6 +529,8 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit,
 		if (!(p->object.flags & SEEN)) {
 			p->object.flags |= SEEN;
 			commit_list_insert_by_date_cached(p, list, cached_base, cache_ptr);
+			if (revs->fill_reset_list)
+				add_object_array(&p->object, NULL, &revs->walked);
 		}
 		if (revs->first_parent_only)
 			break;
@@ -1950,6 +1954,23 @@ static void set_children(struct rev_info *revs)
 	}
 }
 
+void reset_revision_walk(struct rev_info *revs)
+{
+	int nr = revs->walked.nr;
+	struct object_array_entry *e = revs->walked.objects;
+
+	/* reset the seen flags set by prepare_revision_walk */
+	while (--nr >= 0) {
+		struct object *o = e->item;
+		o->flags &= ~(ALL_REV_FLAGS);
+		e++;
+	}
+	free(revs->walked.objects);
+	revs->walked.nr = 0;
+	revs->walked.alloc = 0;
+	revs->walked.objects = NULL;
+}
+
 int prepare_revision_walk(struct rev_info *revs)
 {
 	int nr = revs->pending.nr;
@@ -1964,6 +1985,9 @@ int prepare_revision_walk(struct rev_info *revs)
 		if (commit) {
 			if (!(commit->object.flags & SEEN)) {
 				commit->object.flags |= SEEN;
+				if (revs->fill_reset_list)
+					add_object_array(&commit->object, NULL,
+							 &revs->walked);
 				commit_list_insert_by_date(commit, &revs->commits);
 			}
 		}
diff --git a/revision.h b/revision.h
index 3d64ada..6a0fa99 100644
--- a/revision.h
+++ b/revision.h
@@ -28,6 +28,7 @@ struct rev_info {
 	/* Starting list */
 	struct commit_list *commits;
 	struct object_array pending;
+	struct object_array walked;
 
 	/* Parents of shown commits */
 	struct object_array boundary_commits;
@@ -72,6 +73,7 @@ struct rev_info {
 			bisect:1,
 			ancestry_path:1,
 			first_parent_only:1;
+	unsigned int	fill_reset_list:1;
 
 	/* Diff flags */
 	unsigned int	diff:1,
@@ -169,6 +171,7 @@ extern void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ct
 				 const char * const usagestr[]);
 extern int handle_revision_arg(const char *arg, struct rev_info *revs,int flags,int cant_be_filename);
 
+extern void reset_revision_walk(struct rev_info *revs);
 extern int prepare_revision_walk(struct rev_info *revs);
 extern struct commit *get_revision(struct rev_info *revs);
 extern char *get_revision_mark(const struct rev_info *revs, const struct commit *commit);
diff --git a/submodule.c b/submodule.c
index dc95498..410d8e4 100644
--- a/submodule.c
+++ b/submodule.c
@@ -441,6 +441,7 @@ static int inspect_superproject_commits(unsigned char new_sha1[20], const char *
 
 	strbuf_addf(&remotes_arg, "--remotes=%s", remotes_name);
 	init_revisions(&rev, NULL);
+	rev.fill_reset_list = 1;
 	sha1_copy = xstrdup(sha1_to_hex(new_sha1));
 	argv[1] = sha1_copy;
 	argv[3] = remotes_arg.buf;
@@ -451,6 +452,8 @@ static int inspect_superproject_commits(unsigned char new_sha1[20], const char *
 	while ((commit = get_revision(&rev)) && do_continue)
 		do_continue = commit_need_pushing(commit, commit->parents, func, data);
 
+
+	reset_revision_walk(&rev);
 	free(sha1_copy);
 	strbuf_release(&remotes_arg);
 
-- 
1.7.6.553.g84dc

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]