summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2012-12-18 10:50:07 -0800
committerJunio C Hamano <gitster@pobox.com>2012-12-18 10:50:07 -0800
commit8e8c8817cd3e61d974e02f7276ded1f4cb97d8f3 (patch)
treeb0c53545af2a313e94ecb59663417840f00f879b
parent31d66aa4084cb292b15cfdcd6ff73f22f45ab9af (diff)
parentef90ab66e8eaa863777a8d383c5af2ff43a426d2 (diff)
downloadgit-8e8c8817cd3e61d974e02f7276ded1f4cb97d8f3.tar.gz
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.
-rw-r--r--diffcore-pickaxe.c61
-rwxr-xr-xt/t4030-diff-textconv.sh12
2 files changed, 54 insertions, 19 deletions
diff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c
index a209376354..b097fa7661 100644
--- a/diffcore-pickaxe.c
+++ b/diffcore-pickaxe.c
@@ -157,19 +157,15 @@ static void diffcore_pickaxe_grep(struct diff_options *o)
return;
}
-static unsigned int contains(struct diff_filespec *one, struct diff_options *o,
+static unsigned int contains(mmfile_t *mf, struct diff_options *o,
regex_t *regexp, kwset_t kws)
{
unsigned int cnt;
unsigned long sz;
const char *data;
- if (!o->pickaxe[0])
- return 0;
- if (diff_populate_filespec(one, 0))
- return 0;
- sz = one->size;
- data = one->data;
+ sz = mf->size;
+ data = mf->ptr;
cnt = 0;
if (regexp) {
@@ -199,26 +195,53 @@ static unsigned int contains(struct diff_filespec *one, struct diff_options *o,
cnt++;
}
}
- diff_free_filespec_data(one);
return cnt;
}
static int has_changes(struct diff_filepair *p, struct diff_options *o,
regex_t *regexp, kwset_t kws)
{
- if (!DIFF_FILE_VALID(p->one)) {
- if (!DIFF_FILE_VALID(p->two))
- return 0; /* ignore unmerged */
+ struct userdiff_driver *textconv_one = get_textconv(p->one);
+ struct userdiff_driver *textconv_two = get_textconv(p->two);
+ mmfile_t mf1, mf2;
+ int ret;
+
+ if (!o->pickaxe[0])
+ return 0;
+
+ /*
+ * If we have an unmodified pair, we know that the count will be the
+ * same and don't even have to load the blobs. Unless textconv is in
+ * play, _and_ we are using two different textconv filters (e.g.,
+ * because a pair is an exact rename with different textconv attributes
+ * for each side, which might generate different content).
+ */
+ if (textconv_one == textconv_two && diff_unmodified_pair(p))
+ return 0;
+
+ fill_one(p->one, &mf1, &textconv_one);
+ fill_one(p->two, &mf2, &textconv_two);
+
+ if (!mf1.ptr) {
+ if (!mf2.ptr)
+ ret = 0; /* ignore unmerged */
/* created */
- return contains(p->two, o, regexp, kws) != 0;
- }
- if (!DIFF_FILE_VALID(p->two))
- return contains(p->one, o, regexp, kws) != 0;
- if (!diff_unmodified_pair(p)) {
- return contains(p->one, o, regexp, kws) !=
- contains(p->two, o, regexp, kws);
+ ret = contains(&mf2, o, regexp, kws) != 0;
}
- return 0;
+ else if (!mf2.ptr) /* removed */
+ ret = contains(&mf1, o, regexp, kws) != 0;
+ else
+ ret = contains(&mf1, o, regexp, kws) !=
+ contains(&mf2, o, regexp, kws);
+
+ if (textconv_one)
+ free(mf1.ptr);
+ if (textconv_two)
+ free(mf2.ptr);
+ diff_free_filespec_data(p->one);
+ diff_free_filespec_data(p->two);
+
+ return ret;
}
static void diffcore_pickaxe_count(struct diff_options *o)
diff --git a/t/t4030-diff-textconv.sh b/t/t4030-diff-textconv.sh
index 461d27ac20..53ec330ce8 100755
--- a/t/t4030-diff-textconv.sh
+++ b/t/t4030-diff-textconv.sh
@@ -96,6 +96,18 @@ test_expect_success 'grep-diff (-G) operates on textconv data (modification)' '
test_cmp expect actual
'
+test_expect_success 'pickaxe (-S) operates on textconv data (add)' '
+ echo one >expect &&
+ git log --root --format=%s -S0 >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'pickaxe (-S) operates on textconv data (modification)' '
+ echo two >expect &&
+ git log --root --format=%s -S1 >actual &&
+ test_cmp expect actual
+'
+
cat >expect.stat <<'EOF'
file | Bin 2 -> 4 bytes
1 file changed, 0 insertions(+), 0 deletions(-)