{"thread":{"id":"1059","subject":"problem with git-diff-tree -S","startedAt":"2005-06-30T12:48:44Z","lastAt":"2005-07-17T08:21:28Z","messageCount":2,"participants":["Paul Mackerras","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"5450","messageId":"17091.59948.453311.980846@cargo.ozlabs.ibm.com","threadId":"1059","inReplyTo":null,"subject":"problem with git-diff-tree -S","fromName":"Paul Mackerras","fromEmail":"paulus@samba.org","sentAt":"2005-06-30T12:48:44Z","receivedAt":"2005-06-30T12:48:44Z","isPatch":false,"sender":{"key":"paulus@samba.org","avatar":"https://avatars.githubusercontent.com/u/1606439?v=4"},"body":"I'm trying to implement a find function in gitk that will find commits\nwhere the patch includes a particular string, using git-diff-tree.\nIt's not doing what I expect - am I expecting the wrong thing, or is\nthere a bug in git-diff-tree?\n\nAs an example, take commit 92a582ed2757456ca9599f8b4ea2064f2154eb02,\n\"[IA64] sparse cleanup of TIOCA files\".  If I put that ID in a file\ncalled id and do:\n\ngit-diff-tree --stdin -p <id\n\nthe resulting patch includes the lines:\n\n-uint64_t\n+static uint64_t\n\n+int sn_topology_open(struct inode *inode, struct file *file);\n+int sn_topology_release(struct inode *inode, struct file *file);\n\n+extern struct list_head tioca_list;\n\nNow if I do:\n\ngit-diff-tree --stdin -r -s -Ssn_topology <id\n\nI get the ID printed to stdout, but if I do:\n\ngit-diff-tree --stdin -r -s -Stioca <id\n\nI get nothing on stdout, and similarly if I use \"-Sstatic\".  What's\ngoing on?\n\nPaul.\n"},{"id":"6211","messageId":"7vek9x3ks7.fsf_-_@assigned-by-dhcp.cox.net","threadId":"1059","inReplyTo":"7vy886e1ry.fsf@assigned-by-dhcp.cox.net","subject":"[PATCH] diffcore-pickaxe: switch to \"counting\" behaviour.","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-07-17T08:21:28Z","receivedAt":"2005-07-17T08:21:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Instead of finding old/new pair that one side has and the\nother side does not have the specified string, find old/new pair\nthat contains the specified string as a substring different\nnumber of times.  This would still not catch a case where you\nintroduce two static variable declarations and remove two static\nfunction definitions from a file with -S\"static\", but would make\nit behave a bit more intuitively.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\n*** Linus, the \"counting\" behaviour that came up in our private\n*** exchange was brought up independently by Paul.  I think it\n*** is a good compromise.\n\n diffcore-pickaxe.c |   23 +++++++++++++++++------\n 1 files changed, 17 insertions(+), 6 deletions(-)\n\n7532cfc15932595d679c16ae007f9a910a5b1d1e\ndiff --git a/diffcore-pickaxe.c b/diffcore-pickaxe.c\n--- a/diffcore-pickaxe.c\n+++ b/diffcore-pickaxe.c\n@@ -5,19 +5,30 @@\n #include \"diff.h\"\n #include \"diffcore.h\"\n \n-static int contains(struct diff_filespec *one,\n-\t\t    const char *needle, unsigned long len)\n+static unsigned int contains(struct diff_filespec *one,\n+\t\t\t     const char *needle, unsigned long len)\n {\n+\tunsigned int cnt;\n \tunsigned long offset, sz;\n \tconst char *data;\n \tif (diff_populate_filespec(one, 0))\n \t\treturn 0;\n+\n \tsz = one->size;\n \tdata = one->data;\n-\tfor (offset = 0; offset + len <= sz; offset++)\n-\t\t     if (!strncmp(needle, data + offset, len))\n-\t\t\t     return 1;\n-\treturn 0;\n+\tcnt = 0;\n+\n+\t/* Yes, I've heard of strstr(), but the thing is *data may\n+\t * not be NUL terminated.  Sue me.\n+\t */\n+\tfor (offset = 0; offset + len <= sz; offset++) {\n+\t\t/* we count non-overlapping occurrences of needle */\n+\t\tif (!memcmp(needle, data + offset, len)) {\n+\t\t\toffset += len - 1;\n+\t\t\tcnt++;\n+\t\t}\n+\t}\n+\treturn cnt;\n }\n \n void diffcore_pickaxe(const char *needle, int opts)\n"}]}