@@ -11,10 +11,33 @@ enum prompt_mode_type {
11
11
PROMPT_MODE_CHANGE = 0 , PROMPT_DELETION , PROMPT_HUNK
12
12
};
13
13
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" )
18
41
};
19
42
20
43
struct hunk_header {
@@ -47,6 +70,10 @@ struct add_p_state {
47
70
unsigned deleted :1 , mode_change :1 ,binary :1 ;
48
71
} * file_diff ;
49
72
size_t file_diff_nr ;
73
+
74
+ /* patch mode */
75
+ struct patch_mode * mode ;
76
+ const char * revision ;
50
77
};
51
78
52
79
static void err (struct add_p_state * s , const char * fmt , ...)
@@ -162,9 +189,18 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps)
162
189
struct hunk * hunk = NULL ;
163
190
int res ;
164
191
192
+ argv_array_pushv (& args , s -> mode -> diff );
193
+ if (s -> revision ) {
194
+ struct object_id oid ;
195
+ argv_array_push (& args ,
196
+ /* could be on an unborn branch */
197
+ !strcmp ("HEAD" , s -> revision ) &&
198
+ get_oid ("HEAD" , & oid ) ?
199
+ empty_tree_oid_hex () : s -> revision );
200
+ }
201
+ color_arg_index = args .argc ;
165
202
/* Use `--no-color` explicitly, just in case `diff.color = always`. */
166
- argv_array_pushl (& args , "diff-files" , "-p" , "--no-color" , "--" , NULL );
167
- color_arg_index = args .argc - 2 ;
203
+ argv_array_pushl (& args , "--no-color" , "-p" , "--" , NULL );
168
204
for (i = 0 ; i < ps -> nr ; i ++ )
169
205
argv_array_push (& args , ps -> items [i ].original );
170
206
@@ -382,7 +418,10 @@ static void render_hunk(struct add_p_state *s, struct hunk *hunk,
382
418
- header -> colored_extra_start ;
383
419
}
384
420
385
- new_offset += delta ;
421
+ if (s -> mode -> is_reverse )
422
+ old_offset -= delta ;
423
+ else
424
+ new_offset += delta ;
386
425
387
426
strbuf_addf (out , "@@ -%lu,%lu +%lu,%lu @@" ,
388
427
old_offset , header -> old_count ,
@@ -805,11 +844,10 @@ static int edit_hunk_manually(struct add_p_state *s, struct hunk *hunk)
805
844
"(context).\n"
806
845
"To remove '%c' lines, delete them.\n"
807
846
"Lines starting with %c will be removed.\n" ),
808
- '-' , '+' , comment_line_char );
809
- strbuf_commented_addf (& s -> buf ,
810
- _ ("If the patch applies cleanly, the edited hunk "
811
- "will immediately be\n"
812
- "marked for staging.\n" ));
847
+ s -> mode -> is_reverse ? '+' : '-' ,
848
+ s -> mode -> is_reverse ? '-' : '+' ,
849
+ comment_line_char );
850
+ strbuf_commented_addf (& s -> buf , "%s" , _ (s -> mode -> edit_hunk_hint ));
813
851
/*
814
852
* TRANSLATORS: 'it' refers to the patch mentioned in the previous
815
853
* messages.
@@ -890,7 +928,8 @@ static int run_apply_check(struct add_p_state *s,
890
928
reassemble_patch (s , file_diff , 1 , & s -> buf );
891
929
892
930
setup_child_process (s , & cp ,
893
- "apply" , "--cached" , "--check" , NULL );
931
+ "apply" , "--check" , NULL );
932
+ argv_array_pushv (& cp .args , s -> mode -> apply_check );
894
933
if (pipe_command (& cp , s -> buf .buf , s -> buf .len , NULL , 0 , NULL , 0 ))
895
934
return error (_ ("'git apply --cached' failed" ));
896
935
@@ -1005,13 +1044,6 @@ static size_t display_hunks(struct add_p_state *s,
1005
1044
return end_index ;
1006
1045
}
1007
1046
1008
- static const char help_patch_text [] =
1009
- N_ ("y - stage this hunk\n"
1010
- "n - do not stage this hunk\n"
1011
- "q - quit; do not stage this hunk or any of the remaining ones\n"
1012
- "a - stage this and all the remaining hunks\n"
1013
- "d - do not stage this hunk nor any of the remaining hunks\n" );
1014
-
1015
1047
static const char help_patch_remainder [] =
1016
1048
N_ ("j - leave this hunk undecided, see next undecided hunk\n"
1017
1049
"J - leave this hunk undecided, see next hunk\n"
@@ -1097,7 +1129,8 @@ static int patch_update_file(struct add_p_state *s,
1097
1129
(uintmax_t )hunk_index + 1 ,
1098
1130
(uintmax_t )file_diff -> hunk_nr );
1099
1131
color_fprintf (stdout , s -> s .prompt_color ,
1100
- _ (prompt_mode [prompt_mode_type ]), s -> buf .buf );
1132
+ _ (s -> mode -> prompt_mode [prompt_mode_type ]),
1133
+ s -> buf .buf );
1101
1134
fflush (stdout );
1102
1135
if (strbuf_getline (& s -> answer , stdin ) == EOF )
1103
1136
break ;
@@ -1254,7 +1287,7 @@ static int patch_update_file(struct add_p_state *s,
1254
1287
const char * p = _ (help_patch_remainder ), * eol = p ;
1255
1288
1256
1289
color_fprintf (stdout , s -> s .help_color , "%s" ,
1257
- _ (help_patch_text ));
1290
+ _ (s -> mode -> help_patch_text ));
1258
1291
1259
1292
/*
1260
1293
* Show only those lines of the remainder that are
@@ -1288,10 +1321,11 @@ static int patch_update_file(struct add_p_state *s,
1288
1321
reassemble_patch (s , file_diff , 0 , & s -> buf );
1289
1322
1290
1323
discard_index (s -> s .r -> index );
1291
- setup_child_process (s , & cp , "apply" , "--cached" , NULL );
1324
+ setup_child_process (s , & cp , "apply" , NULL );
1325
+ argv_array_pushv (& cp .args , s -> mode -> apply );
1292
1326
if (pipe_command (& cp , s -> buf .buf , s -> buf .len ,
1293
1327
NULL , 0 , NULL , 0 ))
1294
- error (_ ("'git apply --cached ' failed" ));
1328
+ error (_ ("'git apply' failed" ));
1295
1329
if (!repo_read_index (s -> s .r ))
1296
1330
repo_refresh_and_write_index (s -> s .r , REFRESH_QUIET , 0 ,
1297
1331
1 , NULL , NULL , NULL );
@@ -1301,7 +1335,8 @@ static int patch_update_file(struct add_p_state *s,
1301
1335
return quit ;
1302
1336
}
1303
1337
1304
- int run_add_p (struct repository * r , const struct pathspec * ps )
1338
+ int run_add_p (struct repository * r , enum add_p_mode mode ,
1339
+ const char * revision , const struct pathspec * ps )
1305
1340
{
1306
1341
struct add_p_state s = {
1307
1342
{ r }, STRBUF_INIT , STRBUF_INIT , STRBUF_INIT , STRBUF_INIT
@@ -1310,6 +1345,9 @@ int run_add_p(struct repository *r, const struct pathspec *ps)
1310
1345
1311
1346
init_add_i_state (& s .s , r );
1312
1347
1348
+ s .mode = & patch_mode_stage ;
1349
+ s .revision = revision ;
1350
+
1313
1351
if (discard_index (r -> index ) < 0 || repo_read_index (r ) < 0 ||
1314
1352
repo_refresh_and_write_index (r , REFRESH_QUIET , 0 , 1 ,
1315
1353
NULL , NULL , NULL ) < 0 ||
0 commit comments