@@ -11,10 +11,33 @@ enum prompt_mode_type {
1111 PROMPT_MODE_CHANGE = 0 , PROMPT_DELETION , PROMPT_HUNK
1212};
1313
14- static const char * prompt_mode [] = {
15- N_ ("Stage mode change [y,n,a,q,d%s,?]? " ),
16- N_ ("Stage deletion [y,n,a,q,d%s,?]? " ),
17- N_ ("Stage this hunk [y,n,a,q,d%s,?]? " )
14+ struct patch_mode {
15+ const char * diff [4 ], * apply [4 ], * apply_check [4 ];
16+ unsigned is_reverse :1 , apply_for_checkout :1 ;
17+ const char * prompt_mode [PROMPT_HUNK + 1 ];
18+ const char * edit_hunk_hint , * help_patch_text ;
19+ };
20+
21+ static struct patch_mode patch_mode_stage = {
22+ .diff = { "diff-files" , NULL },
23+ .apply = { "--cached" , NULL },
24+ .apply_check = { "--cached" , NULL },
25+ .is_reverse = 0 ,
26+ .prompt_mode = {
27+ N_ ("Stage mode change [y,n,q,a,d%s,?]? " ),
28+ N_ ("Stage deletion [y,n,q,a,d%s,?]? " ),
29+ N_ ("Stage this hunk [y,n,q,a,d%s,?]? " )
30+ },
31+ .edit_hunk_hint = N_ ("If the patch applies cleanly, the edited hunk "
32+ "will immediately be marked for staging." ),
33+ .help_patch_text =
34+ N_ ("y - stage this hunk\n"
35+ "n - do not stage this hunk\n"
36+ "q - quit; do not stage this hunk or any of the remaining "
37+ "ones\n"
38+ "a - stage this hunk and all later hunks in the file\n"
39+ "d - do not stage this hunk or any of the later hunks in "
40+ "the file\n" )
1841};
1942
2043struct hunk_header {
@@ -47,6 +70,10 @@ struct add_p_state {
4770 unsigned deleted :1 , mode_change :1 ,binary :1 ;
4871 } * file_diff ;
4972 size_t file_diff_nr ;
73+
74+ /* patch mode */
75+ struct patch_mode * mode ;
76+ const char * revision ;
5077};
5178
5279static void err (struct add_p_state * s , const char * fmt , ...)
@@ -159,9 +186,18 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
159186 struct hunk * hunk = NULL ;
160187 int res ;
161188
189+ argv_array_pushv (& args , s -> mode -> diff );
190+ if (s -> revision ) {
191+ struct object_id oid ;
192+ argv_array_push (& args ,
193+ /* could be on an unborn branch */
194+ !strcmp ("HEAD" , s -> revision ) &&
195+ get_oid ("HEAD" , & oid ) ?
196+ empty_tree_oid_hex () : s -> revision );
197+ }
198+ color_arg_index = args .argc ;
162199 /* Use `--no-color` explicitly, just in case `diff.color = always`. */
163- argv_array_pushl (& args , "diff-files" , "-p" , "--no-color" , "--" , NULL );
164- color_arg_index = args .argc - 2 ;
200+ argv_array_pushl (& args , "--no-color" , "-p" , "--" , NULL );
165201 for (i = 0 ; i < ps -> nr ; i ++ )
166202 argv_array_push (& args , ps -> items [i ].original );
167203
@@ -738,11 +774,10 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
738774 "(context).\n"
739775 "To remove '%c' lines, delete them.\n"
740776 "Lines starting with %c will be removed.\n" ),
741- '-' , '+' , comment_line_char );
742- strbuf_commented_addf (& buf ,
743- _ ("If the patch applies cleanly, the edited hunk "
744- "will immediately be\n"
745- "marked for staging.\n" ));
777+ s -> mode -> is_reverse ? '+' : '-' ,
778+ s -> mode -> is_reverse ? '-' : '+' ,
779+ comment_line_char );
780+ strbuf_commented_addf (& buf , "%s" , _ (s -> mode -> edit_hunk_hint ));
746781 /*
747782 * TRANSLATORS: 'it' refers to the patch mentioned in the previous
748783 * messages.
@@ -838,7 +873,8 @@ static int run_apply_check(struct add_p_state *s,
838873 reassemble_patch (s , file_diff , 1 , & s -> buf );
839874
840875 setup_child_process (& cp , s ,
841- "apply" , "--cached" , "--check" , NULL );
876+ "apply" , "--check" , NULL );
877+ argv_array_pushv (& cp .args , s -> mode -> apply_check );
842878 if (pipe_command (& cp , s -> buf .buf , s -> buf .len , NULL , 0 , NULL , 0 ))
843879 return error (_ ("'git apply --cached' failed" ));
844880
@@ -953,13 +989,6 @@ static size_t display_hunks(struct add_p_state *s,
953989 return end_index ;
954990}
955991
956- static const char help_patch_text [] =
957- N_ ("y - stage this hunk\n"
958- "n - do not stage this hunk\n"
959- "q - quit; do not stage this hunk or any of the remaining ones\n"
960- "a - stage this and all the remaining hunks\n"
961- "d - do not stage this hunk nor any of the remaining hunks\n" );
962-
963992static const char help_patch_remainder [] =
964993N_ ("j - leave this hunk undecided, see next undecided hunk\n"
965994 "J - leave this hunk undecided, see next hunk\n"
@@ -1041,7 +1070,8 @@ static int patch_update_file(struct add_p_state *s,
10411070 prompt_mode_type = PROMPT_HUNK ;
10421071
10431072 color_fprintf (stdout , s -> s .prompt_color ,
1044- _ (prompt_mode [prompt_mode_type ]), s -> buf .buf );
1073+ _ (s -> mode -> prompt_mode [prompt_mode_type ]),
1074+ s -> buf .buf );
10451075 fflush (stdout );
10461076 if (strbuf_getline (& s -> answer , stdin ) == EOF )
10471077 break ;
@@ -1198,7 +1228,7 @@ static int patch_update_file(struct add_p_state *s,
11981228 const char * p = _ (help_patch_remainder ), * eol = p ;
11991229
12001230 color_fprintf (stdout , s -> s .help_color , "%s" ,
1201- _ (help_patch_text ));
1231+ _ (s -> mode -> help_patch_text ));
12021232
12031233 /*
12041234 * Show only those lines of the remainder that are
@@ -1231,18 +1261,20 @@ static int patch_update_file(struct add_p_state *s,
12311261 strbuf_reset (& s -> buf );
12321262 reassemble_patch (s , file_diff , 0 , & s -> buf );
12331263
1234- setup_child_process (& cp , s , "apply" , "--cached" , NULL );
1264+ setup_child_process (& cp , s , "apply" , NULL );
1265+ argv_array_pushv (& cp .args , s -> mode -> apply );
12351266 if (pipe_command (& cp , s -> buf .buf , s -> buf .len ,
12361267 NULL , 0 , NULL , 0 ))
1237- error (_ ("'git apply --cached ' failed" ));
1268+ error (_ ("'git apply' failed" ));
12381269 repo_refresh_and_write_index (s -> s .r , REFRESH_QUIET , 0 );
12391270 }
12401271
12411272 putchar ('\n' );
12421273 return quit ;
12431274}
12441275
1245- int run_add_p (struct repository * r , const struct pathspec * ps )
1276+ int run_add_p (struct repository * r , enum add_p_mode mode ,
1277+ const char * revision , const struct pathspec * ps )
12461278{
12471279 struct add_p_state s = {
12481280 { r }, STRBUF_INIT , STRBUF_INIT , STRBUF_INIT , STRBUF_INIT
@@ -1252,6 +1284,9 @@ int run_add_p(struct repository *r, const struct pathspec *ps)
12521284 if (init_add_i_state (r , & s .s ))
12531285 return error ("Could not read `add -i` config" );
12541286
1287+ s .mode = & patch_mode_stage ;
1288+ s .revision = revision ;
1289+
12551290 if (repo_refresh_and_write_index (r , REFRESH_QUIET , 0 ) < 0 ||
12561291 parse_diff (& s , ps ) < 0 ) {
12571292 strbuf_release (& s .plain );
0 commit comments