Jacob Keller <jacob.keller@xxxxxxxxx> writes: > On Thu, Nov 2, 2017 at 10:18 PM, Junio C Hamano <gitster@xxxxxxxxx> wrote: >> ... >> It is easy to imagine that we can restrict "git log" traversal with >> a "--blobchange=<blob>" option instead of (or in addition to) the >> limitation <pathspec> gives us. Instead of treating a commit whose >> diff against its parent commit has any filepair that is different >> within <pathspec> as "!TREESAME", we can treat a commit whose diff >> against its parent commit has a filepair that has the <blob> on >> either side of the filepair as "!TREESAME" (in other words, we >> ignore a transition that is not about introducing or forgetting the >> <blob> we are looking for as an "interesting change"). That would >> give you a commit history graph in which only (and all) such commits >> that either adds or removes the <blob> in it. >> >> Hmm? > > This seems quite useful in the context of figuring out how a file got > to such a state. This is useful to me, since if I know the state of a > file (ie: it's exact contents) I can determine the blob name, and then > use that to lookup where it was introduced. This is probably a bit harder than an average #leftoverbits, but if somebody wants to get their hands dirty, it should be reasonably straightforward. The needed changes would roughly go like so: - Add "struct oid *blob_change;" to diff_options, initialized to NULL. - Teach diff_opt_parse() a new option "--blobchange=<blob>". Allocate a struct oid when you parse this option and point at it with the blob_change field above. - Write diffcore-blobchange.c, modeled after diffcore-pickaxe.c, but this should be a lot simpler (as there is no need for an equivalent for "pickaxe-all" option). It would - prepare an empty diff_queue_struct "outq"; - iterate over the given diff_queue "q", and - a filepair p whose p->one is blob_change and p->two is not, (or the other way around) is added to outq with diff_q() - a filepair whose p->one/p->two do not involve blob_change is freed with diff_free_filepair(). - replace "q" with "outq". - Add a call to diffcore_blobchange() early in diffcore_std(), probably immediately after skip-stat-unmatch, when blob_change field is not NULL. - Arrange that blob_change is propagated to revs->pruning in setup_revisions().