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

Re: [PATCH] Add git-bundle: move objects and references by archive

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Feb 22, 2007, 20:25 UTC
Message-ID
<Pine.LNX.4.63.0702222119010.22628@wbgn013.biozentrum.uni-wuerzburg.de>
In-Reply-To
<7vy7mqdklr.fsf@assigned-by-dhcp.cox.net>
Hi,
On Thu, 22 Feb 2007, Junio C Hamano wrote:
Show 10 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> >> The only worry I would have is if that exact number is too large
> >> that you cannot pass them sensibly in argv[].
> >
> > I thought there is only a limitation in bash?
> 
> I am sure kernel folks on the list would correct me, but my
> understanding is that is execve(2) limitation and you would get
> E2BIG.
Okay. So how about this (on top of my previous fixup):

-- snipsnap -- [PATCH] git-bundle: avoid fork() in verify_bundle()

We can use the revision walker easily for checking if the prerequisites are met, instead of fork()ing off a rev-list, which would list only the first unmet prerequisite.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
 builtin-bundle.c |   75 ++++++++++++++++++++++++++++++++++-------------------
 1 files changed, 48 insertions(+), 27 deletions(-)
diff --git a/builtin-bundle.c b/builtin-bundle.c
index 521bbda..4ac06f9 100644
--- a/builtin-bundle.c
+++ b/builtin-bundle.c
@@ -19,7 +19,7 @@ static const char bundle_signature[] = "# v2 git bundle\n";
 
 struct ref_list {
 	unsigned int nr, alloc;
-	struct {
+	struct ref_list_entry {
 		unsigned char sha1[20];
 		char *name;
 	} *list;
@@ -167,33 +167,54 @@ static int verify_bundle(struct bundle_header *header)
 	 * to be verbose about the errors
 	 */
 	struct ref_list *p = &header->prerequisites;
-	char **argv;
-	int pid, out, i, ret = 0;
-	char buffer[1024];
+	struct rev_info revs;
+	const char *argv[] = {NULL, "--all"};
+	struct object_array refs;
+	struct commit *commit;
+	int i, ret = 0, req_nr;
+	const char *message = "The bundle requires these lacking revs:";
 
-	argv = xmalloc((p->nr + 4) * sizeof(const char *));
-	argv[0] = "rev-list";
-	argv[1] = "--not";
-	argv[2] = "--all";
-	for (i = 0; i < p->nr; i++)
-		argv[i + 3] = xstrdup(sha1_to_hex(p->list[i].sha1));
-	argv[p->nr + 3] = NULL;
-	out = -1;
-	pid = fork_with_pipe((const char **)argv, NULL, &out);
-	if (pid < 0)
-		return error("Could not fork rev-list");
-	while (read_string(out, buffer, sizeof(buffer)) > 0)
-		; /* do nothing */
-	close(out);
-	for (i = 0; i < p->nr; i++)
-		free(argv[i + 3]);
-	free(argv);
-
-	while (waitpid(pid, &i, 0) < 0)
-		if (errno != EINTR)
-			return -1;
-	if (!ret && (!WIFEXITED(i) || WEXITSTATUS(i)))
-		return error("At least one prerequisite is lacking.");
+	init_revisions(&revs, NULL);
+	for (i = 0; i < p->nr; i++) {
+		struct ref_list_entry *e = p->list + i;
+		struct object *o = parse_object(e->sha1);
+		if (o) {
+			o->flags |= BOUNDARY_SHOW;
+			add_pending_object(&revs, o, e->name);
+			continue;
+		}
+		if (++ret == 1)
+			error(message);
+		error("%s %s", sha1_to_hex(e->sha1), e->name);
+	}
+	if (revs.pending.nr == 0)
+		return ret;
+	req_nr = revs.pending.nr;
+	setup_revisions(2, argv, &revs, NULL);
+
+	memset(&refs, 0, sizeof(struct object_array));
+	for (i = 0; i < revs.pending.nr; i++) {
+		struct object_array_entry *e = revs.pending.objects + i;
+		add_object_array(e->item, e->name, &refs);
+	}
+
+	prepare_revision_walk(&revs);
+
+	i = req_nr;
+	while (i && (commit = get_revision(&revs)))
+		if (commit->object.flags & BOUNDARY_SHOW)
+			i--;
+
+	for (i = 0; i < req_nr; i++)
+		if (!(refs.objects[i].item->flags & SHOWN)) {
+			if (++ret == 1)
+				error(message);
+			error("%s %s", sha1_to_hex(refs.objects[i].item->sha1),
+				refs.objects[i].name);
+		}
+
+	for (i = 0; i < refs.nr; i++)
+		clear_commit_marks((struct commit *)refs.objects[i].item, -1);
 
 	return ret;
 }
-- 
1.5.0.1.2214.gf22e-dirty
Previous: Junio C HamanoNext: Johannes Schindelin
Message 18 of 28 in “Add git-bundle: move objects and references by archive”
  1. Add git-bundle: move objects and references by archiveJohannes Schindelin, Feb 22, 2007
  2. Nicolas PitreFeb 22, 2007
  3. Johannes SchindelinFeb 22, 2007
  4. Simon 'corecode' SchubertFeb 22, 2007
  5. Nicolas PitreFeb 22, 2007
  6. Johannes SchindelinFeb 22, 2007
  7. Simon 'corecode' SchubertFeb 22, 2007
  8. Johannes SchindelinFeb 22, 2007
  9. Nicolas PitreFeb 22, 2007
  10. Johannes SchindelinFeb 22, 2007
  11. Nicolas PitreFeb 22, 2007
  12. Junio C HamanoFeb 22, 2007
  13. Junio C HamanoFeb 22, 2007
  14. Johannes SchindelinFeb 22, 2007
  15. Junio C HamanoFeb 22, 2007
  16. Johannes SchindelinFeb 22, 2007
  17. Junio C HamanoFeb 22, 2007
  18. Johannes SchindelinFeb 22, 2007
  19. Johannes SchindelinFeb 22, 2007
  20. Mark LevedahlFeb 23, 2007
  21. Junio C HamanoFeb 23, 2007
  22. Johannes SixtFeb 22, 2007
  23. git-bundle: assorted fixesJohannes Schindelin, Feb 22, 2007
  24. Mark LevedahlFeb 23, 2007
  25. Johannes SchindelinFeb 23, 2007
  26. Mark LevedahlFeb 23, 2007
  27. Johannes SchindelinFeb 23, 2007
  28. Mark LevedahlFeb 23, 2007

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.