mv: replace src_dir with a strvec

We manually manage the src_dir array with ALLOC_GROW. Using a strvec is a little more ergonomic, and makes the memory ownership more clear. It does mean that we copy the strings (which were otherwise just pointers into the "sources" strvec), but using the same rationale as 9fcd9e4e72 (builtin/mv duplicate string list memory, 2024-05-27), it's just not enough to be worth worrying about here. As a bonus, this gets rid of some "int"s used for allocation management (though in practice these were limited to command-line sizes and thus not overflowable). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed May 30, 2024 at 02:46 UTC 64f8502b40affcb4c956c511fef7e704a88b0e25
1 file changed +4 -6
builtin/mv.c
+4 -6
@@ -197,8 +197,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
197 struct strvec submodule_gitfiles_to_free = STRVEC_INIT;
198 const char **submodule_gitfiles;
199 char *dst_w_slash = NULL;
200 - const char **src_dir = NULL;
201 - int src_dir_nr = 0, src_dir_alloc = 0;
200 + struct strvec src_dir = STRVEC_INIT;
201 enum update_mode *modes, dst_mode = 0;
202 struct stat st, dest_st;
203 struct string_list src_for_dst = STRING_LIST_INIT_DUP;
@@ -344,8 +343,7 @@ dir_check:
343 /* last - first >= 1 */
344 modes[i] |= WORKING_DIRECTORY;
345
347 - ALLOC_GROW(src_dir, src_dir_nr + 1, src_dir_alloc);
348 - src_dir[src_dir_nr++] = src;
346 + strvec_push(&src_dir, src);
347
348 n = argc + last - first;
349 REALLOC_ARRAY(modes, n);
@@ -559,7 +557,7 @@ remove_entry:
557 }
558 }
559
562 - remove_empty_src_dirs(src_dir, src_dir_nr);
560 + remove_empty_src_dirs(src_dir.v, src_dir.nr);
561
562 if (dirty_paths.nr)
563 advise_on_moving_dirty_path(&dirty_paths);
@@ -574,7 +572,7 @@ remove_entry:
572 ret = 0;
573
574 out:
577 - free(src_dir);
575 + strvec_clear(&src_dir);
576 free(dst_w_slash);
577 string_list_clear(&src_for_dst, 0);
578 string_list_clear(&dirty_paths, 0);