graph API: fix "git log --graph --first-parent"
This change teaches the graph API that only the first parent of each commit is interesting when "--first-parent" was specified. This change also consolidates the graph parent walking logic into two new internal functions, first_interesting_parent() and next_interesting_parent(). A simpler fix would have been to simply break at the end of the 2 existing for loops when graph->revs->first_parent_only is set. However, this change seems nicer, especially if we ever need to add any new loops over the parent list in the future. Signed-off-by: Adam Simpkins <adam@adamsimpkins.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Adam Simpkins committed
Jun 5, 2008 at 01:56 UTC
a0ebe573a516a1530a2c072e513fa7f529781dd0
1 file changed
+53
-11
graph.c
+53
-11
@@ -237,18 +237,58 @@ static int graph_is_interesting(struct git_graph *graph, struct commit *commit)
237
return (commit->object.flags & (UNINTERESTING | TREESAME)) ? 0 : 1;
238
}
239
240
+static struct commit_list *next_interesting_parent(struct git_graph *graph,
241
+ struct commit_list *orig)
242
+{
243
+ struct commit_list *list;
244
+
245
+ /*
246
+ * If revs->first_parent_only is set, only the first
247
+ * parent is interesting. None of the others are.
248
+ */
249
+ if (graph->revs->first_parent_only)
250
+ return NULL;
251
+
252
+ /*
253
+ * Return the next interesting commit after orig
254
+ */
255
+ for (list = orig->next; list; list = list->next) {
256
+ if (graph_is_interesting(graph, list->item))
257
+ return list;
258
+ }
259
+
260
+ return NULL;
261
+}
262
+
263
+static struct commit_list *first_interesting_parent(struct git_graph *graph)
264
+{
265
+ struct commit_list *parents = graph->commit->parents;
266
+
267
+ /*
268
+ * If this commit has no parents, ignore it
269
+ */
270
+ if (!parents)
271
+ return NULL;
272
+
273
+ /*
274
+ * If the first parent is interesting, return it
275
+ */
276
+ if (graph_is_interesting(graph, parents->item))
277
+ return parents;
278
+
279
+ /*
280
+ * Otherwise, call next_interesting_parent() to get
281
+ * the next interesting parent
282
+ */
283
+ return next_interesting_parent(graph, parents);
284
+}
285
+
286
static void graph_insert_into_new_columns(struct git_graph *graph,
287
struct commit *commit,
288
int *mapping_index)
289
{
290
int i;
291
246
- /*
247
- * Ignore uinteresting commits
248
- */
249
- if (!graph_is_interesting(graph, commit))
250
- return;
251
-
292
/*
293
* If the commit is already in the new_columns list, we don't need to
294
* add it. Just update the mapping correctly.
@@ -373,9 +413,9 @@ static void graph_update_columns(struct git_graph *graph)
413
int old_mapping_idx = mapping_idx;
414
seen_this = 1;
415
graph->commit_index = i;
376
- for (parent = graph->commit->parents;
416
+ for (parent = first_interesting_parent(graph);
417
parent;
378
- parent = parent->next) {
418
+ parent = next_interesting_parent(graph, parent)) {
419
graph_insert_into_new_columns(graph,
420
parent->item,
421
&mapping_idx);
@@ -420,9 +460,11 @@ void graph_update(struct git_graph *graph, struct commit *commit)
460
* Count how many interesting parents this commit has
461
*/
462
graph->num_parents = 0;
423
- for (parent = commit->parents; parent; parent = parent->next) {
424
- if (graph_is_interesting(graph, parent->item))
425
- graph->num_parents++;
463
+ for (parent = first_interesting_parent(graph);
464
+ parent;
465
+ parent = next_interesting_parent(graph, parent))
466
+ {
467
+ graph->num_parents++;
468
}
469
470
/*