This includes the suggestions by Junio, Thanks, Stefan interdiff to currently queued below. Stefan Beller (1): diffcore: add a filter to find a specific blob Documentation/diff-options.txt | 5 +++++ Makefile | 1 + builtin/log.c | 2 +- diff.c | 20 +++++++++++++++++++- diff.h | 3 +++ diffcore-blobfind.c | 41 +++++++++++++++++++++++++++++++++++++++++ diffcore.h | 1 + revision.c | 5 ++++- t/t4064-diff-blobfind.sh | 35 +++++++++++++++++++++++++++++++++++ 9 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 diffcore-blobfind.c create mode 100755 t/t4064-diff-blobfind.sh -- 2.15.1.424.g9478a66081-goog diff --git c/Documentation/diff-options.txt w/Documentation/diff-options.txt index 252a21cc19..34d53b95f1 100644 --- c/Documentation/diff-options.txt +++ w/Documentation/diff-options.txt @@ -500,6 +500,7 @@ information. --pickaxe-regex:: Treat the <string> given to `-S` as an extended POSIX regular expression to match. + --blobfind=<blob-id>:: Restrict the output such that one side of the diff matches the given blob-id. diff --git c/diffcore-blobfind.c w/diffcore-blobfind.c index 5d222fc336..e65c7cad6e 100644 --- c/diffcore-blobfind.c +++ w/diffcore-blobfind.c @@ -8,40 +8,30 @@ static void diffcore_filter_blobs(struct diff_queue_struct *q, struct diff_options *options) { - int i, j = 0, c = q->nr; + int src, dst; if (!options->blobfind) BUG("blobfind oidset not initialized???"); - for (i = 0; i < q->nr; i++) { - struct diff_filepair *p = q->queue[i]; + for (src = dst = 0; src < q->nr; src++) { + struct diff_filepair *p = q->queue[src]; - if (DIFF_PAIR_UNMERGED(p) || - (DIFF_FILE_VALID(p->one) && + if ((DIFF_FILE_VALID(p->one) && oidset_contains(options->blobfind, &p->one->oid)) || (DIFF_FILE_VALID(p->two) && - oidset_contains(options->blobfind, &p->two->oid))) - continue; - - diff_free_filepair(p); - q->queue[i] = NULL; - c--; - } - - /* Keep it sorted. */ - i = 0; j = 0; - while (i < c) { - while (!q->queue[j]) - j++; - q->queue[i] = q->queue[j]; - i++; j++; + oidset_contains(options->blobfind, &p->two->oid))) { + q->queue[dst] = p; + dst++; + } else { + diff_free_filepair(p); + } } - q->nr = c; - - if (!c) { + if (!dst) { free(q->queue); DIFF_QUEUE_CLEAR(q); + } else { + q->nr = dst; } } diff --git c/revision.c w/revision.c index 6449619c0a..8e1a89f832 100644 --- c/revision.c +++ w/revision.c @@ -2884,6 +2884,8 @@ int prepare_revision_walk(struct rev_info *revs) simplify_merges(revs); if (revs->children.name) set_children(revs); + if (revs->diffopt.blobfind) + revs->simplify_history = 0; return 0; }