12
#include "blob.h"
13
#include "delta.h"
14
#include "builtin.h"
15
+#include "path-list.h"
16
17
/*
18
* --check turns on checking that the working tree matches the
186
struct line *line;
187
};
188
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
+
196
static uint32_t hash_line(const char *cp, size_t len)
197
{
198
size_t i;
2184
return 0;
2185
}
2186
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
+
2225
static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce)
2226
{
2227
struct strbuf buf;
2228
struct image image;
2229
size_t len;
2230
char *img;
2231
+ struct patch *tpatch;
2232
2233
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) {
2243
if (read_file_or_gitlink(ce, &buf))
2244
return error("read of %s failed", patch->old_name);
2245
} else if (patch->old_name) {
2266
return -1; /* note with --reject this succeeds. */
2267
patch->result = image.buf;
2268
patch->resultsize = image.len;
2269
+ add_to_fn_table(patch);
2270
free(image.line_allocated);
2271
2272
if (0 < patch->is_delete && patch->resultsize)
2311
static int check_preimage(struct patch *patch, struct cache_entry **ce, struct stat *st)
2312
{
2313
const char *old_name = patch->old_name;
2314
+ struct patch *tpatch;
2315
int stat_ret = 0;
2316
unsigned st_mode = 0;
2317
2325
return 0;
2326
2327
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) {
2334
stat_ret = lstat(old_name, st);
2335
if (stat_ret && errno != ENOENT)
2336
return error("%s: %s", old_name, strerror(errno));
2337
}
2276
- if (check_index) {
2338
+ if (check_index && !tpatch) {
2339
int pos = cache_name_pos(old_name, strlen(old_name));
2340
if (pos < 0) {
2341
if (patch->is_new < 0)
2387
return 0;
2388
}
2389
2328
-static int check_patch(struct patch *patch, struct patch *prev_patch)
2390
+static int check_patch(struct patch *patch)
2391
{
2392
struct stat st;
2393
const char *old_name = patch->old_name;
2404
return status;
2405
old_name = patch->old_name;
2406
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)
2408
/*
2409
* A type-change diff is always split into a patch to
2410
* delete old, immediately followed by a patch to
2454
2455
static int check_patch_list(struct patch *patch)
2456
{
2396
- struct patch *prev_patch = NULL;
2457
int err = 0;
2458
2399
- for (prev_patch = NULL; patch ; patch = patch->next) {
2459
+ while (patch) {
2460
if (apply_verbosely)
2461
say_patch_name(stderr,
2462
"Checking patch ", patch, "...\n");
2403
- err |= check_patch(patch, prev_patch);
2404
- prev_patch = patch;
2463
+ err |= check_patch(patch);
2464
+ patch = patch->next;
2465
}
2466
return err;
2467
}
2979
struct patch *list = NULL, **listp = &list;
2980
int skipped_patch = 0;
2981
2982
+ /* FIXME - memory leak when using multiple patch files as inputs */
2983
+ memset(&fn_table, 0, sizeof(struct path_list));
2984
strbuf_init(&buf, 0);
2985
patch_input_file = filename;
2986
read_patch_file(&buf, fd);