Browse Source
This steals the "pickaxe" feature from JIT and make it available to the bare Plumbing layer. From the command line, the user gives a string he is intersted in. Using the diff-core infrastructure previously introduced, it filters the differences to limit the output only to the diffs between <src> and <dst> where the string appears only in one but not in the other. For example: $ ./git-rev-list HEAD | ./git-diff-tree -Sdiff-tree-helper --stdin -M would show the diffs that touch the string "diff-tree-helper". In real software-archaeologist application, you would typically look for a few to several lines of code and see where that code came from. The "pickaxe" module runs after "rename/copy detection" module, so it even crosses the file rename boundary, as the above example demonstrates. Signed-off-by: Junio C Hamano <junkio@cox.net> Signed-off-by: Linus Torvalds <torvalds@osdl.org>maint
Junio C Hamano
20 years ago
committed by
Linus Torvalds
14 changed files with 140 additions and 51 deletions
@ -0,0 +1,56 @@ |
|||||||
|
/* |
||||||
|
* Copyright (C) 2005 Junio C Hamano |
||||||
|
*/ |
||||||
|
#include "cache.h" |
||||||
|
#include "diff.h" |
||||||
|
#include "diffcore.h" |
||||||
|
#include "delta.h" |
||||||
|
|
||||||
|
static int contains(struct diff_filespec *one, |
||||||
|
const char *needle, unsigned long len) |
||||||
|
{ |
||||||
|
unsigned long offset, sz; |
||||||
|
const char *data; |
||||||
|
if (diff_populate_filespec(one)) |
||||||
|
return 0; |
||||||
|
sz = one->size; |
||||||
|
data = one->data; |
||||||
|
for (offset = 0; offset + len <= sz; offset++) |
||||||
|
if (!strncmp(needle, data + offset, len)) |
||||||
|
return 1; |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
void diff_pickaxe(struct diff_queue_struct *q, const char *needle) |
||||||
|
{ |
||||||
|
unsigned long len = strlen(needle); |
||||||
|
int i; |
||||||
|
struct diff_queue_struct outq; |
||||||
|
outq.queue = NULL; |
||||||
|
outq.nr = outq.alloc = 0; |
||||||
|
|
||||||
|
for (i = 0; i < q->nr; i++) { |
||||||
|
struct diff_filepair *p = q->queue[i]; |
||||||
|
if (!p->one->file_valid) { |
||||||
|
if (!p->two->file_valid) |
||||||
|
continue; /* ignore nonsense */ |
||||||
|
/* created */ |
||||||
|
if (contains(p->two, needle, len)) |
||||||
|
diff_queue(&outq, p->one, p->two); |
||||||
|
} |
||||||
|
else if (!p->two->file_valid) { |
||||||
|
if (contains(p->one, needle, len)) |
||||||
|
diff_queue(&outq, p->one, p->two); |
||||||
|
} |
||||||
|
else if (contains(p->one, needle, len) != |
||||||
|
contains(p->two, needle, len)) |
||||||
|
diff_queue(&outq, p->one, p->two); |
||||||
|
} |
||||||
|
for (i = 0; i < q->nr; i++) { |
||||||
|
struct diff_filepair *p = q->queue[i]; |
||||||
|
free(p); |
||||||
|
} |
||||||
|
free(q->queue); |
||||||
|
*q = outq; |
||||||
|
return; |
||||||
|
} |
Loading…
Reference in new issue