Skip to content

Commit 8e8c881

Browse files
committed
Merge branch 'jk/pickaxe-textconv' into maint
"git log -p -S<string>" now looks for the <string> after applying the textconv filter (if defined); earlier it inspected the contents of the blobs without filtering.
2 parents 31d66aa + ef90ab6 commit 8e8c881

File tree

2 files changed

+54
-19
lines changed

2 files changed

+54
-19
lines changed

diffcore-pickaxe.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -157,19 +157,15 @@ static void diffcore_pickaxe_grep(struct diff_options *o)
157157
return;
158158
}
159159

160-
static unsigned int contains(struct diff_filespec *one, struct diff_options *o,
160+
static unsigned int contains(mmfile_t *mf, struct diff_options *o,
161161
regex_t *regexp, kwset_t kws)
162162
{
163163
unsigned int cnt;
164164
unsigned long sz;
165165
const char *data;
166-
if (!o->pickaxe[0])
167-
return 0;
168-
if (diff_populate_filespec(one, 0))
169-
return 0;
170166

171-
sz = one->size;
172-
data = one->data;
167+
sz = mf->size;
168+
data = mf->ptr;
173169
cnt = 0;
174170

175171
if (regexp) {
@@ -199,26 +195,53 @@ static unsigned int contains(struct diff_filespec *one, struct diff_options *o,
199195
cnt++;
200196
}
201197
}
202-
diff_free_filespec_data(one);
203198
return cnt;
204199
}
205200

206201
static int has_changes(struct diff_filepair *p, struct diff_options *o,
207202
regex_t *regexp, kwset_t kws)
208203
{
209-
if (!DIFF_FILE_VALID(p->one)) {
210-
if (!DIFF_FILE_VALID(p->two))
211-
return 0; /* ignore unmerged */
204+
struct userdiff_driver *textconv_one = get_textconv(p->one);
205+
struct userdiff_driver *textconv_two = get_textconv(p->two);
206+
mmfile_t mf1, mf2;
207+
int ret;
208+
209+
if (!o->pickaxe[0])
210+
return 0;
211+
212+
/*
213+
* If we have an unmodified pair, we know that the count will be the
214+
* same and don't even have to load the blobs. Unless textconv is in
215+
* play, _and_ we are using two different textconv filters (e.g.,
216+
* because a pair is an exact rename with different textconv attributes
217+
* for each side, which might generate different content).
218+
*/
219+
if (textconv_one == textconv_two && diff_unmodified_pair(p))
220+
return 0;
221+
222+
fill_one(p->one, &mf1, &textconv_one);
223+
fill_one(p->two, &mf2, &textconv_two);
224+
225+
if (!mf1.ptr) {
226+
if (!mf2.ptr)
227+
ret = 0; /* ignore unmerged */
212228
/* created */
213-
return contains(p->two, o, regexp, kws) != 0;
214-
}
215-
if (!DIFF_FILE_VALID(p->two))
216-
return contains(p->one, o, regexp, kws) != 0;
217-
if (!diff_unmodified_pair(p)) {
218-
return contains(p->one, o, regexp, kws) !=
219-
contains(p->two, o, regexp, kws);
229+
ret = contains(&mf2, o, regexp, kws) != 0;
220230
}
221-
return 0;
231+
else if (!mf2.ptr) /* removed */
232+
ret = contains(&mf1, o, regexp, kws) != 0;
233+
else
234+
ret = contains(&mf1, o, regexp, kws) !=
235+
contains(&mf2, o, regexp, kws);
236+
237+
if (textconv_one)
238+
free(mf1.ptr);
239+
if (textconv_two)
240+
free(mf2.ptr);
241+
diff_free_filespec_data(p->one);
242+
diff_free_filespec_data(p->two);
243+
244+
return ret;
222245
}
223246

224247
static void diffcore_pickaxe_count(struct diff_options *o)

t/t4030-diff-textconv.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,18 @@ test_expect_success 'grep-diff (-G) operates on textconv data (modification)' '
9696
test_cmp expect actual
9797
'
9898

99+
test_expect_success 'pickaxe (-S) operates on textconv data (add)' '
100+
echo one >expect &&
101+
git log --root --format=%s -S0 >actual &&
102+
test_cmp expect actual
103+
'
104+
105+
test_expect_success 'pickaxe (-S) operates on textconv data (modification)' '
106+
echo two >expect &&
107+
git log --root --format=%s -S1 >actual &&
108+
test_cmp expect actual
109+
'
110+
99111
cat >expect.stat <<'EOF'
100112
file | Bin 2 -> 4 bytes
101113
1 file changed, 0 insertions(+), 0 deletions(-)

0 commit comments

Comments
 (0)