[PATCH] Introducing software archaeologist's tool "pickaxe".
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>
This commit is contained in:

committed by
Linus Torvalds

parent
427dcb4bca
commit
52e9578985
56
diffcore-pickaxe.c
Normal file
56
diffcore-pickaxe.c
Normal file
@ -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;
|
||||
}
|
Reference in New Issue
Block a user