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

[PATCH 2/2] fetch: use argv_array instead of hand-building arrays

From
Jeff King <peff@peff.net>
Date
Sep 1, 2012, 11:27 UTC
Message-ID
<20120901112735.GB19163@sigill.intra.peff.net>
In-Reply-To
<20120901112251.GA11445@sigill.intra.peff.net>

Fetch invokes itself recursively when recursing into submodules or handling "fetch --multiple". In both cases, it builds the child's command line by pushing options onto a statically-sized array. In both cases, the array is currently just big enough to handle the largest possible case. However, this technique is brittle and error-prone, so let's replace it with a dynamic argv_array.

Signed-off-by: Jeff King <peff@peff.net>
---
Not very well tested by me, but hopefully it is simple enough that I
managed not to screw it up.

It may be that fetch_populated_submodules would also benefit from conversion (here I just pass in the argc and argv separately), but I didn't look.

 builtin/fetch.c | 47 +++++++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 22 deletions(-)
diff --git a/builtin/fetch.c b/builtin/fetch.c
index bb9a074..b6a8be0 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -14,6 +14,7 @@
 #include "transport.h"
 #include "submodule.h"
 #include "connected.h"
+#include "argv-array.h"
 
 static const char * const builtin_fetch_usage[] = {
 	"git fetch [<options>] [<repository> [<refspec>...]]",
@@ -841,38 +842,35 @@ static int fetch_multiple(struct string_list *list)
 	return 1;
 }
 
-static void add_options_to_argv(int *argc, const char **argv)
+static void add_options_to_argv(struct argv_array *argv)
 {
 	if (dry_run)
-		argv[(*argc)++] = "--dry-run";
+		argv_array_push(argv, "--dry-run");
 	if (prune)
-		argv[(*argc)++] = "--prune";
+		argv_array_push(argv, "--prune");
 	if (update_head_ok)
-		argv[(*argc)++] = "--update-head-ok";
+		argv_array_push(argv, "--update-head-ok");
 	if (force)
-		argv[(*argc)++] = "--force";
+		argv_array_push(argv, "--force");
 	if (keep)
-		argv[(*argc)++] = "--keep";
+		argv_array_push(argv, "--keep");
 	if (recurse_submodules == RECURSE_SUBMODULES_ON)
-		argv[(*argc)++] = "--recurse-submodules";
+		argv_array_push(argv, "--recurse-submodules");
 	else if (recurse_submodules == RECURSE_SUBMODULES_ON_DEMAND)
-		argv[(*argc)++] = "--recurse-submodules=on-demand";
+		argv_array_push(argv, "--recurse-submodules=on-demand");
 	if (verbosity >= 2)
-		argv[(*argc)++] = "-v";
+		argv_array_push(argv, "-v");
 	if (verbosity >= 1)
-		argv[(*argc)++] = "-v";
+		argv_array_push(argv, "-v");
 	else if (verbosity < 0)
-		argv[(*argc)++] = "-q";
+		argv_array_push(argv, "-q");
 
 }
 
 static int fetch_multiple(struct string_list *list)
 {
 	int i, result = 0;
-	const char *argv[12] = { "fetch", "--append" };
-	int argc = 2;
-
-	add_options_to_argv(&argc, argv);
+	struct argv_array argv = ARGV_ARRAY_INIT;
 
 	if (!append && !dry_run) {
 		int errcode = truncate_fetch_head();
@@ -880,18 +878,22 @@ static int fetch_multiple(struct string_list *list)
 			return errcode;
 	}
 
+	argv_array_pushl(&argv, "fetch", "--append", NULL);
+	add_options_to_argv(&argv);
+
 	for (i = 0; i < list->nr; i++) {
 		const char *name = list->items[i].string;
-		argv[argc] = name;
-		argv[argc + 1] = NULL;
+		argv_array_push(&argv, name);
 		if (verbosity >= 0)
 			printf(_("Fetching %s\n"), name);
-		if (run_command_v_opt(argv, RUN_GIT_CMD)) {
+		if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
 			error(_("Could not fetch %s"), name);
 			result = 1;
 		}
+		argv_array_pop(&argv);
 	}
 
+	argv_array_clear(&argv);
 	return result;
 }
 
@@ -1007,13 +1009,14 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 	}
 
 	if (!result && (recurse_submodules != RECURSE_SUBMODULES_OFF)) {
-		const char *options[10];
-		int num_options = 0;
-		add_options_to_argv(&num_options, options);
-		result = fetch_populated_submodules(num_options, options,
+		struct argv_array options = ARGV_ARRAY_INIT;
+
+		add_options_to_argv(&options);
+		result = fetch_populated_submodules(options.argc, options.argv,
 						    submodule_prefix,
 						    recurse_submodules,
 						    verbosity < 0);
+		argv_array_clear(&options);
 	}
 
 	/* All names were strdup()ed or strndup()ed */
-- 
1.7.12.rc3.8.g89db099
Previous: Jeff KingNext: Jens Lehmann
Message 20 of 26 in “Bringing a bit more sanity to $GIT_DIR/objects/info/alternates?”
  1. Junio C HamanoAug 5, 2012
  2. Michael HaggertyAug 5, 2012
  3. Junio C HamanoAug 5, 2012
  4. Jeff KingAug 7, 2012
  5. Junio C HamanoAug 6, 2012
  6. Sascha CunzAug 8, 2012
  7. Hallvard Breien FurusethAug 11, 2012
  8. Oswald BuddenhagenAug 27, 2012
  9. GC of alternate object store (was: Bringing a bit more sanity to $GIT_DIR/objects/info/alternates?)Hallvard Breien Furuseth, Aug 28, 2012
  10. Oswald BuddenhagenAug 29, 2012
  11. Junio C HamanoAug 29, 2012
  12. Oswald BuddenhagenAug 30, 2012
  13. Junio C HamanoAug 30, 2012
  14. Oswald BuddenhagenAug 31, 2012
  15. Dan JohnsonAug 31, 2012
  16. Junio C HamanoAug 31, 2012
  17. fetch --all: pass --tags/--no-tags through to each remoteDan Johnson, Sep 1, 2012
  18. Jeff KingSep 1, 2012
  19. 1/2 argv-array: add pop functionJeff King, Sep 1, 2012
  20. 2/2 fetch: use argv_array instead of hand-building arraysJeff King, Sep 1, 2012
  21. Jens LehmannSep 1, 2012
  22. submodule: use argv_array instead of hand-building arraysJens Lehmann, Sep 1, 2012
  23. Jeff KingSep 1, 2012
  24. 3/2 argv-array: fix bogus cast when freeing arrayJeff King, Sep 1, 2012
  25. [PATCHv2] fetch --all: pass --tags/--no-tags through to each remoteDan Johnson, Sep 5, 2012
  26. Junio C HamanoSep 7, 2012

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.