2 * Copyright (C) 2011 Kirill Smelkov <kirr@navytux.spb.ru>
4 * This program is free software: you can Use, Study, Modify and Redistribute it
5 * under the terms of the GNU General Public License version 2. This program is
6 * distributed WITHOUT ANY WARRANTY. See COPYING file for full License terms.
10 #include "navymail/gbox-walk.h"
14 /* TODO die -> error codes */
15 void prepare_gbox_walk(struct gbox_walk
*w
)
17 /* TODO convert to argv_array */
18 const char *rev_argv
[3];
21 rev_argv
[rev_argc
++] = NULL
;
22 if (w
->original_order
)
23 rev_argv
[rev_argc
++] = "--reverse";
24 rev_argv
[rev_argc
++] = w
->gbox
;
27 init_revisions(&w
->revs
, NULL
/*prefix - ok?*/);
28 if (setup_revisions(rev_argc
, rev_argv
, &w
->revs
, NULL
) != 1)
29 die("gbox-walk: setup revision failed");
31 /* unmark revs.pending commits as seen, so gbox walking could be used
32 * several times (this mimics git/handle_commit() a bit
34 for (i
= 0; i
< w
->revs
.pending
.nr
; ++i
) {
35 struct object
*object
= w
->revs
.pending
.objects
[i
].item
;
38 while (object
->type
== OBJ_TAG
) {
39 struct tag
*tag
= (struct tag
*) object
;
42 object
= parse_object(tag
->tagged
->sha1
);
44 die("bad object %s", sha1_to_hex(tag
->tagged
->sha1
));
47 if (object
->type
== OBJ_COMMIT
)
48 clear_commit_marks((struct commit
*)object
, SEEN
| UNINTERESTING
| SHOWN
| ADDED
);
52 if (prepare_revision_walk(&w
->revs
))
53 die("gbox-walk: revision walk setup failed");
56 w
->tree_entries
.sha1
= NULL
; /* = SHA1_ARRAY_INIT */
61 const unsigned char * /*sha1*/ next_gbox_entry(struct gbox_walk
*w
)
63 struct name_entry entry
;
66 /* see, if we need to fetch next commit */
68 struct commit
*commit
;
70 commit
= get_revision(&w
->revs
);
74 /* printf("%s\n", sha1_to_hex(commit->object.sha1)); */
75 w
->tree
= commit
->tree
;
76 if (parse_tree(w
->tree
))
77 die("gbox-walk: parse_tree failed");
79 init_tree_desc(&w
->tree_desc
, w
->tree
->buffer
, w
->tree
->size
);
82 /* preload the tree for original order */
83 if (w
->original_order
) {
84 while (tree_entry(&w
->tree_desc
, &entry
))
85 sha1_array_append(&w
->tree_entries
, entry
.sha1
);
87 w
->entry_idx
= w
->tree_entries
.nr
- 1;
92 /* fast case - walking gbox in reverse order */
93 if (!w
->original_order
) {
94 if (tree_entry(&w
->tree_desc
, &entry
))
98 /* slow case - exporting mbox in original order */
100 if (w
->entry_idx
>= 0)
101 return w
->tree_entries
.sha1
[w
->entry_idx
--];
103 sha1_array_clear(&w
->tree_entries
);
107 /* restart from next commit */