Commit | Line | Data |
---|---|---|
f5dd754c JS |
1 | #include "blame.h" |
2 | ||
3 | void blame_origin_decref(struct blame_origin *o) | |
4 | { | |
5 | if (o && --o->refcnt <= 0) { | |
6 | struct blame_origin *p, *l = NULL; | |
7 | if (o->previous) | |
8 | blame_origin_decref(o->previous); | |
9 | free(o->file.ptr); | |
10 | /* Should be present exactly once in commit chain */ | |
11 | for (p = o->commit->util; p; l = p, p = p->next) { | |
12 | if (p == o) { | |
13 | if (l) | |
14 | l->next = p->next; | |
15 | else | |
16 | o->commit->util = p->next; | |
17 | free(o); | |
18 | return; | |
19 | } | |
20 | } | |
21 | die("internal error in blame_origin_decref"); | |
22 | } | |
23 | } | |
24 | ||
25 | /* | |
26 | * Given a commit and a path in it, create a new origin structure. | |
27 | * The callers that add blame to the scoreboard should use | |
28 | * get_origin() to obtain shared, refcounted copy instead of calling | |
29 | * this function directly. | |
30 | */ | |
31 | struct blame_origin *make_origin(struct commit *commit, const char *path) | |
32 | { | |
33 | struct blame_origin *o; | |
34 | FLEX_ALLOC_STR(o, path, path); | |
35 | o->commit = commit; | |
36 | o->refcnt = 1; | |
37 | o->next = commit->util; | |
38 | commit->util = o; | |
39 | return o; | |
40 | } | |
41 | ||
42 | /* | |
43 | * Locate an existing origin or create a new one. | |
44 | * This moves the origin to front position in the commit util list. | |
45 | */ | |
46 | struct blame_origin *get_origin(struct commit *commit, const char *path) | |
47 | { | |
48 | struct blame_origin *o, *l; | |
49 | ||
50 | for (o = commit->util, l = NULL; o; l = o, o = o->next) { | |
51 | if (!strcmp(o->path, path)) { | |
52 | /* bump to front */ | |
53 | if (l) { | |
54 | l->next = o->next; | |
55 | o->next = commit->util; | |
56 | commit->util = o; | |
57 | } | |
58 | return blame_origin_incref(o); | |
59 | } | |
60 | } | |
61 | return make_origin(commit, path); | |
62 | } |