7 #include "list-objects.h"
9 unsigned long default_ignore_size = 50 * 1024 * 1024; /* 50mb */
11 /* porcelain for rev-cache.c */
12 static int handle_add(int argc, const char *argv[]) /* args beyond this command */
15 struct rev_cache_info rci;
17 unsigned int flags = 0;
19 unsigned char cache_sha1[20];
20 struct commit_list *starts = 0, *ends = 0;
21 struct commit *commit;
23 init_revisions(&revs, 0);
24 init_rev_cache_info(&rci);
26 for (i = 0; i < argc; i++) {
27 if (!strcmp(argv[i], "--stdin"))
29 else if (!strcmp(argv[i], "--fresh") || !strcmp(argv[i], "--incremental"))
30 starts_from_slices(&revs, UNINTERESTING, 0, 0);
31 else if (!strcmp(argv[i], "--not"))
32 flags ^= UNINTERESTING;
33 else if (!strcmp(argv[i], "--legs"))
35 else if (!strcmp(argv[i], "--no-objects"))
37 else if (!strcmp(argv[i], "--all")) {
41 args[argn++] = "rev-list";
42 args[argn++] = "--all";
43 setup_revisions(argn, args, &revs, 0);
45 handle_revision_arg(argv[i], &revs, flags, 1);
52 while (fgets(line, sizeof(line), stdin)) {
53 int len = strlen(line);
54 while (len && (line[len - 1] == '\n' || line[len - 1] == '\r'))
60 if (!strcmp(line, "--not"))
61 flags ^= UNINTERESTING;
63 handle_revision_arg(line, &revs, flags, 1);
67 retval = make_cache_slice(&rci, &revs, &starts, &ends, cache_sha1);
71 printf("%s\n", sha1_to_hex(cache_sha1));
73 fprintf(stderr, "endpoints:\n");
74 while ((commit = pop_commit(&starts)))
75 fprintf(stderr, "S %s\n", sha1_to_hex(commit->object.sha1));
76 while ((commit = pop_commit(&ends)))
77 fprintf(stderr, "E %s\n", sha1_to_hex(commit->object.sha1));
82 static void show_commit(struct commit *commit, void *data)
84 printf("%s\n", sha1_to_hex(commit->object.sha1));
87 static void show_object(struct object *obj, const struct name_path *path, const char *last)
89 printf("%s\n", sha1_to_hex(obj->sha1));
92 static int test_rev_list(int argc, const char *argv[])
95 unsigned int flags = 0;
98 init_revisions(&revs, 0);
100 for (i = 0; i < argc; i++) {
101 if (!strcmp(argv[i], "--not"))
102 flags ^= UNINTERESTING;
103 else if (!strcmp(argv[i], "--objects"))
104 revs.tree_objects = revs.blob_objects = 1;
106 handle_revision_arg(argv[i], &revs, flags, 1);
109 setup_revisions(0, 0, &revs, 0);
112 prepare_revision_walk(&revs);
114 traverse_commit_list(&revs, show_commit, show_object, 0);
119 static int handle_walk(int argc, const char *argv[])
121 struct commit *commit;
122 struct rev_info revs;
123 struct commit_list *queue, *work, **qp;
124 unsigned char *sha1p, *sha1pt;
125 unsigned long date = 0;
126 unsigned int flags = 0;
127 int retval, slop = 5, i;
129 init_revisions(&revs, 0);
131 for (i = 0; i < argc; i++) {
132 if (!strcmp(argv[i], "--not"))
133 flags ^= UNINTERESTING;
134 else if (!strcmp(argv[i], "--objects"))
135 revs.tree_objects = revs.blob_objects = 1;
137 handle_revision_arg(argv[i], &revs, flags, 1);
142 for (i = 0; i < revs.pending.nr; i++) {
143 commit = lookup_commit(revs.pending.objects[i].item->sha1);
145 sha1pt = get_cache_slice(commit);
147 die("%s: not in a cache slice", sha1_to_hex(commit->object.sha1));
151 else if (sha1p != sha1pt)
152 die("walking porcelain is /per/ cache slice; commits cannot be spread out amoung several");
154 insert_by_date(commit, &work);
158 die("nothing to traverse!");
162 commit = pop_commit(&work);
163 retval = traverse_cache_slice(&revs, sha1p, commit, &date, &slop, &qp, &work);
167 fprintf(stderr, "queue:\n");
168 while ((commit = pop_commit(&queue)) != 0) {
169 printf("%s\n", sha1_to_hex(commit->object.sha1));
172 fprintf(stderr, "work:\n");
173 while ((commit = pop_commit(&work)) != 0) {
174 printf("%s\n", sha1_to_hex(commit->object.sha1));
177 fprintf(stderr, "pending:\n");
178 for (i = 0; i < revs.pending.nr; i++) {
179 struct object *obj = revs.pending.objects[i].item;
181 /* unfortunately, despite our careful generation, object duplication *is* a possibility...
182 * (eg. same object introduced into two different branches) */
183 if (obj->flags & SEEN)
186 printf("%s\n", sha1_to_hex(revs.pending.objects[i].item->sha1));
193 static int handle_fuse(int argc, const char *argv[])
195 struct rev_info revs;
196 struct rev_cache_info rci;
201 init_revisions(&revs, 0);
202 init_rev_cache_info(&rci);
203 args[argn++] = "rev-list";
205 for (i = 0; i < argc; i++) {
206 if (!strcmp(argv[i], "--all")) {
207 args[argn++] = "--all";
208 setup_revisions(argn, args, &revs, 0);
210 } else if (!strcmp(argv[i], "--no-objects"))
212 else if (!strncmp(argv[i], "--ignore-size", 13)) {
215 if (argv[i][13] == '=')
216 git_parse_ulong(argv[i] + 14, &sz);
218 sz = default_ignore_size;
220 rci.ignore_size = sz;
226 starts_from_slices(&revs, 0, 0, 0);
228 return fuse_cache_slices(&rci, &revs);
231 static int handle_index(int argc, const char *argv[])
233 return regenerate_cache_index(0);
236 static int handle_alt(int argc, const char *argv[])
241 return make_cache_slice_pointer(0, argv[0]);
244 static int handle_help(void)
248 git-rev-cache COMMAND [options] [<commit-id>...]\n\
250 add - add revisions to the cache. reads commit ids from stdin, \n\
251 formatted as: START START ... --not END END ...\n\
253 --all use all branch heads as starts\n\
254 --fresh/--incremental exclude everything already in a cache slice\n\
255 --stdin also read commit ids from stdin (same form\n\
257 --legs ensure branch is entirely self-contained\n\
258 --no-objects don't add non-commit objects to slice\n\
259 walk - walk a cache slice based on set of commits; formatted as add\n\
261 --objects include non-commit objects in traversals\n\
262 fuse - coalesce cache slices into a single cache.\n\
264 --all include all objects in repository\n\
265 --no-objects don't add non-commit objects to slice\n\
266 --ignore-size[=N] ignore slices of size >= N; defaults to ~5MB\n\
267 index - regnerate the cache index.";
274 static int rev_cache_config(const char *k, const char *v, void *cb)
276 /* this could potentially be related to pack.windowmemory, but we want a max around 50mb,
277 * and .windowmemory is often >700mb, with *large* variations */
278 if (!strcmp(k, "revcache.ignoresize")) {
281 t = git_config_ulong(k, v);
283 default_ignore_size = t;
289 int cmd_rev_cache(int argc, const char *argv[], const char *prefix)
294 git_config(git_default_config, NULL);
295 git_config(rev_cache_config, NULL);
304 if (!strcmp(arg, "add"))
305 r = handle_add(argc, argv);
306 else if (!strcmp(arg, "fuse"))
307 r = handle_fuse(argc, argv);
308 else if (!strcmp(arg, "walk"))
309 r = handle_walk(argc, argv);
310 else if (!strcmp(arg, "index"))
311 r = handle_index(argc, argv);
312 else if (!strcmp(arg, "test"))
313 r = test_rev_list(argc, argv);
314 else if (!strcmp(arg, "alt"))
315 r = handle_alt(argc, argv);
317 return handle_help();
319 fprintf(stderr, "final return value: %d\n", r);