@@ -29,6 +29,7 @@
#include "entry.h"
#include "ll-merge.h"
#include "object-store.h"
+#include "promisor-remote.h"
#include "revision.h"
#include "strmap.h"
#include "submodule.h"
@@ -3485,6 +3486,54 @@ static void process_entry(struct merge_options *opt,
record_entry_for_tree(dir_metadata, path, &ci->merged);
}
+static void prefetch_for_content_merges(struct merge_options *opt,
+ struct string_list *plist)
+{
+ struct string_list_item *e;
+ struct oid_array to_fetch = OID_ARRAY_INIT;
+
+ if (opt->repo != the_repository || !has_promisor_remote())
+ return;
+
+ for (e = &plist->items[plist->nr-1]; e >= plist->items; --e) {
+ /* char *path = e->string; */
+ struct conflict_info *ci = e->util;
+ int i;
+
+ /* Ignore clean entries */
+ if (ci->merged.clean)
+ continue;
+
+ /* Ignore entries that don't need a content merge */
+ if (ci->match_mask || ci->filemask < 6 ||
+ !S_ISREG(ci->stages[1].mode) ||
+ !S_ISREG(ci->stages[2].mode) ||
+ oideq(&ci->stages[1].oid, &ci->stages[2].oid))
+ continue;
+
+ /* Also don't need content merge if base matches either side */
+ if (ci->filemask == 7 &&
+ S_ISREG(ci->stages[0].mode) &&
+ (oideq(&ci->stages[0].oid, &ci->stages[1].oid) ||
+ oideq(&ci->stages[0].oid, &ci->stages[2].oid)))
+ continue;
+
+ for (i = 0; i < 3; i++) {
+ unsigned side_mask = (1 << i);
+ struct version_info *vi = &ci->stages[i];
+
+ if ((ci->filemask & side_mask) &&
+ S_ISREG(vi->mode) &&
+ oid_object_info_extended(opt->repo, &vi->oid, NULL,
+ OBJECT_INFO_FOR_PREFETCH))
+ oid_array_append(&to_fetch, &vi->oid);
+ }
+ }
+
+ promisor_remote_get_direct(opt->repo, to_fetch.oid, to_fetch.nr);
+ oid_array_clear(&to_fetch);
+}
+
static void process_entries(struct merge_options *opt,
struct object_id *result_oid)
{
@@ -3531,6 +3580,7 @@ static void process_entries(struct merge_options *opt,
* the way when it is time to process the file at the same path).
*/
trace2_region_enter("merge", "processing", opt->repo);
+ prefetch_for_content_merges(opt, &plist);
for (entry = &plist.items[plist.nr-1]; entry >= plist.items; --entry) {
char *path = entry->string;
/*
@@ -392,7 +392,7 @@ test_expect_merge_algorithm failure success 'Objects downloaded when a directory
#
# Summary: 4 fetches (1 for 6 objects, 1 for 8, 1 for 3, 1 for 2)
#
-test_expect_merge_algorithm failure failure 'Objects downloaded with lots of renames and modifications' '
+test_expect_merge_algorithm failure success 'Objects downloaded with lots of renames and modifications' '
test_setup_repo &&
git clone --sparse --filter=blob:none "file://$(pwd)/server" objects-many &&
(