]>
Commit | Line | Data |
---|---|---|
84fe9720 | 1 | #include "cache.h" |
5873b67e | 2 | #include "commit.h" |
84fe9720 | 3 | |
28258afe | 4 | /* |
458754a9 LT |
5 | * revision.h leaves the low 16 bits of the "flags" field of the |
6 | * revision data structure unused. We use it for a "reachable from | |
7 | * this commit <N>" bitmask. | |
28258afe | 8 | */ |
458754a9 | 9 | #define MAX_COMMITS 16 |
28258afe LT |
10 | |
11 | static int show_edges = 0; | |
727ff277 | 12 | static int basemask = 0; |
97d9c3cd | 13 | |
84fe9720 LT |
14 | static void read_cache_file(const char *path) |
15 | { | |
5873b67e | 16 | die("no revtree cache file yet"); |
84fe9720 LT |
17 | } |
18 | ||
19 | /* | |
28258afe LT |
20 | * Some revisions are less interesting than others. |
21 | * | |
22 | * For example, if we use a cache-file, that one may contain | |
23 | * revisions that were never used. They are never interesting. | |
24 | * | |
25 | * And sometimes we're only interested in "edge" commits, ie | |
26 | * places where the marking changes between parent and child. | |
27 | */ | |
5873b67e | 28 | static int interesting(struct commit *rev) |
28258afe | 29 | { |
5873b67e | 30 | unsigned mask = rev->object.flags; |
28258afe LT |
31 | |
32 | if (!mask) | |
33 | return 0; | |
34 | if (show_edges) { | |
5873b67e | 35 | struct commit_list *p = rev->parents; |
28258afe | 36 | while (p) { |
5873b67e | 37 | if (mask != p->item->object.flags) |
28258afe LT |
38 | return 1; |
39 | p = p->next; | |
40 | } | |
41 | return 0; | |
42 | } | |
727ff277 DW |
43 | if (mask & basemask) |
44 | return 0; | |
45 | ||
28258afe LT |
46 | return 1; |
47 | } | |
48 | ||
5873b67e DB |
49 | void process_commit(unsigned char *sha1) |
50 | { | |
51 | struct commit_list *parents; | |
52 | struct commit *obj = lookup_commit(sha1); | |
3b7d368f LT |
53 | |
54 | if (obj->object.parsed) | |
55 | return; | |
56 | ||
5873b67e DB |
57 | parse_commit(obj); |
58 | ||
59 | parents = obj->parents; | |
60 | while (parents) { | |
61 | process_commit(parents->item->object.sha1); | |
62 | parents = parents->next; | |
63 | } | |
64 | } | |
65 | ||
28258afe LT |
66 | /* |
67 | * Usage: rev-tree [--edges] [--cache <cache-file>] <commit-id> [<commit-id2>] | |
84fe9720 LT |
68 | * |
69 | * The cache-file can be quite important for big trees. This is an | |
70 | * expensive operation if you have to walk the whole chain of | |
71 | * parents in a tree with a long revision history. | |
72 | */ | |
73 | int main(int argc, char **argv) | |
74 | { | |
75 | int i; | |
28258afe LT |
76 | int nr = 0; |
77 | unsigned char sha1[MAX_COMMITS][20]; | |
84fe9720 | 78 | |
28258afe LT |
79 | /* |
80 | * First - pick up all the revisions we can (both from | |
81 | * caches and from commit file chains). | |
82 | */ | |
83 | for (i = 1; i < argc ; i++) { | |
84 | char *arg = argv[i]; | |
85 | ||
86 | if (!strcmp(arg, "--cache")) { | |
94dfb7f2 | 87 | read_cache_file(argv[++i]); |
28258afe LT |
88 | continue; |
89 | } | |
90 | ||
91 | if (!strcmp(arg, "--edges")) { | |
92 | show_edges = 1; | |
84fe9720 LT |
93 | continue; |
94 | } | |
28258afe | 95 | |
727ff277 DW |
96 | if (arg[0] == '^') { |
97 | arg++; | |
98 | basemask |= 1<<nr; | |
99 | } | |
3c249c95 | 100 | if (nr >= MAX_COMMITS || get_sha1(arg, sha1[nr])) |
28258afe | 101 | usage("rev-tree [--edges] [--cache <cache-file>] <commit-id> [<commit-id>]"); |
5873b67e | 102 | process_commit(sha1[nr]); |
28258afe | 103 | nr++; |
84fe9720 LT |
104 | } |
105 | ||
28258afe LT |
106 | /* |
107 | * Now we have the maximal tree. Walk the different sha files back to the root. | |
108 | */ | |
109 | for (i = 0; i < nr; i++) | |
5873b67e | 110 | mark_reachable(&lookup_commit(sha1[i])->object, 1 << i); |
28258afe LT |
111 | |
112 | /* | |
113 | * Now print out the results.. | |
114 | */ | |
5873b67e DB |
115 | for (i = 0; i < nr_objs; i++) { |
116 | struct object *obj = objs[i]; | |
117 | struct commit *commit; | |
118 | struct commit_list *p; | |
119 | ||
120 | if (obj->type != commit_type) | |
121 | continue; | |
122 | ||
123 | commit = (struct commit *) obj; | |
97d9c3cd | 124 | |
5873b67e | 125 | if (!interesting(commit)) |
28258afe LT |
126 | continue; |
127 | ||
5873b67e DB |
128 | printf("%lu %s:%d", commit->date, sha1_to_hex(obj->sha1), |
129 | obj->flags); | |
130 | p = commit->parents; | |
97d9c3cd | 131 | while (p) { |
5873b67e DB |
132 | printf(" %s:%d", sha1_to_hex(p->item->object.sha1), |
133 | p->item->object.flags); | |
97d9c3cd LT |
134 | p = p->next; |
135 | } | |
136 | printf("\n"); | |
84fe9720 LT |
137 | } |
138 | return 0; | |
139 | } |