git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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

From
Heiko Voigt <hvoigt@hvoigt.net>
Date
Aug 24, 2011, 21:14 UTC
Message-ID
<20110824211431.GH45292@book.hvoigt.net>
In-Reply-To
<7vd3fxulw8.fsf@alter.siamese.dyndns.org>

--- Hi,

On Mon, Aug 22, 2011 at 03:22:31PM -0700, Junio C Hamano wrote:
Show 14 quoted lines
> Heiko Voigt <hvoigt@hvoigt.net> 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
Previous: Heiko VoigtNext: Junio C Hamano
Message 9 of 20 in “push: submodule support”
  1. 0/2 push: submodule supportFredrik Gustafsson, Aug 19, 2011
  2. 1/2 push: Don't push a repository with unpushed submodulesFredrik Gustafsson, Aug 19, 2011
  3. Junio C HamanoAug 19, 2011
  4. Junio C HamanoAug 20, 2011
  5. Junio C HamanoAug 21, 2011
  6. Heiko VoigtAug 22, 2011
  7. Junio C HamanoAug 22, 2011
  8. Heiko VoigtAug 23, 2011
  9. revision-walking: allow iterating revisions multiple timesHeiko Voigt, Aug 24, 2011
  10. Junio C HamanoAug 24, 2011
  11. 2/2 demonstrate format-callback used in combined diffJunio C Hamano, Aug 20, 2011
  12. Fredrik GustafssonAug 21, 2011
  13. 2/2 push: teach --recurse-submodules the on-demand optionFredrik Gustafsson, Aug 19, 2011
  14. Junio C HamanoSep 2, 2011
  15. Junio C HamanoOct 17, 2011
  16. Jens LehmannOct 18, 2011
  17. Phil HordDec 12, 2011
  18. Jens LehmannDec 12, 2011
  19. Phil HordDec 12, 2011
  20. Jens LehmannDec 13, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.