[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
@ -129,7 +129,7 @@ static void record_rename_pair(struct diff_queue_struct *outq,
|
||||
* To achieve this sort order, we give xform_work the number
|
||||
* above.
|
||||
*/
|
||||
struct diff_file_pair *dp = diff_queue(outq, src, dst);
|
||||
struct diff_filepair *dp = diff_queue(outq, src, dst);
|
||||
dp->xfrm_work = (rank * 2 + 1) | (score<<RENAME_SCORE_SHIFT);
|
||||
dst->xfrm_flags |= RENAME_DST_MATCHED;
|
||||
}
|
||||
@ -148,7 +148,7 @@ static void debug_filespec(struct diff_filespec *s, int x, const char *one)
|
||||
s->size, s->xfrm_flags);
|
||||
}
|
||||
|
||||
static void debug_filepair(const struct diff_file_pair *p, int i)
|
||||
static void debug_filepair(const struct diff_filepair *p, int i)
|
||||
{
|
||||
debug_filespec(p->one, i, "one");
|
||||
debug_filespec(p->two, i, "two");
|
||||
@ -165,7 +165,7 @@ static void debug_queue(const char *msg, struct diff_queue_struct *q)
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
fprintf(stderr, "q->nr = %d\n", q->nr);
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_file_pair *p = q->queue[i];
|
||||
struct diff_filepair *p = q->queue[i];
|
||||
debug_filepair(p, i);
|
||||
}
|
||||
}
|
||||
@ -180,8 +180,8 @@ static void debug_queue(const char *msg, struct diff_queue_struct *q)
|
||||
*/
|
||||
static int rank_compare(const void *a_, const void *b_)
|
||||
{
|
||||
const struct diff_file_pair *a = *(const struct diff_file_pair **)a_;
|
||||
const struct diff_file_pair *b = *(const struct diff_file_pair **)b_;
|
||||
const struct diff_filepair *a = *(const struct diff_filepair **)a_;
|
||||
const struct diff_filepair *b = *(const struct diff_filepair **)b_;
|
||||
int a_rank = a->xfrm_work & ((1<<RENAME_SCORE_SHIFT) - 1);
|
||||
int b_rank = b->xfrm_work & ((1<<RENAME_SCORE_SHIFT) - 1);
|
||||
|
||||
@ -207,7 +207,7 @@ static int needs_to_stay(struct diff_queue_struct *q, int i,
|
||||
* as the source of rename/copy), we need to copy, not rename.
|
||||
*/
|
||||
while (i < q->nr) {
|
||||
struct diff_file_pair *p = q->queue[i++];
|
||||
struct diff_filepair *p = q->queue[i++];
|
||||
if (!p->two->file_valid)
|
||||
continue; /* removed is fine */
|
||||
if (strcmp(p->one->path, it->path))
|
||||
@ -243,15 +243,8 @@ void diff_detect_rename(struct diff_queue_struct *q,
|
||||
srcs[0] = &deleted;
|
||||
srcs[1] = &stay;
|
||||
|
||||
/* NEEDSWORK:
|
||||
* (1) make sure we properly ignore but pass trees.
|
||||
*
|
||||
* (2) make sure we do right thing on the same path deleted
|
||||
* and created in the same patch.
|
||||
*/
|
||||
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_file_pair *p = q->queue[i];
|
||||
struct diff_filepair *p = q->queue[i];
|
||||
if (!p->one->file_valid)
|
||||
if (!p->two->file_valid)
|
||||
continue; /* ignore nonsense */
|
||||
@ -340,11 +333,11 @@ void diff_detect_rename(struct diff_queue_struct *q,
|
||||
* See comments at the top of record_rename_pair for numbers used
|
||||
* to assign xfrm_work.
|
||||
*
|
||||
* Note that we have not annotated the diff_file_pair with any comment
|
||||
* Note that we have not annotated the diff_filepair with any comment
|
||||
* so there is nothing other than p to free.
|
||||
*/
|
||||
for (i = 0; i < q->nr; i++) {
|
||||
struct diff_file_pair *dp, *p = q->queue[i];
|
||||
struct diff_filepair *dp, *p = q->queue[i];
|
||||
if (!p->one->file_valid) {
|
||||
if (p->two->file_valid) {
|
||||
/* creation */
|
||||
@ -378,7 +371,7 @@ void diff_detect_rename(struct diff_queue_struct *q,
|
||||
|
||||
/* Copy it out to q, removing duplicates. */
|
||||
for (i = 0; i < outq.nr; i++) {
|
||||
struct diff_file_pair *p = outq.queue[i];
|
||||
struct diff_filepair *p = outq.queue[i];
|
||||
if (!p->one->file_valid) {
|
||||
/* created */
|
||||
if (p->two->xfrm_flags & RENAME_DST_MATCHED)
|
||||
@ -395,7 +388,7 @@ void diff_detect_rename(struct diff_queue_struct *q,
|
||||
}
|
||||
else if (strcmp(p->one->path, p->two->path)) {
|
||||
/* rename or copy */
|
||||
struct diff_file_pair *dp =
|
||||
struct diff_filepair *dp =
|
||||
diff_queue(q, p->one, p->two);
|
||||
int msglen = (strlen(p->one->path) +
|
||||
strlen(p->two->path) + 100);
|
||||
|
||||
Reference in New Issue
Block a user