1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
/*
* Copyright (C) 2005 Junio C Hamano
*/
#include "cache.h"
#include "diff.h"
#include "diffcore.h"
static char **order;
static int order_cnt;
static void prepare_order(const char *orderfile)
{
int fd, cnt, pass;
void *map;
char *cp, *endp;
struct stat st;
size_t sz;
if (order)
return;
fd = open(orderfile, O_RDONLY);
if (fd < 0)
return;
if (fstat(fd, &st)) {
close(fd);
return;
}
sz = xsize_t(st.st_size);
map = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
close(fd);
if (map == MAP_FAILED)
return;
endp = (char *) map + sz;
for (pass = 0; pass < 2; pass++) {
cnt = 0;
cp = map;
while (cp < endp) {
char *ep;
for (ep = cp; ep < endp && *ep != '\n'; ep++)
;
/* cp to ep has one line */
if (*cp == '\n' || *cp == '#')
; /* comment */
else if (pass == 0)
cnt++;
else {
if (*ep == '\n') {
*ep = 0;
order[cnt] = cp;
} else {
order[cnt] = xmemdupz(cp, ep - cp);
}
cnt++;
}
if (ep < endp)
ep++;
cp = ep;
}
if (pass == 0) {
order_cnt = cnt;
order = xmalloc(sizeof(*order) * cnt);
}
}
}
struct pair_order {
struct diff_filepair *pair;
int orig_order;
int order;
};
static int match_order(const char *path)
{
int i;
static struct strbuf p = STRBUF_INIT;
for (i = 0; i < order_cnt; i++) {
strbuf_reset(&p);
strbuf_addstr(&p, path);
while (p.buf[0]) {
char *cp;
if (!fnmatch(order[i], p.buf, 0))
return i;
cp = strrchr(p.buf, '/');
if (!cp)
break;
*cp = 0;
}
}
return order_cnt;
}
static int compare_pair_order(const void *a_, const void *b_)
{
struct pair_order const *a, *b;
a = (struct pair_order const *)a_;
b = (struct pair_order const *)b_;
if (a->order != b->order)
return a->order - b->order;
return a->orig_order - b->orig_order;
}
void diffcore_order(const char *orderfile)
{
struct diff_queue_struct *q = &diff_queued_diff;
struct pair_order *o;
int i;
if (!q->nr)
return;
o = xmalloc(sizeof(*o) * q->nr);
prepare_order(orderfile);
for (i = 0; i < q->nr; i++) {
o[i].pair = q->queue[i];
o[i].orig_order = i;
o[i].order = match_order(o[i].pair->two->path);
}
qsort(o, q->nr, sizeof(*o), compare_pair_order);
for (i = 0; i < q->nr; i++)
q->queue[i] = o[i].pair;
free(o);
return;
}
|