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
;
180 const char *name
= revs
.pending
.objects
[i
].name
;
182 /* unfortunately, despite our careful generation, object duplication *is* a possibility...
183 * (eg. same object introduced into two different branches) */
184 if (obj
->flags
& SEEN
)
187 printf("%s %s\n", sha1_to_hex(revs
.pending
.objects
[i
].item
->sha1
), name
);
194 static int handle_fuse(int argc
, const char *argv
[])
196 struct rev_info revs
;
197 struct rev_cache_info rci
;
202 init_revisions(&revs
, 0);
203 init_rev_cache_info(&rci
);
204 args
[argn
++] = "rev-list";
206 for (i
= 0; i
< argc
; i
++) {
207 if (!strcmp(argv
[i
], "--all")) {
208 args
[argn
++] = "--all";
209 setup_revisions(argn
, args
, &revs
, 0);
211 } else if (!strcmp(argv
[i
], "--no-objects"))
213 else if (!strncmp(argv
[i
], "--ignore-size", 13)) {
216 if (argv
[i
][13] == '=')
217 git_parse_ulong(argv
[i
] + 14, &sz
);
219 sz
= default_ignore_size
;
221 rci
.ignore_size
= sz
;
227 starts_from_slices(&revs
, 0, 0, 0);
229 return fuse_cache_slices(&rci
, &revs
);
232 static int handle_index(int argc
, const char *argv
[])
234 return regenerate_cache_index(0);
237 static int handle_alt(int argc
, const char *argv
[])
242 return make_cache_slice_pointer(0, argv
[0]);
245 static int handle_help(void)
249 git-rev-cache COMMAND [options] [<commit-id>...]\n\
251 add - add revisions to the cache. reads commit ids from stdin, \n\
252 formatted as: START START ... --not END END ...\n\
254 --all use all branch heads as starts\n\
255 --fresh/--incremental exclude everything already in a cache slice\n\
256 --stdin also read commit ids from stdin (same form\n\
258 --legs ensure branch is entirely self-contained\n\
259 --no-objects don't add non-commit objects to slice\n\
260 walk - walk a cache slice based on set of commits; formatted as add\n\
262 --objects include non-commit objects in traversals\n\
263 fuse - coalesce cache slices into a single cache.\n\
265 --all include all objects in repository\n\
266 --no-objects don't add non-commit objects to slice\n\
267 --ignore-size[=N] ignore slices of size >= N; defaults to ~5MB\n\
268 index - regnerate the cache index.";
275 static int rev_cache_config(const char *k
, const char *v
, void *cb
)
277 /* this could potentially be related to pack.windowmemory, but we want a max around 50mb,
278 * and .windowmemory is often >700mb, with *large* variations */
279 if (!strcmp(k
, "revcache.ignoresize")) {
282 t
= git_config_ulong(k
, v
);
284 default_ignore_size
= t
;
290 int cmd_rev_cache(int argc
, const char *argv
[], const char *prefix
)
295 git_config(git_default_config
, NULL
);
296 git_config(rev_cache_config
, NULL
);
305 if (!strcmp(arg
, "add"))
306 r
= handle_add(argc
, argv
);
307 else if (!strcmp(arg
, "fuse"))
308 r
= handle_fuse(argc
, argv
);
309 else if (!strcmp(arg
, "walk"))
310 r
= handle_walk(argc
, argv
);
311 else if (!strcmp(arg
, "index"))
312 r
= handle_index(argc
, argv
);
313 else if (!strcmp(arg
, "test"))
314 r
= test_rev_list(argc
, argv
);
315 else if (!strcmp(arg
, "alt"))
316 r
= handle_alt(argc
, argv
);
318 return handle_help();
320 fprintf(stderr
, "final return value: %d\n", r
);