@@ -87,7 +87,7 @@ struct rebase_options {
8787 REBASE_FORCE = 1 <<3 ,
8888 REBASE_INTERACTIVE_EXPLICIT = 1 <<4 ,
8989 } flags ;
90- struct strbuf git_am_opt ;
90+ struct argv_array git_am_opts ;
9191 const char * action ;
9292 int signoff ;
9393 int allow_rerere_autoupdate ;
@@ -339,7 +339,7 @@ N_("Resolve all conflicts manually, mark them as resolved with\n"
339339static int run_specific_rebase (struct rebase_options * opts )
340340{
341341 const char * argv [] = { NULL , NULL };
342- struct strbuf script_snippet = STRBUF_INIT ;
342+ struct strbuf script_snippet = STRBUF_INIT , buf = STRBUF_INIT ;
343343 int status ;
344344 const char * backend , * backend_func ;
345345
@@ -433,7 +433,9 @@ static int run_specific_rebase(struct rebase_options *opts)
433433 oid_to_hex (& opts -> restrict_revision -> object .oid ) : NULL );
434434 add_var (& script_snippet , "GIT_QUIET" ,
435435 opts -> flags & REBASE_NO_QUIET ? "" : "t" );
436- add_var (& script_snippet , "git_am_opt" , opts -> git_am_opt .buf );
436+ sq_quote_argv_pretty (& buf , opts -> git_am_opts .argv );
437+ add_var (& script_snippet , "git_am_opt" , buf .buf );
438+ strbuf_release (& buf );
437439 add_var (& script_snippet , "verbose" ,
438440 opts -> flags & REBASE_VERBOSE ? "t" : "" );
439441 add_var (& script_snippet , "diffstat" ,
@@ -756,7 +758,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
756758 struct rebase_options options = {
757759 .type = REBASE_UNSPECIFIED ,
758760 .flags = REBASE_NO_QUIET ,
759- .git_am_opt = STRBUF_INIT ,
761+ .git_am_opts = ARGV_ARRAY_INIT ,
760762 .allow_rerere_autoupdate = -1 ,
761763 .allow_empty_message = 1 ,
762764 .git_format_patch_opt = STRBUF_INIT ,
@@ -777,12 +779,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
777779 ACTION_EDIT_TODO ,
778780 ACTION_SHOW_CURRENT_PATCH ,
779781 } action = NO_ACTION ;
780- int committer_date_is_author_date = 0 ;
781- int ignore_date = 0 ;
782- int ignore_whitespace = 0 ;
783782 const char * gpg_sign = NULL ;
784- int opt_c = -1 ;
785- struct string_list whitespace = STRING_LIST_INIT_NODUP ;
786783 struct string_list exec = STRING_LIST_INIT_NODUP ;
787784 const char * rebase_merges = NULL ;
788785 int fork_point = -1 ;
@@ -804,15 +801,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
804801 {OPTION_NEGBIT , 'n' , "no-stat" , & options .flags , NULL ,
805802 N_ ("do not show diffstat of what changed upstream" ),
806803 PARSE_OPT_NOARG , NULL , REBASE_DIFFSTAT },
807- OPT_BOOL (0 , "ignore-whitespace" , & ignore_whitespace ,
808- N_ ("passed to 'git apply'" )),
809804 OPT_BOOL (0 , "signoff" , & options .signoff ,
810805 N_ ("add a Signed-off-by: line to each commit" )),
811- OPT_BOOL (0 , "committer-date-is-author-date" ,
812- & committer_date_is_author_date ,
813- N_ ("passed to 'git am'" )),
814- OPT_BOOL (0 , "ignore-date" , & ignore_date ,
815- N_ ("passed to 'git am'" )),
806+ OPT_PASSTHRU_ARGV (0 , "ignore-whitespace" , & options .git_am_opts ,
807+ NULL , N_ ("passed to 'git am'" ),
808+ PARSE_OPT_NOARG ),
809+ OPT_PASSTHRU_ARGV (0 , "committer-date-is-author-date" ,
810+ & options .git_am_opts , NULL ,
811+ N_ ("passed to 'git am'" ), PARSE_OPT_NOARG ),
812+ OPT_PASSTHRU_ARGV (0 , "ignore-date" , & options .git_am_opts , NULL ,
813+ N_ ("passed to 'git am'" ), PARSE_OPT_NOARG ),
814+ OPT_PASSTHRU_ARGV ('C' , NULL , & options .git_am_opts , N_ ("n" ),
815+ N_ ("passed to 'git apply'" ), 0 ),
816+ OPT_PASSTHRU_ARGV (0 , "whitespace" , & options .git_am_opts ,
817+ N_ ("action" ), N_ ("passed to 'git apply'" ), 0 ),
816818 OPT_BIT ('f' , "force-rebase" , & options .flags ,
817819 N_ ("cherry-pick all commits, even if unchanged" ),
818820 REBASE_FORCE ),
@@ -856,10 +858,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
856858 { OPTION_STRING , 'S' , "gpg-sign" , & gpg_sign , N_ ("key-id" ),
857859 N_ ("GPG-sign commits" ),
858860 PARSE_OPT_OPTARG , NULL , (intptr_t ) "" },
859- OPT_STRING_LIST (0 , "whitespace" , & whitespace ,
860- N_ ("whitespace" ), N_ ("passed to 'git apply'" )),
861- OPT_SET_INT ('C' , NULL , & opt_c , N_ ("passed to 'git apply'" ),
862- REBASE_AM ),
863861 OPT_BOOL (0 , "autostash" , & options .autostash ,
864862 N_ ("automatically stash/stash pop before and after" )),
865863 OPT_STRING_LIST ('x' , "exec" , & exec , N_ ("exec" ),
@@ -884,6 +882,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
884882 N_ ("rebase all reachable commits up to the root(s)" )),
885883 OPT_END (),
886884 };
885+ int i ;
887886
888887 /*
889888 * NEEDSWORK: Once the builtin rebase has been tested enough
@@ -1064,22 +1063,17 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10641063 state_dir_base , cmd_live_rebase , buf .buf );
10651064 }
10661065
1067- if (!( options .flags & REBASE_NO_QUIET ))
1068- strbuf_addstr ( & options . git_am_opt , " -q" ) ;
1069-
1070- if ( committer_date_is_author_date ) {
1071- strbuf_addstr ( & options . git_am_opt ,
1072- " --committer-date-is-author-date" );
1073- options .flags |= REBASE_FORCE ;
1066+ for ( i = 0 ; i < options .git_am_opts . argc ; i ++ ) {
1067+ const char * option = options . git_am_opts . argv [ i ] ;
1068+ if (! strcmp ( option , "--committer-date-is-author-date" ) ||
1069+ ! strcmp ( option , "--ignore-date" ) ||
1070+ ! strcmp ( option , "--whitespace=fix" ) ||
1071+ ! strcmp ( option , "--whitespace=strip" ))
1072+ options .flags |= REBASE_FORCE ;
10741073 }
10751074
1076- if (ignore_whitespace )
1077- strbuf_addstr (& options .git_am_opt , " --ignore-whitespace" );
1078-
1079- if (ignore_date ) {
1080- strbuf_addstr (& options .git_am_opt , " --ignore-date" );
1081- options .flags |= REBASE_FORCE ;
1082- }
1075+ if (!(options .flags & REBASE_NO_QUIET ))
1076+ argv_array_push (& options .git_am_opts , "-q" );
10831077
10841078 if (options .keep_empty )
10851079 imply_interactive (& options , "--keep-empty" );
@@ -1089,23 +1083,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
10891083 options .gpg_sign_opt = xstrfmt ("-S%s" , gpg_sign );
10901084 }
10911085
1092- if (opt_c >= 0 )
1093- strbuf_addf (& options .git_am_opt , " -C%d" , opt_c );
1094-
1095- if (whitespace .nr ) {
1096- int i ;
1097-
1098- for (i = 0 ; i < whitespace .nr ; i ++ ) {
1099- const char * item = whitespace .items [i ].string ;
1100-
1101- strbuf_addf (& options .git_am_opt , " --whitespace=%s" ,
1102- item );
1103-
1104- if ((!strcmp (item , "fix" )) || (!strcmp (item , "strip" )))
1105- options .flags |= REBASE_FORCE ;
1106- }
1107- }
1108-
11091086 if (exec .nr ) {
11101087 int i ;
11111088
@@ -1181,23 +1158,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
11811158 break ;
11821159 }
11831160
1184- if (options .git_am_opt .len ) {
1185- const char * p ;
1186-
1161+ if (options .git_am_opts .argc ) {
11871162 /* all am options except -q are compatible only with --am */
1188- strbuf_reset (& buf );
1189- strbuf_addbuf (& buf , & options .git_am_opt );
1190- strbuf_addch (& buf , ' ' );
1191- while ((p = strstr (buf .buf , " -q " )))
1192- strbuf_splice (& buf , p - buf .buf , 4 , " " , 1 );
1193- strbuf_trim (& buf );
1163+ for (i = options .git_am_opts .argc - 1 ; i >= 0 ; i -- )
1164+ if (strcmp (options .git_am_opts .argv [i ], "-q" ))
1165+ break ;
11941166
1195- if (is_interactive (& options ) && buf . len )
1167+ if (is_interactive (& options ) && i >= 0 )
11961168 die (_ ("error: cannot combine interactive options "
11971169 "(--interactive, --exec, --rebase-merges, "
11981170 "--preserve-merges, --keep-empty, --root + "
11991171 "--onto) with am options (%s)" ), buf .buf );
1200- if (options .type == REBASE_MERGE && buf . len )
1172+ if (options .type == REBASE_MERGE && i >= 0 )
12011173 die (_ ("error: cannot combine merge options (--merge, "
12021174 "--strategy, --strategy-option) with am options "
12031175 "(%s)" ), buf .buf );
@@ -1207,7 +1179,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
12071179 if (options .type == REBASE_PRESERVE_MERGES )
12081180 die ("cannot combine '--signoff' with "
12091181 "'--preserve-merges'" );
1210- strbuf_addstr (& options .git_am_opt , " --signoff" );
1182+ argv_array_push (& options .git_am_opts , "--signoff" );
12111183 options .flags |= REBASE_FORCE ;
12121184 }
12131185
0 commit comments