builtin-apply: accept patch to an empty file
A patch from a foreign SCM (or plain "diff" output) often have both preimage and postimage filename on ---/+++ lines even for a patch that creates a new file. However, when there is a filename for preimage, we used to insist the file to exist (either in the work tree and/or in the index). When we cannot be sure by parsing the patch that it is not a creation patch, we shouldn't complain when if there is no such a file. This commit fixes the logic. Refactor the code that validates the preimage file into a separate function while we are at it, as it is getting rather big. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
May 17, 2008 at 01:51 UTC
5c47f4c6e71e6de08348f837f38a446a2f2b0ed7
1 file changed
+77
-56
builtin-apply.c
+77
-56
@@ -2267,16 +2267,11 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
2267
return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID);
2268
}
2269
2270
-static int check_patch(struct patch *patch, struct patch *prev_patch)
2270
+static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)
2271
{
2272
- struct stat st;
2272
const char *old_name = patch->old_name;
2274
- const char *new_name = patch->new_name;
2275
- const char *name = old_name ? old_name : new_name;
2276
- struct cache_entry *ce = NULL;
2277
- int ok_if_exists;
2278
-
2279
- patch->rejected = 1; /* we will drop this after we succeed */
2273
+ int stat_ret = 0;
2274
+ unsigned st_mode = 0;
2275
2276
/*
2277
* Make sure that we do not have local modifications from the
@@ -2284,58 +2279,84 @@ static int check_patch(struct patch *patch, struct patch *prev_patch)
2279
* we have the preimage file to be patched in the work tree,
2280
* unless --cached, which tells git to apply only in the index.
2281
*/
2287
- if (old_name) {
2288
- int stat_ret = 0;
2289
- unsigned st_mode = 0;
2290
-
2291
- if (!cached)
2292
- stat_ret = lstat(old_name, &st);
2293
- if (check_index) {
2294
- int pos = cache_name_pos(old_name, strlen(old_name));
2295
- if (pos < 0)
2296
- return error("%s: does not exist in index",
2297
- old_name);
2298
- ce = active_cache[pos];
2299
- if (stat_ret < 0) {
2300
- struct checkout costate;
2301
- if (errno != ENOENT)
2302
- return error("%s: %s", old_name,
2303
- strerror(errno));
2304
- /* checkout */
2305
- costate.base_dir = "";
2306
- costate.base_dir_len = 0;
2307
- costate.force = 0;
2308
- costate.quiet = 0;
2309
- costate.not_new = 0;
2310
- costate.refresh_cache = 1;
2311
- if (checkout_entry(ce,
2312
- &costate,
2313
- NULL) ||
2314
- lstat(old_name, &st))
2315
- return -1;
2316
- }
2317
- if (!cached && verify_index_match(ce, &st))
2318
- return error("%s: does not match index",
2319
- old_name);
2320
- if (cached)
2321
- st_mode = ce->ce_mode;
2322
- } else if (stat_ret < 0)
2323
- return error("%s: %s", old_name, strerror(errno));
2324
-
2325
- if (!cached)
2326
- st_mode = ce_mode_from_stat(ce, st.st_mode);
2282
+ if (!old_name)
2283
+ return 0;
2284
2285
+ assert(patch->is_new <= 0);
2286
+ if (!cached) {
2287
+ stat_ret = lstat(old_name, st);
2288
+ if (stat_ret && errno != ENOENT)
2289
+ return error("%s: %s", old_name, strerror(errno));
2290
+ }
2291
+ if (check_index) {
2292
+ int pos = cache_name_pos(old_name, strlen(old_name));
2293
+ if (pos < 0) {
2294
+ if (patch->is_new < 0)
2295
+ goto is_new;
2296
+ return error("%s: does not exist in index", old_name);
2297
+ }
2298
+ *ce = active_cache[pos];
2299
+ if (stat_ret < 0) {
2300
+ struct checkout costate;
2301
+ /* checkout */
2302
+ costate.base_dir = "";
2303
+ costate.base_dir_len = 0;
2304
+ costate.force = 0;
2305
+ costate.quiet = 0;
2306
+ costate.not_new = 0;
2307
+ costate.refresh_cache = 1;
2308
+ if (checkout_entry(*ce, &costate, NULL) ||
2309
+ lstat(old_name, st))
2310
+ return -1;
2311
+ }
2312
+ if (!cached && verify_index_match(*ce, st))
2313
+ return error("%s: does not match index", old_name);
2314
+ if (cached)
2315
+ st_mode = (*ce)->ce_mode;
2316
+ } else if (stat_ret < 0) {
2317
if (patch->is_new < 0)
2329
- patch->is_new = 0;
2330
- if (!patch->old_mode)
2331
- patch->old_mode = st_mode;
2332
- if ((st_mode ^ patch->old_mode) & S_IFMT)
2333
- return error("%s: wrong type", old_name);
2334
- if (st_mode != patch->old_mode)
2335
- fprintf(stderr, "warning: %s has type %o, expected %o\n",
2336
- old_name, st_mode, patch->old_mode);
2318
+ goto is_new;
2319
+ return error("%s: %s", old_name, strerror(errno));
2320
}
2321
2322
+ if (!cached)
2323
+ st_mode = ce_mode_from_stat(*ce, st->st_mode);
2324
+
2325
+ if (patch->is_new < 0)
2326
+ patch->is_new = 0;
2327
+ if (!patch->old_mode)
2328
+ patch->old_mode = st_mode;
2329
+ if ((st_mode ^ patch->old_mode) & S_IFMT)
2330
+ return error("%s: wrong type", old_name);
2331
+ if (st_mode != patch->old_mode)
2332
+ fprintf(stderr, "warning: %s has type %o, expected %o\n",
2333
+ old_name, st_mode, patch->old_mode);
2334
+ return 0;
2335
+
2336
+ is_new:
2337
+ patch->is_new = 1;
2338
+ patch->is_delete = 0;
2339
+ patch->old_name = NULL;
2340
+ return 0;
2341
+}
2342
+
2343
+static int check_patch(struct patch *patch, struct patch *prev_patch)
2344
+{
2345
+ struct stat st;
2346
+ const char *old_name = patch->old_name;
2347
+ const char *new_name = patch->new_name;
2348
+ const char *name = old_name ? old_name : new_name;
2349
+ struct cache_entry *ce = NULL;
2350
+ int ok_if_exists;
2351
+ int status;
2352
+
2353
+ patch->rejected = 1; /* we will drop this after we succeed */
2354
+
2355
+ status = check_preimage(patch, &ce, &st);
2356
+ if (status)
2357
+ return status;
2358
+ old_name = patch->old_name;
2359
+
2360
if (new_name && prev_patch && 0 < prev_patch->is_delete &&
2361
!strcmp(prev_patch->old_name, new_name))
2362
/*