get_revision(): honor the topo_order flag for boundary commits
Now get_revision() sorts the boundary commits when topo_order is set. Since sort_in_topological_order() takes a struct commit_list, it first places the boundary commits into revs->commits. Signed-off-by: Adam Simpkins <adam@adamsimpkins.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Adam Simpkins committed
May 24, 2008 at 16:02 UTC
4603ec0f960e582a7da7241563d3f235ad7f0d3e
2 files changed
+58
-24
graph.c
+1
-8
@@ -195,16 +195,9 @@ static int graph_is_interesting(struct git_graph *graph, struct commit *commit)
195
* If revs->boundary is set, commits whose children have
196
* been shown are always interesting, even if they have the
197
* UNINTERESTING or TREESAME flags set.
198
- *
199
- * However, ignore the commit if SHOWN is set. If SHOWN is set,
200
- * the commit is interesting, but it has already been printed.
201
- * This can happen because get_revision() doesn't return the
202
- * boundary commits in topological order, even when
203
- * revs->topo_order is set.
198
*/
199
if (graph->revs && graph->revs->boundary) {
206
- if ((commit->object.flags & (SHOWN | CHILD_SHOWN)) ==
207
- CHILD_SHOWN)
200
+ if (commit->object.flags & CHILD_SHOWN)
201
return 1;
202
}
203
revision.c
+57
-16
@@ -1612,28 +1612,62 @@ static void gc_boundary(struct object_array *array)
1612
}
1613
}
1614
1615
+static void create_boundary_commit_list(struct rev_info *revs)
1616
+{
1617
+ unsigned i;
1618
+ struct commit *c;
1619
+ struct object_array *array = &revs->boundary_commits;
1620
+ struct object_array_entry *objects = array->objects;
1621
+
1622
+ /*
1623
+ * If revs->commits is non-NULL at this point, an error occurred in
1624
+ * get_revision_1(). Ignore the error and continue printing the
1625
+ * boundary commits anyway. (This is what the code has always
1626
+ * done.)
1627
+ */
1628
+ if (revs->commits) {
1629
+ free_commit_list(revs->commits);
1630
+ revs->commits = NULL;
1631
+ }
1632
+
1633
+ /*
1634
+ * Put all of the actual boundary commits from revs->boundary_commits
1635
+ * into revs->commits
1636
+ */
1637
+ for (i = 0; i < array->nr; i++) {
1638
+ c = (struct commit *)(objects[i].item);
1639
+ if (!c)
1640
+ continue;
1641
+ if (!(c->object.flags & CHILD_SHOWN))
1642
+ continue;
1643
+ if (c->object.flags & (SHOWN | BOUNDARY))
1644
+ continue;
1645
+ c->object.flags |= BOUNDARY;
1646
+ commit_list_insert(c, &revs->commits);
1647
+ }
1648
+
1649
+ /*
1650
+ * If revs->topo_order is set, sort the boundary commits
1651
+ * in topological order
1652
+ */
1653
+ sort_in_topological_order(&revs->commits, revs->lifo);
1654
+}
1655
+
1656
static struct commit *get_revision_internal(struct rev_info *revs)
1657
{
1658
struct commit *c = NULL;
1659
struct commit_list *l;
1660
1661
if (revs->boundary == 2) {
1621
- unsigned i;
1622
- struct object_array *array = &revs->boundary_commits;
1623
- struct object_array_entry *objects = array->objects;
1624
- for (i = 0; i < array->nr; i++) {
1625
- c = (struct commit *)(objects[i].item);
1626
- if (!c)
1627
- continue;
1628
- if (!(c->object.flags & CHILD_SHOWN))
1629
- continue;
1630
- if (!(c->object.flags & SHOWN))
1631
- break;
1632
- }
1633
- if (array->nr <= i)
1634
- return NULL;
1635
-
1636
- c->object.flags |= SHOWN | BOUNDARY;
1662
+ /*
1663
+ * All of the normal commits have already been returned,
1664
+ * and we are now returning boundary commits.
1665
+ * create_boundary_commit_list() has populated
1666
+ * revs->commits with the remaining commits to return.
1667
+ */
1668
+ c = pop_commit(&revs->commits);
1669
+ if (c)
1670
+ c->object.flags |= SHOWN;
1671
return c;
1672
}
1673
@@ -1697,6 +1731,13 @@ static struct commit *get_revision_internal(struct rev_info *revs)
1731
* switch to boundary commits output mode.
1732
*/
1733
revs->boundary = 2;
1734
+
1735
+ /*
1736
+ * Update revs->commits to contain the list of
1737
+ * boundary commits.
1738
+ */
1739
+ create_boundary_commit_list(revs);
1740
+
1741
return get_revision_internal(revs);
1742
}
1743