]> git.ipfire.org Git - thirdparty/git.git/blobdiff - diffcore-rename.c
Merge branch 'jt/t5500-unflake'
[thirdparty/git.git] / diffcore-rename.c
index bf4c0b874089aac87b860c3bc3c3d5dc9317e146..99e63e90f89afaf55ef16bb3c11c1546c4d76c2a 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ *
  * Copyright (C) 2005 Junio C Hamano
  */
 #include "cache.h"
@@ -7,6 +8,7 @@
 #include "object-store.h"
 #include "hashmap.h"
 #include "progress.h"
+#include "promisor-remote.h"
 
 /* Table of rename/copy destinations */
 
@@ -128,10 +130,46 @@ struct diff_score {
        short name_score;
 };
 
+struct prefetch_options {
+       struct repository *repo;
+       int skip_unmodified;
+};
+static void prefetch(void *prefetch_options)
+{
+       struct prefetch_options *options = prefetch_options;
+       int i;
+       struct oid_array to_fetch = OID_ARRAY_INIT;
+
+       for (i = 0; i < rename_dst_nr; i++) {
+               if (rename_dst[i].pair)
+                       /*
+                        * The loop in diffcore_rename() will not need these
+                        * blobs, so skip prefetching.
+                        */
+                       continue; /* already found exact match */
+               diff_add_if_missing(options->repo, &to_fetch,
+                                   rename_dst[i].two);
+       }
+       for (i = 0; i < rename_src_nr; i++) {
+               if (options->skip_unmodified &&
+                   diff_unmodified_pair(rename_src[i].p))
+                       /*
+                        * The loop in diffcore_rename() will not need these
+                        * blobs, so skip prefetching.
+                        */
+                       continue;
+               diff_add_if_missing(options->repo, &to_fetch,
+                                   rename_src[i].p->one);
+       }
+       promisor_remote_get_direct(options->repo, to_fetch.oid, to_fetch.nr);
+       oid_array_clear(&to_fetch);
+}
+
 static int estimate_similarity(struct repository *r,
                               struct diff_filespec *src,
                               struct diff_filespec *dst,
-                              int minimum_score)
+                              int minimum_score,
+                              int skip_unmodified)
 {
        /* src points at a file that existed in the original tree (or
         * optionally a file in the destination tree) and dst points
@@ -151,6 +189,12 @@ static int estimate_similarity(struct repository *r,
        struct diff_populate_filespec_options dpf_options = {
                .check_size_only = 1
        };
+       struct prefetch_options prefetch_options = {r, skip_unmodified};
+
+       if (r == the_repository && has_promisor_remote()) {
+               dpf_options.missing_object_cb = prefetch;
+               dpf_options.missing_object_data = &prefetch_options;
+       }
 
        /* We deal only with regular files.  Symlink renames are handled
         * only when they are exact matches --- in other words, no edits
@@ -190,9 +234,11 @@ static int estimate_similarity(struct repository *r,
        if (max_size * (MAX_SCORE-minimum_score) < delta_size * MAX_SCORE)
                return 0;
 
-       if (!src->cnt_data && diff_populate_filespec(r, src, NULL))
+       dpf_options.check_size_only = 0;
+
+       if (!src->cnt_data && diff_populate_filespec(r, src, &dpf_options))
                return 0;
-       if (!dst->cnt_data && diff_populate_filespec(r, dst, NULL))
+       if (!dst->cnt_data && diff_populate_filespec(r, dst, &dpf_options))
                return 0;
 
        if (diffcore_count_changes(r, src, dst,
@@ -569,7 +615,8 @@ void diffcore_rename(struct diff_options *options)
 
                        this_src.score = estimate_similarity(options->repo,
                                                             one, two,
-                                                            minimum_score);
+                                                            minimum_score,
+                                                            skip_unmodified);
                        this_src.name_score = basename_same(one, two);
                        this_src.dst = i;
                        this_src.src = j;