@matheusbsbs / matheus-bagliano / commits / 5c47f4c6e7
Fork 0

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 /*