@@ -88,7 +88,7 @@ struct rebase_options {
88
88
REBASE_FORCE = 1 <<3 ,
89
89
REBASE_INTERACTIVE_EXPLICIT = 1 <<4 ,
90
90
} flags ;
91
- struct strbuf git_am_opt ;
91
+ struct argv_array git_am_opts ;
92
92
const char * action ;
93
93
int signoff ;
94
94
int allow_rerere_autoupdate ;
@@ -340,7 +340,7 @@ N_("Resolve all conflicts manually, mark them as resolved with\n"
340
340
static int run_specific_rebase (struct rebase_options * opts )
341
341
{
342
342
const char * argv [] = { NULL , NULL };
343
- struct strbuf script_snippet = STRBUF_INIT ;
343
+ struct strbuf script_snippet = STRBUF_INIT , buf = STRBUF_INIT ;
344
344
int status ;
345
345
const char * backend , * backend_func ;
346
346
@@ -434,7 +434,9 @@ static int run_specific_rebase(struct rebase_options *opts)
434
434
oid_to_hex (& opts -> restrict_revision -> object .oid ) : NULL );
435
435
add_var (& script_snippet , "GIT_QUIET" ,
436
436
opts -> flags & REBASE_NO_QUIET ? "" : "t" );
437
- add_var (& script_snippet , "git_am_opt" , opts -> git_am_opt .buf );
437
+ sq_quote_argv_pretty (& buf , opts -> git_am_opts .argv );
438
+ add_var (& script_snippet , "git_am_opt" , buf .buf );
439
+ strbuf_release (& buf );
438
440
add_var (& script_snippet , "verbose" ,
439
441
opts -> flags & REBASE_VERBOSE ? "t" : "" );
440
442
add_var (& script_snippet , "diffstat" ,
@@ -775,7 +777,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
775
777
struct rebase_options options = {
776
778
.type = REBASE_UNSPECIFIED ,
777
779
.flags = REBASE_NO_QUIET ,
778
- .git_am_opt = STRBUF_INIT ,
780
+ .git_am_opts = ARGV_ARRAY_INIT ,
779
781
.allow_rerere_autoupdate = -1 ,
780
782
.allow_empty_message = 1 ,
781
783
.git_format_patch_opt = STRBUF_INIT ,
@@ -796,12 +798,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
796
798
ACTION_EDIT_TODO ,
797
799
ACTION_SHOW_CURRENT_PATCH ,
798
800
} action = NO_ACTION ;
799
- int committer_date_is_author_date = 0 ;
800
- int ignore_date = 0 ;
801
- int ignore_whitespace = 0 ;
802
801
const char * gpg_sign = NULL ;
803
- int opt_c = -1 ;
804
- struct string_list whitespace = STRING_LIST_INIT_NODUP ;
805
802
struct string_list exec = STRING_LIST_INIT_NODUP ;
806
803
const char * rebase_merges = NULL ;
807
804
int fork_point = -1 ;
@@ -823,15 +820,20 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
823
820
{OPTION_NEGBIT , 'n' , "no-stat" , & options .flags , NULL ,
824
821
N_ ("do not show diffstat of what changed upstream" ),
825
822
PARSE_OPT_NOARG , NULL , REBASE_DIFFSTAT },
826
- OPT_BOOL (0 , "ignore-whitespace" , & ignore_whitespace ,
827
- N_ ("passed to 'git apply'" )),
828
823
OPT_BOOL (0 , "signoff" , & options .signoff ,
829
824
N_ ("add a Signed-off-by: line to each commit" )),
830
- OPT_BOOL (0 , "committer-date-is-author-date" ,
831
- & committer_date_is_author_date ,
832
- N_ ("passed to 'git am'" )),
833
- OPT_BOOL (0 , "ignore-date" , & ignore_date ,
834
- N_ ("passed to 'git am'" )),
825
+ OPT_PASSTHRU_ARGV (0 , "ignore-whitespace" , & options .git_am_opts ,
826
+ NULL , N_ ("passed to 'git am'" ),
827
+ PARSE_OPT_NOARG ),
828
+ OPT_PASSTHRU_ARGV (0 , "committer-date-is-author-date" ,
829
+ & options .git_am_opts , NULL ,
830
+ N_ ("passed to 'git am'" ), PARSE_OPT_NOARG ),
831
+ OPT_PASSTHRU_ARGV (0 , "ignore-date" , & options .git_am_opts , NULL ,
832
+ N_ ("passed to 'git am'" ), PARSE_OPT_NOARG ),
833
+ OPT_PASSTHRU_ARGV ('C' , NULL , & options .git_am_opts , N_ ("n" ),
834
+ N_ ("passed to 'git apply'" ), 0 ),
835
+ OPT_PASSTHRU_ARGV (0 , "whitespace" , & options .git_am_opts ,
836
+ N_ ("action" ), N_ ("passed to 'git apply'" ), 0 ),
835
837
OPT_BIT ('f' , "force-rebase" , & options .flags ,
836
838
N_ ("cherry-pick all commits, even if unchanged" ),
837
839
REBASE_FORCE ),
@@ -875,10 +877,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
875
877
{ OPTION_STRING , 'S' , "gpg-sign" , & gpg_sign , N_ ("key-id" ),
876
878
N_ ("GPG-sign commits" ),
877
879
PARSE_OPT_OPTARG , NULL , (intptr_t ) "" },
878
- OPT_STRING_LIST (0 , "whitespace" , & whitespace ,
879
- N_ ("whitespace" ), N_ ("passed to 'git apply'" )),
880
- OPT_SET_INT ('C' , NULL , & opt_c , N_ ("passed to 'git apply'" ),
881
- REBASE_AM ),
882
880
OPT_BOOL (0 , "autostash" , & options .autostash ,
883
881
N_ ("automatically stash/stash pop before and after" )),
884
882
OPT_STRING_LIST ('x' , "exec" , & exec , N_ ("exec" ),
@@ -903,6 +901,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
903
901
N_ ("rebase all reachable commits up to the root(s)" )),
904
902
OPT_END (),
905
903
};
904
+ int i ;
906
905
907
906
/*
908
907
* NEEDSWORK: Once the builtin rebase has been tested enough
@@ -1087,22 +1086,27 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1087
1086
state_dir_base , cmd_live_rebase , buf .buf );
1088
1087
}
1089
1088
1090
- if (!(options .flags & REBASE_NO_QUIET ))
1091
- strbuf_addstr (& options .git_am_opt , " -q" );
1092
-
1093
- if (committer_date_is_author_date ) {
1094
- strbuf_addstr (& options .git_am_opt ,
1095
- " --committer-date-is-author-date" );
1096
- options .flags |= REBASE_FORCE ;
1089
+ for (i = 0 ; i < options .git_am_opts .argc ; i ++ ) {
1090
+ const char * option = options .git_am_opts .argv [i ], * p ;
1091
+ if (!strcmp (option , "--committer-date-is-author-date" ) ||
1092
+ !strcmp (option , "--ignore-date" ) ||
1093
+ !strcmp (option , "--whitespace=fix" ) ||
1094
+ !strcmp (option , "--whitespace=strip" ))
1095
+ options .flags |= REBASE_FORCE ;
1096
+ else if (skip_prefix (option , "-C" , & p )) {
1097
+ while (* p )
1098
+ if (!isdigit (* (p ++ )))
1099
+ die (_ ("switch `C' expects a "
1100
+ "numerical value" ));
1101
+ } else if (skip_prefix (option , "--whitespace=" , & p )) {
1102
+ if (* p && strcmp (p , "warn" ) && strcmp (p , "nowarn" ) &&
1103
+ strcmp (p , "error" ) && strcmp (p , "error-all" ))
1104
+ die ("Invalid whitespace option: '%s'" , p );
1105
+ }
1097
1106
}
1098
1107
1099
- if (ignore_whitespace )
1100
- strbuf_addstr (& options .git_am_opt , " --ignore-whitespace" );
1101
-
1102
- if (ignore_date ) {
1103
- strbuf_addstr (& options .git_am_opt , " --ignore-date" );
1104
- options .flags |= REBASE_FORCE ;
1105
- }
1108
+ if (!(options .flags & REBASE_NO_QUIET ))
1109
+ argv_array_push (& options .git_am_opts , "-q" );
1106
1110
1107
1111
if (options .keep_empty )
1108
1112
imply_interactive (& options , "--keep-empty" );
@@ -1112,23 +1116,6 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1112
1116
options .gpg_sign_opt = xstrfmt ("-S%s" , gpg_sign );
1113
1117
}
1114
1118
1115
- if (opt_c >= 0 )
1116
- strbuf_addf (& options .git_am_opt , " -C%d" , opt_c );
1117
-
1118
- if (whitespace .nr ) {
1119
- int i ;
1120
-
1121
- for (i = 0 ; i < whitespace .nr ; i ++ ) {
1122
- const char * item = whitespace .items [i ].string ;
1123
-
1124
- strbuf_addf (& options .git_am_opt , " --whitespace=%s" ,
1125
- item );
1126
-
1127
- if ((!strcmp (item , "fix" )) || (!strcmp (item , "strip" )))
1128
- options .flags |= REBASE_FORCE ;
1129
- }
1130
- }
1131
-
1132
1119
if (exec .nr ) {
1133
1120
int i ;
1134
1121
@@ -1204,23 +1191,18 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1204
1191
break ;
1205
1192
}
1206
1193
1207
- if (options .git_am_opt .len ) {
1208
- const char * p ;
1209
-
1194
+ if (options .git_am_opts .argc ) {
1210
1195
/* all am options except -q are compatible only with --am */
1211
- strbuf_reset (& buf );
1212
- strbuf_addbuf (& buf , & options .git_am_opt );
1213
- strbuf_addch (& buf , ' ' );
1214
- while ((p = strstr (buf .buf , " -q " )))
1215
- strbuf_splice (& buf , p - buf .buf , 4 , " " , 1 );
1216
- strbuf_trim (& buf );
1196
+ for (i = options .git_am_opts .argc - 1 ; i >= 0 ; i -- )
1197
+ if (strcmp (options .git_am_opts .argv [i ], "-q" ))
1198
+ break ;
1217
1199
1218
- if (is_interactive (& options ) && buf . len )
1200
+ if (is_interactive (& options ) && i >= 0 )
1219
1201
die (_ ("error: cannot combine interactive options "
1220
1202
"(--interactive, --exec, --rebase-merges, "
1221
1203
"--preserve-merges, --keep-empty, --root + "
1222
1204
"--onto) with am options (%s)" ), buf .buf );
1223
- if (options .type == REBASE_MERGE && buf . len )
1205
+ if (options .type == REBASE_MERGE && i >= 0 )
1224
1206
die (_ ("error: cannot combine merge options (--merge, "
1225
1207
"--strategy, --strategy-option) with am options "
1226
1208
"(%s)" ), buf .buf );
@@ -1230,7 +1212,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix)
1230
1212
if (options .type == REBASE_PRESERVE_MERGES )
1231
1213
die ("cannot combine '--signoff' with "
1232
1214
"'--preserve-merges'" );
1233
- strbuf_addstr (& options .git_am_opt , " --signoff" );
1215
+ argv_array_push (& options .git_am_opts , "--signoff" );
1234
1216
options .flags |= REBASE_FORCE ;
1235
1217
}
1236
1218
0 commit comments