From: Junio C Hamano Date: Wed, 10 May 2006 02:32:08 +0000 (-0700) Subject: Merge branch 'master' into next X-Git-Tag: v1.4.1-rc1~117 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/7278a29a277750e9e3cccce3cfb751d6171b1a43?hp=-c Merge branch 'master' into next * master: checkout: use --aggressive when running a 3-way merge (-m). revert/cherry-pick: use aggressive merge. read-cache.c: use xcalloc() not calloc() apply: fix infinite loop with multiple patches with --index --- 7278a29a277750e9e3cccce3cfb751d6171b1a43 diff --combined apply.c index 88d2a3206b,7c8146a7f3..ea6fb4c880 --- a/apply.c +++ b/apply.c @@@ -8,7 -8,6 +8,7 @@@ */ #include #include "cache.h" +#include "cache-tree.h" #include "quote.h" #include "blob.h" #include "delta.h" @@@ -21,6 -20,7 +21,7 @@@ // static const char *prefix; static int prefix_length = -1; + static int newfd = -1; static int p_value = 1; static int allow_binary_replacement = 0; @@@ -1893,7 -1893,6 +1894,7 @@@ static void remove_file(struct patch *p if (write_index) { if (remove_file_from_cache(patch->old_name) < 0) die("unable to remove %s from index", patch->old_name); + cache_tree_invalidate_path(active_cache_tree, patch->old_name); } unlink(patch->old_name); } @@@ -1990,9 -1989,8 +1991,9 @@@ static void create_file(struct patch *p if (!mode) mode = S_IFREG | 0644; - create_one_file(path, mode, buf, size); + create_one_file(path, mode, buf, size); add_index_file(path, mode, buf, size); + cache_tree_invalidate_path(active_cache_tree, path); } static void write_out_one_result(struct patch *patch) @@@ -2051,7 -2049,6 +2052,6 @@@ static int use_patch(struct patch *p static int apply_patch(int fd, const char *filename) { - int newfd; unsigned long offset, size; char *buffer = read_patch_file(fd, &size); struct patch *list = NULL, **listp = &list; @@@ -2082,12 -2079,11 +2082,11 @@@ size -= nr; } - newfd = -1; if (whitespace_error && (new_whitespace == error_on_whitespace)) apply = 0; write_index = check_index && apply; - if (write_index) + if (write_index && newfd < 0) newfd = hold_index_file_for_update(&cache_file, get_index_file()); if (check_index) { if (read_cache() < 0) @@@ -2100,12 -2096,6 +2099,6 @@@ if (apply) write_out_results(list, skipped_patch); - if (write_index) { - if (write_cache(newfd, active_cache, active_nr) || - commit_index_file(&cache_file)) - die("Unable to write new cachefile"); - } - if (show_index_info) show_index_list(list); @@@ -2264,5 -2254,12 +2257,12 @@@ int main(int argc, char **argv whitespace_error == 1 ? "" : "s", whitespace_error == 1 ? "s" : ""); } + + if (write_index) { + if (write_cache(newfd, active_cache, active_nr) || + commit_index_file(&cache_file)) + die("Unable to write new cachefile"); + } + return 0; } diff --combined read-cache.c index 1f71d12578,a917ab0cfe..ed0da38e07 --- a/read-cache.c +++ b/read-cache.c @@@ -4,26 -4,11 +4,26 @@@ * Copyright (C) Linus Torvalds, 2005 */ #include "cache.h" +#include "cache-tree.h" + +/* Index extensions. + * + * The first letter should be 'A'..'Z' for extensions that are not + * necessary for a correct operation (i.e. optimization data). + * When new extensions are added that _needs_ to be understood in + * order to correctly interpret the index file, pick character that + * is outside the range, to cause the reader to abort. + */ + +#define CACHE_EXT(s) ( (s[0]<<24)|(s[1]<<16)|(s[2]<<8)|(s[3]) ) +#define CACHE_EXT_TREE 0x54524545 /* "TREE" */ struct cache_entry **active_cache = NULL; static time_t index_file_timestamp; unsigned int active_nr = 0, active_alloc = 0, active_cache_changed = 0; +struct cache_tree *active_cache_tree = NULL; + /* * This only updates the "non-critical" parts of the directory * cache, ie the parts that aren't tracked by GIT, and only used @@@ -528,22 -513,6 +528,22 @@@ static int verify_hdr(struct cache_head return 0; } +static int read_index_extension(const char *ext, void *data, unsigned long sz) +{ + switch (CACHE_EXT(ext)) { + case CACHE_EXT_TREE: + active_cache_tree = cache_tree_read(data, sz); + break; + default: + if (*ext < 'A' || 'Z' < *ext) + return error("index uses %.4s extension, which we do not understand", + ext); + fprintf(stderr, "ignoring %.4s extension\n", ext); + break; + } + return 0; +} + int read_cache(void) { int fd, i; @@@ -583,7 -552,7 +583,7 @@@ active_nr = ntohl(hdr->hdr_entries); active_alloc = alloc_nr(active_nr); - active_cache = calloc(active_alloc, sizeof(struct cache_entry *)); + active_cache = xcalloc(active_alloc, sizeof(struct cache_entry *)); offset = sizeof(*hdr); for (i = 0; i < active_nr; i++) { @@@ -592,22 -561,6 +592,22 @@@ active_cache[i] = ce; } index_file_timestamp = st.st_mtime; + while (offset <= size - 20 - 8) { + /* After an array of active_nr index entries, + * there can be arbitrary number of extended + * sections, each of which is prefixed with + * extension name (4-byte) and section length + * in 4-byte network byte order. + */ + unsigned long extsize; + memcpy(&extsize, map + offset + 4, 4); + extsize = ntohl(extsize); + if (read_index_extension(map + offset, + map + offset + 8, extsize) < 0) + goto unmap; + offset += 8; + offset += extsize; + } return active_nr; unmap: @@@ -642,17 -595,6 +642,17 @@@ static int ce_write(SHA_CTX *context, i return 0; } +static int write_index_ext_header(SHA_CTX *context, int fd, + unsigned long ext, unsigned long sz) +{ + ext = htonl(ext); + sz = htonl(sz); + if ((ce_write(context, fd, &ext, 4) < 0) || + (ce_write(context, fd, &sz, 4) < 0)) + return -1; + return 0; +} + static int ce_flush(SHA_CTX *context, int fd) { unsigned int left = write_buffer_len; @@@ -749,19 -691,5 +749,19 @@@ int write_cache(int newfd, struct cache if (ce_write(&c, newfd, ce, ce_size(ce)) < 0) return -1; } + + /* Write extension data here */ + if (active_cache_tree) { + unsigned long sz; + void *data = cache_tree_write(active_cache_tree, &sz); + if (data && + !write_index_ext_header(&c, newfd, CACHE_EXT_TREE, sz) && + !ce_write(&c, newfd, data, sz)) + ; + else { + free(data); + return -1; + } + } return ce_flush(&c, newfd); }