4034
*/
4035
info.contentp = &s->data;
4036
4037
+ if (options && options->missing_object_cb) {
4038
+ if (!oid_object_info_extended(r, &s->oid, &info,
4039
+ OBJECT_INFO_LOOKUP_REPLACE |
4040
+ OBJECT_INFO_SKIP_FETCH_OBJECT))
4041
+ goto object_read;
4042
+ options->missing_object_cb(options->missing_object_data);
4043
+ }
4044
if (oid_object_info_extended(r, &s->oid, &info,
4045
OBJECT_INFO_LOOKUP_REPLACE))
4046
die("unable to read %s", oid_to_hex(&s->oid));
4047
4048
+object_read:
4049
if (size_only || check_binary) {
4050
if (size_only)
4051
return 0;
6452
{
6453
struct diff_populate_filespec_options dpf_options = {
6454
.check_size_only = 1,
6455
+ .missing_object_cb = diff_queued_diff_prefetch,
6456
+ .missing_object_data = r,
6457
};
6458
6459
if (p->done_skip_stat_unmatch)
6530
QSORT(q->queue, q->nr, diffnamecmp);
6531
}
6532
6523
-static void add_if_missing(struct repository *r,
6524
- struct oid_array *to_fetch,
6525
- const struct diff_filespec *filespec)
6533
+void diff_add_if_missing(struct repository *r,
6534
+ struct oid_array *to_fetch,
6535
+ const struct diff_filespec *filespec)
6536
{
6537
if (filespec && filespec->oid_valid &&
6538
!S_ISGITLINK(filespec->mode) &&
6541
oid_array_append(to_fetch, &filespec->oid);
6542
}
6543
6534
-void diffcore_std(struct diff_options *options)
6544
+void diff_queued_diff_prefetch(void *repository)
6545
{
6536
- if (options->repo == the_repository && has_promisor_remote()) {
6537
- /*
6538
- * Prefetch the diff pairs that are about to be flushed.
6539
- */
6540
- int i;
6541
- struct diff_queue_struct *q = &diff_queued_diff;
6542
- struct oid_array to_fetch = OID_ARRAY_INIT;
6546
+ struct repository *repo = repository;
6547
+ int i;
6548
+ struct diff_queue_struct *q = &diff_queued_diff;
6549
+ struct oid_array to_fetch = OID_ARRAY_INIT;
6550
6544
- for (i = 0; i < q->nr; i++) {
6545
- struct diff_filepair *p = q->queue[i];
6546
- add_if_missing(options->repo, &to_fetch, p->one);
6547
- add_if_missing(options->repo, &to_fetch, p->two);
6548
- }
6549
- /*
6550
- * NEEDSWORK: Consider deduplicating the OIDs sent.
6551
- */
6552
- promisor_remote_get_direct(options->repo,
6553
- to_fetch.oid, to_fetch.nr);
6554
- oid_array_clear(&to_fetch);
6551
+ for (i = 0; i < q->nr; i++) {
6552
+ struct diff_filepair *p = q->queue[i];
6553
+ diff_add_if_missing(repo, &to_fetch, p->one);
6554
+ diff_add_if_missing(repo, &to_fetch, p->two);
6555
}
6556
6557
+ /*
6558
+ * NEEDSWORK: Consider deduplicating the OIDs sent.
6559
+ */
6560
+ promisor_remote_get_direct(repo, to_fetch.oid, to_fetch.nr);
6561
+
6562
+ oid_array_clear(&to_fetch);
6563
+}
6564
+
6565
+void diffcore_std(struct diff_options *options)
6566
+{
6567
+ int output_formats_to_prefetch = DIFF_FORMAT_DIFFSTAT |
6568
+ DIFF_FORMAT_NUMSTAT |
6569
+ DIFF_FORMAT_PATCH |
6570
+ DIFF_FORMAT_SHORTSTAT |
6571
+ DIFF_FORMAT_DIRSTAT;
6572
+
6573
+ /*
6574
+ * Check if the user requested a blob-data-requiring diff output and/or
6575
+ * break-rewrite detection (which requires blob data). If yes, prefetch
6576
+ * the diff pairs.
6577
+ *
6578
+ * If no prefetching occurs, diffcore_rename() will prefetch if it
6579
+ * decides that it needs inexact rename detection.
6580
+ */
6581
+ if (options->repo == the_repository && has_promisor_remote() &&
6582
+ (options->output_format & output_formats_to_prefetch ||
6583
+ options->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK))
6584
+ diff_queued_diff_prefetch(options->repo);
6585
+
6586
/* NOTE please keep the following in sync with diff_tree_combined() */
6587
if (options->skip_stat_unmatch)
6588
diffcore_skip_stat_unmatch(options);