@@ -696,63 +696,57 @@ void load_builtin_commands(const char *prefix, struct cmdnames *cmds)
696696}
697697
698698#ifdef STRIP_EXTENSION
699- static void strip_extension (const char * * argv )
699+ static void strip_extension (struct strvec * args )
700700{
701701 size_t len ;
702702
703- if (strip_suffix (argv [0 ], STRIP_EXTENSION , & len ))
704- argv [0 ] = xmemdupz (argv [0 ], len );
703+ if (strip_suffix (args -> v [0 ], STRIP_EXTENSION , & len )) {
704+ char * stripped = xmemdupz (args -> v [0 ], len );
705+ strvec_replace (args , 0 , stripped );
706+ free (stripped );
707+ }
705708}
706709#else
707710#define strip_extension (cmd )
708711#endif
709712
710- static void handle_builtin (int argc , const char * * argv )
713+ static void handle_builtin (struct strvec * args )
711714{
712- struct strvec args = STRVEC_INIT ;
713- const char * * argv_copy = NULL ;
714715 const char * cmd ;
715716 struct cmd_struct * builtin ;
716717
717- strip_extension (argv );
718- cmd = argv [0 ];
718+ strip_extension (args );
719+ cmd = args -> v [0 ];
719720
720721 /* Turn "git cmd --help" into "git help --exclude-guides cmd" */
721- if (argc > 1 && !strcmp (argv [1 ], "--help" )) {
722- int i ;
723-
724- argv [1 ] = argv [0 ];
725- argv [0 ] = cmd = "help" ;
726-
727- for (i = 0 ; i < argc ; i ++ ) {
728- strvec_push (& args , argv [i ]);
729- if (!i )
730- strvec_push (& args , "--exclude-guides" );
731- }
722+ if (args -> nr > 1 && !strcmp (args -> v [1 ], "--help" )) {
723+ const char * exclude_guides_arg [] = { "--exclude-guides" };
724+
725+ strvec_replace (args , 1 , args -> v [0 ]);
726+ strvec_replace (args , 0 , "help" );
727+ cmd = "help" ;
728+ strvec_splice (args , 2 , 0 , exclude_guides_arg ,
729+ ARRAY_SIZE (exclude_guides_arg ));
730+ }
732731
733- argc ++ ;
732+ builtin = get_builtin (cmd );
733+ if (builtin ) {
734+ const char * * argv_copy = NULL ;
735+ int ret ;
734736
735737 /*
736738 * `run_builtin()` will modify the argv array, so we need to
737739 * create a shallow copy such that we can free all of its
738740 * strings.
739741 */
740- CALLOC_ARRAY ( argv_copy , argc + 1 );
741- COPY_ARRAY (argv_copy , args . v , argc );
742+ if ( args -> nr )
743+ DUP_ARRAY (argv_copy , args -> v , args -> nr + 1 );
742744
743- argv = argv_copy ;
744- }
745-
746- builtin = get_builtin (cmd );
747- if (builtin ) {
748- int ret = run_builtin (builtin , argc , argv , the_repository );
749- strvec_clear (& args );
745+ ret = run_builtin (builtin , args -> nr , argv_copy , the_repository );
746+ strvec_clear (args );
750747 free (argv_copy );
751748 exit (ret );
752749 }
753-
754- strvec_clear (& args );
755- free (argv_copy );
756750}
757751
758752static void execv_dashed_external (const char * * argv )
@@ -815,7 +809,7 @@ static int run_argv(struct strvec *args)
815809 * process.
816810 */
817811 if (!done_alias )
818- handle_builtin (args -> nr , args -> v );
812+ handle_builtin (args );
819813 else if (get_builtin (args -> v [0 ])) {
820814 struct child_process cmd = CHILD_PROCESS_INIT ;
821815 int i ;
@@ -916,8 +910,10 @@ int cmd_main(int argc, const char **argv)
916910 * that one cannot handle it.
917911 */
918912 if (skip_prefix (cmd , "git-" , & cmd )) {
919- argv [0 ] = cmd ;
920- handle_builtin (argc , argv );
913+ strvec_push (& args , cmd );
914+ strvec_pushv (& args , argv + 1 );
915+ handle_builtin (& args );
916+ strvec_clear (& args );
921917 die (_ ("cannot handle %s as a builtin" ), cmd );
922918 }
923919
0 commit comments