Commit | Line | Data |
---|---|---|
52e95789 JH |
1 | /* |
2 | * Copyright (C) 2005 Junio C Hamano | |
3 | */ | |
4 | #include "cache.h" | |
5 | #include "diff.h" | |
6 | #include "diffcore.h" | |
7 | #include "delta.h" | |
8 | ||
9 | static int contains(struct diff_filespec *one, | |
10 | const char *needle, unsigned long len) | |
11 | { | |
12 | unsigned long offset, sz; | |
13 | const char *data; | |
14 | if (diff_populate_filespec(one)) | |
15 | return 0; | |
16 | sz = one->size; | |
17 | data = one->data; | |
18 | for (offset = 0; offset + len <= sz; offset++) | |
19 | if (!strncmp(needle, data + offset, len)) | |
20 | return 1; | |
21 | return 0; | |
22 | } | |
23 | ||
367cec1c | 24 | void diffcore_pickaxe(const char *needle, int opts) |
52e95789 | 25 | { |
38c6f780 | 26 | struct diff_queue_struct *q = &diff_queued_diff; |
52e95789 | 27 | unsigned long len = strlen(needle); |
367cec1c | 28 | int i, has_changes; |
52e95789 JH |
29 | struct diff_queue_struct outq; |
30 | outq.queue = NULL; | |
31 | outq.nr = outq.alloc = 0; | |
32 | ||
367cec1c JH |
33 | if (opts & DIFF_PICKAXE_ALL) { |
34 | /* Showing the whole changeset if needle exists */ | |
35 | for (i = has_changes = 0; !has_changes && i < q->nr; i++) { | |
36 | struct diff_filepair *p = q->queue[i]; | |
37 | if (!DIFF_FILE_VALID(p->one)) { | |
38 | if (!DIFF_FILE_VALID(p->two)) | |
39 | continue; /* ignore unmerged */ | |
40 | /* created */ | |
41 | if (contains(p->two, needle, len)) | |
42 | has_changes++; | |
43 | } | |
44 | else if (!DIFF_FILE_VALID(p->two)) { | |
45 | if (contains(p->one, needle, len)) | |
46 | has_changes++; | |
47 | } | |
48 | else if (!diff_unmodified_pair(p) && | |
49 | contains(p->one, needle, len) != | |
50 | contains(p->two, needle, len)) | |
51 | has_changes++; | |
52e95789 | 52 | } |
367cec1c JH |
53 | if (has_changes) |
54 | return; /* not munge the queue */ | |
55 | ||
56 | /* otherwise we will clear the whole queue | |
57 | * by copying the empty outq at the end of this | |
58 | * function, but first clear the current entries | |
59 | * in the queue. | |
60 | */ | |
61 | for (i = 0; i < q->nr; i++) | |
62 | diff_free_filepair(q->queue[i]); | |
63 | } | |
64 | else | |
65 | /* Showing only the filepairs that has the needle */ | |
66 | for (i = 0; i < q->nr; i++) { | |
67 | struct diff_filepair *p = q->queue[i]; | |
68 | has_changes = 0; | |
69 | if (!DIFF_FILE_VALID(p->one)) { | |
70 | if (!DIFF_FILE_VALID(p->two)) | |
71 | ; /* ignore unmerged */ | |
72 | /* created */ | |
73 | else if (contains(p->two, needle, len)) | |
74 | has_changes = 1; | |
75 | } | |
76 | else if (!DIFF_FILE_VALID(p->two)) { | |
77 | if (contains(p->one, needle, len)) | |
78 | has_changes = 1; | |
79 | } | |
80 | else if (!diff_unmodified_pair(p) && | |
81 | contains(p->one, needle, len) != | |
82 | contains(p->two, needle, len)) | |
83 | has_changes = 1; | |
84 | ||
85 | if (has_changes) | |
6b14d7fa | 86 | diff_q(&outq, p); |
367cec1c JH |
87 | else |
88 | diff_free_filepair(p); | |
52e95789 | 89 | } |
367cec1c | 90 | |
52e95789 JH |
91 | free(q->queue); |
92 | *q = outq; | |
93 | return; | |
94 | } |