1212#include "blob.h"
1313#include "delta.h"
1414#include "builtin.h"
15+ #include "path-list.h"
1516
1617/*
1718 * --check turns on checking that the working tree matches the
@@ -185,6 +186,13 @@ struct image {
185186 struct line * line ;
186187};
187188
189+ /*
190+ * Records filenames that have been touched, in order to handle
191+ * the case where more than one patches touch the same file.
192+ */
193+
194+ static struct path_list fn_table ;
195+
188196static uint32_t hash_line (const char * cp , size_t len )
189197{
190198 size_t i ;
@@ -2176,15 +2184,62 @@ static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf)
21762184 return 0 ;
21772185}
21782186
2187+ static struct patch * in_fn_table (const char * name )
2188+ {
2189+ struct path_list_item * item ;
2190+
2191+ if (name == NULL )
2192+ return NULL ;
2193+
2194+ item = path_list_lookup (name , & fn_table );
2195+ if (item != NULL )
2196+ return (struct patch * )item -> util ;
2197+
2198+ return NULL ;
2199+ }
2200+
2201+ static void add_to_fn_table (struct patch * patch )
2202+ {
2203+ struct path_list_item * item ;
2204+
2205+ /*
2206+ * Always add new_name unless patch is a deletion
2207+ * This should cover the cases for normal diffs,
2208+ * file creations and copies
2209+ */
2210+ if (patch -> new_name != NULL ) {
2211+ item = path_list_insert (patch -> new_name , & fn_table );
2212+ item -> util = patch ;
2213+ }
2214+
2215+ /*
2216+ * store a failure on rename/deletion cases because
2217+ * later chunks shouldn't patch old names
2218+ */
2219+ if ((patch -> new_name == NULL ) || (patch -> is_rename )) {
2220+ item = path_list_insert (patch -> old_name , & fn_table );
2221+ item -> util = (struct patch * ) -1 ;
2222+ }
2223+ }
2224+
21792225static int apply_data (struct patch * patch , struct stat * st , struct cache_entry * ce )
21802226{
21812227 struct strbuf buf ;
21822228 struct image image ;
21832229 size_t len ;
21842230 char * img ;
2231+ struct patch * tpatch ;
21852232
21862233 strbuf_init (& buf , 0 );
2187- if (cached ) {
2234+
2235+ if ((tpatch = in_fn_table (patch -> old_name )) != NULL ) {
2236+ if (tpatch == (struct patch * ) -1 ) {
2237+ return error ("patch %s has been renamed/deleted" ,
2238+ patch -> old_name );
2239+ }
2240+ /* We have a patched copy in memory use that */
2241+ strbuf_add (& buf , tpatch -> result , tpatch -> resultsize );
2242+ } else if (cached ) {
21882243 if (read_file_or_gitlink (ce , & buf ))
21892244 return error ("read of %s failed" , patch -> old_name );
21902245 } else if (patch -> old_name ) {
@@ -2211,6 +2266,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
22112266 return -1 ; /* note with --reject this succeeds. */
22122267 patch -> result = image .buf ;
22132268 patch -> resultsize = image .len ;
2269+ add_to_fn_table (patch );
22142270 free (image .line_allocated );
22152271
22162272 if (0 < patch -> is_delete && patch -> resultsize )
@@ -2255,6 +2311,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
22552311static int check_preimage (struct patch * patch , struct cache_entry * * ce , struct stat * st )
22562312{
22572313 const char * old_name = patch -> old_name ;
2314+ struct patch * tpatch ;
22582315 int stat_ret = 0 ;
22592316 unsigned st_mode = 0 ;
22602317
@@ -2268,12 +2325,17 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
22682325 return 0 ;
22692326
22702327 assert (patch -> is_new <= 0 );
2271- if (!cached ) {
2328+ if ((tpatch = in_fn_table (old_name )) != NULL ) {
2329+ if (tpatch == (struct patch * ) -1 ) {
2330+ return error ("%s: has been deleted/renamed" , old_name );
2331+ }
2332+ st_mode = tpatch -> new_mode ;
2333+ } else if (!cached ) {
22722334 stat_ret = lstat (old_name , st );
22732335 if (stat_ret && errno != ENOENT )
22742336 return error ("%s: %s" , old_name , strerror (errno ));
22752337 }
2276- if (check_index ) {
2338+ if (check_index && ! tpatch ) {
22772339 int pos = cache_name_pos (old_name , strlen (old_name ));
22782340 if (pos < 0 ) {
22792341 if (patch -> is_new < 0 )
@@ -2325,7 +2387,7 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
23252387 return 0 ;
23262388}
23272389
2328- static int check_patch (struct patch * patch , struct patch * prev_patch )
2390+ static int check_patch (struct patch * patch )
23292391{
23302392 struct stat st ;
23312393 const char * old_name = patch -> old_name ;
@@ -2342,8 +2404,7 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
23422404 return status ;
23432405 old_name = patch -> old_name ;
23442406
2345- if (new_name && prev_patch && 0 < prev_patch -> is_delete &&
2346- !strcmp (prev_patch -> old_name , new_name ))
2407+ if (in_fn_table (new_name ) == (struct patch * ) -1 )
23472408 /*
23482409 * A type-change diff is always split into a patch to
23492410 * delete old, immediately followed by a patch to
@@ -2393,15 +2454,14 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
23932454
23942455static int check_patch_list (struct patch * patch )
23952456{
2396- struct patch * prev_patch = NULL ;
23972457 int err = 0 ;
23982458
2399- for ( prev_patch = NULL ; patch ; patch = patch -> next ) {
2459+ while ( patch ) {
24002460 if (apply_verbosely )
24012461 say_patch_name (stderr ,
24022462 "Checking patch " , patch , "...\n" );
2403- err |= check_patch (patch , prev_patch );
2404- prev_patch = patch ;
2463+ err |= check_patch (patch );
2464+ patch = patch -> next ;
24052465 }
24062466 return err ;
24072467}
@@ -2919,6 +2979,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
29192979 struct patch * list = NULL , * * listp = & list ;
29202980 int skipped_patch = 0 ;
29212981
2982+ /* FIXME - memory leak when using multiple patch files as inputs */
2983+ memset (& fn_table , 0 , sizeof (struct path_list ));
29222984 strbuf_init (& buf , 0 );
29232985 patch_input_file = filename ;
29242986 read_patch_file (& buf , fd );
0 commit comments