This updates git-apply to maintain cache-tree information. With this and the previous write-tree patch, repeated "apply --index" followed by "write-tree" on a huge tree will hopefully become faster. Signed-off-by: Junio C Hamano <junkio@xxxxxxx> --- * ... then the big rock falls. With this, I tried to apply and then write-tree "diff-tree -p $commit^1 $commit" on top of "$commit^1" for the last 20 or so commits in the kernel tree. The "master" version takes 0.15 second per patch on my Duron 750 with 700MB, while this one does that in 0.06 second. This also helps the memory pressure because we do not have to regenerate unchanged trees. 810 minor faults with the patch vs 2150 minor faults without. apply.c | 16 ++++++++++++++-- 1 files changed, 14 insertions(+), 2 deletions(-) 94005d7bb4b55e9984f6505a8916d23d304ccc4d diff --git a/apply.c b/apply.c index 269210a..f7cdefa 100644 --- a/apply.c +++ b/apply.c @@ -8,9 +8,14 @@ */ #include <fnmatch.h> #include "cache.h" +#include "cache-tree.h" #include "quote.h" #include "blob.h" +static unsigned char active_cache_sha1[20]; +static struct cache_tree *active_cache_tree; + + // --check turns on checking that the working tree matches the // files that are being modified, but doesn't apply the patch // --stat does just a diffstat, and doesn't actually apply @@ -1717,6 +1722,7 @@ static void remove_file(struct patch *pa 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); } @@ -1815,6 +1821,7 @@ static void create_file(struct patch *pa mode = S_IFREG | 0644; 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) @@ -1912,8 +1919,9 @@ static int apply_patch(int fd, const cha if (write_index) newfd = hold_index_file_for_update(&cache_file, get_index_file()); if (check_index) { - if (read_cache() < 0) + if (read_cache_1(active_cache_sha1) < 0) die("unable to read index file"); + active_cache_tree = read_cache_tree(active_cache_sha1); } if ((check || apply) && check_patch_list(list) < 0) @@ -1923,9 +1931,13 @@ static int apply_patch(int fd, const cha write_out_results(list, skipped_patch); if (write_index) { - if (write_cache(newfd, active_cache, active_nr) || + if (write_cache_1(newfd, active_cache, active_nr, + active_cache_sha1) || commit_index_file(&cache_file)) die("Unable to write new cachefile"); + cache_tree_update(active_cache_tree, + active_cache, active_nr, 1); + write_cache_tree(active_cache_sha1, active_cache_tree); } if (show_index_info) -- 1.3.0.g623a - : send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html