From patchwork Tue Apr 7 22:11:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Tan X-Patchwork-Id: 11479043 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7E9521744 for ; Tue, 7 Apr 2020 22:11:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5D1E62074F for ; Tue, 7 Apr 2020 22:11:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="N74H1d4j" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726438AbgDGWLu (ORCPT ); Tue, 7 Apr 2020 18:11:50 -0400 Received: from mail-pj1-f73.google.com ([209.85.216.73]:37110 "EHLO mail-pj1-f73.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726386AbgDGWLu (ORCPT ); Tue, 7 Apr 2020 18:11:50 -0400 Received: by mail-pj1-f73.google.com with SMTP id w4so844666pjt.2 for ; Tue, 07 Apr 2020 15:11:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=bmeGpckLvyJH+KO+r8gy9KGUkRNvdgUpS/eIbC3Vj9c=; b=N74H1d4j6xPZyB4UAX0vuDRi/hjPQ+Wslq4CDY85ZveXXKcGP52Z+5c26Or35c94LA KfuEkTC6m8+U3lQy72WJ9jCPdkUXa6H67+596T3syphiHaDI7Ss2RoZrypdQMTlFryJ6 4UjOMYqOwyiRw0YINMOSZNYpu3RMwyrNV+gnCFyT1EHX+moHOl8MuEv12Q/zORZCW5Na KhAhmWdnnE9u34Up0lbwKZMZihtIWMqrGCcQasoNAI51wwf5GZ2OOIE/5GI7f0iQ6l8M /c0abTjuP74dw2VJsB/0NMT/pbvSk1PeQIndUzvkb154V33R2jFl3jpRtsnzzgKeA7TC HUYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=bmeGpckLvyJH+KO+r8gy9KGUkRNvdgUpS/eIbC3Vj9c=; b=fzlGla683dFIkKSn8naUytf4JrjPb6LrDh4/gkRWJkDyNJLGawS7h7DRBXfMHY+vBg LTvR3cYvZZ9FSX9xJolt1WuRxJGndI9oOsLg2Dr1Sk8wxPurWAgfQJDC0CMaiJ8GfpAF KciVgA5alQaF2BnwK/+T/gOdb4kTO/2KPioCO02aWyy9Asl3nFPhu5O4YXGvg/w6DkKh nPcx9zHdtUTJaGNbbBoYpQpB10hq7RANSl0E66kEbbdnkYMGPjCdWynh2QzEPFyAN/rR M4Kta57mnXXy75Qmd2DeeywFtwPCO9sZFizI+d2MP1d98wusiZMrELvRE8uY+JB9rERP 7QBQ== X-Gm-Message-State: AGi0PuZtgwVurCPjlsJlljjjNbnlcvzVWeiPmfpWugIxyXF/k6ShUj2N Rbo0yA7CDqwYGHSR+2ZJrLIG6v1SLp3nc1M6UeTBRJ4YZoQK/V2UdK1dHEhj/8ugacmLOFS2gkp wS593jY2TuLMo4WDOeDXGxD3TyuBgWOVeRPdyo8dKl7RPUIjwJ0HAAi8T7BEP5gEieX8fEJUxb7 ae X-Google-Smtp-Source: APiQypK2+TUxfMZVDQdb7bI1MTuoTNYFV07RH+pwbCBnWD/q0g2i1pxL4QGKPAavDCtOBJQcDOLhHktPha4Rrf44DesQ X-Received: by 2002:a63:1718:: with SMTP id x24mr4181538pgl.421.1586297508819; Tue, 07 Apr 2020 15:11:48 -0700 (PDT) Date: Tue, 7 Apr 2020 15:11:40 -0700 In-Reply-To: Message-Id: <474eb27d9c136fb69e961546004cfb531d722e2c.1586296510.git.jonathantanmy@google.com> Mime-Version: 1.0 References: <20200331020418.55640-1-jonathantanmy@google.com> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog Subject: [PATCH v3 1/4] promisor-remote: accept 0 as oid_nr in function From: Jonathan Tan To: git@vger.kernel.org Cc: Jonathan Tan , garimasigit@gmail.com, gitster@pobox.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org There are 3 callers to promisor_remote_get_direct() that first check if the number of objects to be fetched is equal to 0. Fold that check into promisor_remote_get_direct(), and in doing so, be explicit as to what promisor_remote_get_direct() does if oid_nr is 0 (it returns 0, success, immediately). Signed-off-by: Jonathan Tan --- builtin/index-pack.c | 5 ++--- diff.c | 11 +++++------ promisor-remote.c | 3 +++ promisor-remote.h | 8 ++++++++ unpack-trees.c | 5 ++--- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index d967d188a3..f176dd28c8 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1368,9 +1368,8 @@ static void fix_unresolved_deltas(struct hashfile *f) continue; oid_array_append(&to_fetch, &d->oid); } - if (to_fetch.nr) - promisor_remote_get_direct(the_repository, - to_fetch.oid, to_fetch.nr); + promisor_remote_get_direct(the_repository, + to_fetch.oid, to_fetch.nr); oid_array_clear(&to_fetch); } diff --git a/diff.c b/diff.c index 1010d806f5..f01b4d91b8 100644 --- a/diff.c +++ b/diff.c @@ -6520,12 +6520,11 @@ void diffcore_std(struct diff_options *options) add_if_missing(options->repo, &to_fetch, p->one); add_if_missing(options->repo, &to_fetch, p->two); } - if (to_fetch.nr) - /* - * NEEDSWORK: Consider deduplicating the OIDs sent. - */ - promisor_remote_get_direct(options->repo, - to_fetch.oid, to_fetch.nr); + /* + * NEEDSWORK: Consider deduplicating the OIDs sent. + */ + promisor_remote_get_direct(options->repo, + to_fetch.oid, to_fetch.nr); oid_array_clear(&to_fetch); } diff --git a/promisor-remote.c b/promisor-remote.c index 9f338c945f..2155dfe657 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -241,6 +241,9 @@ int promisor_remote_get_direct(struct repository *repo, int to_free = 0; int res = -1; + if (oid_nr == 0) + return 0; + promisor_remote_init(); for (r = promisors; r; r = r->next) { diff --git a/promisor-remote.h b/promisor-remote.h index 737bac3a33..6343c47d18 100644 --- a/promisor-remote.h +++ b/promisor-remote.h @@ -20,6 +20,14 @@ struct promisor_remote { void promisor_remote_reinit(void); struct promisor_remote *promisor_remote_find(const char *remote_name); int has_promisor_remote(void); + +/* + * Fetches all requested objects from all promisor remotes, trying them one at + * a time until all objects are fetched. Returns 0 upon success, and non-zero + * otherwise. + * + * If oid_nr is 0, this function returns 0 (success) immediately. + */ int promisor_remote_get_direct(struct repository *repo, const struct object_id *oids, int oid_nr); diff --git a/unpack-trees.c b/unpack-trees.c index f618a644ef..4c3191b947 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -423,9 +423,8 @@ static int check_updates(struct unpack_trees_options *o) continue; oid_array_append(&to_fetch, &ce->oid); } - if (to_fetch.nr) - promisor_remote_get_direct(the_repository, - to_fetch.oid, to_fetch.nr); + promisor_remote_get_direct(the_repository, + to_fetch.oid, to_fetch.nr); oid_array_clear(&to_fetch); } for (i = 0; i < index->cache_nr; i++) { From patchwork Tue Apr 7 22:11:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Tan X-Patchwork-Id: 11479047 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 742EA92C for ; Tue, 7 Apr 2020 22:11:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3E72A20747 for ; Tue, 7 Apr 2020 22:11:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="QS5Lq7gM" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726446AbgDGWLw (ORCPT ); Tue, 7 Apr 2020 18:11:52 -0400 Received: from mail-pg1-f202.google.com ([209.85.215.202]:49572 "EHLO mail-pg1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726386AbgDGWLw (ORCPT ); Tue, 7 Apr 2020 18:11:52 -0400 Received: by mail-pg1-f202.google.com with SMTP id d124so3720199pgc.16 for ; Tue, 07 Apr 2020 15:11:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=43MYbE/hyG1izc8rMNXHcDfyydvqL4rfIdexbBL/YP4=; b=QS5Lq7gMSt9uo+66caFZaIubvqYh3e5tnYR3q9HOQeUqBYPc5QUgxuGNLNqCJsEpyO oSurAABFCNNkYB43xJZb6innI0TEK7Hjje6GchsDbjtGIXoQ/uinIM8od321QwRdWREa gBH9hTu1NvwejJ+WW8dlkixysDK1fEqPEp+qLDKPAmCnyMGWjx15jEZ08CQlWETSt6zU vMLvw70L7MpsKkSNwF5JDGhQ0asx6FfSsF06RsnICzW2nKAOF6V4pekvsM7AVOLN6p9w uE97Z6FBwXMhtPr215uPY3SRhRHqgEQ0J7hj3IXqkrydz3FXfo4DU6hMASeZFqWUq78A we/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=43MYbE/hyG1izc8rMNXHcDfyydvqL4rfIdexbBL/YP4=; b=VojrJ3nKDlbn+kpu3VjxY5YlFBcj1AYjtzJOJgWJ3v6Ez/qWr8lp5Xo2fe5ycdN1ZY nP5yXFsM5Ekl3JXsNEvUeUPvTiIHquRzallOKtxe/+6OaTNRKamhg16fzh1VHsjVMnsj tKSyn3HG21NbjdMPf7l1OXAvDKIi835xxxjGDuOtmJuR/gInWwK+gpb2/V1z+e9VOW2l A/jDTgeGCdlCHGlb0b4+thoVskZqmI5n33VB0GunFkwUkvANMOsJjp9BaClt9L5nmJJy 6Aufk13LtV7T0hdjmMp31GnWbYnFsTypOhnrrM7vVvd2H/vQpI3J3eAGy9ybep3zg89g asLw== X-Gm-Message-State: AGi0PuZlVzTRhcRCCcauIqyCc9Nl+CM/YbJiTR2g224MxOq531xkqxC1 4o6TxA7YAT8eagmFCOWlAImo6jT+a/mj2vrzRYE7y8I4m3dgvBwNaBc1RWgOPDQ8C+9EJSRG0kH Gfb0rGc80nJZ7ic4Ade62oE5F2an3/civzGMlArNCbzWGbO7LoUrOKSyyKh2LZAnOBPj4y0//oR RO X-Google-Smtp-Source: APiQypIDIv3613/lL4g3l1RllD90R57164vEWQz+p2nM/awk8gah65btHBFJTsbcwHdqymv/czdp5ULlpTawrlX3uApP X-Received: by 2002:a17:90a:c206:: with SMTP id e6mr1520435pjt.35.1586297510980; Tue, 07 Apr 2020 15:11:50 -0700 (PDT) Date: Tue, 7 Apr 2020 15:11:41 -0700 In-Reply-To: Message-Id: Mime-Version: 1.0 References: <20200331020418.55640-1-jonathantanmy@google.com> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog Subject: [PATCH v3 2/4] diff: make diff_populate_filespec_options struct From: Jonathan Tan To: git@vger.kernel.org Cc: Jonathan Tan , garimasigit@gmail.com, gitster@pobox.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The behavior of diff_populate_filespec() currently can be customized through a bitflag, but a subsequent patch requires it to support a non-boolean option. Replace the bitflag with an options struct. Signed-off-by: Jonathan Tan --- diff.c | 54 ++++++++++++++++++++++++++++++----------------- diffcore-break.c | 4 ++-- diffcore-rename.c | 13 +++++++----- diffcore.h | 9 +++++--- line-log.c | 6 +++--- 5 files changed, 54 insertions(+), 32 deletions(-) diff --git a/diff.c b/diff.c index f01b4d91b8..f337d837ac 100644 --- a/diff.c +++ b/diff.c @@ -573,7 +573,7 @@ static int fill_mmfile(struct repository *r, mmfile_t *mf, mf->size = 0; return 0; } - else if (diff_populate_filespec(r, one, 0)) + else if (diff_populate_filespec(r, one, NULL)) return -1; mf->ptr = one->data; @@ -585,9 +585,13 @@ static int fill_mmfile(struct repository *r, mmfile_t *mf, static unsigned long diff_filespec_size(struct repository *r, struct diff_filespec *one) { + struct diff_populate_filespec_options dpf_options = { + .check_size_only = 1, + }; + if (!DIFF_FILE_VALID(one)) return 0; - diff_populate_filespec(r, one, CHECK_SIZE_ONLY); + diff_populate_filespec(r, one, &dpf_options); return one->size; } @@ -3020,6 +3024,9 @@ static void show_dirstat(struct diff_options *options) struct diff_filepair *p = q->queue[i]; const char *name; unsigned long copied, added, damage; + struct diff_populate_filespec_options dpf_options = { + .check_size_only = 1, + }; name = p->two->path ? p->two->path : p->one->path; @@ -3047,19 +3054,19 @@ static void show_dirstat(struct diff_options *options) } if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) { - diff_populate_filespec(options->repo, p->one, 0); - diff_populate_filespec(options->repo, p->two, 0); + diff_populate_filespec(options->repo, p->one, NULL); + diff_populate_filespec(options->repo, p->two, NULL); diffcore_count_changes(options->repo, p->one, p->two, NULL, NULL, &copied, &added); diff_free_filespec_data(p->one); diff_free_filespec_data(p->two); } else if (DIFF_FILE_VALID(p->one)) { - diff_populate_filespec(options->repo, p->one, CHECK_SIZE_ONLY); + diff_populate_filespec(options->repo, p->one, &dpf_options); copied = added = 0; diff_free_filespec_data(p->one); } else if (DIFF_FILE_VALID(p->two)) { - diff_populate_filespec(options->repo, p->two, CHECK_SIZE_ONLY); + diff_populate_filespec(options->repo, p->two, &dpf_options); copied = 0; added = p->two->size; diff_free_filespec_data(p->two); @@ -3339,13 +3346,17 @@ static void emit_binary_diff(struct diff_options *o, int diff_filespec_is_binary(struct repository *r, struct diff_filespec *one) { + struct diff_populate_filespec_options dpf_options = { + .check_binary = 1, + }; + if (one->is_binary == -1) { diff_filespec_load_driver(one, r->index); if (one->driver->binary != -1) one->is_binary = one->driver->binary; else { if (!one->data && DIFF_FILE_VALID(one)) - diff_populate_filespec(r, one, CHECK_BINARY); + diff_populate_filespec(r, one, &dpf_options); if (one->is_binary == -1 && one->data) one->is_binary = buffer_is_binary(one->data, one->size); @@ -3677,8 +3688,8 @@ static void builtin_diffstat(const char *name_a, const char *name_b, } else if (complete_rewrite) { - diff_populate_filespec(o->repo, one, 0); - diff_populate_filespec(o->repo, two, 0); + diff_populate_filespec(o->repo, one, NULL); + diff_populate_filespec(o->repo, two, NULL); data->deleted = count_lines(one->data, one->size); data->added = count_lines(two->data, two->size); } @@ -3914,9 +3925,10 @@ static int diff_populate_gitlink(struct diff_filespec *s, int size_only) */ int diff_populate_filespec(struct repository *r, struct diff_filespec *s, - unsigned int flags) + const struct diff_populate_filespec_options *options) { - int size_only = flags & CHECK_SIZE_ONLY; + int size_only = options ? options->check_size_only : 0; + int check_binary = options ? options->check_binary : 0; int err = 0; int conv_flags = global_conv_flags_eol; /* @@ -3986,7 +3998,7 @@ int diff_populate_filespec(struct repository *r, * opening the file and inspecting the contents, this * is probably fine. */ - if ((flags & CHECK_BINARY) && + if (check_binary && s->size > big_file_threshold && s->is_binary == -1) { s->is_binary = 1; return 0; @@ -4012,7 +4024,7 @@ int diff_populate_filespec(struct repository *r, } else { enum object_type type; - if (size_only || (flags & CHECK_BINARY)) { + if (size_only || check_binary) { type = oid_object_info(r, &s->oid, &s->size); if (type < 0) die("unable to read %s", @@ -4144,7 +4156,7 @@ static struct diff_tempfile *prepare_temp_file(struct repository *r, return temp; } else { - if (diff_populate_filespec(r, one, 0)) + if (diff_populate_filespec(r, one, NULL)) die("cannot read data blob for %s", one->path); prep_temp_blob(r->index, name, temp, one->data, one->size, @@ -6410,9 +6422,9 @@ static int diff_filespec_is_identical(struct repository *r, { if (S_ISGITLINK(one->mode)) return 0; - if (diff_populate_filespec(r, one, 0)) + if (diff_populate_filespec(r, one, NULL)) return 0; - if (diff_populate_filespec(r, two, 0)) + if (diff_populate_filespec(r, two, NULL)) return 0; return !memcmp(one->data, two->data, one->size); } @@ -6420,6 +6432,10 @@ static int diff_filespec_is_identical(struct repository *r, static int diff_filespec_check_stat_unmatch(struct repository *r, struct diff_filepair *p) { + struct diff_populate_filespec_options dpf_options = { + .check_size_only = 1, + }; + if (p->done_skip_stat_unmatch) return p->skip_stat_unmatch_result; @@ -6442,8 +6458,8 @@ static int diff_filespec_check_stat_unmatch(struct repository *r, !DIFF_FILE_VALID(p->two) || (p->one->oid_valid && p->two->oid_valid) || (p->one->mode != p->two->mode) || - diff_populate_filespec(r, p->one, CHECK_SIZE_ONLY) || - diff_populate_filespec(r, p->two, CHECK_SIZE_ONLY) || + diff_populate_filespec(r, p->one, &dpf_options) || + diff_populate_filespec(r, p->two, &dpf_options) || (p->one->size != p->two->size) || !diff_filespec_is_identical(r, p->one, p->two)) /* (2) */ p->skip_stat_unmatch_result = 1; @@ -6773,7 +6789,7 @@ size_t fill_textconv(struct repository *r, *outbuf = ""; return 0; } - if (diff_populate_filespec(r, df, 0)) + if (diff_populate_filespec(r, df, NULL)) die("unable to read files to diff"); *outbuf = df->data; return df->size; diff --git a/diffcore-break.c b/diffcore-break.c index 9d20a6a6fc..e8f6322c6a 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -62,8 +62,8 @@ static int should_break(struct repository *r, oideq(&src->oid, &dst->oid)) return 0; /* they are the same */ - if (diff_populate_filespec(r, src, 0) || - diff_populate_filespec(r, dst, 0)) + if (diff_populate_filespec(r, src, NULL) || + diff_populate_filespec(r, dst, NULL)) return 0; /* error but caught downstream */ max_size = ((src->size > dst->size) ? src->size : dst->size); diff --git a/diffcore-rename.c b/diffcore-rename.c index e189f407af..bf4c0b8740 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -148,6 +148,9 @@ static int estimate_similarity(struct repository *r, */ unsigned long max_size, delta_size, base_size, src_copied, literal_added; int score; + struct diff_populate_filespec_options dpf_options = { + .check_size_only = 1 + }; /* We deal only with regular files. Symlink renames are handled * only when they are exact matches --- in other words, no edits @@ -166,10 +169,10 @@ static int estimate_similarity(struct repository *r, * say whether the size is valid or not!) */ if (!src->cnt_data && - diff_populate_filespec(r, src, CHECK_SIZE_ONLY)) + diff_populate_filespec(r, src, &dpf_options)) return 0; if (!dst->cnt_data && - diff_populate_filespec(r, dst, CHECK_SIZE_ONLY)) + diff_populate_filespec(r, dst, &dpf_options)) return 0; max_size = ((src->size > dst->size) ? src->size : dst->size); @@ -187,9 +190,9 @@ 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, 0)) + if (!src->cnt_data && diff_populate_filespec(r, src, NULL)) return 0; - if (!dst->cnt_data && diff_populate_filespec(r, dst, 0)) + if (!dst->cnt_data && diff_populate_filespec(r, dst, NULL)) return 0; if (diffcore_count_changes(r, src, dst, @@ -261,7 +264,7 @@ static unsigned int hash_filespec(struct repository *r, struct diff_filespec *filespec) { if (!filespec->oid_valid) { - if (diff_populate_filespec(r, filespec, 0)) + if (diff_populate_filespec(r, filespec, NULL)) return 0; hash_object_file(r->hash_algo, filespec->data, filespec->size, "blob", &filespec->oid); diff --git a/diffcore.h b/diffcore.h index 7c07347e42..3b2020ce93 100644 --- a/diffcore.h +++ b/diffcore.h @@ -65,9 +65,12 @@ void free_filespec(struct diff_filespec *); void fill_filespec(struct diff_filespec *, const struct object_id *, int, unsigned short); -#define CHECK_SIZE_ONLY 1 -#define CHECK_BINARY 2 -int diff_populate_filespec(struct repository *, struct diff_filespec *, unsigned int); +struct diff_populate_filespec_options { + unsigned check_size_only : 1; + unsigned check_binary : 1; +}; +int diff_populate_filespec(struct repository *, struct diff_filespec *, + const struct diff_populate_filespec_options *); void diff_free_filespec_data(struct diff_filespec *); void diff_free_filespec_blob(struct diff_filespec *); int diff_filespec_is_binary(struct repository *, struct diff_filespec *); diff --git a/line-log.c b/line-log.c index 9010e00950..40e1738dbb 100644 --- a/line-log.c +++ b/line-log.c @@ -519,7 +519,7 @@ static void fill_line_ends(struct repository *r, unsigned long *ends = NULL; char *data = NULL; - if (diff_populate_filespec(r, spec, 0)) + if (diff_populate_filespec(r, spec, NULL)) die("Cannot read blob %s", oid_to_hex(&spec->oid)); ALLOC_ARRAY(ends, size); @@ -1045,12 +1045,12 @@ static int process_diff_filepair(struct rev_info *rev, return 0; assert(pair->two->oid_valid); - diff_populate_filespec(rev->diffopt.repo, pair->two, 0); + diff_populate_filespec(rev->diffopt.repo, pair->two, NULL); file_target.ptr = pair->two->data; file_target.size = pair->two->size; if (pair->one->oid_valid) { - diff_populate_filespec(rev->diffopt.repo, pair->one, 0); + diff_populate_filespec(rev->diffopt.repo, pair->one, NULL); file_parent.ptr = pair->one->data; file_parent.size = pair->one->size; } else { From patchwork Tue Apr 7 22:11:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Tan X-Patchwork-Id: 11479049 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C3F2D159A for ; Tue, 7 Apr 2020 22:11:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A2FB52074F for ; Tue, 7 Apr 2020 22:11:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="dcBXGuSN" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726469AbgDGWLz (ORCPT ); Tue, 7 Apr 2020 18:11:55 -0400 Received: from mail-pj1-f74.google.com ([209.85.216.74]:35487 "EHLO mail-pj1-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726386AbgDGWLz (ORCPT ); Tue, 7 Apr 2020 18:11:55 -0400 Received: by mail-pj1-f74.google.com with SMTP id nk12so858553pjb.0 for ; Tue, 07 Apr 2020 15:11:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=SfiPv0d5hANtFtTTJf19/5S09fI2BAcLImCQQ0YC5GM=; b=dcBXGuSNyjjHz9aFZFOlQgFL+VnvxkFBbBaHcj31Ig19KQrsR5juFiGfBN5RNUVrUE 29xWDIKozn2K3BGFvQOgmJJ3fSp9bHwm5GmJ2FMkD95kZpwuzZvGrWA7vwH7rjKsqU97 1gt5KqMIVdRrd4e0zbzsGDUUdHTm4oxSoDTwGb8DJyHF4eTcFXkH7zmpOoCi7dGS4Ry0 uXzhm3X7SmpydLnqT9nyvkT6+Cx490tVBSP63HgI8of8KQYJ8aV2Hn5tBdKpovSswvd4 GVi0IbYD5Ot7cyhjEoW5oAViiWLLY4ysd8/O0KLEoh7D/h4cOX1QkNOYoYSXhAcF8BOw uFKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=SfiPv0d5hANtFtTTJf19/5S09fI2BAcLImCQQ0YC5GM=; b=WgijeYBt2BPk5eZN52SJEAqTBo/wO+4Ikk9HjekKKEcARVvbi5J+Y+ZljPqz5mb13h R1V90blHmtnZz51QaDwPRlT4U6umTr7XZKX/sjvi6TW+d1eNfeHZWcTC//4ANjEkeshL 0464EObVvom5PaXzpLn1/yPettLYLOoMK1HZQbs1nsdvgRC0ccpsGqe1elelWaeH6Ouq YAzAQOeRGzQuBTsc/exevZFjzegkhvtJHTaU3D29pM0XCnlToaV6MXZe/B+K3aMc1Xaa EVs10uCSVAHaixW5VsJGvKqlGpwY5FlTiX96zomPZInWXFD+atFRwPIl8S7ImN8MNHML STBQ== X-Gm-Message-State: AGi0PubMnLk2Htr7D4ArmegCunqh6xOyIj6MjpT5s4fAUUPg2B0JBlKr XslUBOzl8Pob3dwp7yFwwm69YhCfEM0lHvb77UzGxqwE5NCKnirr9XVHUFw/X4rDJ7Zqnh56SAD mCcmYK0WVVUyybcodQgTkWm13NSUC1uvoJobGhBt36RX2bBQlUKBGKs2z7ytTfliAzNA9XcnNOQ NE X-Google-Smtp-Source: APiQypLh/AJZ5jPcCaQbyiqfOEm6YndU3tukd6o2rfsM/nZT5KuYp6qPjuuAQiBk9YBJGyZdWvhXBM8Cq7CaL52dtu1+ X-Received: by 2002:a63:8041:: with SMTP id j62mr3809263pgd.273.1586297513173; Tue, 07 Apr 2020 15:11:53 -0700 (PDT) Date: Tue, 7 Apr 2020 15:11:42 -0700 In-Reply-To: Message-Id: <34c239aa07233d5fc71c1e3cc2ea0ad32ad2bf78.1586296510.git.jonathantanmy@google.com> Mime-Version: 1.0 References: <20200331020418.55640-1-jonathantanmy@google.com> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog Subject: [PATCH v3 3/4] diff: refactor object read From: Jonathan Tan To: git@vger.kernel.org Cc: Jonathan Tan , garimasigit@gmail.com, gitster@pobox.com Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Refactor the object reads in diff_populate_filespec() to have the first object read not be in an if/else branch, because in a future patch, a retry will be added to that first object read. Signed-off-by: Jonathan Tan --- diff.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/diff.c b/diff.c index f337d837ac..8db981b906 100644 --- a/diff.c +++ b/diff.c @@ -4023,12 +4023,22 @@ int diff_populate_filespec(struct repository *r, } } else { - enum object_type type; + struct object_info info = { + .sizep = &s->size + }; + + if (!(size_only || check_binary)) + /* + * Set contentp, since there is no chance that merely + * the size is sufficient. + */ + info.contentp = &s->data; + + if (oid_object_info_extended(r, &s->oid, &info, + OBJECT_INFO_LOOKUP_REPLACE)) + die("unable to read %s", oid_to_hex(&s->oid)); + if (size_only || check_binary) { - type = oid_object_info(r, &s->oid, &s->size); - if (type < 0) - die("unable to read %s", - oid_to_hex(&s->oid)); if (size_only) return 0; if (s->size > big_file_threshold && s->is_binary == -1) { @@ -4036,9 +4046,12 @@ int diff_populate_filespec(struct repository *r, return 0; } } - s->data = repo_read_object_file(r, &s->oid, &type, &s->size); - if (!s->data) - die("unable to read %s", oid_to_hex(&s->oid)); + if (!info.contentp) { + info.contentp = &s->data; + if (oid_object_info_extended(r, &s->oid, &info, + OBJECT_INFO_LOOKUP_REPLACE)) + die("unable to read %s", oid_to_hex(&s->oid)); + } s->should_free = 1; } return 0; From patchwork Tue Apr 7 22:11:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Tan X-Patchwork-Id: 11479051 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D303C159A for ; Tue, 7 Apr 2020 22:11:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9C8052075E for ; Tue, 7 Apr 2020 22:11:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="PwzE3S3I" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726481AbgDGWL6 (ORCPT ); Tue, 7 Apr 2020 18:11:58 -0400 Received: from mail-pf1-f202.google.com ([209.85.210.202]:39301 "EHLO mail-pf1-f202.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726386AbgDGWL6 (ORCPT ); Tue, 7 Apr 2020 18:11:58 -0400 Received: by mail-pf1-f202.google.com with SMTP id x189so3664483pfd.6 for ; Tue, 07 Apr 2020 15:11:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=xbnHtHtDrH2y9KBSX9107Uch0U5c+Fj0/bg20AFOJPU=; b=PwzE3S3Irf9+DzSTc++jeuN+pZVgJurKeYD0xAnvN+ZE5hYSsvKthukxA9IJ2T/EUs GvdJx7f04N1iZ+mKnQHnj7qXafH9zlZ69uwseSfpqoTJbX21gZZPy8vdu5XNna2SJcOP x+vOBjLWiNxnwEBJr/nK69jgPLhu4b7wMrJvwr3AOm0PlGeV4ca5c4HJDeJY0ZVCLCoA cUxibyelkPijnN21YWd1fbb/ExcZRniceS1p1j2MTu4ziGMp4xtuy4/VfCcXLRlz56i0 mwiGBHRom2ZHjzWGodk4uaz+Ji8xQ1GYrYa7KrEhFNeWQhg+pZmaXDRqJfkd+wlIAKQE ex5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=xbnHtHtDrH2y9KBSX9107Uch0U5c+Fj0/bg20AFOJPU=; b=i4fLCeWiT7y+O8J+gopxVpbiLiEhBpuKs9e9nHnt3K1P27l4UF6qoiotgw2lmWGo2M ax3OfGi3TM+jdGoPKlHK6pwvVVbNncoNTMxc42iuOQ3NXYbfYEIvclt5PAfGhFsiLgk7 jlpFTBExcv4vxFgOPczmQCtNRfIYmNqAJ5Toj87ka1LrPbxzfW1bAX232xmIY/PRlApv vX3hnGuIrU7VGbTf7vZMc3XIpjANk2gyDyy8FQXBRwl6tD+K63Q9entFPRlepy7eXs6T 2ifTDzITEaj3yBdZwPc+dD6tqYTcbxZROS6S0TlUV+fm2NtIEYuXk566pu0Fk+3ZMiHC IlPA== X-Gm-Message-State: AGi0PuYcyJCU3vOfljgK8QIzgKcvdYBAHzep+zfhRKkEGwJQZ8zfx/vE nXeAqCgpOA02AqAE/upQcKMzB9v+k/GftXX0aaqCxmYLI6mhm6Iz8Uu/vg1TjXXozxFnB7vXKOH 0F+qgBLMu/A8ge8IdD2i/zm7WoU/iBdkbbA4S8RUNt0FdESn8J7cWu2fBeWPYIgcW/o7REsDtG/ ST X-Google-Smtp-Source: APiQypLptkYaelI6i9Z/NFDzQ++jT06570CosvgJcDu6lS76h8uuUiQ8ooPPm2QllLyfifdvlBDgsFXvJQKwJtuknQ6i X-Received: by 2002:a17:90a:c085:: with SMTP id o5mr1507015pjs.85.1586297515130; Tue, 07 Apr 2020 15:11:55 -0700 (PDT) Date: Tue, 7 Apr 2020 15:11:43 -0700 In-Reply-To: Message-Id: Mime-Version: 1.0 References: <20200331020418.55640-1-jonathantanmy@google.com> X-Mailer: git-send-email 2.26.0.292.g33ef6b2f38-goog Subject: [PATCH v3 4/4] diff: restrict when prefetching occurs From: Jonathan Tan To: git@vger.kernel.org Cc: Jonathan Tan , garimasigit@gmail.com, gitster@pobox.com, Jeff King Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Commit 7fbbcb21b1 ("diff: batch fetching of missing blobs", 2019-04-08) optimized "diff" by prefetching blobs in a partial clone, but there are some cases wherein blobs do not need to be prefetched. In these cases, any command that uses the diff machinery will unnecessarily fetch blobs. diffcore_std() may read blobs when it calls the following functions: (1) diffcore_skip_stat_unmatch() (controlled by the config variable diff.autorefreshindex) (2) diffcore_break() and diffcore_merge_broken() (for break-rewrite detection) (3) diffcore_rename() (for rename detection) (4) diffcore_pickaxe() (for detecting addition/deletion of specified string) Instead of always prefetching blobs, teach diffcore_skip_stat_unmatch(), diffcore_break(), and diffcore_rename() to prefetch blobs upon the first read of a missing object. This covers (1), (2), and (3): to cover the rest, teach diffcore_std() to prefetch if the output type is one that includes blob data (and hence blob data will be required later anyway), or if it knows that (4) will be run. Helped-by: Jeff King Signed-off-by: Jonathan Tan --- diff.c | 73 ++++++++++++++++++++++++----------- diffcore-break.c | 12 +++++- diffcore-rename.c | 55 ++++++++++++++++++++++++-- diffcore.h | 21 ++++++++++ t/t4067-diff-partial-clone.sh | 48 +++++++++++++++++++++++ 5 files changed, 181 insertions(+), 28 deletions(-) diff --git a/diff.c b/diff.c index 8db981b906..d1ad6a3c4a 100644 --- a/diff.c +++ b/diff.c @@ -4034,10 +4034,18 @@ int diff_populate_filespec(struct repository *r, */ info.contentp = &s->data; + if (options && options->missing_object_cb) { + if (!oid_object_info_extended(r, &s->oid, &info, + OBJECT_INFO_LOOKUP_REPLACE | + OBJECT_INFO_SKIP_FETCH_OBJECT)) + goto object_read; + options->missing_object_cb(options->missing_object_data); + } if (oid_object_info_extended(r, &s->oid, &info, OBJECT_INFO_LOOKUP_REPLACE)) die("unable to read %s", oid_to_hex(&s->oid)); +object_read: if (size_only || check_binary) { if (size_only) return 0; @@ -6447,6 +6455,8 @@ static int diff_filespec_check_stat_unmatch(struct repository *r, { struct diff_populate_filespec_options dpf_options = { .check_size_only = 1, + .missing_object_cb = diff_queued_diff_prefetch, + .missing_object_data = r, }; if (p->done_skip_stat_unmatch) @@ -6523,9 +6533,9 @@ void diffcore_fix_diff_index(void) QSORT(q->queue, q->nr, diffnamecmp); } -static void add_if_missing(struct repository *r, - struct oid_array *to_fetch, - const struct diff_filespec *filespec) +void diff_add_if_missing(struct repository *r, + struct oid_array *to_fetch, + const struct diff_filespec *filespec) { if (filespec && filespec->oid_valid && !S_ISGITLINK(filespec->mode) && @@ -6534,29 +6544,48 @@ static void add_if_missing(struct repository *r, oid_array_append(to_fetch, &filespec->oid); } -void diffcore_std(struct diff_options *options) +void diff_queued_diff_prefetch(void *repository) { - if (options->repo == the_repository && has_promisor_remote()) { - /* - * Prefetch the diff pairs that are about to be flushed. - */ - int i; - struct diff_queue_struct *q = &diff_queued_diff; - struct oid_array to_fetch = OID_ARRAY_INIT; + struct repository *repo = repository; + int i; + struct diff_queue_struct *q = &diff_queued_diff; + struct oid_array to_fetch = OID_ARRAY_INIT; - for (i = 0; i < q->nr; i++) { - struct diff_filepair *p = q->queue[i]; - add_if_missing(options->repo, &to_fetch, p->one); - add_if_missing(options->repo, &to_fetch, p->two); - } - /* - * NEEDSWORK: Consider deduplicating the OIDs sent. - */ - promisor_remote_get_direct(options->repo, - to_fetch.oid, to_fetch.nr); - oid_array_clear(&to_fetch); + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + diff_add_if_missing(repo, &to_fetch, p->one); + diff_add_if_missing(repo, &to_fetch, p->two); } + /* + * NEEDSWORK: Consider deduplicating the OIDs sent. + */ + promisor_remote_get_direct(repo, to_fetch.oid, to_fetch.nr); + + oid_array_clear(&to_fetch); +} + +void diffcore_std(struct diff_options *options) +{ + int output_formats_to_prefetch = DIFF_FORMAT_DIFFSTAT | + DIFF_FORMAT_NUMSTAT | + DIFF_FORMAT_PATCH | + DIFF_FORMAT_SHORTSTAT | + DIFF_FORMAT_DIRSTAT; + + /* + * Check if the user requested a blob-data-requiring diff output and/or + * break-rewrite detection (which requires blob data). If yes, prefetch + * the diff pairs. + * + * If no prefetching occurs, diffcore_rename() will prefetch if it + * decides that it needs inexact rename detection. + */ + if (options->repo == the_repository && has_promisor_remote() && + (options->output_format & output_formats_to_prefetch || + options->pickaxe_opts & DIFF_PICKAXE_KINDS_MASK)) + diff_queued_diff_prefetch(options->repo); + /* NOTE please keep the following in sync with diff_tree_combined() */ if (options->skip_stat_unmatch) diffcore_skip_stat_unmatch(options); diff --git a/diffcore-break.c b/diffcore-break.c index e8f6322c6a..0d4a14964d 100644 --- a/diffcore-break.c +++ b/diffcore-break.c @@ -4,6 +4,7 @@ #include "cache.h" #include "diff.h" #include "diffcore.h" +#include "promisor-remote.h" static int should_break(struct repository *r, struct diff_filespec *src, @@ -49,6 +50,8 @@ static int should_break(struct repository *r, unsigned long delta_size, max_size; unsigned long src_copied, literal_added, src_removed; + struct diff_populate_filespec_options options = { 0 }; + *merge_score_p = 0; /* assume no deletion --- "do not break" * is the default. */ @@ -62,8 +65,13 @@ static int should_break(struct repository *r, oideq(&src->oid, &dst->oid)) return 0; /* they are the same */ - if (diff_populate_filespec(r, src, NULL) || - diff_populate_filespec(r, dst, NULL)) + if (r == the_repository && has_promisor_remote()) { + options.missing_object_cb = diff_queued_diff_prefetch; + options.missing_object_data = r; + } + + if (diff_populate_filespec(r, src, &options) || + diff_populate_filespec(r, dst, &options)) return 0; /* error but caught downstream */ max_size = ((src->size > dst->size) ? src->size : dst->size); diff --git a/diffcore-rename.c b/diffcore-rename.c index bf4c0b8740..99e63e90f8 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -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; diff --git a/diffcore.h b/diffcore.h index 3b2020ce93..d2a63c5c71 100644 --- a/diffcore.h +++ b/diffcore.h @@ -65,9 +65,22 @@ void free_filespec(struct diff_filespec *); void fill_filespec(struct diff_filespec *, const struct object_id *, int, unsigned short); +/* + * Prefetch the entries in diff_queued_diff. The parameter is a pointer to a + * struct repository. + */ +void diff_queued_diff_prefetch(void *repository); + struct diff_populate_filespec_options { unsigned check_size_only : 1; unsigned check_binary : 1; + + /* + * If an object is missing, diff_populate_filespec() will invoke this + * callback before attempting to read that object again. + */ + void (*missing_object_cb)(void *); + void *missing_object_data; }; int diff_populate_filespec(struct repository *, struct diff_filespec *, const struct diff_populate_filespec_options *); @@ -185,4 +198,12 @@ int diffcore_count_changes(struct repository *r, unsigned long *src_copied, unsigned long *literal_added); +/* + * If filespec contains an OID and if that object is missing from the given + * repository, add that OID to to_fetch. + */ +void diff_add_if_missing(struct repository *r, + struct oid_array *to_fetch, + const struct diff_filespec *filespec); + #endif diff --git a/t/t4067-diff-partial-clone.sh b/t/t4067-diff-partial-clone.sh index 4831ad35e6..c1ed1c2fc4 100755 --- a/t/t4067-diff-partial-clone.sh +++ b/t/t4067-diff-partial-clone.sh @@ -131,4 +131,52 @@ test_expect_success 'diff with rename detection batches blobs' ' test_line_count = 1 done_lines ' +test_expect_success 'diff does not fetch anything if inexact rename detection is not needed' ' + test_when_finished "rm -rf server client trace" && + + test_create_repo server && + echo a >server/a && + printf "b\nb\nb\nb\nb\n" >server/b && + git -C server add a b && + git -C server commit -m x && + mv server/b server/c && + git -C server add c && + git -C server commit -a -m x && + + test_config -C server uploadpack.allowfilter 1 && + test_config -C server uploadpack.allowanysha1inwant 1 && + git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client && + + # Ensure no fetches. + GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD && + ! test_path_exists trace +' + +test_expect_success 'diff --break-rewrites fetches only if necessary, and batches blobs if it does' ' + test_when_finished "rm -rf server client trace" && + + test_create_repo server && + echo a >server/a && + printf "b\nb\nb\nb\nb\n" >server/b && + git -C server add a b && + git -C server commit -m x && + printf "c\nc\nc\nc\nc\n" >server/b && + git -C server commit -a -m x && + + test_config -C server uploadpack.allowfilter 1 && + test_config -C server uploadpack.allowanysha1inwant 1 && + git clone --bare --filter=blob:limit=0 "file://$(pwd)/server" client && + + # Ensure no fetches. + GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --raw -M HEAD^ HEAD && + ! test_path_exists trace && + + # But with --break-rewrites, ensure that there is exactly 1 negotiation + # by checking that there is only 1 "done" line sent. ("done" marks the + # end of negotiation.) + GIT_TRACE_PACKET="$(pwd)/trace" git -C client diff --break-rewrites --raw -M HEAD^ HEAD && + grep "git> done" trace >done_lines && + test_line_count = 1 done_lines +' + test_done