@@ -52,12 +52,9 @@ static void mark_tree_contents_uninteresting(struct tree *tree)
52
52
{
53
53
struct tree_desc desc ;
54
54
struct name_entry entry ;
55
- struct object * obj = & tree -> object ;
56
55
57
- if (! has_object_file ( & obj -> oid ) )
56
+ if (parse_tree_gently ( tree , 1 ) < 0 )
58
57
return ;
59
- if (parse_tree (tree ) < 0 )
60
- die ("bad tree %s" , oid_to_hex (& obj -> oid ));
61
58
62
59
init_tree_desc (& desc , tree -> buffer , tree -> size );
63
60
while (tree_entry (& desc , & entry )) {
@@ -95,50 +92,63 @@ void mark_tree_uninteresting(struct tree *tree)
95
92
mark_tree_contents_uninteresting (tree );
96
93
}
97
94
98
- void mark_parents_uninteresting (struct commit * commit )
95
+ struct commit_stack {
96
+ struct commit * * items ;
97
+ size_t nr , alloc ;
98
+ };
99
+ #define COMMIT_STACK_INIT { NULL, 0, 0 }
100
+
101
+ static void commit_stack_push (struct commit_stack * stack , struct commit * commit )
99
102
{
100
- struct commit_list * parents = NULL , * l ;
103
+ ALLOC_GROW (stack -> items , stack -> nr + 1 , stack -> alloc );
104
+ stack -> items [stack -> nr ++ ] = commit ;
105
+ }
101
106
102
- for (l = commit -> parents ; l ; l = l -> next )
103
- commit_list_insert (l -> item , & parents );
107
+ static struct commit * commit_stack_pop (struct commit_stack * stack )
108
+ {
109
+ return stack -> nr ? stack -> items [-- stack -> nr ] : NULL ;
110
+ }
104
111
105
- while (parents ) {
106
- struct commit * commit = pop_commit (& parents );
112
+ static void commit_stack_clear (struct commit_stack * stack )
113
+ {
114
+ FREE_AND_NULL (stack -> items );
115
+ stack -> nr = stack -> alloc = 0 ;
116
+ }
107
117
108
- while (commit ) {
109
- /*
110
- * A missing commit is ok iff its parent is marked
111
- * uninteresting.
112
- *
113
- * We just mark such a thing parsed, so that when
114
- * it is popped next time around, we won't be trying
115
- * to parse it and get an error.
116
- */
117
- if (!commit -> object .parsed &&
118
- !has_object_file (& commit -> object .oid ))
119
- commit -> object .parsed = 1 ;
118
+ static void mark_one_parent_uninteresting (struct commit * commit ,
119
+ struct commit_stack * pending )
120
+ {
121
+ struct commit_list * l ;
120
122
121
- if (commit -> object .flags & UNINTERESTING )
122
- break ;
123
+ if (commit -> object .flags & UNINTERESTING )
124
+ return ;
125
+ commit -> object .flags |= UNINTERESTING ;
126
+
127
+ /*
128
+ * Normally we haven't parsed the parent
129
+ * yet, so we won't have a parent of a parent
130
+ * here. However, it may turn out that we've
131
+ * reached this commit some other way (where it
132
+ * wasn't uninteresting), in which case we need
133
+ * to mark its parents recursively too..
134
+ */
135
+ for (l = commit -> parents ; l ; l = l -> next )
136
+ commit_stack_push (pending , l -> item );
137
+ }
123
138
124
- commit -> object .flags |= UNINTERESTING ;
139
+ void mark_parents_uninteresting (struct commit * commit )
140
+ {
141
+ struct commit_stack pending = COMMIT_STACK_INIT ;
142
+ struct commit_list * l ;
125
143
126
- /*
127
- * Normally we haven't parsed the parent
128
- * yet, so we won't have a parent of a parent
129
- * here. However, it may turn out that we've
130
- * reached this commit some other way (where it
131
- * wasn't uninteresting), in which case we need
132
- * to mark its parents recursively too..
133
- */
134
- if (!commit -> parents )
135
- break ;
144
+ for (l = commit -> parents ; l ; l = l -> next )
145
+ mark_one_parent_uninteresting (l -> item , & pending );
136
146
137
- for ( l = commit -> parents -> next ; l ; l = l -> next )
138
- commit_list_insert ( l -> item , & parents );
139
- commit = commit -> parents -> item ;
140
- }
141
- }
147
+ while ( pending . nr > 0 )
148
+ mark_one_parent_uninteresting ( commit_stack_pop ( & pending ),
149
+ & pending ) ;
150
+
151
+ commit_stack_clear ( & pending );
142
152
}
143
153
144
154
static void add_pending_object_with_path (struct rev_info * revs ,
0 commit comments